Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Main Simple MFI code and layout files.

  • Loading branch information...
commit 80913ff2121207849e4b6f40d038ec9638099241 1 parent 253e0ee
@kevgibbs authored
Showing with 2,392 additions and 0 deletions.
  1. +8 −0 .classpath
  2. +5 −0 .gitignore
  3. +33 −0 .project
  4. +89 −0 AndroidManifest.xml
  5. +210 −0 LICENSE-2.0.html
  6. +13 −0 README
  7. +26 −0 default.properties
  8. +36 −0 proguard.cfg
  9. BIN  res/drawable-mdpi/ic_menu_cc.png
  10. BIN  res/drawable-mdpi/ic_menu_friendslist.png
  11. BIN  res/drawable/ic_menu_allfriends.png
  12. BIN  res/drawable/icon.png
  13. +60 −0 res/layout/client.xml
  14. +57 −0 res/layout/client_item.xml
  15. +22 −0 res/layout/clients.xml
  16. +46 −0 res/layout/collection.xml
  17. +62 −0 res/layout/collection_item.xml
  18. +229 −0 res/layout/loan.xml
  19. +51 −0 res/layout/loan_item.xml
  20. +36 −0 res/layout/main.xml
  21. +48 −0 res/layout/receipts.xml
  22. +56 −0 res/layout/receipts_item.xml
  23. +52 −0 res/layout/transaction_item.xml
  24. +69 −0 res/values/strings.xml
  25. +177 −0 src/org/simplemfi/app/ClientActivity.java
  26. +58 −0 src/org/simplemfi/app/ClientListActivity.java
  27. +69 −0 src/org/simplemfi/app/CollectionSheetActivity.java
  28. +104 −0 src/org/simplemfi/app/GroupListActivity.java
  29. +99 −0 src/org/simplemfi/app/GroupReceiptsActivity.java
  30. +137 −0 src/org/simplemfi/app/GroupTabActivity.java
  31. +166 −0 src/org/simplemfi/app/LoanActivity.java
  32. +237 −0 src/org/simplemfi/app/OfficerListActivity.java
  33. +137 −0 src/org/simplemfi/app/Util.java
