diff --git a/CashPoint/.classpath b/CashPoint/.classpath
new file mode 100755
index 0000000..4160c21
--- /dev/null
+++ b/CashPoint/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/CashPoint/.project b/CashPoint/.project
new file mode 100755
index 0000000..ffa801c
--- /dev/null
+++ b/CashPoint/.project
@@ -0,0 +1,33 @@
+
+
+ CashPoint
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/CashPoint/.settings/org.eclipse.jdt.core.prefs b/CashPoint/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e5239a2
--- /dev/null
+++ b/CashPoint/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+#Sun Dec 25 14:05:34 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/CashPoint/AndroidManifest.xml b/CashPoint/AndroidManifest.xml
new file mode 100755
index 0000000..cb4a676
--- /dev/null
+++ b/CashPoint/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CashPoint/doc/allclasses-frame.html b/CashPoint/doc/allclasses-frame.html
new file mode 100644
index 0000000..7bbb686
--- /dev/null
+++ b/CashPoint/doc/allclasses-frame.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+All Classes
+
+
+
+
+All Classes
+
+
+
diff --git a/CashPoint/doc/allclasses-noframe.html b/CashPoint/doc/allclasses-noframe.html
new file mode 100644
index 0000000..4777392
--- /dev/null
+++ b/CashPoint/doc/allclasses-noframe.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+All Classes
+
+
+
+
+All Classes
+
+
+
diff --git a/CashPoint/doc/app/learn/CashPoint.html b/CashPoint/doc/app/learn/CashPoint.html
new file mode 100644
index 0000000..776aa4d
--- /dev/null
+++ b/CashPoint/doc/app/learn/CashPoint.html
@@ -0,0 +1,259 @@
+
+
+
+
+
+CashPoint
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+CashPoint ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+Methods
+
+Modifier and Type
+Method and Description
+
+
+void
+onCreate (Bundle savedInstanceState)
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+CashPoint
+public CashPoint()
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/DbAdapter.QueryEvaluator.html b/CashPoint/doc/app/learn/DbAdapter.QueryEvaluator.html
new file mode 100644
index 0000000..d56801b
--- /dev/null
+++ b/CashPoint/doc/app/learn/DbAdapter.QueryEvaluator.html
@@ -0,0 +1,214 @@
+
+
+
+
+
+DbAdapter.QueryEvaluator
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+Methods
+
+Modifier and Type
+Method and Description
+
+
+T
+evaluate (Cursor cursor,
+ T defaultResult,
+ java.lang.Object... params)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Summary:
+Nested |
+Field |
+Constr |
+Method
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/DbAdapter.html b/CashPoint/doc/app/learn/DbAdapter.html
new file mode 100644
index 0000000..332f9d3
--- /dev/null
+++ b/CashPoint/doc/app/learn/DbAdapter.html
@@ -0,0 +1,584 @@
+
+
+
+
+
+DbAdapter
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+SQLiteOpenHelper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Nested Class Summary
+
+
+
+
+
+
+
+
+Field Summary
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+DbAdapter (Context context)
+
+
+
+
+
+
+
+
+
+Method Summary
+
+Methods
+
+Modifier and Type
+Method and Description
+
+
+int
+addEntry (java.lang.String name,
+ double amount,
+ java.lang.String currency,
+ java.lang.String comment,
+ boolean expense)
+
+
+boolean
+allocate (boolean expense,
+ int entryId,
+ java.util.Map<java.lang.String,java.lang.Double> portions)
+
+
+void
+clear ()
+
+
+void
+drop (java.lang.String tableName)
+
+
+<T> T
+fetchEntry (int entryId,
+ DbAdapter.QueryEvaluator <T> qe,
+ T defaultResult,
+ java.lang.Object... params)
+
+
+java.lang.String
+fetchField (int entryId,
+ java.lang.String name)
+
+
+int
+getCount (java.lang.String clause)
+
+
+java.lang.Integer[]
+getEntryIds (java.lang.String clause)
+
+
+int
+getNewEntryId ()
+
+
+java.lang.Long[]
+getRowIds (java.lang.String clause)
+
+
+java.lang.String[]
+getSortedNames ()
+
+
+double
+getSum (java.lang.String clause)
+
+
+boolean
+isExpense (long rowId)
+
+
+void
+onCreate (SQLiteDatabase db)
+
+
+void
+onUpgrade (SQLiteDatabase db,
+ int oldVersion,
+ int newVersion)
+
+
+int
+removeEntry (int entryId)
+
+
+java.lang.String
+timestampNow ()
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+clear
+public void clear()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+addEntry
+public int addEntry(java.lang.String name,
+ double amount,
+ java.lang.String currency,
+ java.lang.String comment,
+ boolean expense)
+
+
+
+
+
+
+
+
+
+
+
+
+
+fetchEntry
+public <T> T fetchEntry(int entryId,
+ DbAdapter.QueryEvaluator <T> qe,
+ T defaultResult,
+ java.lang.Object... params)
+
+
+
+
+
+
+
+
+
+
+
+allocate
+public boolean allocate(boolean expense,
+ int entryId,
+ java.util.Map<java.lang.String,java.lang.Double> portions)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/R.attr.html b/CashPoint/doc/app/learn/R.attr.html
new file mode 100644
index 0000000..375706e
--- /dev/null
+++ b/CashPoint/doc/app/learn/R.attr.html
@@ -0,0 +1,230 @@
+
+
+
+
+
+R.attr
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+R.attr ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+R.attr
+public R.attr()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/R.drawable.html b/CashPoint/doc/app/learn/R.drawable.html
new file mode 100644
index 0000000..fed20cb
--- /dev/null
+++ b/CashPoint/doc/app/learn/R.drawable.html
@@ -0,0 +1,267 @@
+
+
+
+
+
+R.drawable
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Summary
+
+Fields
+
+Modifier and Type
+Field and Description
+
+
+static int
+icon
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+R.drawable ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Detail
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+R.drawable
+public R.drawable()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/R.html b/CashPoint/doc/app/learn/R.html
new file mode 100644
index 0000000..1488c10
--- /dev/null
+++ b/CashPoint/doc/app/learn/R.html
@@ -0,0 +1,261 @@
+
+
+
+
+
+R
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Nested Class Summary
+
+Nested Classes
+
+Modifier and Type
+Class and Description
+
+
+static class
+R.attr
+
+
+static class
+R.drawable
+
+
+static class
+R.id
+
+
+static class
+R.layout
+
+
+static class
+R.string
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+R ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Detail:
+Field |
+Constr |
+Method
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/R.id.html b/CashPoint/doc/app/learn/R.id.html
new file mode 100644
index 0000000..06c871e
--- /dev/null
+++ b/CashPoint/doc/app/learn/R.id.html
@@ -0,0 +1,309 @@
+
+
+
+
+
+R.id
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Summary
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+R.id ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+R.id
+public R.id()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/R.layout.html b/CashPoint/doc/app/learn/R.layout.html
new file mode 100644
index 0000000..93467c1
--- /dev/null
+++ b/CashPoint/doc/app/learn/R.layout.html
@@ -0,0 +1,281 @@
+
+
+
+
+
+R.layout
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Summary
+
+Fields
+
+Modifier and Type
+Field and Description
+
+
+static int
+main
+
+
+static int
+nameview
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+R.layout ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+R.layout
+public R.layout()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/R.string.html b/CashPoint/doc/app/learn/R.string.html
new file mode 100644
index 0000000..ccc8786
--- /dev/null
+++ b/CashPoint/doc/app/learn/R.string.html
@@ -0,0 +1,323 @@
+
+
+
+
+
+R.string
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Summary
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+R.string ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+R.string
+public R.string()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/ShareMap.html b/CashPoint/doc/app/learn/ShareMap.html
new file mode 100644
index 0000000..bb30f92
--- /dev/null
+++ b/CashPoint/doc/app/learn/ShareMap.html
@@ -0,0 +1,399 @@
+
+
+
+
+
+ShareMap
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+java.util.AbstractMap<K,V>
+
+
+java.util.TreeMap<java.lang.String,java.lang.Double>
+
+
+
+
+
+
+
+
+
+
+
+
+All Implemented Interfaces:
+java.io.Serializable, java.lang.Cloneable, java.util.Map<java.lang.String,java.lang.Double>, java.util.NavigableMap<java.lang.String,java.lang.Double>, java.util.SortedMap<java.lang.String,java.lang.Double>
+
+
+
+public class ShareMap
+extends java.util.TreeMap<java.lang.String,java.lang.Double>
+A map containing names as keys and sharing amounts as values
+See Also: Serialized Form
+
+
+
+
+
+
+
+
+
+
+
+Nested Class Summary
+
+
+
+
+Nested classes/interfaces inherited from class java.util.AbstractMap
+java.util.AbstractMap.SimpleEntry<K,V>, java.util.AbstractMap.SimpleImmutableEntry<K,V>
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+ShareMap (java.lang.String[] names,
+ java.lang.Double[] portions)
+creates a sorted map of deals for a number of participants.
+
+
+
+ShareMap (java.lang.String[] names,
+ double amount,
+ java.lang.Double... portions)
+creates a sorted map of shares for a number of sharers optionally allowing for fixed portions of any of the sharers
+ except the first one whom the remainder of the amount is assigned to in any case.
+
+
+
+ShareMap (java.lang.String[] names,
+ double amount,
+ java.lang.Integer[] proportions)
+creates a sorted map of shares for a number of sharers according to fixed proportions for any of the sharers
+ If no proportions are specified uniform sharing is assumed (amount divided by the number of sharers).
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+Methods
+
+Modifier and Type
+Method and Description
+
+
+void
+minus (java.util.Collection<java.lang.Double> vector)
+subtracts a vector from the values (vector) of this map
+
+
+
+ShareMap
+negated ()
+turns each value in the map to its negative
+
+
+
+double
+sum ()
+calculates the sum of all the values in the map
+
+
+
+
+
+
+
+Methods inherited from class java.util.TreeMap
+ceilingEntry, ceilingKey, clear, clone, comparator, containsKey, containsValue, descendingKeySet, descendingMap, entrySet, firstEntry, firstKey, floorEntry, floorKey, get, headMap, headMap, higherEntry, higherKey, keySet, lastEntry, lastKey, lowerEntry, lowerKey, navigableKeySet, pollFirstEntry, pollLastEntry, put, putAll, remove, size, subMap, subMap, tailMap, tailMap, values
+
+
+
+
+
+Methods inherited from class java.util.AbstractMap
+equals, hashCode, isEmpty, toString
+
+
+
+
+
+Methods inherited from class java.lang.Object
+getClass, notify, notifyAll, wait, wait, wait
+
+
+
+
+
+Methods inherited from interface java.util.Map
+equals, hashCode, isEmpty
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+ShareMap
+public ShareMap(java.lang.String[] names,
+ java.lang.Double[] portions)
+creates a sorted map of deals for a number of participants.
+ A portion is assigned to the name in the corresponding spot.
+ If the portion of an participant appears as null value the corresponding name is ignored in the map.
+Parameters: names - the array of names of the dealers (not necessarily sorted)portions - given deals, if any, for individual participants according to the order of the names
+
+
+
+
+
+
+
+ShareMap
+public ShareMap(java.lang.String[] names,
+ double amount,
+ java.lang.Integer[] proportions)
+creates a sorted map of shares for a number of sharers according to fixed proportions for any of the sharers
+ If no proportions are specified uniform sharing is assumed (amount divided by the number of sharers).
+Parameters: names - the array of names of the sharers (not necessarily sorted)amount - the value of the amount to shareproportions - given proportions for the sharers according to the order of the names
+
+
+
+
+
+
+
+ShareMap
+public ShareMap(java.lang.String[] names,
+ double amount,
+ java.lang.Double... portions)
+creates a sorted map of shares for a number of sharers optionally allowing for fixed portions of any of the sharers
+ except the first one whom the remainder of the amount is assigned to in any case.
+ If no portion is specified for an individual sharer an uniformly shared portion is assumed (amount divided by the number of sharers).
+ If the portion of an individual sharer appears as null value the corresponding name is ignored in the map.
+ The values in the resulting map are the negated portions of the amount so that their sum equals the negative value of the amount.
+Parameters: names - the array of names of the sharers (not necessarily sorted)amount - the value of the amount to shareportions - given portions, if any, for individual sharers according to the order of the names
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/Transactor.ShareMap.html b/CashPoint/doc/app/learn/Transactor.ShareMap.html
new file mode 100644
index 0000000..61f2cc0
--- /dev/null
+++ b/CashPoint/doc/app/learn/Transactor.ShareMap.html
@@ -0,0 +1,364 @@
+
+
+
+
+
+Transactor.ShareMap
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+java.util.AbstractMap<K,V>
+
+
+java.util.TreeMap<java.lang.String,java.lang.Number>
+
+
+app.learn.Transactor.ShareMap
+
+
+
+
+
+
+
+
+
+
+
+All Implemented Interfaces:
+java.io.Serializable, java.lang.Cloneable, java.util.Map<java.lang.String,java.lang.Number>, java.util.NavigableMap<java.lang.String,java.lang.Number>, java.util.SortedMap<java.lang.String,java.lang.Number>
+
+
+Enclosing class:
+Transactor
+
+
+
+public static class Transactor.ShareMap
+extends java.util.TreeMap<java.lang.String,java.lang.Number>
+A map containing names as keys and sharing amounts as values
+See Also: Serialized Form
+
+
+
+
+
+
+
+
+
+
+
+Nested Class Summary
+
+
+
+
+Nested classes/interfaces inherited from class java.util.AbstractMap
+java.util.AbstractMap.SimpleEntry<K,V>, java.util.AbstractMap.SimpleImmutableEntry<K,V>
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Transactor.ShareMap (java.lang.String[] names,
+ java.lang.Float[] portions)
+creates a sorted map of deals for a number of individuals.
+
+
+
+Transactor.ShareMap (java.lang.String[] names,
+ float amount,
+ java.lang.Float... portions)
+creates a sorted map of shares for a number of sharers optionally allowing for fixed portions of any of the sharers
+ except the first one whom the remainder of the amount is assigned to in any case.
+
+
+
+
+
+
+
+
+
+
+Method Summary
+
+Methods
+
+Modifier and Type
+Method and Description
+
+
+Transactor.ShareMap
+negated ()
+turns each value in the map to its negative
+
+
+
+float
+sum ()
+calculates the sum of all the values in the map
+
+
+
+
+
+
+
+Methods inherited from class java.util.TreeMap
+ceilingEntry, ceilingKey, clear, clone, comparator, containsKey, containsValue, descendingKeySet, descendingMap, entrySet, firstEntry, firstKey, floorEntry, floorKey, get, headMap, headMap, higherEntry, higherKey, keySet, lastEntry, lastKey, lowerEntry, lowerKey, navigableKeySet, pollFirstEntry, pollLastEntry, put, putAll, remove, size, subMap, subMap, tailMap, tailMap, values
+
+
+
+
+
+Methods inherited from class java.util.AbstractMap
+equals, hashCode, isEmpty, toString
+
+
+
+
+
+Methods inherited from class java.lang.Object
+getClass, notify, notifyAll, wait, wait, wait
+
+
+
+
+
+Methods inherited from interface java.util.Map
+equals, hashCode, isEmpty
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Transactor.ShareMap
+public Transactor.ShareMap(java.lang.String[] names,
+ java.lang.Float[] portions)
+creates a sorted map of deals for a number of individuals.
+ A portion is assigned to the name in the corresponding spot.
+ If the portion of an individual appears as null value the corresponding name is ignored in the map.
+Parameters: names - the array of names of the dealers (not necessarily sorted)portions - given deals, if any, for individuals according to the order of the names
+
+
+
+
+
+
+
+Transactor.ShareMap
+public Transactor.ShareMap(java.lang.String[] names,
+ float amount,
+ java.lang.Float... portions)
+creates a sorted map of shares for a number of sharers optionally allowing for fixed portions of any of the sharers
+ except the first one whom the remainder of the amount is assigned to in any case.
+ If no portion is given for an individual sharer an equally shared portion is assumed (amount divided by the number of sharers).
+ If the portion of an individual sharer appears as null value the corresponding name is ignored in the map.
+ The values in the resulting map are the negated portions of the amount so that their sum equals the negative value of the amount.
+Parameters: names - the array of names of the sharers (not necessarily sorted)amount - the value of the amount to shareportions - given portions, if any, for individual sharers according to the order of the names
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/Transactor.html b/CashPoint/doc/app/learn/Transactor.html
new file mode 100644
index 0000000..38aafc4
--- /dev/null
+++ b/CashPoint/doc/app/learn/Transactor.html
@@ -0,0 +1,721 @@
+
+
+
+
+
+Transactor
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+SQLiteOpenHelper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Nested Class Summary
+
+
+
+
+
+
+
+
+Field Summary
+
+Fields
+
+Modifier and Type
+Field and Description
+
+
+static double
+minAmount
+no discussion about that amount
+
+
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Transactor (Context context)
+
+
+
+
+
+
+
+
+
+Method Summary
+
+Methods
+
+Modifier and Type
+Method and Description
+
+
+ShareMap
+balances ()
+calculates the balances of all participants identified by their names
+
+
+
+ShareMap
+cashFlow ()
+calculates the cash flows caused by the participants
+
+
+
+void
+clear ()
+deletes all records from the current table and recreates it
+
+
+
+void
+clearAll ()
+clears the current table and drops all saved tables
+
+
+
+ShareMap
+compensations ()
+calculates a compensation for each participant from the balance and the all-over cash flow at this point.
+
+
+
+double
+expenses ()
+calculates the accumulated costs
+
+
+
+java.lang.String
+getCurrency ()
+
+
+java.lang.Integer[]
+getSharingPolicy ()
+A sharing policy depicts the way the volume of all the cash flows is to be shared among the participants
+ when it comes to calculating compensations.
+
+
+
+boolean
+loadFrom (java.lang.String oldSuffix)
+restores one of the saved tables as the current table.
+
+
+
+int
+performComplexExpense (ShareMap deals,
+ java.lang.String comment,
+ ShareMap shares)
+The transaction registers the negated sum of the shares as an expense by a group of contributors.
+
+
+
+int
+performDiscard (int entryId)
+The transaction discards any record with that entry id.
+
+
+
+int
+performExpense (java.lang.String submitter,
+ java.lang.String comment,
+ ShareMap shares)
+The transaction registers the negated sum of the shares with the submitter.
+
+
+
+int
+performMultiple (ShareMap shares,
+ java.lang.String comment)
+The transaction registers multiple submissions.
+
+
+
+int
+performSubmission (java.lang.String submitter,
+ double amount,
+ java.lang.String comment)
+The transaction registers the amount as a contribution (positive) or a retrieval (negative).
+
+
+
+int
+performTransfer (java.lang.String sender,
+ double amount,
+ java.lang.String comment,
+ java.lang.String recipient)
+The transaction performs a transfer of the amount from a submitter to a recipient.
+
+
+
+boolean
+saveAs (java.lang.String newSuffix)
+changes the name of the table that has been worked on via transactions (current table).
+
+
+
+java.util.Set<java.lang.String>
+savedTables ()
+retrieves the names of tables that had been 'saved' in the past
+
+
+
+void
+setCurrency (java.lang.String currency)
+
+
+void
+setSharingPolicy (java.lang.Integer[] sharingPolicy)
+sets the sharing policy.
+
+
+
+java.lang.String
+tableName (java.lang.String suffix)
+
+
+double
+total ()
+calculates the current over-all amount
+
+
+
+
+
+
+
+Methods inherited from class app.learn.DbAdapter
+addEntry , allocate , drop , fetchEntry , fetchField , getCount , getEntryIds , getNewEntryId , getRowIds , getSortedNames , getSum , isExpense , onCreate , onUpgrade , removeEntry , timestampNow
+
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Detail
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+
+
+
+
+
+
+Method Detail
+
+
+
+
+
+performExpense
+public int performExpense(java.lang.String submitter,
+ java.lang.String comment,
+ ShareMap shares)
+The transaction registers the negated sum of the shares with the submitter.
+ Additionally all the shares in the map are registered with the same entry id.
+ This transaction does not change the total. It registers an allocation of a certain amount.
+ If submitter is an empty String it means there is an internal reallocation which is not an expense.
+ Such an internal reallocation is not allowed if the transaction causes a negative total.
+Parameters: submitter - the name of the participant who expended an amount matching the negated sum of the sharescomment - a String to make the transaction recognizableshares - a ShareMap containing the shares of participants involved
+Returns: the entry id of the transaction or -1 in case the transaction failed or -2 if the transaction violates the 'no negative total' rule
+
+
+
+
+
+
+
+performComplexExpense
+public int performComplexExpense(ShareMap deals,
+ java.lang.String comment,
+ ShareMap shares)
+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 String trigger transfers of internal amounts.
+ Such an internal transfer is not allowed if the transaction causes a negative total.
+Parameters: deals - the names of the contributors and their contributions who expended an amount matching the negated sum of the dealscomment - a String to make the transaction recognizableshares - a ShareMap containing the shares of participants involved
+Returns: the entry id of the transaction or a negative value in case the transaction failed
+
+
+
+
+
+
+
+performTransfer
+public int performTransfer(java.lang.String sender,
+ double amount,
+ java.lang.String comment,
+ java.lang.String recipient)
+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.
+Parameters: sender - the name of the participant who lost the amountamount - the amount of the transfercomment - a String to make the transaction recognizablerecipient - the name of the participant who got the amount
+Returns: the entry id of the transaction or -1 in case the transaction failed or -2 if the transaction violates the 'no negative total' rule
+
+
+
+
+
+
+
+performSubmission
+public int performSubmission(java.lang.String submitter,
+ double amount,
+ java.lang.String comment)
+The transaction registers the amount as a contribution (positive) or a retrieval (negative).
+ A retrieval is not allowed if it surmounts the current total.
+Parameters: submitter - the name of the participant who did the submissionamount - the amount of the submissioncomment - a String to make the transaction recognizable
+Returns: the entry id of the transaction or -1 in case the transaction failed or -2 if the transaction violates the 'no negative total' rule
+
+
+
+
+
+
+
+performMultiple
+public int performMultiple(ShareMap shares,
+ java.lang.String comment)
+The transaction registers multiple submissions.
+ This transaction as a whole is not allowed if it causes a negative total.
+Parameters: shares - a ShareMap containing the shares of participants involvedcomment - a String to make the transactions recognizable
+Returns: 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+getSharingPolicy
+public java.lang.Integer[] getSharingPolicy()
+A sharing policy depicts the way the volume of all the cash flows is to be shared among the participants
+ when it comes to calculating compensations. The given integers are proportional weights for those participants
+ who are involved in the compensation procedure. They are read according to the sorted list of names.
+Returns: an array containing integer values or empty meaning the default sharing policy (uniform sharing among all participants)
+
+
+
+
+
+
+
+setSharingPolicy
+public void setSharingPolicy(java.lang.Integer[] sharingPolicy)
+sets the sharing policy.
+ Note that a call of clear or clearAll
+ resets the sharing policy to its default (uniform sharing among all participants).
+Parameters: sharingPolicy -
+
+
+
+
+
+
+
+compensations
+public ShareMap compensations()
+calculates a compensation for each participant from the balance and the all-over cash flow at this point.
+ The sharing policy is taken into account for this calculation.
+ An example: A sharing policy 1:2:3 splits the volume of all the cash flows minus the current total
+ which is the remaining amount among the first, second and third participants out of the sorted list of names.
+ The first portion is 1/6, the second 2/6 and the third is 3/6 of the volume.
+Returns: a sorted map containing the names as keys and the compensations as values
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+saveAs
+public boolean saveAs(java.lang.String newSuffix)
+changes the name of the table that has been worked on via transactions (current table).
+ Thus this table is 'saved' in the same database. Note that the current table is non-existing after this operation.
+ In order to continue the current table has to be restored (loadFrom) or recreated (clear).
+Parameters: newSuffix - the String to append to the name of the current table in order to form the new table name
+Returns: success if true
+
+
+
+
+
+
+
+loadFrom
+public boolean loadFrom(java.lang.String oldSuffix)
+restores one of the saved tables as the current table. Note that the table that was current up to this point will be dropped.
+ Also there will be one less 'saved' table after this operation.
+Parameters: oldSuffix - the String to append to the name of the current table in order to form the old table name
+Returns: success if true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/Util.html b/CashPoint/doc/app/learn/Util.html
new file mode 100644
index 0000000..e75e145
--- /dev/null
+++ b/CashPoint/doc/app/learn/Util.html
@@ -0,0 +1,361 @@
+
+
+
+
+
+Util
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+java.lang.Object
+
+
+
+
+
+
+
+
+
+
+
+
+
+Field Summary
+
+Fields
+
+Modifier and Type
+Field and Description
+
+
+static double
+delta
+
+
+static java.text.SimpleDateFormat
+timestampFormat
+
+
+
+
+
+
+
+
+
+Constructor Summary
+
+Constructors
+
+Constructor and Description
+
+
+Util ()
+
+
+
+
+
+
+
+
+
+Method Summary
+
+Methods
+
+Modifier and Type
+Method and Description
+
+
+static java.lang.String
+formatAmount (double value)
+
+
+static <T> boolean
+isAvailable (int i,
+ T[] array)
+
+
+static <T> boolean
+isNullOrEmpty (T[] array)
+
+
+static boolean
+notNullOrEmpty (java.lang.String value)
+
+
+static java.lang.String
+timestamp (java.util.Date date)
+
+
+
+
+
+
+Methods inherited from class java.lang.Object
+equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Constructor Detail
+
+
+
+
+
+Util
+public Util()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/CashPoint.html b/CashPoint/doc/app/learn/class-use/CashPoint.html
new file mode 100644
index 0000000..0e29c03
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/CashPoint.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.CashPoint
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.CashPoint
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/DbAdapter.QueryEvaluator.html b/CashPoint/doc/app/learn/class-use/DbAdapter.QueryEvaluator.html
new file mode 100644
index 0000000..8aca296
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/DbAdapter.QueryEvaluator.html
@@ -0,0 +1,141 @@
+
+
+
+
+
+Uses of Interface app.learn.DbAdapter.QueryEvaluator
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/DbAdapter.html b/CashPoint/doc/app/learn/class-use/DbAdapter.html
new file mode 100644
index 0000000..389651b
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/DbAdapter.html
@@ -0,0 +1,140 @@
+
+
+
+
+
+Uses of Class app.learn.DbAdapter
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Subclasses of DbAdapter in app.learn
+
+Modifier and Type
+Class and Description
+
+
+
+class
+Transactor
+A class containing transactions and evaluation tools for a cost sharing system
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/R.attr.html b/CashPoint/doc/app/learn/class-use/R.attr.html
new file mode 100644
index 0000000..7bd226a
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/R.attr.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.R.attr
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.R.attr
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/R.drawable.html b/CashPoint/doc/app/learn/class-use/R.drawable.html
new file mode 100644
index 0000000..27df42d
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/R.drawable.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.R.drawable
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.R.drawable
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/R.html b/CashPoint/doc/app/learn/class-use/R.html
new file mode 100644
index 0000000..87797c6
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/R.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.R
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.R
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/R.id.html b/CashPoint/doc/app/learn/class-use/R.id.html
new file mode 100644
index 0000000..7ec0f6e
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/R.id.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.R.id
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.R.id
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/R.layout.html b/CashPoint/doc/app/learn/class-use/R.layout.html
new file mode 100644
index 0000000..95e5752
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/R.layout.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.R.layout
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.R.layout
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/R.string.html b/CashPoint/doc/app/learn/class-use/R.string.html
new file mode 100644
index 0000000..06b9656
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/R.string.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.R.string
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.R.string
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/ShareMap.html b/CashPoint/doc/app/learn/class-use/ShareMap.html
new file mode 100644
index 0000000..c5953aa
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/ShareMap.html
@@ -0,0 +1,190 @@
+
+
+
+
+
+Uses of Class app.learn.ShareMap
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Methods in app.learn that return ShareMap
+
+Modifier and Type
+Method and Description
+
+
+
+ShareMap
+Transactor. balances ()
+calculates the balances of all participants identified by their names
+
+
+
+ShareMap
+Transactor. cashFlow ()
+calculates the cash flows caused by the participants
+
+
+
+ShareMap
+Transactor. compensations ()
+calculates a compensation for each participant from the balance and the all-over cash flow at this point.
+
+
+
+ShareMap
+ShareMap. negated ()
+turns each value in the map to its negative
+
+
+
+
+
+Methods in app.learn with parameters of type ShareMap
+
+Modifier and Type
+Method and Description
+
+
+
+int
+Transactor. performComplexExpense (ShareMap deals,
+ java.lang.String comment,
+ ShareMap shares)
+The transaction registers the negated sum of the shares as an expense by a group of contributors.
+
+
+
+int
+Transactor. performExpense (java.lang.String submitter,
+ java.lang.String comment,
+ ShareMap shares)
+The transaction registers the negated sum of the shares with the submitter.
+
+
+
+int
+Transactor. performMultiple (ShareMap shares,
+ java.lang.String comment)
+The transaction registers multiple submissions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/Transactor.ShareMap.html b/CashPoint/doc/app/learn/class-use/Transactor.ShareMap.html
new file mode 100644
index 0000000..38e7e73
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/Transactor.ShareMap.html
@@ -0,0 +1,178 @@
+
+
+
+
+
+Uses of Class app.learn.Transactor.ShareMap
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/Transactor.html b/CashPoint/doc/app/learn/class-use/Transactor.html
new file mode 100644
index 0000000..ea67d4b
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/Transactor.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.Transactor
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.Transactor
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/class-use/Util.html b/CashPoint/doc/app/learn/class-use/Util.html
new file mode 100644
index 0000000..ccbd178
--- /dev/null
+++ b/CashPoint/doc/app/learn/class-use/Util.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Uses of Class app.learn.Util
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+No usage of app.learn.Util
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/package-frame.html b/CashPoint/doc/app/learn/package-frame.html
new file mode 100644
index 0000000..bd5e91c
--- /dev/null
+++ b/CashPoint/doc/app/learn/package-frame.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+app.learn
+
+
+
+
+
+
+
Interfaces
+
+
Classes
+
+
+
+
diff --git a/CashPoint/doc/app/learn/package-summary.html b/CashPoint/doc/app/learn/package-summary.html
new file mode 100644
index 0000000..6316f48
--- /dev/null
+++ b/CashPoint/doc/app/learn/package-summary.html
@@ -0,0 +1,192 @@
+
+
+
+
+
+app.learn
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+Prev Package
+Next Package
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Class Summary
+
+Class
+Description
+
+
+
+CashPoint
+
+
+
+DbAdapter
+
+facilitates database access for a cost sharing system
+
+
+
+R
+
+
+
+R.attr
+
+
+
+R.drawable
+
+
+
+R.id
+
+
+
+R.layout
+
+
+
+R.string
+
+
+
+ShareMap
+
+A map containing names as keys and sharing amounts as values
+
+
+
+Transactor
+
+A class containing transactions and evaluation tools for a cost sharing system
+
+
+
+Util
+
+
+
+
+
+
+
+
+
+
+
+Prev Package
+Next Package
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/package-tree.html b/CashPoint/doc/app/learn/package-tree.html
new file mode 100644
index 0000000..52f7b70
--- /dev/null
+++ b/CashPoint/doc/app/learn/package-tree.html
@@ -0,0 +1,155 @@
+
+
+
+
+
+app.learn Class Hierarchy
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
Class Hierarchy
+
+java.lang.Object
+
+java.util.AbstractMap<K,V> (implements java.util.Map<K,V>)
+
+java.util.TreeMap<K,V> (implements java.lang.Cloneable, java.util.NavigableMap<K,V>, java.io.Serializable)
+
+
+
+
+Activity
+
+
+app.learn.R
+app.learn.R.attr
+app.learn.R.drawable
+app.learn.R.id
+app.learn.R.layout
+app.learn.R.string
+SQLiteOpenHelper
+
+
+app.learn.Util
+
+
+
+
Interface Hierarchy
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/app/learn/package-use.html b/CashPoint/doc/app/learn/package-use.html
new file mode 100644
index 0000000..9d2a727
--- /dev/null
+++ b/CashPoint/doc/app/learn/package-use.html
@@ -0,0 +1,141 @@
+
+
+
+
+
+Uses of Package app.learn
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/constant-values.html b/CashPoint/doc/constant-values.html
new file mode 100644
index 0000000..ffa17c6
--- /dev/null
+++ b/CashPoint/doc/constant-values.html
@@ -0,0 +1,288 @@
+
+
+
+
+
+Constant Field Values
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
app.learn.*
+
+
+
+
+
+
+app.learn.R.drawable
+
+Modifier and Type
+Constant Field
+Value
+
+
+
+
+
+ public static final int
+icon
+2130837504
+
+
+
+
+
+
+app.learn.R.id
+
+Modifier and Type
+Constant Field
+Value
+
+
+
+
+
+ public static final int
+exportButton
+2131034112
+
+
+
+
+ public static final int
+importButton
+2131034113
+
+
+
+
+ public static final int
+nameLabel
+2131034114
+
+
+
+
+ public static final int
+nameView
+2131034115
+
+
+
+
+
+
+app.learn.R.layout
+
+Modifier and Type
+Constant Field
+Value
+
+
+
+
+
+ public static final int
+main
+2130903040
+
+
+
+
+ public static final int
+nameview
+2130903041
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/deprecated-list.html b/CashPoint/doc/deprecated-list.html
new file mode 100644
index 0000000..3044d5f
--- /dev/null
+++ b/CashPoint/doc/deprecated-list.html
@@ -0,0 +1,113 @@
+
+
+
+
+
+Deprecated List
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/help-doc.html b/CashPoint/doc/help-doc.html
new file mode 100644
index 0000000..52febf1
--- /dev/null
+++ b/CashPoint/doc/help-doc.html
@@ -0,0 +1,214 @@
+
+
+
+
+
+API Help
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+Package
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+Interfaces (italic)
+Classes
+Enums
+Exceptions
+Errors
+Annotation Types
+
+
+
+Class/Interface
+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+Class inheritance diagram
+Direct Subclasses
+All Known Subinterfaces
+All Known Implementing Classes
+Class/interface declaration
+Class/interface description
+
+
+Nested Class Summary
+Field Summary
+Constructor Summary
+Method Summary
+
+
+Field Detail
+Constructor Detail
+Method Detail
+
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+Annotation Type
+Each annotation type has its own separate page with the following sections:
+
+Annotation Type declaration
+Annotation Type description
+Required Element Summary
+Optional Element Summary
+Element Detail
+
+
+
+Enum
+Each enum has its own separate page with the following sections:
+
+Enum declaration
+Enum description
+Enum Constant Summary
+Enum Constant Detail
+
+
+
+Use
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+
+
+Tree (Class Hierarchy)
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+Deprecated API
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+Index
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+Prev/Next
+These links take you to the next or previous class, interface, package, or related page.
+
+
+Frames/No Frames
+These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+All Classes
+The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+Serialized Form
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+
+
+Constant Field Values
+The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.
+
+
+
This help file applies to API documentation generated using the standard doclet.
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-1.html b/CashPoint/doc/index-files/index-1.html
new file mode 100644
index 0000000..2e182d5
--- /dev/null
+++ b/CashPoint/doc/index-files/index-1.html
@@ -0,0 +1,124 @@
+
+
+
+
+
+A-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
A
+
+addEntry(String, double, String, String, boolean) - Method in class app.learn.DbAdapter
+
+allocate(boolean, int, Map<String, Double>) - Method in class app.learn.DbAdapter
+
+app.learn - package app.learn
+
+app_name - Static variable in class app.learn.R.string
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-10.html b/CashPoint/doc/index-files/index-10.html
new file mode 100644
index 0000000..8c57414
--- /dev/null
+++ b/CashPoint/doc/index-files/index-10.html
@@ -0,0 +1,120 @@
+
+
+
+
+
+L-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
L
+
+loadFrom(String) - Method in class app.learn.Transactor
+
+restores one of the saved tables as the current table.
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-11.html b/CashPoint/doc/index-files/index-11.html
new file mode 100644
index 0000000..bca399d
--- /dev/null
+++ b/CashPoint/doc/index-files/index-11.html
@@ -0,0 +1,126 @@
+
+
+
+
+
+M-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
M
+
+main - Static variable in class app.learn.R.layout
+
+minAmount - Static variable in class app.learn.Transactor
+
+no discussion about that amount
+
+minus(Collection<Double>) - Method in class app.learn.ShareMap
+
+subtracts a vector from the values (vector) of this map
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-12.html b/CashPoint/doc/index-files/index-12.html
new file mode 100644
index 0000000..05fa130
--- /dev/null
+++ b/CashPoint/doc/index-files/index-12.html
@@ -0,0 +1,130 @@
+
+
+
+
+
+N-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
N
+
+nameLabel - Static variable in class app.learn.R.id
+
+nameLabelText - Static variable in class app.learn.R.string
+
+nameView - Static variable in class app.learn.R.id
+
+nameview - Static variable in class app.learn.R.layout
+
+negated() - Method in class app.learn.ShareMap
+
+turns each value in the map to its negative
+
+notNullOrEmpty(String) - Static method in class app.learn.Util
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-13.html b/CashPoint/doc/index-files/index-13.html
new file mode 100644
index 0000000..470db2b
--- /dev/null
+++ b/CashPoint/doc/index-files/index-13.html
@@ -0,0 +1,122 @@
+
+
+
+
+
+O-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
O
+
+onCreate(Bundle) - Method in class app.learn.CashPoint
+
+onCreate(SQLiteDatabase) - Method in class app.learn.DbAdapter
+
+onUpgrade(SQLiteDatabase, int, int) - Method in class app.learn.DbAdapter
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-14.html b/CashPoint/doc/index-files/index-14.html
new file mode 100644
index 0000000..117fcec
--- /dev/null
+++ b/CashPoint/doc/index-files/index-14.html
@@ -0,0 +1,140 @@
+
+
+
+
+
+P-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
P
+
+performComplexExpense(ShareMap, String, ShareMap) - Method in class app.learn.Transactor
+
+The transaction registers the negated sum of the shares as an expense by a group of contributors.
+
+performDiscard(int) - Method in class app.learn.Transactor
+
+The transaction discards any record with that entry id.
+
+performExpense(String, String, ShareMap) - Method in class app.learn.Transactor
+
+The transaction registers the negated sum of the shares with the submitter.
+
+performMultiple(ShareMap, String) - Method in class app.learn.Transactor
+
+The transaction registers multiple submissions.
+
+performSubmission(String, double, String) - Method in class app.learn.Transactor
+
+The transaction registers the amount as a contribution (positive) or a retrieval (negative).
+
+performTransfer(String, double, String, String) - Method in class app.learn.Transactor
+
+The transaction performs a transfer of the amount from a submitter to a recipient.
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-15.html b/CashPoint/doc/index-files/index-15.html
new file mode 100644
index 0000000..9791f42
--- /dev/null
+++ b/CashPoint/doc/index-files/index-15.html
@@ -0,0 +1,142 @@
+
+
+
+
+
+R-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
R
+
+R - Class in app.learn
+
+R() - Constructor for class app.learn.R
+
+R.attr - Class in app.learn
+
+R.attr() - Constructor for class app.learn.R.attr
+
+R.drawable - Class in app.learn
+
+R.drawable() - Constructor for class app.learn.R.drawable
+
+R.id - Class in app.learn
+
+R.id() - Constructor for class app.learn.R.id
+
+R.layout - Class in app.learn
+
+R.layout() - Constructor for class app.learn.R.layout
+
+R.string - Class in app.learn
+
+R.string() - Constructor for class app.learn.R.string
+
+removeEntry(int) - Method in class app.learn.DbAdapter
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-16.html b/CashPoint/doc/index-files/index-16.html
new file mode 100644
index 0000000..7b0e61a
--- /dev/null
+++ b/CashPoint/doc/index-files/index-16.html
@@ -0,0 +1,152 @@
+
+
+
+
+
+S-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
S
+
+saveAs(String) - Method in class app.learn.Transactor
+
+changes the name of the table that has been worked on via transactions (current table).
+
+savedTables() - Method in class app.learn.Transactor
+
+retrieves the names of tables that had been 'saved' in the past
+
+setCurrency(String) - Method in class app.learn.Transactor
+
+setSharingPolicy(Integer[]) - Method in class app.learn.Transactor
+
+sets the sharing policy.
+
+ShareMap - Class in app.learn
+
+A map containing names as keys and sharing amounts as values
+
+ShareMap(String[], Double[]) - Constructor for class app.learn.ShareMap
+
+creates a sorted map of deals for a number of participants.
+
+ShareMap(String[], double, Integer[]) - Constructor for class app.learn.ShareMap
+
+creates a sorted map of shares for a number of sharers according to fixed proportions for any of the sharers
+ If no proportions are specified uniform sharing is assumed (amount divided by the number of sharers).
+
+ShareMap(String[], double, Double...) - Constructor for class app.learn.ShareMap
+
+creates a sorted map of shares for a number of sharers optionally allowing for fixed portions of any of the sharers
+ except the first one whom the remainder of the amount is assigned to in any case.
+
+sum() - Method in class app.learn.ShareMap
+
+calculates the sum of all the values in the map
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-17.html b/CashPoint/doc/index-files/index-17.html
new file mode 100644
index 0000000..000167f
--- /dev/null
+++ b/CashPoint/doc/index-files/index-17.html
@@ -0,0 +1,134 @@
+
+
+
+
+
+T-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
T
+
+tableName(String) - Method in class app.learn.Transactor
+
+timestamp(Date) - Static method in class app.learn.Util
+
+timestampFormat - Static variable in class app.learn.Util
+
+timestampNow() - Method in class app.learn.DbAdapter
+
+total() - Method in class app.learn.Transactor
+
+calculates the current over-all amount
+
+Transactor - Class in app.learn
+
+A class containing transactions and evaluation tools for a cost sharing system
+
+Transactor(Context) - Constructor for class app.learn.Transactor
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-18.html b/CashPoint/doc/index-files/index-18.html
new file mode 100644
index 0000000..8823aa3
--- /dev/null
+++ b/CashPoint/doc/index-files/index-18.html
@@ -0,0 +1,120 @@
+
+
+
+
+
+U-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
U
+
+Util - Class in app.learn
+
+Util() - Constructor for class app.learn.Util
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-2.html b/CashPoint/doc/index-files/index-2.html
new file mode 100644
index 0000000..7fbb788
--- /dev/null
+++ b/CashPoint/doc/index-files/index-2.html
@@ -0,0 +1,120 @@
+
+
+
+
+
+B-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
B
+
+balances() - Method in class app.learn.Transactor
+
+calculates the balances of all participants identified by their names
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-3.html b/CashPoint/doc/index-files/index-3.html
new file mode 100644
index 0000000..034dc05
--- /dev/null
+++ b/CashPoint/doc/index-files/index-3.html
@@ -0,0 +1,138 @@
+
+
+
+
+
+C-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
C
+
+cashFlow() - Method in class app.learn.Transactor
+
+calculates the cash flows caused by the participants
+
+CashPoint - Class in app.learn
+
+CashPoint() - Constructor for class app.learn.CashPoint
+
+clear() - Method in class app.learn.DbAdapter
+
+clear() - Method in class app.learn.Transactor
+
+deletes all records from the current table and recreates it
+
+clearAll() - Method in class app.learn.Transactor
+
+clears the current table and drops all saved tables
+
+compensations() - Method in class app.learn.Transactor
+
+calculates a compensation for each participant from the balance and the all-over cash flow at this point.
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-4.html b/CashPoint/doc/index-files/index-4.html
new file mode 100644
index 0000000..f79341d
--- /dev/null
+++ b/CashPoint/doc/index-files/index-4.html
@@ -0,0 +1,134 @@
+
+
+
+
+
+D-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
D
+
+DATABASE_NAME - Static variable in class app.learn.DbAdapter
+
+DATABASE_TABLE - Static variable in class app.learn.DbAdapter
+
+DATABASE_VERSION - Static variable in class app.learn.DbAdapter
+
+DbAdapter - Class in app.learn
+
+facilitates database access for a cost sharing system
+
+DbAdapter(Context) - Constructor for class app.learn.DbAdapter
+
+DbAdapter.QueryEvaluator <T > - Interface in app.learn
+
+delta - Static variable in class app.learn.Util
+
+drop(String) - Method in class app.learn.DbAdapter
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-5.html b/CashPoint/doc/index-files/index-5.html
new file mode 100644
index 0000000..7178520
--- /dev/null
+++ b/CashPoint/doc/index-files/index-5.html
@@ -0,0 +1,126 @@
+
+
+
+
+
+E-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
E
+
+evaluate(Cursor, T, Object...) - Method in interface app.learn.DbAdapter.QueryEvaluator
+
+expenses() - Method in class app.learn.Transactor
+
+calculates the accumulated costs
+
+exportButton - Static variable in class app.learn.R.id
+
+exportButtonText - Static variable in class app.learn.R.string
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-6.html b/CashPoint/doc/index-files/index-6.html
new file mode 100644
index 0000000..568d92f
--- /dev/null
+++ b/CashPoint/doc/index-files/index-6.html
@@ -0,0 +1,122 @@
+
+
+
+
+
+F-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-7.html b/CashPoint/doc/index-files/index-7.html
new file mode 100644
index 0000000..0e17d7e
--- /dev/null
+++ b/CashPoint/doc/index-files/index-7.html
@@ -0,0 +1,135 @@
+
+
+
+
+
+G-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
G
+
+getCount(String) - Method in class app.learn.DbAdapter
+
+getCurrency() - Method in class app.learn.Transactor
+
+getEntryIds(String) - Method in class app.learn.DbAdapter
+
+getNewEntryId() - Method in class app.learn.DbAdapter
+
+getRowIds(String) - Method in class app.learn.DbAdapter
+
+getSharingPolicy() - Method in class app.learn.Transactor
+
+A sharing policy depicts the way the volume of all the cash flows is to be shared among the participants
+ when it comes to calculating compensations.
+
+getSortedNames() - Method in class app.learn.DbAdapter
+
+getSum(String) - Method in class app.learn.DbAdapter
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-8.html b/CashPoint/doc/index-files/index-8.html
new file mode 100644
index 0000000..defe3b6
--- /dev/null
+++ b/CashPoint/doc/index-files/index-8.html
@@ -0,0 +1,118 @@
+
+
+
+
+
+H-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
H
+
+hello - Static variable in class app.learn.R.string
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index-files/index-9.html b/CashPoint/doc/index-files/index-9.html
new file mode 100644
index 0000000..55a9831
--- /dev/null
+++ b/CashPoint/doc/index-files/index-9.html
@@ -0,0 +1,128 @@
+
+
+
+
+
+I-Index
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+A B C D E F G H I L M N O P R S T U
+
+
+
I
+
+icon - Static variable in class app.learn.R.drawable
+
+importButton - Static variable in class app.learn.R.id
+
+importButtonText - Static variable in class app.learn.R.string
+
+isAvailable(int, T[]) - Static method in class app.learn.Util
+
+isExpense(long) - Method in class app.learn.DbAdapter
+
+isNullOrEmpty(T[]) - Static method in class app.learn.Util
+
+
+
A B C D E F G H I L M N O P R S T U
+
+
+
+
+
+
diff --git a/CashPoint/doc/index.html b/CashPoint/doc/index.html
new file mode 100644
index 0000000..c81ff11
--- /dev/null
+++ b/CashPoint/doc/index.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+Generated Documentation (Untitled)
+
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+Frame Alert
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to Non-frame version .
+
+
+
diff --git a/CashPoint/doc/overview-tree.html b/CashPoint/doc/overview-tree.html
new file mode 100644
index 0000000..4d5b938
--- /dev/null
+++ b/CashPoint/doc/overview-tree.html
@@ -0,0 +1,159 @@
+
+
+
+
+
+Class Hierarchy
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
Class Hierarchy
+
+java.lang.Object
+
+java.util.AbstractMap<K,V> (implements java.util.Map<K,V>)
+
+java.util.TreeMap<K,V> (implements java.lang.Cloneable, java.util.NavigableMap<K,V>, java.io.Serializable)
+
+
+
+
+Activity
+
+
+app.learn.R
+app.learn.R.attr
+app.learn.R.drawable
+app.learn.R.id
+app.learn.R.layout
+app.learn.R.string
+SQLiteOpenHelper
+
+
+app.learn.Util
+
+
+
+
Interface Hierarchy
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/package-list b/CashPoint/doc/package-list
new file mode 100644
index 0000000..60e3bd9
--- /dev/null
+++ b/CashPoint/doc/package-list
@@ -0,0 +1 @@
+app.learn
diff --git a/CashPoint/doc/resources/background.gif b/CashPoint/doc/resources/background.gif
new file mode 100644
index 0000000..f471940
Binary files /dev/null and b/CashPoint/doc/resources/background.gif differ
diff --git a/CashPoint/doc/resources/tab.gif b/CashPoint/doc/resources/tab.gif
new file mode 100644
index 0000000..1a73a83
Binary files /dev/null and b/CashPoint/doc/resources/tab.gif differ
diff --git a/CashPoint/doc/resources/titlebar.gif b/CashPoint/doc/resources/titlebar.gif
new file mode 100644
index 0000000..17443b3
Binary files /dev/null and b/CashPoint/doc/resources/titlebar.gif differ
diff --git a/CashPoint/doc/resources/titlebar_end.gif b/CashPoint/doc/resources/titlebar_end.gif
new file mode 100644
index 0000000..3ad78d4
Binary files /dev/null and b/CashPoint/doc/resources/titlebar_end.gif differ
diff --git a/CashPoint/doc/serialized-form.html b/CashPoint/doc/serialized-form.html
new file mode 100644
index 0000000..736e174
--- /dev/null
+++ b/CashPoint/doc/serialized-form.html
@@ -0,0 +1,126 @@
+
+
+
+
+
+Serialized Form
+
+
+
+
+
+
+JavaScript is disabled on your browser.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CashPoint/doc/stylesheet.css b/CashPoint/doc/stylesheet.css
new file mode 100644
index 0000000..0aeaa97
--- /dev/null
+++ b/CashPoint/doc/stylesheet.css
@@ -0,0 +1,474 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:Arial, Helvetica, sans-serif;
+ font-size:76%;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4c6b87;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4c6b87;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-size:1.3em;
+}
+h1 {
+ font-size:1.8em;
+}
+h2 {
+ font-size:1.5em;
+}
+h3 {
+ font-size:1.4em;
+}
+h4 {
+ font-size:1.3em;
+}
+h5 {
+ font-size:1.2em;
+}
+h6 {
+ font-size:1.1em;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-size:1.2em;
+}
+dt code {
+ font-size:1.2em;
+}
+table tr td dt code {
+ font-size:1.2em;
+ vertical-align:top;
+}
+sup {
+ font-size:.6em;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:.8em;
+ z-index:200;
+ margin-top:-7px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ background-image:url(resources/titlebar.gif);
+ background-position:left top;
+ background-repeat:no-repeat;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:1em;
+ margin:0;
+}
+.topNav {
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+}
+.bottomNav {
+ margin-top:10px;
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+}
+.subNav {
+ background-color:#dee3e9;
+ border-bottom:1px solid #9eadc0;
+ float:left;
+ width:100%;
+ overflow:hidden;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding:3px 6px;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+ font-size:90%;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+.navBarCell1Rev {
+ background-image:url(resources/tab.gif);
+ background-color:#a88834;
+ color:#FFFFFF;
+ margin: auto 5px;
+ border:1px solid #c9aa44;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader h1 {
+ font-size:1.3em;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 25px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:1.2em;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ margin:0 0 6px -8px;
+ padding:2px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ margin:0 0 6px -8px;
+ padding:2px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:1.0em;
+}
+.indexContainer h2 {
+ font-size:1.1em;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:1.1em;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:10px 0 10px 20px;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:25px;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #9eadc0;
+ background-color:#f9f9f9;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:1px solid #9eadc0;
+ border-top:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+ border-bottom:1px solid #9eadc0;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.contentContainer table, .classUseContainer table, .constantValuesContainer table {
+ border-bottom:1px solid #9eadc0;
+ width:100%;
+}
+.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
+ width:100%;
+}
+.contentContainer .description table, .contentContainer .details table {
+ border-bottom:none;
+}
+.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
+ vertical-align:top;
+ padding-right:20px;
+}
+.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
+.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
+.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
+.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
+ padding-right:3px;
+}
+.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#FFFFFF;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ margin:0px;
+}
+caption a:link, caption a:hover, caption a:active, caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
+ white-space:nowrap;
+ padding-top:8px;
+ padding-left:8px;
+ display:block;
+ float:left;
+ background-image:url(resources/titlebar.gif);
+ height:18px;
+}
+.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
+ width:10px;
+ background-image:url(resources/titlebar_end.gif);
+ background-repeat:no-repeat;
+ background-position:top right;
+ position:relative;
+ float:left;
+}
+ul.blockList ul.blockList li.blockList table {
+ margin:0 0 12px 0px;
+ width:100%;
+}
+.tableSubHeadingColor {
+ background-color: #EEEEFF;
+}
+.altColor {
+ background-color:#eeeeef;
+}
+.rowColor {
+ background-color:#ffffff;
+}
+.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
+ text-align:left;
+ padding:3px 3px 3px 7px;
+}
+th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
+ background:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ text-align:left;
+ padding:3px 3px 3px 7px;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+td.colFirst, th.colFirst {
+ border-left:1px solid #9eadc0;
+ white-space:nowrap;
+}
+td.colLast, th.colLast {
+ border-right:1px solid #9eadc0;
+}
+td.colOne, th.colOne {
+ border-right:1px solid #9eadc0;
+ border-left:1px solid #9eadc0;
+}
+table.overviewSummary {
+ padding:0px;
+ margin-left:0px;
+}
+table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
+table.overviewSummary td.colOne, table.overviewSummary th.colOne {
+ width:25%;
+ vertical-align:middle;
+}
+table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
+ width:25%;
+ vertical-align:middle;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:.9em;
+}
+.block {
+ display:block;
+ margin:3px 0 0 0;
+}
+.strong {
+ font-weight:bold;
+}
diff --git a/CashPoint/proguard.cfg b/CashPoint/proguard.cfg
new file mode 100755
index 0000000..b1cdf17
--- /dev/null
+++ b/CashPoint/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+-keepclasseswithmembers class * {
+ public (android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public (android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
diff --git a/TripCostCalculator/default.properties b/CashPoint/project.properties
similarity index 80%
rename from TripCostCalculator/default.properties
rename to CashPoint/project.properties
index b74c488..c957743 100644
--- a/TripCostCalculator/default.properties
+++ b/CashPoint/project.properties
@@ -4,7 +4,7 @@
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
+# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
diff --git a/CashPoint/res/drawable-hdpi/icon.png b/CashPoint/res/drawable-hdpi/icon.png
new file mode 100755
index 0000000..8074c4c
Binary files /dev/null and b/CashPoint/res/drawable-hdpi/icon.png differ
diff --git a/CashPoint/res/drawable-ldpi/icon.png b/CashPoint/res/drawable-ldpi/icon.png
new file mode 100755
index 0000000..1095584
Binary files /dev/null and b/CashPoint/res/drawable-ldpi/icon.png differ
diff --git a/CashPoint/res/drawable-mdpi/icon.png b/CashPoint/res/drawable-mdpi/icon.png
new file mode 100755
index 0000000..a07c69f
Binary files /dev/null and b/CashPoint/res/drawable-mdpi/icon.png differ
diff --git a/CashPoint/res/layout-finger/nameview.xml b/CashPoint/res/layout-finger/nameview.xml
new file mode 100644
index 0000000..f5e5154
--- /dev/null
+++ b/CashPoint/res/layout-finger/nameview.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/CashPoint/res/layout/main.xml b/CashPoint/res/layout/main.xml
new file mode 100755
index 0000000..a729681
--- /dev/null
+++ b/CashPoint/res/layout/main.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CashPoint/res/values/strings.xml b/CashPoint/res/values/strings.xml
new file mode 100755
index 0000000..d5c84ad
--- /dev/null
+++ b/CashPoint/res/values/strings.xml
@@ -0,0 +1,8 @@
+
+
+ This is CashPoint !
+ Cashpoint
+ Name
+ Export
+ Import
+
diff --git a/CashPoint/src/app/learn/CashPoint.java b/CashPoint/src/app/learn/CashPoint.java
new file mode 100755
index 0000000..e0a1ae7
--- /dev/null
+++ b/CashPoint/src/app/learn/CashPoint.java
@@ -0,0 +1,143 @@
+package app.learn;
+
+import java.io.*;
+import java.nio.channels.FileChannel;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.View;
+import android.view.View.*;
+import android.widget.*;
+
+public class CashPoint extends Activity {
+ /** Called when the activity is first created. */
+
+ private Button exportButton;
+ private Button importButton;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ this.importButton = (Button)this.findViewById(R.id.importButton);
+ this.importButton.setOnClickListener(new OnClickListener() {
+ public void onClick(final View v) {
+ doImpex(true);
+ }
+ });
+
+ this.exportButton = (Button)this.findViewById(R.id.exportButton);
+ this.exportButton.setOnClickListener(new OnClickListener() {
+ public void onClick(final View v) {
+ doImpex(false);
+ }
+ });
+ }
+
+ void doImpex(boolean flag) {
+ String s = flag ? "import" : "export";
+ if (isExternalStorageAvailable()) {
+ new ImpexTask(flag).execute();
+ } else {
+ Toast.makeText(CashPoint.this,
+ String.format("External storage is not available, unable to %s data.", s),
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private boolean isExternalStorageAvailable() {
+ return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
+ }
+
+ private class ImpexTask extends AsyncTask {
+ /**
+ *
+ * @param impex if true then import else export
+ */
+ public ImpexTask(boolean impex) {
+ this.impex = impex;
+ }
+
+ boolean impex;
+
+ String dbName = DbAdapter.DATABASE_NAME;
+
+ private final ProgressDialog dialog = new ProgressDialog(CashPoint.this);
+
+ // can use UI thread here
+ protected void onPreExecute() {
+ this.dialog.setMessage(String.format(impex ? "Importing '%s' ..." : "Exporting '%s' ...", this.dbName));
+ this.dialog.show();
+ }
+
+ // automatically done on worker thread (separate from UI thread)
+ protected Boolean doInBackground(final String... args) {
+ String path = "data/app.learn/databases";
+ File importDir = new File(Environment.getDataDirectory(), path);
+ File exportDir = new File(Environment.getExternalStorageDirectory(), path);
+
+ if (!exportDir.exists())
+ exportDir.mkdirs();
+
+ try {
+ File source, destination;
+ if (impex) {
+ source = new File(exportDir, this.dbName);
+ destination = new File(importDir, this.dbName);
+ }
+ else {
+ source = new File(importDir, this.dbName);
+ destination = new File(exportDir, this.dbName);
+ }
+ if (!source.exists())
+ return false;
+
+ if (!impex && !destination.exists())
+ destination.createNewFile();
+
+ this.copyFile(source, destination);
+ } catch (IOException e) {
+ Resources res = CashPoint.this.getResources();
+ Log.e(res.getString(R.string.app_name), e.getMessage(), e);
+ return false;
+ }
+
+ return true;
+ }
+
+ void copyFile(File src, File dst) throws IOException {
+ FileChannel inChannel = new FileInputStream(src).getChannel();
+ FileChannel outChannel = new FileOutputStream(dst).getChannel();
+ try {
+ inChannel.transferTo(0, inChannel.size(), outChannel);
+ } finally {
+ if (inChannel != null)
+ inChannel.close();
+ if (outChannel != null)
+ outChannel.close();
+ }
+ }
+
+ // can use UI thread here
+ protected void onPostExecute(final Boolean success) {
+ if (this.dialog.isShowing()) {
+ this.dialog.dismiss();
+ }
+
+ String s = impex ? "Import" : "Export";
+ if (success) {
+ Toast.makeText(CashPoint.this, s + " successful !", Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(CashPoint.this, s + " failed !", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/CashPoint/src/app/learn/DbAdapter.java b/CashPoint/src/app/learn/DbAdapter.java
new file mode 100755
index 0000000..cce3add
--- /dev/null
+++ b/CashPoint/src/app/learn/DbAdapter.java
@@ -0,0 +1,291 @@
+package app.learn;
+
+import java.util.*;
+
+import android.content.*;
+import android.database.*;
+import android.database.sqlite.*;
+import android.util.Log;
+
+/**
+ * facilitates database access for a cost sharing system
+ *
+ * @author lotharla
+ */
+public class DbAdapter extends SQLiteOpenHelper
+{
+ private static final String TAG = "DbAdapter";
+
+ public static final String DATABASE_NAME = "data";
+ public static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_TABLE = "kitty";
+
+ public DbAdapter(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ mDb = getWritableDatabase();
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("create table " + DATABASE_TABLE + " (" +
+ " entry integer not null," + // unique for the entries, reference for the portions
+ " name text not null," + // the person involved
+ " amount real not null," + // the amount of money, negative for portions
+ " currency text," + // if null it's the default currency (Euro or Dollar or ...)
+ " timestamp text," + // if null it's a portion
+ " comment text," + // optional, for recognition
+ " expense integer not null" + // boolean, if true then the amount has been expended and likely shared among others
+ " );"
+ );
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ + newVersion + ", which will destroy all old data");
+
+ recreate(db);
+ }
+
+ private void recreate(SQLiteDatabase db) {
+ db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
+ onCreate(db);
+ }
+
+ private SQLiteDatabase mDb;
+
+ public void clear() {
+ recreate(mDb);
+ }
+
+ public void drop(String tableName) {
+ mDb.execSQL("DROP TABLE IF EXISTS " + tableName);
+ }
+
+ protected void rename(String oldTableName, String newTableName) {
+ mDb.execSQL("ALTER TABLE " + oldTableName + " RENAME TO " + newTableName);
+ }
+
+ protected String[] getFieldNames() {
+ return new String[] {"entry", "name", "amount", "currency", "timestamp", "comment", "expense", "ROWID"};
+ }
+
+ protected ContentValues putValues(int entry, String name, double amount, String currency, String timestamp, String comment, boolean expense) {
+ ContentValues values = new ContentValues();
+
+ String[] fields = getFieldNames();
+ values.put(fields[0], entry);
+ values.put(fields[1], name);
+ values.put(fields[2], amount);
+ values.put(fields[3], currency);
+ values.put(fields[4], timestamp);
+ values.put(fields[5], comment);
+ values.put(fields[6], expense ? 1 : 0);
+
+ return values;
+ }
+
+ protected long addRecord(int entryId, String name, double amount, String currency, String timestamp, String comment) {
+ ContentValues values = putValues(entryId, name, amount, currency, timestamp, comment, false);
+ long rowId = mDb.insert(DATABASE_TABLE, null, values);
+ if (rowId < 0)
+ Log.w(TAG, String.format("addRecord failed with : %s", values.toString()));
+ return rowId;
+ }
+
+ public interface QueryEvaluator
+ {
+ public T evaluate(Cursor cursor, T defaultResult, Object... params);
+ }
+
+ protected T rawQuery(String sql, String[] selectionArgs, QueryEvaluator qe, T defaultResult, Object... params) {
+ Cursor cursor = null;
+
+ try {
+ cursor = mDb.rawQuery(sql, selectionArgs);
+ if (cursor != null) {
+ if (cursor.getCount() > 0)
+ cursor.moveToFirst();
+
+ return qe.evaluate(cursor, defaultResult, params);
+ }
+ }
+ catch (SQLiteException ex) {
+ }
+ finally {
+ if (cursor != null)
+ cursor.close();
+ }
+
+ return defaultResult;
+ }
+
+ protected int updateExpenseFlag(long rowId, boolean expense) {
+ ContentValues values = new ContentValues();
+ values.put(getFieldNames()[6], expense ? 1 : 0);
+ return mDb.update(DATABASE_TABLE, values, "ROWID=" + rowId, null);
+ }
+
+ public boolean isExpense(long rowId) {
+ return rawQuery("select expense from " + DATABASE_TABLE + " where ROWID=" + rowId, null,
+ new QueryEvaluator() {
+ public Boolean evaluate(Cursor cursor, Boolean defaultResult, Object... params) {
+ return cursor.getCount() > 0 && cursor.getInt(0) > 0;
+ }
+ }, false);
+ }
+
+ public int getNewEntryId() {
+ return 1 + rawQuery("select max(entry) from " + DATABASE_TABLE, null,
+ new QueryEvaluator() {
+ public Integer evaluate(Cursor cursor, Integer defaultResult, Object... params) {
+ if (cursor.getCount() > 0)
+ return cursor.getInt(0);
+ else
+ return defaultResult;
+ }
+ }, -1);
+ }
+
+ public String timestampNow() {
+ return Util.timestamp(new Date());
+ }
+
+ public int addEntry(String name, double amount, String currency, String comment, boolean expense) {
+ int entryId = getNewEntryId();
+
+ long rowId = addRecord(entryId, name, amount, currency, timestampNow(), comment);
+ if (rowId < 0) {
+ removeEntry(entryId);
+ return -1;
+ }
+ else {
+ if (updateExpenseFlag(rowId, expense) != 1)
+ return -1;
+
+ return entryId;
+ }
+ }
+
+ public int removeEntry(int entryId) {
+ return mDb.delete(DATABASE_TABLE, "entry=" + entryId, null);
+ }
+
+ public T fetchEntry(int entryId, QueryEvaluator qe, T defaultResult, Object... params) {
+ Cursor cursor = null;
+
+ try {
+ cursor = mDb.query(true,
+ DATABASE_TABLE,
+ getFieldNames(),
+ "entry=" + entryId,
+ null, null, null, null, null);
+
+ if (cursor != null) {
+ if (cursor.getCount() > 0)
+ cursor.moveToFirst();
+ }
+
+ return qe.evaluate(cursor, defaultResult, params);
+ }
+ catch (SQLiteException ex) {
+ }
+ finally {
+ if (cursor != null)
+ cursor.close();
+ }
+
+ return defaultResult;
+ }
+
+ public String fetchField(int entryId, final String name) {
+ return fetchEntry(entryId,
+ new QueryEvaluator() {
+ public String evaluate(Cursor cursor, String defaultResult, Object... params) {
+ int timestampIndex = cursor.getColumnIndex("timestamp");
+ do {
+ if (cursor.getString(timestampIndex) != null)
+ return cursor.getString(cursor.getColumnIndex(name));
+ } while (cursor.moveToNext());
+ return defaultResult;
+ }
+ }, null);
+ }
+
+ public boolean allocate(boolean expense, int entryId, Map portions) {
+ long rowId;
+
+ for (String name : portions.keySet()) {
+ double portion = portions.get(name);
+
+ if ((rowId = addRecord(entryId, name, portion, null, null, null)) < 0)
+ return false;
+
+ if (updateExpenseFlag(rowId, expense) != 1)
+ return false;
+ }
+
+ return portions.size() > 0;
+ }
+
+ public String[] getSortedNames() {
+ return rawQuery("select distinct name from " + DATABASE_TABLE + " where length(name) > 0", null,
+ new QueryEvaluator() {
+ public String[] evaluate(Cursor cursor, String[] defaultResult, Object... params) {
+ TreeSet names = new TreeSet();
+ do {
+ names.add(cursor.getString(0));
+ } while (cursor.moveToNext());
+ return names.toArray(defaultResult);
+ }
+ }, new String[0]);
+ }
+
+ public Integer[] getEntryIds(String clause) {
+ return rawQuery("select entry from " + DATABASE_TABLE +
+ (Util.notNullOrEmpty(clause) ? " where " + clause : ""), null,
+ new QueryEvaluator() {
+ public Integer[] evaluate(Cursor cursor, Integer[] defaultResult, Object... params) {
+ TreeSet ids = new TreeSet();
+ do {
+ ids.add(cursor.getInt(0));
+ } while (cursor.moveToNext());
+ return ids.toArray(defaultResult);
+ }
+ }, new Integer[0]);
+ }
+
+ public Long[] getRowIds(String clause) {
+ return rawQuery("select rowid from " + DATABASE_TABLE +
+ (Util.notNullOrEmpty(clause) ? " where " + clause : ""), null,
+ new QueryEvaluator() {
+ public Long[] evaluate(Cursor cursor, Long[] defaultResult, Object... params) {
+ TreeSet ids = new TreeSet();
+ do {
+ ids.add(cursor.getLong(0));
+ } while (cursor.moveToNext());
+ return ids.toArray(defaultResult);
+ }
+ }, new Long[0]);
+ }
+
+ public double getSum(String clause) {
+ return rawQuery("select sum(amount) from " + DATABASE_TABLE +
+ (Util.notNullOrEmpty(clause) ? " where " + clause : ""), null,
+ new QueryEvaluator() {
+ public Double evaluate(Cursor cursor, Double defaultResult, Object... params) {
+ return cursor.getDouble(0);
+ }
+ }, 0.);
+ }
+
+ public int getCount(String clause) {
+ return rawQuery("select count(*) from " + DATABASE_TABLE +
+ (Util.notNullOrEmpty(clause) ? " where " + clause : ""), null,
+ new QueryEvaluator() {
+ public Integer evaluate(Cursor cursor, Integer defaultResult, Object... params) {
+ return cursor.getInt(0);
+ }
+ }, 0);
+ }
+}
\ No newline at end of file
diff --git a/CashPoint/src/app/learn/ShareMap.java b/CashPoint/src/app/learn/ShareMap.java
new file mode 100644
index 0000000..a61b094
--- /dev/null
+++ b/CashPoint/src/app/learn/ShareMap.java
@@ -0,0 +1,129 @@
+package app.learn;
+
+import java.util.*;
+
+/**
+ * A TreeMap containing names as keys and sharing amounts as values
+ *
+ */
+@SuppressWarnings("serial")
+public class ShareMap extends TreeMap
+{
+ protected ShareMap() {}
+ /**
+ * creates a sorted map of deals for a number of participants.
+ * A portion is assigned to the name in the corresponding spot.
+ * If the portion of an participant appears as null value the corresponding name is ignored in the map.
+ * @param names the array of names of the dealers (not necessarily sorted)
+ * @param portions given deals, if any, for individual participants according to the order of the names
+ */
+ public ShareMap(String[] names, Double[] portions) {
+ int n = Math.min(names.length, portions.length);
+ for (int i = 0; i < n; i++) {
+ if (Util.isAvailable(i, portions))
+ put(names[i], portions[i]);
+ }
+ }
+ /**
+ * creates a sorted map of shares for a number of sharers according to fixed proportions for any of the sharers
+ * If no proportions are specified uniform sharing is assumed (amount divided by the number of sharers).
+ * @param names the array of names of the sharers (not necessarily sorted)
+ * @param amount the value of the amount to share
+ * @param proportions given proportions for the sharers according to the order of the names
+ */
+ public ShareMap(String[] names, double amount, Integer[] proportions) {
+ this(names, amount);
+
+ int n = Util.isNullOrEmpty(proportions) ? 0 : proportions.length;
+ if (n > 0) {
+ Double[] normalized = normalize(proportions);
+ if (normalized.length > 0)
+ for (int i = 0; i < names.length; i++)
+ if (Util.isAvailable(i, normalized))
+ put(names[i], -amount * normalized[i]);
+ else
+ put(names[i], 0.);
+ }
+ }
+ /**
+ * creates a sorted map of shares for a number of sharers optionally allowing for fixed portions of any of the sharers
+ * except the first one whom the remainder of the amount is assigned to in any case.
+ * If no portion is specified for an individual sharer an uniformly shared portion is assumed (amount divided by the number of sharers).
+ * If the portion of an individual sharer appears as null value the corresponding name is ignored in the map.
+ * The values in the resulting map are the negated portions of the amount so that their sum equals the negative value of the amount.
+ * @param names the array of names of the sharers (not necessarily sorted)
+ * @param amount the value of the amount to share
+ * @param portions given portions, if any, for individual sharers according to the order of the names
+ */
+ public ShareMap(String[] names, double amount, Double... portions) {
+ int n = names.length;
+ if (n > 0) {
+ double portion = amount / n;
+
+ for (int i = 1; i < n; i++) {
+ String name = names[i];
+
+ if (Util.isAvailable(i, portions))
+ put(name, -portions[i]);
+ else if (i >= portions.length)
+ put(name, -portion);
+
+ if (containsKey(name))
+ amount += get(name);
+ }
+
+ put(names[0], -amount);
+ }
+ }
+ /**
+ * calculates the sum of all the values in the map
+ * @return the value of the sum
+ */
+ public double sum() {
+ double sum = 0;
+ for (double value : values())
+ sum += value;
+ return sum;
+ }
+ /**
+ * turns each value in the map to its negative
+ * @return the negated map
+ */
+ public ShareMap negated() {
+ for (Map.Entry share : entrySet())
+ put(share.getKey(), -share.getValue());
+ return this;
+ }
+ /**
+ * subtracts a vector from the values (vector) of this map
+ * @param subtrahend the vector to be subtracted from this
+ */
+ public void minus(Collection vector) {
+ Double[] subtrahend = vector.toArray(new Double[0]);
+ int n = Math.min(size(), subtrahend.length);
+ if (n > 0) {
+ Set keys = keySet();
+ Iterator it = keys.iterator();
+ for (int i = 0; i < n; i++) {
+ String name = it.next();
+ put(name, get(name) - subtrahend[i]);
+ }
+ }
+ }
+
+ Double[] normalize(Integer[] proportions) {
+ int n = proportions.length;
+ Double[] normalized = new Double[n];
+
+ double denominator = 0;
+ for (int i = 0; i < n; i++)
+ denominator += Math.abs(proportions[i]);
+
+ if (denominator > 0) {
+ for (int i = 0; i < n; i++)
+ normalized[i] = Math.abs(proportions[i]) / denominator;
+ }
+
+ return normalized;
+ }
+}
\ No newline at end of file
diff --git a/CashPoint/src/app/learn/Transactor.java b/CashPoint/src/app/learn/Transactor.java
new file mode 100644
index 0000000..488634f
--- /dev/null
+++ b/CashPoint/src/app/learn/Transactor.java
@@ -0,0 +1,416 @@
+package app.learn;
+
+import java.util.*;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.util.Log;
+
+/**
+ * A class containing transactions and evaluation tools for a cost sharing system
+ *
+ * @author lotharla
+ */
+public class Transactor extends DbAdapter
+{
+ public Transactor(Context context) {
+ super(context);
+ }
+
+ private static final String TAG = "Transactor";
+ /**
+ * no discussion about that amount
+ */
+ public static double minAmount = 0.01;
+
+ private boolean hasNegativeTotalWith(double amount) {
+ double total = total();
+ if (total - amount < -minAmount) {
+ Log.w(TAG, String.format("retrieval of %f is more than allowed : %f", amount, total));
+ return true;
+ }
+ else
+ return false;
+ }
+
+ private boolean isInternal(String name) {
+ return name.length() < 1;
+ }
+ /**
+ * The transaction registers the negated sum of the shares with the submitter.
+ * Additionally all the shares in the map are registered with the same entry id.
+ * This transaction does not change the total. It registers an allocation of a certain amount.
+ * If submitter is an empty String it means there is an internal reallocation which is not an expense.
+ * Such an internal reallocation is not allowed if the transaction causes a negative total.
+ * @param submitter the name of the participant who expended an amount matching the negated sum of the shares
+ * @param comment a String to make the transaction recognizable
+ * @param shares a ShareMap containing the shares of participants involved
+ * @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 performExpense(String submitter, String comment, ShareMap shares) {
+ double amount = -shares.sum();
+
+ boolean internal = isInternal(submitter);
+ if (internal) {
+ if (hasNegativeTotalWith(-amount))
+ return -2;
+ }
+
+ int entryId = addEntry(submitter, amount, currency, comment, !internal);
+ if (entryId < 0)
+ return -1;
+
+ if (allocate(!internal, entryId, shares)) {
+ String action = internal ? "reallocation of" : submitter + " expended";
+ Log.i(TAG, String.format("entry %d: %s %f %s for '%s' shared by %s",
+ entryId, action, Math.abs(amount), currency, comment, shares.toString()));
+ }
+ else {
+ removeEntry(entryId);
+ entryId = -1;
+ }
+
+ 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 String 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 String to make the transaction recognizable
+ * @param shares a ShareMap 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;
+
+ double amount = deals.sum();
+ if (Math.abs(amount + shares.sum()) < Util.delta)
+ for (Map.Entry deal : deals.entrySet()) {
+ String name = deal.getKey();
+
+ if (isInternal(name))
+ entryId = performTransfer(name, -deal.getValue(), comment, name);
+ else {
+ long rowId = addRecord(entryId < 0 ? getNewEntryId() : entryId,
+ name, deal.getValue(), currency, timestampNow(), comment);
+ if (rowId < 0)
+ entryId = -1;
+ else
+ updateExpenseFlag(rowId, true);
+ }
+
+ if (entryId < 0)
+ 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(true, entryId, shares)) {
+ 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;
+ }
+ /**
+ * 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 String 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 (hasNegativeTotalWith(amount))
+ return -2;
+ }
+
+ int entryId = addEntry(sender, amount, currency, comment, false);
+ if (entryId < 0)
+ return -1;
+
+ long rowId = addRecord(entryId, recipient, -amount, currency, timestampNow(), comment);
+ if (rowId < 0){
+ removeEntry(entryId);
+ return -1;
+ }
+ if (sender.equals(recipient))
+ updateExpenseFlag(rowId, true);
+
+ Log.i(TAG, String.format("entry %d: %s transfer %f %s for '%s' to %s", entryId,
+ internal ? "internal" : sender,
+ amount, currency, comment,
+ isInternal(recipient) ? "internal" : recipient));
+
+ return entryId;
+ }
+ /**
+ * The transaction registers the amount as a contribution (positive) or a retrieval (negative).
+ * A retrieval is not allowed if it surmounts the current total.
+ * @param submitter the name of the participant who did the submission
+ * @param amount the amount of the submission
+ * @param comment a String to make the transaction recognizable
+ * @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 performSubmission(String submitter, double amount, String comment) {
+ int entryId = addEntry(submitter, amount, currency, comment, false);
+
+ if (entryId > -1) {
+ if (hasNegativeTotalWith(-amount)) {
+ removeEntry(entryId);
+ return -2;
+ }
+
+ String action = amount > 0 ? "contributed" : "retrieved";
+ Log.i(TAG, String.format("entry %d: %s %s %f %s as '%s'",
+ entryId, submitter, action, Math.abs(amount), currency, comment));
+ }
+
+ return entryId;
+ }
+ /**
+ * The transaction registers multiple submissions.
+ * This transaction as a whole is not allowed if it causes a negative total.
+ * @param shares a ShareMap containing the shares of participants involved
+ * @param comment a String 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 shares, String comment) {
+ if (hasNegativeTotalWith(-shares.sum()))
+ return -2;
+
+ int entryId = getNewEntryId();
+
+ if (entryId > -1) {
+ for (Map.Entry share : shares.entrySet())
+ if (addRecord(entryId, share.getKey(), share.getValue(), currency, timestampNow(), comment) < 0) {
+ removeEntry(entryId);
+ return -1;
+ }
+
+ Log.i(TAG, String.format("entry %d: '%s' submissions : %s",
+ entryId, comment, shares.toString()));
+ }
+
+ return entryId;
+ }
+ /**
+ * The transaction discards any record with that entry id.
+ * @param entryId the entry to be discarded
+ * @return the number of affected records
+ */
+ public int performDiscard(int entryId) {
+ int affected = removeEntry(entryId);
+ Log.i(TAG, String.format("entry %d: discarded, %d records deleted", entryId, affected));
+ return affected;
+ }
+ /**
+ * calculates the cash flows caused by the participants
+ * @return a sorted map containing the names as key and the cash flow of that participant as value
+ */
+ public ShareMap cashFlow() {
+ return rawQuery("select name, sum(amount) as balance from " + DATABASE_TABLE +
+ " where length(name) > 0 and timestamp not null group by name order by name", null,
+ new QueryEvaluator() {
+ public ShareMap evaluate(Cursor cursor, ShareMap defaultResult, Object... params) {
+ ShareMap map = new ShareMap();
+
+ do {
+ map.put(cursor.getString(0), cursor.getDouble(1));
+ } while (cursor.moveToNext());
+
+ Log.i(TAG, String.format("cash flow : %s", map.toString()));
+ return map;
+ }
+ }, null);
+ }
+ /**
+ * calculates the balances of all participants identified by their names
+ * @return a sorted map containing the names as keys and the balances as values
+ */
+ public ShareMap balances() {
+ return rawQuery("select name, sum(amount) as balance from " + DATABASE_TABLE +
+ " where length(name) > 0 group by name order by name", null,
+ new QueryEvaluator() {
+ public ShareMap evaluate(Cursor cursor, ShareMap defaultResult, Object... params) {
+ ShareMap map = new ShareMap();
+
+ do {
+ map.put(cursor.getString(0), cursor.getDouble(1));
+ } while (cursor.moveToNext());
+
+ Log.i(TAG, String.format("balances : %s", map.toString()));
+ return map;
+ }
+ }, null);
+ }
+ /**
+ * calculates the current over-all amount
+ * @return the sum over the amounts of all records in the table
+ */
+ public double total() {
+ return getSum(null);
+ }
+ /**
+ * calculates the accumulated costs
+ * @return the sum over all entries marked as 'expense'
+ */
+ public double expenses() {
+ return getSum("expense > 0 and timestamp not null");
+ }
+
+ private Integer[] sharingPolicy = null; // uniform sharing among all participants
+ /**
+ * A sharing policy depicts the way the volume of all the cash flows is to be shared among the participants
+ * when it comes to calculating compensations. The given integers are proportional weights for those participants
+ * who are involved in the compensation procedure. They are read according to the sorted list of names.
+ * @return an array containing integer values or empty meaning the default sharing policy (uniform sharing among all participants)
+ */
+ public Integer[] getSharingPolicy() {
+ return sharingPolicy;
+ }
+ /**
+ * sets the sharing policy.
+ * Note that a call of clear or clearAll
+ * resets the sharing policy to its default (uniform sharing among all participants).
+ * @param sharingPolicy
+ */
+ public void setSharingPolicy(Integer[] sharingPolicy) {
+ this.sharingPolicy = sharingPolicy;
+ }
+ /**
+ * calculates a compensation for each participant from the balance and the all-over cash flow at this point.
+ * The sharing policy is taken into account for this calculation.
+ * An example: A sharing policy 1:2:3 splits the volume of all the cash flows minus the current total
+ * which is the remaining amount among the first, second and third participants out of the sorted list of names.
+ * The first portion is 1/6, the second 2/6 and the third is 3/6 of the volume.
+ * @return a sorted map containing the names as keys and the compensations as values
+ */
+ public ShareMap compensations() {
+ String[] sortedNames = getSortedNames();
+ ShareMap cashFlow = cashFlow();
+ double volume = cashFlow.sum() - total();
+
+ ShareMap differences = new ShareMap(sortedNames, volume);
+ ShareMap sharedCosts = new ShareMap(sortedNames, volume, sharingPolicy);
+ differences.minus(sharedCosts.values());
+
+ ShareMap compensations = balances().negated();
+ compensations.minus(differences.negated().values());
+ return compensations;
+ }
+
+ /**
+ * retrieves the names of tables that had been 'saved' in the past
+ * @return the Set of saved table names
+ */
+ public Set savedTables() {
+ return rawQuery("select name from sqlite_master where type = 'table'", null,
+ new QueryEvaluator>() {
+ public Set evaluate(Cursor cursor, Set defaultResult, Object... params) {
+ TreeSet names = new TreeSet();
+
+ do {
+ String name = cursor.getString(0);
+ if (name.startsWith(DATABASE_TABLE + "_"))
+ names.add(name);
+ } while (cursor.moveToNext());
+
+ Log.i(TAG, String.format("saved tables : %s", names.toString()));
+ return names;
+ }
+ }, null);
+ }
+ /**
+ *
+ * @param suffix an arbitrary String which is legal as an SQLite table name
+ * @return the complete SQLite table name
+ */
+ public String tableName(String suffix) {
+ return DbAdapter.DATABASE_TABLE + "_" + suffix;
+ }
+ /**
+ * changes the name of the table that has been worked on via transactions (current table).
+ * Thus this table is 'saved' in the same database. Note that the current table is non-existing after this operation.
+ * In order to continue the current table has to be restored (loadFrom) or recreated (clear).
+ * @param newSuffix the String to append to the name of the current table in order to form the new table name
+ * @return success if true
+ */
+ public boolean saveAs(String newSuffix) {
+ if (newSuffix == null || newSuffix.length() < 1)
+ return false;
+
+ String newTableName = tableName(newSuffix);
+ if (savedTables().contains(newTableName))
+ return false;
+
+ rename(DATABASE_TABLE, newTableName);
+ Log.i(TAG, String.format("table saved as '%s'", newTableName));
+ return true;
+ }
+ /**
+ * restores one of the saved tables as the current table. Note that the table that was current up to this point will be dropped.
+ * Also there will be one less 'saved' table after this operation.
+ * @param oldSuffix the String to append to the name of the current table in order to form the old table name
+ * @return success if true
+ */
+ public boolean loadFrom(String oldSuffix) {
+ if (oldSuffix == null || oldSuffix.length() < 1)
+ return false;
+
+ String oldTableName = tableName(oldSuffix);
+ if (!savedTables().contains(oldTableName))
+ return false;
+
+ rename(oldTableName, DATABASE_TABLE);
+ Log.i(TAG, String.format("table loaded from '%s'", oldTableName));
+ return true;
+ }
+ /**
+ * deletes all records from the current table and recreates it
+ */
+ @Override
+ public void clear() {
+ int count = getCount(null);
+ super.clear();
+ Log.i(TAG, String.format("table cleared, %d records deleted", count));
+ setSharingPolicy(null);
+ }
+ /**
+ * clears the current table and drops all saved tables
+ */
+ public void clearAll() {
+ for (String table : savedTables())
+ drop(table);
+
+ super.clear();
+ Log.i(TAG, "table and all saved tables cleared");
+ setSharingPolicy(null);
+ }
+
+ private String currency = "";
+
+ public String getCurrency() {
+ return currency;
+ }
+
+ public void setCurrency(String currency) {
+ this.currency = currency;
+ }
+
+}
diff --git a/CashPoint/src/app/learn/Util.java b/CashPoint/src/app/learn/Util.java
new file mode 100644
index 0000000..90699f3
--- /dev/null
+++ b/CashPoint/src/app/learn/Util.java
@@ -0,0 +1,35 @@
+package app.learn;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class Util {
+
+ public static boolean isAvailable(int i, T[] array) {
+ return array != null &&
+ i > -1 &&
+ i < array.length &&
+ array[i] != null;
+ }
+
+ public static boolean isNullOrEmpty(T[] array) {
+ return array == null || array.length < 1;
+ }
+
+ public static boolean notNullOrEmpty(String value) {
+ return value != null && value.length() > 0;
+ }
+
+ public static double delta = 0.00001;
+
+ public static String formatAmount(double value) {
+ return String.format("%.2f", value);
+ }
+
+ public static SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ public static String timestamp(Date date) {
+ return timestampFormat.format(date);
+ }
+
+}
diff --git a/CashPoint/trip/TripCostCalculation - eine Studie.ods b/CashPoint/trip/TripCostCalculation - eine Studie.ods
new file mode 100755
index 0000000..fc6f881
Binary files /dev/null and b/CashPoint/trip/TripCostCalculation - eine Studie.ods differ
diff --git a/CashPoint/trip/cashpoint.sh b/CashPoint/trip/cashpoint.sh
new file mode 100755
index 0000000..68d0582
--- /dev/null
+++ b/CashPoint/trip/cashpoint.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+pwd
+sqlite3 test.db "drop table if exists cashpoint;"
+sqlite3 test.db "create table cashpoint (
+ entry integer not null, -- unique for the inputs, reference for the distributions
+ name text not null, -- the person involved
+ amount real not null, -- the amount of money, negative for distributions
+ currency text, -- if null it's the default currency (Euro or Dollar or ...)
+ date numeric, -- if null it's a distribution
+ comment text -- optional, for recognition
+);"
diff --git a/CashPoint/trip/cashpoint.sql b/CashPoint/trip/cashpoint.sql
new file mode 100755
index 0000000..738b08c
--- /dev/null
+++ b/CashPoint/trip/cashpoint.sql
@@ -0,0 +1,39 @@
+drop table if exists cashpoint;
+create table cashpoint (
+ entry integer not null, -- unique for the inputs, reference for the distributions
+ name text not null, -- the person involved
+ amount real not null, -- the amount of money, negative for distributions
+ currency text, -- if null it's the default currency (Euro or Dollar or ...)
+ date numeric, -- if null it's a distribution
+ comment text -- optional, for recognition
+);
+
+-- the following insert represents an input to cashpoint
+insert into cashpoint (entry,name,amount,date,comment) values (1,'Bob',100.0,'12/24/11','gas');
+-- the next two inserts represent distributions referring to the above input
+insert into cashpoint (entry,name,amount) values (1,'Bob',-100.0/3);
+insert into cashpoint (entry,name,amount) values (1,'Tom',-100.0/3);
+insert into cashpoint (entry,name,amount) values (1,'Sue',-100.0/3);
+
+-- the following insert represents an input to cashpoint
+insert into cashpoint (entry,name,amount,date,comment)
+ values (2,'Sue',70.0,'12/23/11','groceries');
+-- the next two inserts represent distributions referring to the above input
+insert into cashpoint (entry,name,amount) values (2,'Bob',-70.0/3);
+insert into cashpoint (entry,name,amount) values (2,'Tom',-70.0/3);
+insert into cashpoint (entry,name,amount) values (2,'Sue',-70.0/3);
+
+.header on
+.mode column
+select * from cashpoint;
+select sum(amount) as expenses from cashpoint where date not null;
+select count(name) as names from (select distinct name from cashpoint);
+select name,balance from
+ (select name,sum(amount) as balance from cashpoint where name='Bob' union
+ select name,sum(amount) as balance from cashpoint where name='Tom' union
+ select name,sum(amount) as balance from cashpoint where name='Sue');
+
+-- the following doesn 't work unfortunately
+-- select expenses/names as 'per person' from
+-- (select sum(amount) as expenses from cashpoint where date not null) join
+-- (select count(name) as names from (select distinct name from cashpoint);
diff --git a/CashPoint/trip/cashpoint2.sql b/CashPoint/trip/cashpoint2.sql
new file mode 100755
index 0000000..22ebb16
--- /dev/null
+++ b/CashPoint/trip/cashpoint2.sql
@@ -0,0 +1,52 @@
+drop table if exists cashpoint;
+create table cashpoint (
+ entry integer not null, -- unique for the inputs, reference for the distributions
+ name text not null, -- the person involved
+ amount real not null, -- the amount of money, negative for distributions
+ currency text, -- if null it's the default currency (Euro or Dollar or ...)
+ timestamp text, -- if null it's a distribution
+ comment text, -- optional, for recognition
+ expense integer not null -- boolean, if true then the amount has been expended and possibly shared among others
+);
+
+-- the following insert represents an input to cashpoint
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (1,'Bob',100.0,'12/24/11','gas',1);
+-- the next two inserts represent ditributions referring to the above input
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (1,'Bob',-100.0/3,null,null,1);
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (1,'Tom',-100.0/3,null,null,1);
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (1,'Sue',-100.0/3,null,null,1);
+
+-- the following insert represents an input to cashpoint
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (2,'Sue',70.0,'12/23/11','groceries',1);
+-- the next two inserts represent ditributions referring to the above input
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (2,'Bob',-70.0/3,null,null,1);
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (2,'Tom',-70.0/3,null,null,1);
+insert into cashpoint (entry,name,amount,timestamp,comment,expense)
+ values (2,'Sue',-70.0/3,null,null,1);
+
+.header on
+.mode column
+select * from cashpoint;
+select sum(amount) as expenses from cashpoint where timestamp not null;
+select count(name) as numOfNames from (select distinct name from cashpoint);
+select distinct comment as purposes from cashpoint where comment not null;
+select name,sum(amount) as balance from cashpoint group by name order by name;
+ -- following syntax is not required, 'group by ' gives the same effect
+ -- select name,balance from
+ -- (select name,sum(amount) as balance from cashpoint where name='Bob' union
+ -- select name,sum(amount) as balance from cashpoint where name='Tom'union
+ -- select name,sum(amount) as balance from cashpoint where name='Sue');
+
+
+
+-- the following doesn 't work unfortunately
+-- select expenses/names as 'per person' from
+-- (select sum(amount) as expenses from cashpoint where timestamp not null) join
+-- (select count(name) as names from (select distinct name from cashpoint);
diff --git a/CashPoint/trip/tables.sql b/CashPoint/trip/tables.sql
new file mode 100755
index 0000000..0f1b851
--- /dev/null
+++ b/CashPoint/trip/tables.sql
@@ -0,0 +1,23 @@
+drop table credits;
+create table credits (
+ date text not null,
+ creditor text not null,
+ amount integer not null,
+ purpose text not null);
+
+drop table debits;
+create table debits (
+ ENTRY integer not null,
+ debitor text not null,
+ share integer not null);
+
+insert into credits (ROWID,date,creditor,amount,purpose) values (1,'12/24/11','Bob',100.0,'gas');
+insert into debits (ENTRY,debitor,share) values (1,'Tom',-100.0/3);
+insert into debits (ENTRY,debitor,share) values (1,'Sue',-100.0/3);
+insert into credits (ROWID,date,creditor,amount,purpose) values (2,'12/23/11','Sue',70.0,'groceries');
+insert into debits (ENTRY,debitor,share) values (2,'Bob',-70.0/3);
+insert into debits (ENTRY,debitor,share) values (2,'Tom',-70.0/3);
+
+.header on
+.mode column
+select * from credits JOIN debits where credits.ROWID=debits.ENTRY;
diff --git a/CashPoint/trip/test.db b/CashPoint/trip/test.db
new file mode 100755
index 0000000..001c720
Binary files /dev/null and b/CashPoint/trip/test.db differ
diff --git a/CashPointTest/.classpath b/CashPointTest/.classpath
new file mode 100755
index 0000000..d6e06c3
--- /dev/null
+++ b/CashPointTest/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/CashPointTest/.project b/CashPointTest/.project
new file mode 100755
index 0000000..b0c2fd8
--- /dev/null
+++ b/CashPointTest/.project
@@ -0,0 +1,34 @@
+
+
+ CashPointTest
+
+
+ CashPoint
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/CashPointTest/.settings/org.eclipse.jdt.core.prefs b/CashPointTest/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..abfc958
--- /dev/null
+++ b/CashPointTest/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+#Sun Dec 25 14:05:52 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/CashPointTest/AndroidManifest.xml b/CashPointTest/AndroidManifest.xml
new file mode 100755
index 0000000..5b65a33
--- /dev/null
+++ b/CashPointTest/AndroidManifest.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CashPointTest/proguard.cfg b/CashPointTest/proguard.cfg
new file mode 100755
index 0000000..b1cdf17
--- /dev/null
+++ b/CashPointTest/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+-keepclasseswithmembers class * {
+ public (android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public (android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
diff --git a/CashPointTest/project.properties b/CashPointTest/project.properties
new file mode 100644
index 0000000..c957743
--- /dev/null
+++ b/CashPointTest/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-4
diff --git a/CashPointTest/res/drawable-hdpi/icon.png b/CashPointTest/res/drawable-hdpi/icon.png
new file mode 100755
index 0000000..8074c4c
Binary files /dev/null and b/CashPointTest/res/drawable-hdpi/icon.png differ
diff --git a/CashPointTest/res/drawable-ldpi/icon.png b/CashPointTest/res/drawable-ldpi/icon.png
new file mode 100755
index 0000000..1095584
Binary files /dev/null and b/CashPointTest/res/drawable-ldpi/icon.png differ
diff --git a/CashPointTest/res/drawable-mdpi/icon.png b/CashPointTest/res/drawable-mdpi/icon.png
new file mode 100755
index 0000000..a07c69f
Binary files /dev/null and b/CashPointTest/res/drawable-mdpi/icon.png differ
diff --git a/CashPointTest/res/layout/main.xml b/CashPointTest/res/layout/main.xml
new file mode 100755
index 0000000..3a5f117
--- /dev/null
+++ b/CashPointTest/res/layout/main.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/CashPointTest/res/values/strings.xml b/CashPointTest/res/values/strings.xml
new file mode 100755
index 0000000..b57801c
--- /dev/null
+++ b/CashPointTest/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+
+ Hello World!
+ CashPointTest
+
diff --git a/CashPointTest/src/app/learn/test/ActivityTest.java b/CashPointTest/src/app/learn/test/ActivityTest.java
new file mode 100644
index 0000000..ef74bae
--- /dev/null
+++ b/CashPointTest/src/app/learn/test/ActivityTest.java
@@ -0,0 +1,33 @@
+package app.learn.test;
+
+import android.test.*;
+import android.widget.*;
+
+import app.learn.CashPoint;
+
+public class ActivityTest extends ActivityInstrumentationTestCase2 {
+ public ActivityTest() {
+ super("app.learn", CashPoint.class);
+ }
+
+ private CashPoint mActivity;
+ private TextView mTextView;
+ private String resourceString;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = this.getActivity();
+ mTextView = (TextView) mActivity.findViewById(app.learn.R.id.nameLabel);
+ }
+
+ public void testPreconditions() {
+ assertNotNull(mTextView);
+ }
+
+ public void testText() {
+ resourceString = mActivity.getString(app.learn.R.string.nameLabelText);
+ assertEquals(resourceString,(String)mTextView.getText());
+ }
+
+}
diff --git a/CashPointTest/src/app/learn/test/CashPointTest.java b/CashPointTest/src/app/learn/test/CashPointTest.java
new file mode 100755
index 0000000..7c7aeff
--- /dev/null
+++ b/CashPointTest/src/app/learn/test/CashPointTest.java
@@ -0,0 +1,477 @@
+package app.learn.test;
+
+import java.io.*;
+import java.util.*;
+
+import junit.framework.*;
+
+import android.os.Environment;
+import android.test.*;
+import android.test.suitebuilder.TestSuiteBuilder;
+
+import android.database.Cursor;
+
+import app.learn.*;
+import app.learn.DbAdapter.QueryEvaluator;
+
+public class CashPointTest extends ActivityInstrumentationTestCase2
+{
+ public static void main(String[] args) {
+// TestSuite suite = new TestSuite(CashPointTest.class);
+// InstrumentationTestRunner.run(suite);
+ }
+
+ public static Test suite() {
+ return new TestSuiteBuilder(CashPointTest.class).
+ includePackages("app.learn.test.CashPointTest").build();
+ }
+
+ public CashPointTest() {
+ super("app.learn", CashPoint.class);
+ }
+
+ private CashPoint mActivity;
+ private DbAdapter dbAdapter;
+ private Transactor transactor;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = this.getActivity();
+ transactor = new Transactor(mActivity);
+ dbAdapter = (DbAdapter)transactor;
+
+ dbAdapter.clear();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ dbAdapter.close();
+ super.tearDown();
+ }
+
+ void assertAmountZero(String message, Double actual) {
+ assertEquals(message, 0, actual, Util.delta);
+ }
+
+ void assertAmountEquals(Double expected, Double actual) {
+ assertEquals(expected, actual, Util.delta);
+ }
+
+ void assertAmountEquals(String message, Double expected, Double actual) {
+ assertEquals(message, expected, actual, Util.delta);
+// String exp = Util.formatAmount(expected);
+// String act = Util.formatAmount(actual);
+// assertEquals(message, exp, act);
+ }
+
+ void assertArrayEquals(String message, T[] expected, T[] actual) {
+ assertEquals(message, expected.length, actual.length);
+ for (int i = 0; i < actual.length; i++)
+ assertEquals(message, expected[i], actual[i]);
+ }
+
+ void assertEntrySize(final int expected, int entry) {
+ assertTrue("invalid entry", entry > -1);
+
+ dbAdapter.fetchEntry(entry,
+ new QueryEvaluator() {
+ public Void evaluate(Cursor cursor, Void defaultResult, Object... params) {
+ assertNotNull(cursor);
+ assertEquals(expected, cursor.getCount());
+ return defaultResult;
+ }
+ }, null);
+ }
+
+ public void testEntry() {
+ int entryId = dbAdapter.addEntry("Bob", 100.5, null, "gas", true);
+ assertEquals(dbAdapter.getNewEntryId() - 1, entryId);
+
+ dbAdapter.fetchEntry(entryId,
+ new QueryEvaluator() {
+ public Void evaluate(Cursor cursor, Void defaultResult, Object... params) {
+ assertNotNull(cursor);
+ assertEquals("Bob", cursor.getString(1));
+ assertEquals(100.5, cursor.getDouble(2));
+ assertEquals(null, cursor.getString(3));
+ String now = dbAdapter.timestampNow();
+ assertEquals(now.substring(0, 16),
+ cursor.getString(4).substring(0, 16));
+ assertEquals("gas", cursor.getString(5));
+ assertTrue(cursor.getInt(6) > 0);
+ return defaultResult;
+ }
+ }, null);
+
+ assertEquals(1, dbAdapter.removeEntry(entryId));
+ assertEquals(0, dbAdapter.getCount("entry=" + entryId));
+ }
+
+ String[] participants = new String[] {"Sue", "Bob", "Tom"};
+
+ public void testShareMap() {
+ ShareMap map = new ShareMap(participants, new Double[] {200.,null,300.});
+ assertEquals(2, map.size());
+ assertAmountEquals(200., map.get(participants[0]));
+ assertAmountEquals(300., map.get(participants[2]));
+
+ map = new ShareMap(participants, 600.);
+ assertUniformShares(3, -200., map);
+
+ map = new ShareMap(participants, 600., null, 300.);
+ assertEquals(3, map.size());
+ assertAmountEquals(-100., map.get(participants[0]));
+ assertAmountEquals(-300., map.get(participants[1]));
+ assertAmountEquals(-200., map.get(participants[2]));
+
+ assertAmountEquals(-600., map.sum());
+ assertAmountEquals(map.sum(), -map.negated().sum());
+
+ map = new ShareMap(new String[] {participants[0], "", participants[2]}, 600.);
+ assertEquals("", map.firstKey());
+
+ map = new ShareMap(participants, 120., new Integer[] {1,1,1});
+ assertUniformShares(3, -40., map);
+
+ map = new ShareMap(participants, 120., new Integer[] {0,1,2});
+ assertEquals(3, map.size());
+ assertAmountEquals(0., map.get(participants[0]));
+ assertAmountEquals(-40., map.get(participants[1]));
+ assertAmountEquals(-80., map.get(participants[2]));
+
+ map = new ShareMap(participants, 150., new Integer[] {});
+ assertUniformShares(3, -50., map);
+ }
+
+ void assertUniformShares(int expectedMapSize, double expectedShareSize, Map actualMap) {
+ assertEquals(expectedMapSize, actualMap.size());
+ Iterator it = actualMap.values().iterator();
+ for (int i = 0; i < expectedMapSize; i++)
+ assertAmountEquals(expectedShareSize, it.next());
+ }
+
+ void zeroSumTest(int entry, String andCondition) {
+ double sum = dbAdapter.getSum("entry=" + entry + andCondition);
+ assertAmountZero("Transaction leaking.", sum);
+ }
+
+ int allocationTest(final boolean expense) {
+ final int sign = expense ? 1 : -1;
+ final double allocation = 120 * sign;
+
+ int entryId = dbAdapter.addEntry(expense ? "Bob" : "", allocation, null, "test", expense);
+
+ ShareMap portions = new ShareMap(
+ new String[] {"Bob","Sue","Tom"},
+ allocation,
+ null, allocation / 4, allocation / 3);
+
+ assertTrue(dbAdapter.allocate(expense, entryId, portions));
+
+ assertEntrySize(4, entryId);
+ zeroSumTest(entryId, "");
+
+ assertNotNull("timestamp missing", dbAdapter.fetchField(entryId, "timestamp"));
+
+ dbAdapter.fetchEntry(entryId,
+ new QueryEvaluator() {
+ public Void evaluate(Cursor cursor, Void defaultResult, Object... params) {
+ assertNotNull(cursor);
+ do {
+ assertEquals(expense, dbAdapter.isExpense(cursor.getLong(cursor.getColumnIndex("ROWID"))));
+ double amount = cursor.getDouble(cursor.getColumnIndex("amount"));
+ if (cursor.getString(cursor.getColumnIndex("timestamp")) != null)
+ assertAmountEquals("allocated amount wrong", allocation, amount);
+ else {
+ String name = cursor.getString(cursor.getColumnIndex("name"));
+ if (name.equals("Sue")) assertAmountEquals("Sue 's portion wrong.", -30. * sign, amount);
+ if (name.equals("Tom")) assertAmountEquals("Tom 's portion wrong.", -40. * sign, amount);
+ if (name.equals("Bob")) assertAmountEquals("Bob 's portion wrong.", -50. * sign, amount);
+ }
+ } while (cursor.moveToNext());
+ return defaultResult;
+ }
+ }, null);
+
+ return entryId;
+ }
+
+ public void testAllocation() {
+ Set ids = new HashSet();
+
+ ids.add(allocationTest(true));
+ ids.add(allocationTest(false));
+
+ for (Integer id : ids)
+ if (id > -1) {
+ dbAdapter.removeEntry(id);
+ assertEntrySize(0, id);
+ }
+
+ assertTrue(-1 < transactor.performSubmission(participants[0], 99., "test1"));
+ assertEquals(-2, transactor.performExpense("", "test1", new ShareMap(participants, -100.)));
+
+ int id = transactor.performExpense("", "test1", new ShareMap(participants, -99.));
+ assertEntrySize(4, id);
+ zeroSumTest(id, "");
+
+ totalTest(99.);
+
+ id = transactor.performExpense(participants[2], "test2", new ShareMap(participants, 70., new Integer[] {3,0,4}));
+ assertEntrySize(4, id);
+ zeroSumTest(id, " and expense > 0");
+ }
+
+ public void testSaveLoad() {
+ File dbDir = new File(Environment.getDataDirectory(), "data/app.learn/databases");
+ assertTrue(new File(dbDir, DbAdapter.DATABASE_NAME).exists());
+
+ int count = transactor.getCount(null);
+ double sum = transactor.getSum(null);
+
+ saveTest("test");
+
+ transactor.clear();
+ assertEquals(0, transactor.getCount(null));
+
+ loadTest("test");
+
+ assertEquals(count, transactor.getCount(null));
+ assertEquals(sum, transactor.getSum(null));
+ }
+
+ void saveTest(String suffix) {
+ String tableName = transactor.tableName(suffix);
+ transactor.drop(tableName);
+ assertTrue(transactor.saveAs(suffix));
+ assertTrue(transactor.savedTables().contains(tableName));
+ }
+
+ void loadTest(String suffix) {
+ String tableName = transactor.tableName(suffix);
+ assertTrue(transactor.savedTables().contains(tableName));
+ transactor.drop(DbAdapter.DATABASE_TABLE);
+ assertTrue(transactor.loadFrom(suffix));
+ }
+
+ public void testRingTransfer() {
+ double someAmount = 312.54;
+ String purpose = "ring transfer";
+
+ List names = Arrays.asList(participants);
+ Iterator it = names.iterator();
+ String submitter = it.next();
+ while (it.hasNext()) {
+ String recipient = it.next();
+ transferTest(submitter, someAmount, purpose, recipient);
+ submitter = recipient;
+ }
+ transferTest(submitter, someAmount, purpose, names.iterator().next());
+
+ String[] sortedNames = transactor.getSortedNames();
+ assertTrue("Some name missing.", Arrays.asList(sortedNames).containsAll(Arrays.asList(participants)));
+
+ Integer[] ids = transactor.getEntryIds(String.format("comment='%s'", purpose));
+ for (Integer id : ids)
+ discardTest(id);
+
+ assertEquals("discard failed.", 0, transactor.getCount(null));
+ }
+
+ void transferTest(String submitter, double amount, String purpose, String recipient) {
+ int entryId = transactor.performTransfer(submitter, amount, purpose, recipient);
+ assertEntrySize(2, entryId);
+ zeroSumTest(entryId, "");
+ }
+
+ void discardTest(int entryId) {
+ int discarded = transactor.performDiscard(entryId);
+ assertTrue("Nothing deleted.", discarded > 0);
+ assertEntrySize(0, entryId);
+ }
+
+ int entryTest(int entry, final int size, final ShareMap shares) {
+ assertFalse("Transaction blocked because of negative total.", entry == -2);
+ assertTrue("Invalid entry.", entry > -1);
+
+ transactor.fetchEntry(entry,
+ new QueryEvaluator() {
+ public Void evaluate(Cursor cursor, Void defaultResult, Object... params) {
+ assertNotNull(cursor);
+ if (shares == null)
+ assertEquals(size, cursor.getCount());
+ else {
+ assertEquals(size + shares.size(), cursor.getCount());
+ for (String name : shares.keySet()) {
+ double share = shares.get(name);
+
+ do {
+ if (cursor.getString(cursor.getColumnIndex("timestamp")) == null
+ && name.equals(cursor.getString(cursor.getColumnIndex("name")))) {
+ double amount = cursor.getDouble(cursor.getColumnIndex("amount"));
+ assertAmountEquals("Allocation violated.", share, amount);
+ }
+ } while (cursor.moveToNext());
+
+ cursor.moveToFirst();
+ }
+ }
+ return defaultResult;
+ }
+ }, null);
+
+ if (shares != null)
+ zeroSumTest(entry, " and expense > 0");
+
+ return entry;
+ }
+
+ int submissionTest(String submitter, double amount, String purpose) {
+ double total = transactor.total();
+ int entry = transactor.performSubmission(submitter, amount, purpose);
+
+ entryTest(entry, 1, null);
+
+ assertAmountEquals("Wrong result after submission.", total + amount, transactor.total());
+
+ return entry;
+ }
+
+ int payoutTest(String[] recipients, double amount, String purpose, Double... portions) {
+ double total = transactor.total();
+ ShareMap shares = new ShareMap(recipients, amount, portions);
+ int entry = transactor.performMultiple(shares.negated(), purpose);
+
+ entryTest(entry, 0, shares);
+
+ assertAmountEquals("Wrong result after multiple submissions.", total + shares.sum(), transactor.total());
+
+ return entry;
+ }
+
+ int simpleExpenseTest(String submitter, double amount, String purpose, Double... portions) {
+ ShareMap shares = new ShareMap(participants, amount, portions);
+ int entry = transactor.performExpense(submitter, purpose, shares);
+ return entryTest(entry, 1, shares);
+ }
+
+ int expenseTest(String submitter, double amount, String purpose, Integer[] proportions) {
+ ShareMap shares = new ShareMap(participants, amount, proportions);
+ int entryId = transactor.performExpense(submitter, purpose, shares);
+ return entryTest(entryId, 1, shares);
+ }
+
+ int complexExpenseTest(String[] names, Double[] amounts, String purpose, Double... portions) {
+ ShareMap deals = new ShareMap(names, amounts);
+ ShareMap shares = new ShareMap(participants, deals.sum(), portions);
+ int entry = transactor.performComplexExpense(deals, purpose, shares);
+ return entryTest(entry, deals.size() + (deals.containsKey("") ? 1 : 0), shares);
+ }
+
+ void sharingTest(double expectedExpenses, Integer... proportions) {
+ double costs = transactor.expenses();
+ assertEquals("costs are wrong.", expectedExpenses, costs, Transactor.minAmount);
+ ShareMap shares = new ShareMap(participants, costs, proportions);
+ assertAmountEquals("Sharing sucks.", costs, shares.negated().sum());
+ }
+
+ int compensationTest(Integer[] sharingPolicy, Double... expectedValues) {
+ transactor.setSharingPolicy(sharingPolicy);
+ ShareMap compensations = transactor.compensations();
+ assertMapValuesEqual(compensations, expectedValues);
+
+ int entry = transactor.performMultiple(compensations, "compensation");
+ entryTest(entry, 0, compensations);
+ totalTest();
+ return entry;
+ }
+
+ void assertMapValuesEqual(Map map, Double... expectedValues) {
+ int i = 0;
+ for (Map.Entry ey : map.entrySet()) {
+ if (Util.isAvailable(i, expectedValues))
+ assertEquals(ey.getKey() + "'s balance wrong.", expectedValues[i], ey.getValue(), Transactor.minAmount);
+ i++;
+ }
+ }
+
+ void totalTest(double... expected) {
+ double total = transactor.total();
+ if (expected.length > 0)
+ assertEquals("unexpected total : " + Util.formatAmount(total), expected[0], total, Transactor.minAmount);
+ else
+ assertAmountZero("Total is wrong.", total);
+ }
+
+ public void test_Scenario1() {
+ // cost sharing on a trip
+ submissionTest("Tom", 50, "stake");
+ simpleExpenseTest("Bob", 100, "gas");
+ simpleExpenseTest("Sue", 70, "groceries");
+
+ // Kassensturz !
+ totalTest(50);
+ // total of expenses
+ sharingTest(170);
+
+ assertMapValuesEqual(transactor.balances(), 43.33, 13.33, -6.67);
+ // Tom transfers some money to Sue to improve his balance
+ transferTest("Tom", 10, "better balance", "Sue");
+
+ compensationTest(null, -43.33, -3.33, -3.33);
+
+ saveTest("Scenario1");
+ }
+
+ public void test_Scenario2() {
+ // cost sharing on a trip ... more complex
+ submissionTest("Tom", 60, "stake");
+ // Bob pays 100 for gas and uses 50 from the kitty
+ complexExpenseTest(new String[] {"","Bob"}, new Double[] {50.,50.}, "gas");
+ simpleExpenseTest("Sue", 70, "groceries");
+
+ // Kassensturz !
+ totalTest(10);
+ // total of expenses
+ sharingTest(170);
+
+ compensationTest(null, 6.67, -13.33, -3.33);
+
+ saveTest("Scenario2");
+ }
+
+ public void test_Scenario3() {
+ // non-uniform expenses
+ submissionTest(participants[2], 50, "stake");
+ expenseTest(participants[0], 70, "groceries", new Integer[] {3,0,4});
+ expenseTest(participants[0], 100, "gas", new Integer[] {3,7,0});
+
+ totalTest(50);
+ sharingTest(170);
+
+ compensationTest(null, 70., -110., -10.);
+
+ saveTest("Scenario3");
+ }
+
+ public void test_Scenario4() {
+ // same as Scenario1 but with a sharing policy
+ submissionTest("Tom", 50, "stake");
+ simpleExpenseTest("Bob", 100, "gas");
+ simpleExpenseTest("Sue", 70, "groceries");
+
+ totalTest(50);
+ sharingTest(170);
+ transferTest("Tom", 10, "better balance", "Sue");
+
+ int entry = compensationTest(new Integer[] {1,2,2}, -66., 8., 8.);
+ transactor.performDiscard(entry);
+
+ entry = compensationTest(new Integer[] {1,0,1});
+
+ saveTest("Scenario4");
+ }
+
+}
diff --git a/TripCostCalculator/.classpath b/TripCostCalculator/.classpath
index 6efcbb7..4160c21 100644
--- a/TripCostCalculator/.classpath
+++ b/TripCostCalculator/.classpath
@@ -3,5 +3,6 @@
-
+
+