View
8 .classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="lib" path="/JsonSyncStore/jsonstore-1.0.jar" sourcepath="/JsonSyncStore/src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
5 .gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+*.class
+bin/
+gen/
+jsonstore-*.jar
View
33 .project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>simple-mfi</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
89 AndroidManifest.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.simplemfi.app"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="8" />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.USE_CREDENTIALS" />
+ <uses-permission android:name="android.permission.READ_SYNC_STATS" />
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+
+ <activity android:name=".GroupTabActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.PICK_ACTIVITY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.dir/vnd.jsonstore.app.Client" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".CollectionSheetActivity"
+ android:label="@string/app_name">
+ </activity>
+ <activity android:name=".GroupReceiptsActivity"
+ android:label="@string/app_name">
+ </activity>
+ <activity android:name=".ClientListActivity"
+ android:label="@string/app_name">
+ </activity>
+ <activity android:name=".OfficerListActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.PICK" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.dir/vnd.jsonstore.app.Officer" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".GroupListActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.PICK" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.dir/vnd.jsonstore.app.Group" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".ClientActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.item/vnd.jsonstore.app.Client" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".LoanActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.item/vnd.jsonstore.app.Loan" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
View
210 LICENSE-2.0.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" href="LICENSE-2.0_fichiers/style.css" type="text/css">
+ <meta name="author" content="The Apache Software Foundation">
+ <meta name="email" content="apache.AT.apache.DOT.org">
+ <title>Apache License, Version 2.0 - The Apache Software Foundation</title>
+</head>
+<body>
+<p align="center">
+Apache License<br>
+Version 2.0, January 2004<br>
+<a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a>
+</p>
+<p>
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+</p>
+<p><b><a name="definitions">1. Definitions</a></b>.</p>
+<p>
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+</p>
+<p>
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+</p>
+<p>
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+</p>
+<p>
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+</p>
+<p>
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+</p>
+<p>
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+</p>
+<p>
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+</p>
+<p>
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+</p>
+<p>
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+</p>
+<p>
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+</p>
+<p><b><a name="copyright">2. Grant of Copyright License</a></b>.
+Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+</p>
+<p><b><a name="patent">3. Grant of Patent License</a></b>.
+Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+</p>
+<p><b><a name="redistribution">4. Redistribution</a></b>.
+You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+</p><ol type="a">
+<li>You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+<br> <br></li>
+
+<li>You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+<br> <br></li>
+
+<li>You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+<br> <br></li>
+
+<li>If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.</li>
+</ol>
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+<p><b><a name="contributions">5. Submission of Contributions</a></b>.
+Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+</p>
+<p><b><a name="trademarks">6. Trademarks</a></b>.
+This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+</p>
+<p><b><a name="no-warranty">7. Disclaimer of Warranty</a></b>.
+Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+</p>
+<p><b><a name="no-liability">8. Limitation of Liability</a></b>.
+In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+</p>
+<p><b><a name="additional">9. Accepting Warranty or Additional Liability</a></b>.
+While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+</p>
+<p>
+END OF TERMS AND CONDITIONS
+</p>
+</body></html>
View
13 README
@@ -0,0 +1,13 @@
+Copyright (C) 2011 Kevin Gibbs and The Simple MFI Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
View
26 default.properties
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------------------------
+# Copyright 2011 Kevin Gibbs and The Simple MFI Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#-------------------------------------------------------------------------------
+# 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,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-8
View
36 proguard.cfg
@@ -0,0 +1,36 @@
+-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 <methods>;
+}
+
+-keepclasseswithmembernames class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembernames class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
View
BIN  res/drawable-mdpi/ic_menu_cc.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  res/drawable-mdpi/ic_menu_friendslist.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  res/drawable/ic_menu_allfriends.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  res/drawable/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
60 res/layout/client.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+<TextView
+ android:id="@+id/client_name"
+ android:layout_width="fill_parent"
+ android:text="@string/client_title"
+ android:gravity="center"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:layout_height="wrap_content"
+ />
+ <TextView
+ android:id="@+id/savings"
+ android:layout_width="fill_parent"
+ android:text="@string/client_savings"
+ android:gravity="center"
+ android:layout_height="40dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+<include layout="@layout/loan_item"/>
+<ListView
+ android:id="@+id/loans"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:entries="@array/clients_short"
+ />
+<TextView
+ android:layout_width="fill_parent"
+ android:text="@string/client_transactions"
+ android:gravity="center"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:layout_height="wrap_content"
+ />
+<include layout="@layout/transaction_item"/>
+<ListView
+ android:id="@+id/transactions"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:entries="@array/clients_short"
+ />
+</LinearLayout>
+
View
57 res/layout/client_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_height="40dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:paddingLeft="5dip"
+ android:singleLine="true"
+ android:text="2011-05-22"
+ android:layout_width="110dip"
+ android:gravity="center_vertical|left"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text2"
+ android:layout_height="40dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:singleLine="true"
+ android:text="Amount"
+ android:layout_width="fill_parent"
+ android:layout_weight="1"
+ android:gravity="center_vertical|left"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/text3"
+ android:layout_height="40dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:singleLine="true"
+ android:text="-66000"
+ android:layout_width="70dip"
+ android:gravity="center_vertical|left"
+/>
+</LinearLayout>
View
22 res/layout/clients.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:entries="@array/clients_short"
+ />
View
46 res/layout/collection.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+<TextView
+ android:id="@+id/collection_header"
+ android:layout_width="fill_parent"
+ android:text="@string/collection_title"
+ android:gravity="center"
+ style="?android:attr/listSeparatorTextViewStyle"
+ />
+<ListView
+ android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:entries="@array/clients_short"
+ />
+</LinearLayout>
+
+
+ <!-- android:textSize="24sp"
+ android:gravity="center"
+
+
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:gravity="center"
+
+ !-->
View
62 res/layout/collection_item.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/section"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:paddingLeft="5dip"
+ android:singleLine="true"
+ android:text="Section"
+ android:layout_width="fill_parent"
+ android:layout_height="30dip"
+ android:gravity="center"
+ android:visibility="gone"
+/>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:paddingLeft="5dip"
+ android:singleLine="true"
+ android:text="Client Name"
+ android:layout_width="200dip"
+ android:gravity="center_vertical"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text2"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+
+ android:paddingLeft="5dip"
+ android:paddingRight="10dip"
+ android:singleLine="true"
+ android:text="45000"
+ android:layout_width="100dip"
+ android:layout_weight="1"
+ android:gravity="center_vertical|right"
+/>
+</LinearLayout>
+</LinearLayout>
View
229 res/layout/loan.xml
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="7sp"
+ >
+<TextView
+ android:id="@+id/loan_client_name"
+ android:layout_width="fill_parent"
+ android:text="@string/client_title"
+ android:gravity="center"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+
+ />
+ <TextView
+ android:id="@+id/loan_name"
+ android:layout_width="fill_parent"
+ android:text="@string/loan_title"
+ android:gravity="center"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:paddingBottom="7sp"
+ />
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_application_date_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_application_date"
+ android:text="20/4/2011"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_issued_date_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_issued_date"
+ android:text="28/4/2011"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_amount_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_amount"
+ android:text="44500"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_installments_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_installments"
+ android:text="12"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_status_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_status"
+ android:text="In Repayment"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_disbursement_date_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_disbursement_date"
+ android:text="03/05/2011"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_normal_payment_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_normal_payment"
+ android:text="1440"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:text="@string/loan_balance_title"
+ android:gravity="left|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:textColor="@android:color/secondary_text_dark"
+ android:textSize="18sp"
+ />
+<TextView
+ android:id="@+id/loan_balance"
+ android:text="22000"
+ android:gravity="right|center"
+ android:layout_height="26sp"
+ android:layout_width="160dip"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+</LinearLayout>
+
+</LinearLayout>
+
View
51 res/layout/loan_item.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:paddingLeft="5dip"
+ android:singleLine="true"
+ android:text="Loan"
+ android:layout_width="110dip"
+ android:layout_height="30dip"
+ android:gravity="center_vertical|left"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:singleLine="true"
+ android:text="Amount"
+ android:layout_height="30dip"
+ android:layout_weight="1"
+ android:gravity="center_vertical|left"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:singleLine="true"
+ android:text="Balance"
+ android:layout_height="30dip"
+ android:layout_width="70dip"
+ android:gravity="center_vertical|left"
+/>
+</LinearLayout>
View
36 res/layout/main.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/tabhost"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="5dp">
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="5dp" />
+ </LinearLayout>
+</TabHost>
View
48 res/layout/receipts.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <!--
+<TextView
+ android:layout_width="fill_parent"
+ android:text="@string/receipt_title"
+ android:gravity="center"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:layout_height="wrap_content"
+ />
+ !-->
+<ListView
+ android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:entries="@array/clients_short"
+ />
+</LinearLayout>
+
+
+ <!-- android:textSize="24sp"
+ android:gravity="center"
+
+
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:gravity="center"
+
+ !-->
View
56 res/layout/receipts_item.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:paddingLeft="5dip"
+ android:singleLine="true"
+ android:text="Client Name"
+ android:layout_width="100dip"
+ android:layout_weight="1"
+ android:gravity="center_vertical"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text2"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:singleLine="true"
+ android:text="23000"
+ android:layout_width="80dip"
+ android:gravity="center_vertical|left"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/text3"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+
+ android:paddingLeft="5dip"
+ android:paddingRight="10dip"
+ android:singleLine="true"
+ android:text="100"
+ android:layout_width="60dip"
+ android:gravity="center_vertical|left"
+/>
+</LinearLayout>
View
52 res/layout/transaction_item.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:paddingLeft="5dip"
+ android:singleLine="true"
+ android:text="Date"
+ android:layout_width="110dip"
+ android:layout_height="30dip"
+ android:gravity="center_vertical|left"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:singleLine="true"
+ android:text="Type"
+ android:layout_width="fill_parent"
+ android:layout_height="30dip"
+ android:layout_weight="1"
+ android:gravity="center_vertical|left"
+/>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:singleLine="true"
+ android:text="Amount"
+ android:layout_height="30dip"
+ android:layout_width="70dip"
+ android:gravity="center_vertical|left"
+/>
+</LinearLayout>
View
69 res/values/strings.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2011 Kevin Gibbs and The Simple MFI Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">Simple MFI</string>
+
+ <!-- Simple MFI Strings -->
+ <string name="officer_selection_title">Select Officer</string>
+ <string name="client_list_title">Client List</string>
+ <string name="loan_detail_title">Loan Detail</string>
+
+ <string name="menu_sync">Sync</string>
+ <string name="menu_change_group">Change Group</string>
+ <string name="menu_change_officer">Change Officer</string>
+ <string name="menu_add_officer">Add Officer</string>
+
+ <string name="client_savings">Savings:</string>
+ <string name="client_transactions">Transactions:</string>
+
+ <string name="loan_prefix">Loan:</string>
+ <string name="loan_application_date_title">Application Date:</string>
+ <string name="loan_issued_date_title">Issued Date:</string>
+ <string name="loan_amount_title">Amount:</string>
+ <string name="loan_installments_title">Installments:</string>
+ <string name="loan_status_title">Status:</string>
+ <string name="loan_disbursement_date_title">Disbursed:</string>
+ <string name="loan_balance_title">Balance:</string>
+ <string name="loan_normal_payment_title">Normal Payment:</string>
+
+ <string-array name="status_map">
+ <item>Application</item>
+ <item>Being Processed</item>
+ <item>Rejected</item>
+ <item>Approved</item>
+ <item>Issued</item>
+ <item>Being Repaid</item>
+ <item>Repaid</item>
+ </string-array>
+
+ <!-- Example data, used only for graphical layout tool -->
+ <string name="collection_title">May 2011</string>
+ <string name="client_title">Client Name</string>
+ <string name="loan_title">Loan AL04221</string>
+ <string-array name="clients_short">
+ <item>Jane M.</item>
+ <item>Richard T.</item>
+ <item>Mary M.</item>
+ <item>Joseph G.</item>
+ <item>Sally H.</item>
+ <item>Charity S.</item>
+ <item>Ruth E.</item>
+ <item>Sarah P.</item>
+ <item>John G.</item>
+ </string-array>
+
+</resources>
View
177 src/org/simplemfi/app/ClientActivity.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+import java.util.List;
+
+import org.jsonstore.JsonStore;
+import org.jsonstore.JsonStore.Base;
+import org.simplemfi.app.R;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+public class ClientActivity extends Activity {
+
+ private static final String TAG = "ClientActivity";
+
+ // Menu item ids
+ public static final int MENU_ITEM_SYNC = Menu.FIRST;
+
+ private class ChangeObserver extends ContentObserver {
+ public ChangeObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public boolean deliverSelfNotifications() {
+ return true;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ Log.e(TAG, "Content change reported by ContentResolver, updating display.");
+ updateDisplay();
+ }
+ }
+
+ private Cursor mCursor;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Uri uri = getIntent().getData();
+ List<String> path = uri.getPathSegments();
+
+ setContentView(R.layout.client);
+
+ {
+ final Uri loanUri = uri.buildUpon().path(path.get(0)).appendPath("Loan").build();
+ Cursor cursor = managedQuery(loanUri, new String[] { "key", "loanid", "amount",
+ "case balance when 'NULL' then '--' else round(balance) end as balance" },
+ "clientid = ?", new String[] { path.get(2) }, Base.DEFAULT_SORT_ORDER);
+
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.client_item, cursor,
+ new String[] { "loanid", "amount", "balance" },
+ new int[] { android.R.id.text1, android.R.id.text2, R.id.text3 });
+ final ListView listView = ((ListView)findViewById(R.id.loans));
+ listView.setAdapter(adapter);
+
+ listView.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parent, View view,
+ int position, long id) {
+ Cursor cursor = (Cursor)listView.getAdapter().getItem(position);
+ int loc = cursor.getColumnIndex("key");
+ if (loc != -1) {
+ Uri uri = loanUri.buildUpon().appendPath(cursor.getString(loc)).query("").build();
+ startActivity(new Intent(Intent.ACTION_VIEW, uri));
+ }
+ }
+ });
+ }
+
+ {
+ Uri paymentUri = uri.buildUpon().path(path.get(0)).appendPath("Transaction").build();
+ Cursor cursor = managedQuery(paymentUri,
+ new String[] { "date(posting_date,'unixepoch') as posting_date", "description", "round(amount) as amount" },
+ "clientid = ?", new String[] { path.get(2) }, "posting_date desc");
+
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.client_item, cursor,
+ new String[] { "posting_date", "description", "amount" },
+ new int[] { android.R.id.text1, android.R.id.text2, R.id.text3 });
+ ((ListView)findViewById(R.id.transactions)).setAdapter(adapter);
+ }
+
+ getContentResolver().registerContentObserver(getIntent().getData(), false, new ChangeObserver());
+
+ updateDisplay();
+ }
+
+ public void updateDisplay() {
+ if (mCursor == null || !mCursor.requery()) {
+ mCursor = managedQuery(getIntent().getData(), null, null, null, null);
+ }
+
+ mCursor.moveToFirst();
+ if (mCursor.isAfterLast()) {
+ return;
+ }
+ int keyCol = mCursor.getColumnIndex(JsonStore.Base.KEY);
+ int nameCol = mCursor.getColumnIndex("name");
+ if (keyCol != -1 && nameCol != -1) {
+ TextView name = (TextView)findViewById(R.id.client_name);
+ name.setText(mCursor.getString(keyCol) + ": " + mCursor.getString(nameCol));
+ }
+
+ int balanceCol = mCursor.getColumnIndex("balance");
+ if (balanceCol != -1) {
+ TextView savings = (TextView)findViewById(R.id.savings);
+ String savings_title = getString(R.string.client_savings);
+ savings.setText(savings_title + " " + mCursor.getLong(balanceCol));
+ }
+
+ Uri uri = getIntent().getData();
+
+ String groupName = getIntent().getStringExtra("group_name");
+ if (groupName == null) {
+ List<String> path = uri.getPathSegments();
+ Uri groupUri = uri.buildUpon().path(path.get(0)).appendPath("Group")
+ .appendPath(mCursor.getString(mCursor.getColumnIndex("groupid"))).build();
+ groupName = Util.getFieldForKey(groupUri, getContentResolver(), "name");
+ }
+ setTitle(groupName);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+
+ menu.add(0, MENU_ITEM_SYNC, 0, R.string.menu_sync)
+ .setShortcut('4', 's')
+ .setIcon(android.R.drawable.ic_menu_share);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_SYNC:
+ // Launch activity to sync
+ ContentResolver.requestSync(null, JsonStore.AUTHORITY, new Bundle());
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+}
View
58 src/org/simplemfi/app/ClientListActivity.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+import org.simplemfi.app.R;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.AdapterView.OnItemClickListener;
+import android.database.Cursor;
+
+public class ClientListActivity extends ListActivity {
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.clients);
+
+ final Uri uri = getIntent().getData();
+ Cursor cursor = managedQuery(uri, new String[] { "key", "name" }, null, null,
+ Util.DEFAULT_SORT_ORDER);
+
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor,
+ new String[] { "name" }, new int[] { android.R.id.text1 });
+ setListAdapter(adapter);
+
+ getListView().setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parent, View view,
+ int position, long id) {
+ Cursor cursor = (Cursor)getListAdapter().getItem(position);
+ int loc = cursor.getColumnIndex("key");
+ if (loc != -1) {
+ Uri clientUri = uri.buildUpon().appendPath(cursor.getString(loc)).query("").build();
+ startActivity(new Intent(Intent.ACTION_VIEW, clientUri));
+ }
+ }
+ });
+
+ }
+}
View
69 src/org/simplemfi/app/CollectionSheetActivity.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+import java.util.Date;
+import java.util.List;
+
+import org.simplemfi.app.R;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.format.DateFormat;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.TextView;
+
+public class CollectionSheetActivity extends ListActivity {
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.collection);
+
+ TextView header = (TextView)findViewById(R.id.collection_header);
+ header.setText(DateFormat.format("MMMM yyyy", new Date()));
+
+ Uri uri = getIntent().getData();
+ Cursor cursor = managedQuery(uri, new String[] { "key", "name", "payment_due" },
+ "Loan.balance > 0", null, Util.DEFAULT_SORT_ORDER);
+
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.collection_item, cursor,
+ new String[] { "name", "payment_due" }, new int[] { android.R.id.text1, android.R.id.text2 });
+ setListAdapter(adapter);
+
+ getListView().setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parent, View view,
+ int position, long id) {
+ Cursor cursor = (Cursor)getListAdapter().getItem(position);
+ int loc = cursor.getColumnIndex("key");
+ if (loc != -1) {
+ Uri.Builder builder = getIntent().getData().buildUpon();
+ List<String> pathSegments = getIntent().getData().getPathSegments();
+ builder.path(pathSegments.get(0) + "/Client/" + cursor.getString(loc));
+ builder.query("");
+ Uri clientUri = builder.build();
+ startActivity(new Intent(Intent.ACTION_VIEW, clientUri));
+ }
+ }
+ });
+ }
+}
View
104 src/org/simplemfi/app/GroupListActivity.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+import java.util.List;
+
+import org.jsonstore.JsonStore;
+import org.simplemfi.app.R;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class GroupListActivity extends ListActivity {
+
+ // Menu item ids
+ public static final int MENU_ITEM_CHANGE_OFFICER = Menu.FIRST;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setTitle(R.string.officer_selection_title);
+
+ Intent mainIntent = getIntent();
+ if (mainIntent.getData() == null) {
+ mainIntent.setData(
+ JsonStore.Base.CONTENT_URI_BASE.buildUpon().appendEncodedPath("app/Group").build());
+ }
+
+ final Uri uri = mainIntent.getData();
+ Cursor cursor = managedQuery(uri, new String[] { "key", "name" }, null, null, "name asc");
+
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor,
+ new String[] { "name" }, new int[] { android.R.id.text1 });
+ setListAdapter(adapter);
+
+ getListView().setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parent, View view,
+ int position, long id) {
+ Cursor cursor = (Cursor)getListAdapter().getItem(position);
+ int loc = cursor.getColumnIndex("key");
+ if (loc != -1) {
+ Uri.Builder builder = getIntent().getData().buildUpon();
+ List<String> pathSegments = getIntent().getData().getPathSegments();
+ builder.path(pathSegments.get(0) + "/Client");
+ builder.encodedQuery("groupid=" + cursor.getString(loc));
+ Uri clientUri = builder.build();
+ Intent groupIntent = new Intent(Intent.ACTION_PICK_ACTIVITY, clientUri);
+ groupIntent.putExtra("groupid", cursor.getString(loc));
+ startActivity(groupIntent);
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+
+ menu.add(0, MENU_ITEM_CHANGE_OFFICER, 0, R.string.menu_change_officer)
+ .setShortcut('4', 'o')
+ .setIcon(R.drawable.ic_menu_cc);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_CHANGE_OFFICER:
+ Uri.Builder builder = getIntent().getData().buildUpon();
+ List<String> pathSegments = getIntent().getData().getPathSegments();
+ builder.path(pathSegments.get(0) + "/Officer");
+ builder.query("");
+ Uri clientUri = builder.build();
+ Intent officerIntent = new Intent(Intent.ACTION_PICK, clientUri);
+ startActivity(officerIntent);
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
View
99 src/org/simplemfi/app/GroupReceiptsActivity.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+import java.util.List;
+
+import org.simplemfi.app.R;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.SimpleCursorAdapter.ViewBinder;
+
+public class GroupReceiptsActivity extends ListActivity {
+ static final String TAG = "GroupReceiptsActivity";
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.receipts);
+
+ Uri uri = getIntent().getData();
+ Cursor cursor = managedQuery(uri, new String[] { "Client.key", "name",
+ "(date(posting_date,'unixepoch') || ': #' || documentid) as section", "sum(abs(amount)) as amount" },
+ "transaction_type != 2 group by Client.key, name, documentid", null,
+ "posting_date desc, " + Util.DEFAULT_SORT_ORDER);
+
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.collection_item, cursor,
+ new String[] { "name", "amount", "section" },
+ new int[] { android.R.id.text1, android.R.id.text2, R.id.section } );
+ setListAdapter(adapter);
+
+ getListView().setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parent, View view,
+ int position, long id) {
+ Cursor cursor = (Cursor)getListAdapter().getItem(position);
+ int loc = cursor.getColumnIndex("Client.key");
+ if (loc != -1) {
+ Uri.Builder builder = getIntent().getData().buildUpon();
+ List<String> pathSegments = getIntent().getData().getPathSegments();
+ builder.path(pathSegments.get(0) + "/Client/" + cursor.getString(loc));
+ builder.query("");
+ Uri clientUri = builder.build();
+ startActivity(new Intent(Intent.ACTION_VIEW, clientUri));
+ }
+ }
+ });
+
+ // Quick and easy way to create sections, from a group by.
+ // TODO Extract this to a utility class
+ adapter.setViewBinder(new ViewBinder() {
+ int mSectionColumn = -1;
+ @Override
+ public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
+ if (mSectionColumn == -1) {
+ mSectionColumn = cursor.getColumnIndex("section");
+ }
+ if (columnIndex != mSectionColumn) {
+ return false;
+ }
+ String thisSection = cursor.getString(mSectionColumn);
+ String prevSection = "";
+
+ // previous row, for comparison
+ if (cursor.getPosition() > 0 && cursor.moveToPrevious()) {
+ prevSection = cursor.getString(mSectionColumn);
+ cursor.moveToNext();
+ }
+
+ boolean isSection = !thisSection.contentEquals(prevSection);
+ view.setVisibility(isSection ? View.VISIBLE : View.GONE);
+ view.setFocusable(!isSection);
+ // Have the normal ViewBinder set the text for us.
+ return false;
+ }
+ });
+
+ }
+}
View
137 src/org/simplemfi/app/GroupTabActivity.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+import java.util.List;
+
+import org.jsonstore.JsonStore.Meta;
+import org.simplemfi.app.R;
+
+import android.app.TabActivity;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TabHost;
+
+public class GroupTabActivity extends TabActivity {
+
+ // Menu item ids
+ public static final int MENU_ITEM_SYNC = Menu.FIRST;
+ public static final int MENU_ITEM_CHANGE_GROUP = Menu.FIRST + 1;
+
+ /** Called when the activity is first created. */
+ private Uri mURI;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ mURI = getIntent().getData();
+
+ String groupName = Util.getFieldForKey(
+ mURI.buildUpon().path(mURI.getPathSegments().get(0)).appendPath("Group").build(),
+ getContentResolver(), "name");
+ if (groupName.length() == 0) {
+ groupName = getString(R.string.client_list_title);
+ }
+ setTitle(groupName);
+ getIntent().putExtra("group_name", groupName);
+
+ Resources res = getResources(); // Resource object to get Drawables
+ TabHost tabHost = getTabHost(); // The activity TabHost
+ TabHost.TabSpec spec; // Resusable TabSpec for each tab
+ Intent intent; // Reusable Intent for each tab
+
+ // Create an Intent to launch an Activity for the tab (to be reused)
+ Uri collectionUri = mURI.buildUpon().path(mURI.getPathSegments().get(0)).
+ appendPath("Client.Loan").build();
+ intent = new Intent(Intent.ACTION_VIEW, collectionUri, this, CollectionSheetActivity.class);
+ // Initialize a TabSpec for each tab and add it to the TabHost
+ spec = tabHost.newTabSpec("collection").setIndicator("Collection Sheet",
+ res.getDrawable(android.R.drawable.ic_menu_agenda))
+ .setContent(intent);
+ tabHost.addTab(spec);
+
+ // Do the same for the other tabs
+ Uri receiptUri = mURI.buildUpon().path(mURI.getPathSegments().get(0)).appendPath("Client.Transaction").build();
+ intent = new Intent(Intent.ACTION_VIEW, receiptUri, this, GroupReceiptsActivity.class);
+ spec = tabHost.newTabSpec("receipt").setIndicator("Receipts",
+ res.getDrawable(android.R.drawable.ic_dialog_email))
+ .setContent(intent);
+ tabHost.addTab(spec);
+
+ // Do the same for the other tabs
+ intent = new Intent(Intent.ACTION_VIEW, mURI, this, ClientListActivity.class);
+ spec = tabHost.newTabSpec("clients").setIndicator("Clients",
+ res.getDrawable(R.drawable.ic_menu_allfriends))
+ .setContent(intent);
+ tabHost.addTab(spec);
+
+ tabHost.setCurrentTab(0);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+
+ menu.add(0, MENU_ITEM_SYNC, 0, R.string.menu_sync)
+ .setShortcut('4', 's')
+ .setIcon(android.R.drawable.ic_menu_share);
+
+ menu.add(0, MENU_ITEM_CHANGE_GROUP, 0, R.string.menu_change_group)
+ .setShortcut('5', 'g')
+ .setIcon(R.drawable.ic_menu_friendslist);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_SYNC:
+ // Launch activity to sync
+ startActivity(new Intent(Intent.ACTION_SYNC,
+ Meta.CONTENT_URI.buildUpon().appendEncodedPath("app/").build()));
+ return true;
+
+ case MENU_ITEM_CHANGE_GROUP:
+ Uri.Builder builder = getIntent().getData().buildUpon();
+ List<String> pathSegments = getIntent().getData().getPathSegments();
+ builder.path(pathSegments.get(0) + "/Group");
+ String officerid = getIntent().getStringExtra("officerid");
+ if (officerid == null) {
+ officerid = Util.getFieldForKey(
+ mURI.buildUpon().path(mURI.getPathSegments().get(0)).appendPath("Group").build(),
+ getContentResolver(), "officerid");
+ }
+ builder.query("");
+ if (officerid.length() > 0) {
+ builder.encodedQuery("officerid=" + officerid);
+ }
+ Uri clientUri = builder.build();
+ Intent officerIntent = new Intent(Intent.ACTION_PICK, clientUri);
+ startActivity(officerIntent);
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+}
View
166 src/org/simplemfi/app/LoanActivity.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+
+import org.jsonstore.JsonStore;
+import org.simplemfi.app.R;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.TextView;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class LoanActivity extends Activity {
+
+ private static final String TAG = "LoanActivity";
+
+ // Menu item ids
+ public static final int MENU_ITEM_SYNC = Menu.FIRST;
+
+ private class ChangeObserver extends ContentObserver {
+ public ChangeObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public boolean deliverSelfNotifications() {
+ return true;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ Log.e(TAG, "Content change reported by ContentResolver, updating display.");
+ updateDisplay();
+ }
+ }
+
+ private Cursor mCursor;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setTitle(R.string.loan_detail_title);
+ setContentView(R.layout.loan);
+
+ getContentResolver().registerContentObserver(getIntent().getData(), false, new ChangeObserver());
+ updateDisplay();
+ }
+
+ public void updateDisplay() {
+ if (mCursor == null || !mCursor.requery()) {
+ mCursor = managedQuery(getIntent().getData(),
+ new String[] { "key", "clientid", "date(application_date, 'unixepoch') as application_date",
+ "date(issued_date, 'unixepoch') as issued_date", "amount", "installments", "status",
+ "date(disbursement_date, 'unixepoch') as disbursement_date", "balance", "payment_due" } ,
+ null, null, null);
+ }
+
+ mCursor.moveToFirst();
+ if (mCursor.isAfterLast()) {
+ return;
+ }
+ int clientCol = mCursor.getColumnIndex("clientid");
+ if (clientCol != -1) {
+ String client_id = mCursor.getString(clientCol);
+ String client_name = Util.getFieldForKey(
+ JsonStore.Base.CONTENT_URI_BASE.buildUpon().appendEncodedPath("app/Client/" + client_id).build(),
+ getContentResolver(), "name");
+
+ TextView view = (TextView)findViewById(R.id.loan_client_name);
+ view.setText(client_name);
+ }
+
+ setTextView(R.id.loan_name, "key", R.string.loan_prefix);
+ setTextView(R.id.loan_application_date, "application_date", 0);
+ setTextView(R.id.loan_issued_date, "issued_date", 0);
+ setTextView(R.id.loan_amount, "amount", 0);
+ setTextView(R.id.loan_installments, "installments", 0);
+ if (setTextViewMap(R.id.loan_status, "status", R.array.status_map) >= 4) {
+ setTextView(R.id.loan_disbursement_date, "disbursement_date", 0);
+ } else {
+ clearTextView(R.id.loan_disbursement_date);
+ }
+ setTextView(R.id.loan_balance, "balance", 0);
+ setTextView(R.id.loan_normal_payment, "payment_due", 0);
+
+ }
+
+ public void setTextView(int viewid, String column_name, int prefix_id) {
+ int col = mCursor.getColumnIndex(column_name);
+ if (col != -1) {
+ TextView view = (TextView)findViewById(viewid);
+ String prefix = "";
+ if (prefix_id != 0) {
+ prefix = getString(prefix_id) + " ";
+ }
+ String value = mCursor.getString(col);
+ if (mCursor.isNull(col) || value.toLowerCase().equals("null")) {
+ value = "";
+ }
+ view.setText(prefix + value);
+ }
+ }
+
+ public void clearTextView(int viewid) {
+ TextView view = (TextView)findViewById(viewid);
+ view.setText("");
+ }
+
+ public int setTextViewMap(int viewid, String column_name, int arrayid) {
+ String[] valueMap = getResources().getStringArray(arrayid);
+ int col = mCursor.getColumnIndex(column_name);
+ int index = -1;
+ if (col != -1) {
+ TextView view = (TextView)findViewById(viewid);
+ index = mCursor.getInt(col);
+ if (index >= 0 && index < valueMap.length) {
+ view.setText(valueMap[index]);
+ }
+ }
+ return index;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+
+ menu.add(0, MENU_ITEM_SYNC, 0, R.string.menu_sync)
+ .setShortcut('4', 's')
+ .setIcon(android.R.drawable.ic_menu_share);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ITEM_SYNC:
+ // Launch activity to sync
+ ContentResolver.requestSync(null, JsonStore.AUTHORITY, new Bundle());
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+}
View
237 src/org/simplemfi/app/OfficerListActivity.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright 2011 Kevin Gibbs and The Simple MFI Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.simplemfi.app;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.jsonstore.JsonStore;
+import org.jsonstore.JsonStore.Meta;
+import org.simplemfi.app.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.database.MergeCursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Toast;
+
+public class OfficerListActivity extends ListActivity {
+ @SuppressWarnings("unused")
+ private static final String TAG = "OfficerListActivity";
+
+ // Menu item ids
+ public static final int MENU_ITEM_ADD_OFFICER = Menu.FIRST;
+
+ // Dialog ids
+ public static final int DIALOG_ADD_OFFICER = 0;
+ public static final int DIALOG_NEED_ADDITIONAL_OFFICER = 1;
+
+ // Activity request ids
+ public static final int REQUEST_SYNC_ACTIVITY = 0;
+ public static final int REQUEST_INITIAL_SYNC_ACTIVITY = Util.REQUEST_INITIAL_SYNC_ACTIVITY;
+
+ /** Called when the activity is first created. */
+ Bundle mSavedInstanceState;
+
+ public boolean mCreationComplete = false;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mSavedInstanceState = savedInstanceState;
+
+ Intent intent = getIntent();
+ if (intent.getData() == null) {
+ intent.setData(
+ JsonStore.Base.CONTENT_URI_BASE.buildUpon().appendEncodedPath("app/Officer").build());
+ }
+
+ if (Util.startInitialSyncIfNecessary(getContentResolver(), this)) {
+ return;
+ }
+
+ setTitle(R.string.officer_selection_title);
+
+ Uri uri = getIntent().getData();
+ Uri queryUri = uri.buildUpon().encodedPath(uri.getEncodedPath() + ".Client").build();
+ final Cursor cursor = managedQuery(queryUri, new String[] { "Officer.key as key", "Officer.name" },
+ "group by Officer.key", null, "Officer.name asc");
+
+ final MatrixCursor addOfficer = new MatrixCursor(new String[] { "key", "Officer.name", "_id" });
+ addOfficer.addRow(new Object[] { "add_officer", "Add Officer...", new Integer(Integer.MAX_VALUE) } );
+ MergeCursor merge = new MergeCursor(new Cursor[] { cursor, addOfficer } );
+