You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ra...@apache.org on 2018/07/27 07:23:52 UTC

[fineract-cn-mobile] branch development updated (f228af6 -> 27c51d6)

This is an automated email from the ASF dual-hosted git repository.

rajanmaurya154 pushed a change to branch development
in repository https://gitbox.apache.org/repos/asf/fineract-cn-mobile.git.


    from f228af6  fix: gradle check
     new 3432194  feat: list and search ledger
     new 27c51d6  feat : search and list accounts

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/fineract/FakeJsonName.java     |   2 +
 .../org/apache/fineract/FakeRemoteDataSource.java  |  11 ++
 .../data/datamanager/DataManagerAccounting.kt      |  45 ++++++
 .../fineract/data/models/accounts/Account.kt       |  39 +++++
 .../fineract/data/models/accounts/AccountPage.kt   |   9 ++
 .../fineract/data/models/accounts/AccountType.kt   |  21 +++
 .../apache/fineract/data/models/accounts/Ledger.kt |  25 +++
 .../fineract/data/models/accounts/LedgerPage.kt    |   9 ++
 .../fineract/data/remote/BaseApiManager.java       |   8 +-
 .../org/apache/fineract/data/remote/EndPoints.java |   1 +
 .../fineract/data/services/AccountingService.kt    |  27 ++++
 .../injection/component/ActivityComponent.java     |  48 +++---
 .../injection/component/ApplicationComponent.java  |   2 +
 .../apache/fineract/ui/adapters/AccountsAdapter.kt |  66 ++++++++
 .../apache/fineract/ui/adapters/LedgerAdapter.kt   |  65 ++++++++
 .../fineract/ui/online/DashboardActivity.java      |   8 +
 .../online/accounting/accounts/AccountContract.kt  |  33 ++++
 .../online/accounting/accounts/AccountsFragment.kt | 166 ++++++++++++++++++++
 .../accounting/accounts/AccountsPresenter.kt       |  82 ++++++++++
 .../ui/online/accounting/ledgers/LedgerContract.kt |  32 ++++
 .../ui/online/accounting/ledgers/LedgerFragment.kt | 168 +++++++++++++++++++++
 .../online/accounting/ledgers/LedgerPresenter.kt   |  87 +++++++++++
 .../org/apache/fineract/utils/StatusUtils.java     |  28 ++++
 ...stomer_activities.xml => fragment_accounts.xml} |   6 +-
 ...customer_activities.xml => fragment_ledger.xml} |   6 +-
 .../{item_customer_loans.xml => item_account.xml}  |  54 +++----
 .../{item_customer_loans.xml => item_ledger.xml}   |  54 +++----
 ...fication_search.xml => menu_account_search.xml} |   4 +-
 ...ification_search.xml => menu_ledger_search.xml} |   4 +-
 app/src/main/res/menu/menu_navigation_drawer.xml   |  12 ++
 app/src/main/res/values/strings.xml                |   5 +
 app/src/main/resources/accountsPage.json           |  94 ++++++++++++
 app/src/main/resources/ledgerPage.json             |  62 ++++++++
 33 files changed, 1201 insertions(+), 82 deletions(-)
 create mode 100644 app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt
 create mode 100644 app/src/main/java/org/apache/fineract/data/models/accounts/Account.kt
 create mode 100644 app/src/main/java/org/apache/fineract/data/models/accounts/AccountPage.kt
 create mode 100644 app/src/main/java/org/apache/fineract/data/models/accounts/AccountType.kt
 create mode 100644 app/src/main/java/org/apache/fineract/data/models/accounts/Ledger.kt
 create mode 100644 app/src/main/java/org/apache/fineract/data/models/accounts/LedgerPage.kt
 create mode 100644 app/src/main/java/org/apache/fineract/data/services/AccountingService.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/adapters/AccountsAdapter.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/adapters/LedgerAdapter.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountContract.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsFragment.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsPresenter.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerContract.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerFragment.kt
 create mode 100644 app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerPresenter.kt
 copy app/src/main/res/layout/{fragment_customer_activities.xml => fragment_accounts.xml} (81%)
 copy app/src/main/res/layout/{fragment_customer_activities.xml => fragment_ledger.xml} (81%)
 copy app/src/main/res/layout/{item_customer_loans.xml => item_account.xml} (78%)
 copy app/src/main/res/layout/{item_customer_loans.xml => item_ledger.xml} (78%)
 copy app/src/main/res/menu/{menu_identification_search.xml => menu_account_search.xml} (75%)
 copy app/src/main/res/menu/{menu_identification_search.xml => menu_ledger_search.xml} (75%)
 create mode 100644 app/src/main/resources/accountsPage.json
 create mode 100644 app/src/main/resources/ledgerPage.json


[fineract-cn-mobile] 02/02: feat : search and list accounts

Posted by ra...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rajanmaurya154 pushed a commit to branch development
in repository https://gitbox.apache.org/repos/asf/fineract-cn-mobile.git

commit 27c51d62b73490d9420a9c07c6867b8abcd7034f
Author: Mohak <mo...@gmail.com>
AuthorDate: Thu Jul 19 13:34:30 2018 +0530

    feat : search and list accounts
---
 .../java/org/apache/fineract/FakeJsonName.java     |   1 +
 .../org/apache/fineract/FakeRemoteDataSource.java  |   5 +
 .../data/datamanager/DataManagerAccounting.kt      |  14 ++
 .../fineract/data/models/accounts/Account.kt       |  39 +++++
 .../fineract/data/models/accounts/AccountPage.kt   |   9 ++
 .../fineract/data/services/AccountingService.kt    |   8 +
 .../injection/component/ActivityComponent.java     |   3 +
 .../apache/fineract/ui/adapters/AccountsAdapter.kt |  66 ++++++++
 .../fineract/ui/online/DashboardActivity.java      |   4 +
 .../online/accounting/accounts/AccountContract.kt  |  33 ++++
 .../online/accounting/accounts/AccountsFragment.kt | 166 +++++++++++++++++++++
 .../accounting/accounts/AccountsPresenter.kt       |  82 ++++++++++
 app/src/main/res/layout/fragment_accounts.xml      |  26 ++++
 app/src/main/res/layout/item_account.xml           |  76 ++++++++++
 app/src/main/res/menu/menu_account_search.xml      |  12 ++
 app/src/main/res/menu/menu_navigation_drawer.xml   |   5 +
 app/src/main/res/values/strings.xml                |   2 +
 app/src/main/resources/accountsPage.json           |  94 ++++++++++++
 18 files changed, 645 insertions(+)

diff --git a/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java b/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
index 95a3bdd..29c2de8 100644
--- a/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
+++ b/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
@@ -18,4 +18,5 @@ public class FakeJsonName {
     public static final String PLANNED_PAYMENT_PAGE = "plannedPaymentPage.json";
     public static final String ROLES = "role.json";
     public static final String LEDGER_PAGE = "ledgerPage.json";
+    public static final String ACCOUNT_PAGE = "accountsPage.json";
 }
diff --git a/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java b/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
index 02611f9..c510bc1 100644
--- a/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
+++ b/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
@@ -4,6 +4,7 @@ import com.google.gson.reflect.TypeToken;
 
 import org.apache.fineract.data.models.Authentication;
 import org.apache.fineract.data.models.accounts.LedgerPage;
+import org.apache.fineract.data.models.accounts.AccountPage;
 import org.apache.fineract.data.models.customer.Command;
 import org.apache.fineract.data.models.customer.Customer;
 import org.apache.fineract.data.models.customer.CustomerPage;
@@ -84,4 +85,8 @@ public class FakeRemoteDataSource {
         return testDataFactory.getObjectTypePojo(LedgerPage.class, FakeJsonName.LEDGER_PAGE);
     }
 
+    public static AccountPage getAccountPage() {
+        return testDataFactory.getObjectTypePojo(AccountPage.class, FakeJsonName.ACCOUNT_PAGE);
+    }
+
 }
diff --git a/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt b/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt
index 8d96cc6..ed1304d 100644
--- a/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt
+++ b/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt
@@ -9,6 +9,8 @@ import javax.inject.Inject
 import org.apache.fineract.FakeRemoteDataSource
 import org.apache.fineract.data.datamanager.api.DataManagerAuth
 import org.apache.fineract.data.datamanager.api.FineractBaseDataManager
+import org.apache.fineract.data.models.accounts.Account
+import org.apache.fineract.data.models.accounts.AccountPage
 import org.apache.fineract.data.models.accounts.Ledger
 import org.apache.fineract.data.models.accounts.LedgerPage
 import javax.inject.Singleton
@@ -28,4 +30,16 @@ class DataManagerAccounting @Inject constructor(val baseManagerApi: BaseApiManag
             baseManagerApi.accountingService.findLedger(identifier)
                     .onErrorResumeNext(Function<Throwable, ObservableSource<Ledger>>
                     { Observable.just(FakeRemoteDataSource.getLedgerPage()!!.ledgers!![0]) })
+
+    fun getAccounts(): Observable<AccountPage> =
+            baseManagerApi.accountingService.fetchAccounts()
+                    .onErrorResumeNext(Function<Throwable, ObservableSource<AccountPage>>
+                    { Observable.just(FakeRemoteDataSource.getAccountPage()) })
+
+
+    fun findAccount(identifier: String): Observable<Account> =
+            baseManagerApi.accountingService.findAccount(identifier)
+                    .onErrorResumeNext(Function<Throwable, ObservableSource<Account>>
+                    { Observable.just(FakeRemoteDataSource.getAccountPage()!!.accounts!![0]) })
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/data/models/accounts/Account.kt b/app/src/main/java/org/apache/fineract/data/models/accounts/Account.kt
new file mode 100644
index 0000000..52761c4
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/models/accounts/Account.kt
@@ -0,0 +1,39 @@
+package org.apache.fineract.data.models.accounts
+
+import android.os.Parcelable
+import com.google.gson.annotations.SerializedName
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+data class Account(
+
+        @SerializedName("type") val type: AccountType? = null,
+        @SerializedName("identifier") val identifier: String? = null,
+        @SerializedName("name") val name: String? = null,
+        @SerializedName("holders") val holders: Set<String>? = null,
+        @SerializedName("signatureAuthorities") val signatureAuthorities: Set<String>? = null,
+        @SerializedName("balance") val balance: Double? = null,
+        @SerializedName("referenceAccount") val referenceAccount: String? = null,
+        @SerializedName("ledger") val ledger: String? = null,
+        @SerializedName("state") val state: State? = null,
+        @SerializedName("alternativeAccountNumber") val alternativeAccountNumber: String? = null,
+        @SerializedName("createdOn") val createdOn: String? = null,
+        @SerializedName("createdBy") val createdBy: String? = null,
+        @SerializedName("lastModifiedOn") val lastModifiedOn: String? = null,
+        @SerializedName("lastModifiedBy") val lastModifiedBy: String? = null
+
+) : Parcelable {
+
+    enum class State {
+
+        @SerializedName("OPEN")
+        OPEN,
+
+        @SerializedName("LOCKED")
+        LOCKED,
+
+        @SerializedName("CLOSED")
+        CLOSED
+    }
+}
+
diff --git a/app/src/main/java/org/apache/fineract/data/models/accounts/AccountPage.kt b/app/src/main/java/org/apache/fineract/data/models/accounts/AccountPage.kt
new file mode 100644
index 0000000..b13dcb1
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/models/accounts/AccountPage.kt
@@ -0,0 +1,9 @@
+package org.apache.fineract.data.models.accounts
+
+import com.google.gson.annotations.SerializedName
+
+data class AccountPage(
+        @SerializedName("accounts") val accounts: List<Account>? = null,
+        @SerializedName("totalPages") val totalPages: Int? = null,
+        @SerializedName("totalElements") val totalElements: Long? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/data/services/AccountingService.kt b/app/src/main/java/org/apache/fineract/data/services/AccountingService.kt
index fa94fff..491e11e 100644
--- a/app/src/main/java/org/apache/fineract/data/services/AccountingService.kt
+++ b/app/src/main/java/org/apache/fineract/data/services/AccountingService.kt
@@ -1,6 +1,8 @@
 package org.apache.fineract.data.services
 
 import io.reactivex.Observable
+import org.apache.fineract.data.models.accounts.Account
+import org.apache.fineract.data.models.accounts.AccountPage
 import org.apache.fineract.data.models.accounts.Ledger
 import org.apache.fineract.data.models.accounts.LedgerPage
 import org.apache.fineract.data.remote.EndPoints
@@ -16,4 +18,10 @@ interface AccountingService {
     @GET(EndPoints.API_ACCOUNTING_PATH + "/ledgers/{identifier}")
     fun findLedger(@Path("identifier") identifier: String): Observable<Ledger>
 
+    @GET(EndPoints.API_ACCOUNTING_PATH + "/accounts")
+    fun fetchAccounts() : Observable<AccountPage>
+
+    @GET(EndPoints.API_ACCOUNTING_PATH + "/accounts/{identifier}")
+    fun findAccount(@Path("identifier") identifier: String): Observable<Account>
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java b/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java
index 144a10a..09e014e 100644
--- a/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java
+++ b/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java
@@ -43,6 +43,7 @@ import org.apache.fineract.ui.online.loanaccounts.loandetails.CustomerLoanDetail
 import org.apache.fineract.ui.online.loanaccounts.plannedpayment.PlannedPaymentFragment;
 import org.apache.fineract.ui.online.login.LoginActivity;
 import org.apache.fineract.ui.online.roles.roleslist.RolesFragment;
+import org.apache.fineract.ui.online.accounting.accounts.AccountsFragment;
 
 import dagger.Subcomponent;
 
@@ -112,4 +113,6 @@ public interface ActivityComponent {
     void inject(CustomerPayloadFragment customerPayloadFragment);
 
     void inject(LedgerFragment ledgerFragment);
+
+    void inject(AccountsFragment accountsFragment);
 }
diff --git a/app/src/main/java/org/apache/fineract/ui/adapters/AccountsAdapter.kt b/app/src/main/java/org/apache/fineract/ui/adapters/AccountsAdapter.kt
new file mode 100644
index 0000000..784603a
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/adapters/AccountsAdapter.kt
@@ -0,0 +1,66 @@
+package org.apache.fineract.ui.adapters
+
+import android.content.Context
+import android.support.v7.widget.AppCompatImageView
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import kotlinx.android.synthetic.main.item_account.view.*
+import org.apache.fineract.R
+import org.apache.fineract.data.models.accounts.Account
+import org.apache.fineract.injection.ApplicationContext
+import org.apache.fineract.utils.DateUtils
+import org.apache.fineract.utils.StatusUtils
+import javax.inject.Inject
+
+class AccountsAdapter @Inject constructor(@ApplicationContext val context: Context)
+    : RecyclerView.Adapter<AccountsAdapter.ViewHolder>() {
+
+    var accounts: List<Account> = ArrayList()
+
+    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+
+        val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_account, parent, false)
+        return ViewHolder(view)
+    }
+
+    override fun getItemCount(): Int = accounts.size
+
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+
+        val account = accounts[position]
+
+        holder.tvIdentifier.text = account.identifier
+
+        val modifiedBy = context.getString(R.string.last_modified_by) + context.getString(
+                R.string.colon) + account.lastModifiedBy
+        holder.tvModifiedBy.text = modifiedBy
+
+        val lastModifiedOn = context.getString(R.string.last_modified_on) + context.getString(
+                R.string.colon) +
+                DateUtils.getDate(account.lastModifiedOn,
+                        DateUtils.INPUT_DATE_FORMAT, DateUtils.OUTPUT_DATE_FORMAT)
+
+        StatusUtils.setAccountType(account.type, holder.ivAccountTypeIndicator, context)
+
+        holder.tvModifiedOn.text = lastModifiedOn
+        holder.tvName.text = account.name
+    }
+
+    fun setAccountsList(accounts: List<Account>) {
+        this.accounts = accounts
+        notifyDataSetChanged()
+    }
+
+    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+
+        val tvIdentifier: TextView = itemView.tv_account_identifier
+        val tvModifiedBy: TextView = itemView.tv_modified_by
+        val tvModifiedOn: TextView = itemView.tv_modified_on
+        val tvName: TextView = itemView.tv_name
+        val ivAccountTypeIndicator: AppCompatImageView = itemView.iv_type_indicator
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java b/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java
index 2b782cb..fe07f9d 100644
--- a/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java
+++ b/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java
@@ -18,6 +18,7 @@ import org.apache.fineract.jobs.StartSyncJob;
 import org.apache.fineract.ui.base.FineractBaseActivity;
 import org.apache.fineract.ui.offline.CustomerPayloadFragment;
 import org.apache.fineract.ui.online.accounting.ledgers.LedgerFragment;
+import org.apache.fineract.ui.online.accounting.accounts.AccountsFragment;
 import org.apache.fineract.ui.online.customers.customerlist.CustomersFragment;
 import org.apache.fineract.ui.online.dashboard.DashboardFragment;
 import org.apache.fineract.ui.online.launcher.LauncherActivity;
@@ -117,7 +118,10 @@ public class DashboardActivity extends FineractBaseActivity implements
             case R.id.item_ledger:
                 replaceFragment(LedgerFragment.Companion.newInstance(), true, R.id.container);
                 break;
+            case R.id.item_accounts:
+                replaceFragment(AccountsFragment.Companion.newInstance(), true, R.id.container);
         }
+
         drawerLayout.closeDrawer(Gravity.START);
         setTitle(item.getTitle());
         return true;
diff --git a/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountContract.kt b/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountContract.kt
new file mode 100644
index 0000000..3fab8a6
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountContract.kt
@@ -0,0 +1,33 @@
+package org.apache.fineract.ui.online.accounting.accounts
+
+import org.apache.fineract.data.models.accounts.Account
+import org.apache.fineract.ui.base.MvpView
+
+interface AccountContract {
+
+    interface View : MvpView {
+
+        fun showUserInterface()
+
+        fun showAccounts(accounts: List<Account>)
+
+        fun showEmptyAccounts()
+
+        fun showRecyclerView(status: Boolean)
+
+        fun showProgressbar()
+
+        fun hideProgressbar()
+
+        fun searchedAccount(account: Account)
+
+
+    }
+
+    interface Presenter {
+
+        fun getAccountsPage()
+
+        fun searchAccount(query: String)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsFragment.kt b/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsFragment.kt
new file mode 100644
index 0000000..a195fe3
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsFragment.kt
@@ -0,0 +1,166 @@
+package org.apache.fineract.ui.online.accounting.accounts
+
+import android.app.SearchManager
+import android.content.Context
+import android.os.Bundle
+import android.support.v4.widget.SwipeRefreshLayout
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.SearchView
+import android.text.TextUtils
+import android.view.*
+import kotlinx.android.synthetic.main.fragment_accounts.*
+import kotlinx.android.synthetic.main.layout_exception_handler.*
+import org.apache.fineract.R
+import org.apache.fineract.data.models.accounts.Account
+import org.apache.fineract.ui.adapters.AccountsAdapter
+import org.apache.fineract.ui.base.FineractBaseActivity
+import org.apache.fineract.ui.base.FineractBaseFragment
+import java.util.*
+import javax.inject.Inject
+
+
+class AccountsFragment : FineractBaseFragment(), AccountContract.View, SwipeRefreshLayout.OnRefreshListener {
+
+    @Inject
+    lateinit var accountsPresenter: AccountsPresenter
+
+    @Inject
+    lateinit var accountsAdapter: AccountsAdapter
+
+    lateinit var accountList : List<Account>
+
+    companion object {
+        fun newInstance() = AccountsFragment()
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setHasOptionsMenu(true)
+        accountList= ArrayList()
+    }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+                              savedInstanceState: Bundle?): View? {
+
+        val rootView = inflater.inflate(R.layout.fragment_accounts, container, false)
+        (activity as FineractBaseActivity).activityComponent.inject(this)
+        accountsPresenter.attachView(this)
+        initializeFineractUIErrorHandler(activity, rootView)
+
+        return rootView
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        showUserInterface()
+
+        btn_try_again.setOnClickListener {
+            layoutError.visibility = View.GONE
+            accountsPresenter.getAccountsPage()
+        }
+
+        accountsPresenter.getAccountsPage()
+    }
+
+    override fun showUserInterface() {
+        setToolbarTitle(getString(R.string.accounts))
+        val layoutManager = LinearLayoutManager(activity)
+        layoutManager.orientation = LinearLayoutManager.VERTICAL
+        rvAccount.layoutManager = layoutManager
+        rvAccount.setHasFixedSize(true)
+
+        rvAccount.adapter = accountsAdapter
+
+        swipeContainer.setColorSchemeColors(*activity!!
+                .resources.getIntArray(R.array.swipeRefreshColors))
+        swipeContainer.setOnRefreshListener(this)
+    }
+
+
+    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+        super.onCreateOptionsMenu(menu, inflater)
+        inflater?.inflate(R.menu.menu_account_search, menu)
+        setUpSearchInterface(menu)
+    }
+
+    private fun setUpSearchInterface(menu: Menu?) {
+
+        val searchManager = activity?.getSystemService(Context.SEARCH_SERVICE) as? SearchManager
+        val searchView = menu?.findItem(R.id.account_search)?.actionView as? SearchView
+
+        searchView?.setSearchableInfo(searchManager?.getSearchableInfo(activity?.componentName))
+
+        searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+            override fun onQueryTextSubmit(query: String): Boolean {
+                accountsPresenter.searchAccount(query)
+                return false
+            }
+
+            override fun onQueryTextChange(newText: String): Boolean {
+                if (TextUtils.isEmpty(newText)) {
+                    showRecyclerView(true)
+                    accountsAdapter.setAccountsList(accountList)
+                }
+
+                return false
+            }
+        })
+
+    }
+
+    override fun searchedAccount(account: Account) {
+        showRecyclerView(true)
+        accountsAdapter.setAccountsList(Collections.singletonList(account))
+    }
+
+    override fun onRefresh() {
+        accountsPresenter.getAccountsPage()
+    }
+
+
+    override fun showAccounts(accounts: List<Account>) {
+        showRecyclerView(true)
+        accountList = accounts
+        accountsAdapter.setAccountsList(accountList)
+    }
+
+    override fun showEmptyAccounts() {
+        showRecyclerView(false)
+        showFineractEmptyUI(getString(R.string.accounts), getString(R.string.accounts),
+                R.drawable.ic_person_outline_black_24dp)
+    }
+
+    override fun showRecyclerView(status: Boolean) {
+        if (status) {
+            rvAccount.visibility = View.VISIBLE
+            layoutError.visibility = View.GONE
+        } else {
+            rvAccount.visibility = View.GONE
+            layoutError.visibility = View.VISIBLE
+        }
+    }
+
+    override fun showProgressbar() {
+        swipeContainer.isRefreshing = true
+    }
+
+    override fun hideProgressbar() {
+        swipeContainer.isRefreshing = false
+    }
+
+    override fun showNoInternetConnection() {
+        showRecyclerView(false)
+        showFineractNoInternetUI()
+    }
+
+    override fun showError(message: String) {
+        showRecyclerView(false)
+        showFineractErrorUI(getString(R.string.accounts))
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        accountsPresenter.detachView()
+    }
+
+}
diff --git a/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsPresenter.kt b/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsPresenter.kt
new file mode 100644
index 0000000..870335d
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/accounting/accounts/AccountsPresenter.kt
@@ -0,0 +1,82 @@
+package org.apache.fineract.ui.online.accounting.accounts
+
+import android.content.Context
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.observers.DisposableObserver
+import io.reactivex.schedulers.Schedulers
+import org.apache.fineract.R
+import org.apache.fineract.data.datamanager.DataManagerAccounting
+import org.apache.fineract.data.models.accounts.Account
+import org.apache.fineract.data.models.accounts.AccountPage
+import org.apache.fineract.injection.ApplicationContext
+import org.apache.fineract.ui.base.BasePresenter
+import javax.inject.Inject
+
+class AccountsPresenter @Inject constructor(@ApplicationContext context: Context,
+                                            val dataManagerAccounting: DataManagerAccounting)
+    : BasePresenter<AccountContract.View>(context), AccountContract.Presenter {
+
+    val compositeDisposable: CompositeDisposable = CompositeDisposable()
+
+    override fun getAccountsPage() {
+        checkViewAttached()
+        mvpView.showProgressbar()
+
+        compositeDisposable.add(dataManagerAccounting.getAccounts()
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribeWith(object : DisposableObserver<AccountPage>() {
+                    override fun onComplete() {
+
+                    }
+
+                    override fun onNext(accountPage: AccountPage) {
+
+                        mvpView.hideProgressbar()
+
+                        if (accountPage.accounts != null) {
+                            if (accountPage.accounts.isEmpty()) {
+                                mvpView.showEmptyAccounts()
+                            } else {
+                                mvpView.showAccounts(accountPage.accounts)
+                            }
+                        }
+                    }
+
+                    override fun onError(e: Throwable) {
+                        mvpView.hideProgressbar()
+                        showExceptionError(e, context.getString(R.string.error_fetching_accounts))
+                    }
+                }))
+    }
+
+    override fun searchAccount(query: String) {
+        checkViewAttached()
+        mvpView.showProgressbar()
+
+        compositeDisposable.add(dataManagerAccounting
+                .findAccount(query)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribeWith(object : DisposableObserver<Account>() {
+                    override fun onComplete() {
+
+                    }
+
+                    override fun onNext(account: Account) {
+                        mvpView.hideProgressbar()
+                        mvpView.searchedAccount(account)
+
+                    }
+
+                    override fun onError(e: Throwable) {
+
+                        mvpView.hideProgressbar()
+                        showExceptionError(e, context.getString(R.string.error_fetching_accounts))
+                    }
+                }))
+    }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_accounts.xml b/app/src/main/res/layout/fragment_accounts.xml
new file mode 100644
index 0000000..164d6a0
--- /dev/null
+++ b/app/src/main/res/layout/fragment_accounts.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.design.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipeContainer"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent">
+
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/rvAccount"
+            android:layout_centerHorizontal="true"
+            android:layout_height="0dp"
+            android:layout_marginBottom="@dimen/layout_padding_30dp"
+            android:layout_weight="1"
+            android:layout_width="wrap_content"/>
+    </android.support.v4.widget.SwipeRefreshLayout>
+
+    <include
+        layout="@layout/layout_exception_handler"
+        android:id="@+id/layoutError"
+        android:visibility="gone"/>
+
+</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_account.xml b/app/src/main/res/layout/item_account.xml
new file mode 100644
index 0000000..572c4ae
--- /dev/null
+++ b/app/src/main/res/layout/item_account.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/ll_loan_accounts"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clickable="true"
+    android:foreground="?android:attr/selectableItemBackground"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/ll_account"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/iv_type_indicator"
+            android:layout_width="@dimen/side_bar_width"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="@dimen/default_margin"
+            android:layout_marginTop="@dimen/default_margin"
+            app:srcCompat="@drawable/round_corner" />
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:orientation="vertical"
+            android:padding="@dimen/layout_padding_24dp">
+
+            <TextView
+                android:id="@+id/tv_account_identifier"
+                style="@style/Base.TextAppearance.AppCompat.Medium"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:textColor="@color/black"
+                tools:text="Account Identifier" />
+
+            <TextView
+                android:id="@+id/tv_modified_by"
+                style="@style/Base.TextAppearance.AppCompat.Small"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ellipsize="end"
+                android:lines="1"
+                tools:text="Last modified by: rajan" />
+
+            <TextView
+                android:id="@+id/tv_modified_on"
+                style="@style/Base.TextAppearance.AppCompat.Small"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                tools:text="Last modified on: 10 July 2018" />
+
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/tv_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginEnd="@dimen/layout_padding_24dp"
+            android:layout_marginRight="@dimen/layout_padding_24dp"
+            android:textSize="@dimen/text_medium"
+            tools:text="Total Value" />
+
+    </LinearLayout>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0.2dp"
+        android:background="#E7DFDF" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_account_search.xml b/app/src/main/res/menu/menu_account_search.xml
new file mode 100644
index 0000000..2970d73
--- /dev/null
+++ b/app/src/main/res/menu/menu_account_search.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:app="http://schemas.android.com/apk/res-auto"
+      xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/account_search"
+        android:icon="@drawable/ic_search_black_24dp"
+        android:title="@string/ledger_search"
+        app:showAsAction="always"
+        app:actionViewClass="android.support.v7.widget.SearchView"/>
+
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_navigation_drawer.xml b/app/src/main/res/menu/menu_navigation_drawer.xml
index 0d505c2..086432f 100644
--- a/app/src/main/res/menu/menu_navigation_drawer.xml
+++ b/app/src/main/res/menu/menu_navigation_drawer.xml
@@ -35,6 +35,11 @@
             android:id="@+id/item_ledger"
             android:title="@string/ledger"/>
 
+        <item
+            android:checked="true"
+            android:icon="@drawable/ic_customer_black_24dp"
+            android:id="@+id/item_accounts"
+            android:title="@string/accounts"/>
 
     </group>
 
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e81ddf5..737d1ae 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -83,6 +83,7 @@
     <string name="description">Description</string>
     <string name="products">Products</string>
     <string name="ledger">Ledgers</string>
+    <string name="accounts">Accounts</string>
     <string name="day">Day</string>
     <string name="in">In</string>
     <string name="required">Required</string>
@@ -268,6 +269,7 @@
     <string name="error_fetching_customer_activities">Error fetching customer activities</string>
     <string name="error_fetching_roles">Error fetching roles</string>
     <string name="error_fetching_ledger">Error fetching ledger</string>
+    <string name="error_fetching_accounts">Error fetching accounts</string>
     <string name="error_sorry_not_able_to_load">Sorry we weren\'t able to load</string>
     <string name="error_fetching_customer_details">Failed to fetch customer details</string>
     <string name="error_fetching_deposit_product">Failed to fetch deposit product</string>
diff --git a/app/src/main/resources/accountsPage.json b/app/src/main/resources/accountsPage.json
new file mode 100644
index 0000000..09b69fb
--- /dev/null
+++ b/app/src/main/resources/accountsPage.json
@@ -0,0 +1,94 @@
+{
+  "accounts": [
+    {
+      "type": "ASSET",
+      "identifier": "identifier1",
+      "name": "name1",
+      "holders": [
+        "holders1",
+        "holders2"
+      ],
+      "signatureAuthorities": [
+        "signatureAuthorities1",
+        "signatureAuthorities2"
+      ],
+      "balance": 1200,
+      "referenceAccount": "referenceAccount",
+      "ledger": "ledger",
+      "state": "OPEN",
+      "alternativeAccountNumber": "alternativeAccountNumber",
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy"
+    },
+    {
+      "type": "LIABILITY",
+      "identifier": "identifier2",
+      "name": "name2",
+      "holders": [
+        "holders1",
+        "holders2"
+      ],
+      "signatureAuthorities": [
+        "signatureAuthorities1",
+        "signatureAuthorities2"
+      ],
+      "balance": 1500,
+      "referenceAccount": "referenceAccount",
+      "ledger": "ledger",
+      "state": "LOCKED",
+      "alternativeAccountNumber": "alternativeAccountNumber",
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy"
+    },
+    {
+      "type": "EQUITY",
+      "identifier": "identifier3",
+      "name": "name3",
+      "holders": [
+        "holders1",
+        "holders2"
+      ],
+      "signatureAuthorities": [
+        "signatureAuthorities1",
+        "signatureAuthorities2"
+      ],
+      "balance": 1500,
+      "referenceAccount": "referenceAccount",
+      "ledger": "ledger",
+      "state": "CLOSE",
+      "alternativeAccountNumber": "alternativeAccountNumber",
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy"
+    },
+    {
+      "type": "REVENUE",
+      "identifier": "identifier4",
+      "name": "name4",
+      "holders": [
+        "holders1",
+        "holders2"
+      ],
+      "signatureAuthorities": [
+        "signatureAuthorities1",
+        "signatureAuthorities2"
+      ],
+      "balance": 1500,
+      "referenceAccount": "referenceAccount",
+      "ledger": "ledger",
+      "state": "OPEN",
+      "alternativeAccountNumber": "alternativeAccountNumber",
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy"
+    }
+  ],
+  "totalPages": 1,
+  "totalElements": 4
+}
\ No newline at end of file


[fineract-cn-mobile] 01/02: feat: list and search ledger

Posted by ra...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rajanmaurya154 pushed a commit to branch development
in repository https://gitbox.apache.org/repos/asf/fineract-cn-mobile.git

commit 3432194ca2ea29cee805c678fa98a6f0741f4f17
Author: Mohak <mo...@gmail.com>
AuthorDate: Tue Jul 17 11:28:34 2018 +0530

    feat: list and search ledger
---
 .../java/org/apache/fineract/FakeJsonName.java     |   1 +
 .../org/apache/fineract/FakeRemoteDataSource.java  |   6 +
 .../data/datamanager/DataManagerAccounting.kt      |  31 ++++
 .../fineract/data/models/accounts/AccountType.kt   |  21 +++
 .../apache/fineract/data/models/accounts/Ledger.kt |  25 +++
 .../fineract/data/models/accounts/LedgerPage.kt    |   9 ++
 .../fineract/data/remote/BaseApiManager.java       |   8 +-
 .../org/apache/fineract/data/remote/EndPoints.java |   1 +
 .../fineract/data/services/AccountingService.kt    |  19 +++
 .../injection/component/ActivityComponent.java     |  45 +++---
 .../injection/component/ApplicationComponent.java  |   2 +
 .../apache/fineract/ui/adapters/LedgerAdapter.kt   |  65 ++++++++
 .../fineract/ui/online/DashboardActivity.java      |   4 +
 .../ui/online/accounting/ledgers/LedgerContract.kt |  32 ++++
 .../ui/online/accounting/ledgers/LedgerFragment.kt | 168 +++++++++++++++++++++
 .../online/accounting/ledgers/LedgerPresenter.kt   |  87 +++++++++++
 .../org/apache/fineract/utils/StatusUtils.java     |  28 ++++
 app/src/main/res/layout/fragment_ledger.xml        |  26 ++++
 app/src/main/res/layout/item_ledger.xml            |  76 ++++++++++
 app/src/main/res/menu/menu_ledger_search.xml       |  12 ++
 app/src/main/res/menu/menu_navigation_drawer.xml   |   7 +
 app/src/main/res/values/strings.xml                |   3 +
 app/src/main/resources/ledgerPage.json             |  62 ++++++++
 23 files changed, 720 insertions(+), 18 deletions(-)

diff --git a/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java b/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
index 441ae48..95a3bdd 100644
--- a/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
+++ b/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
@@ -17,4 +17,5 @@ public class FakeJsonName {
     public static final String LOAN_ACCOUNT = "loanAccount.json";
     public static final String PLANNED_PAYMENT_PAGE = "plannedPaymentPage.json";
     public static final String ROLES = "role.json";
+    public static final String LEDGER_PAGE = "ledgerPage.json";
 }
diff --git a/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java b/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
index 01f6bb3..02611f9 100644
--- a/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
+++ b/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
@@ -3,6 +3,7 @@ package org.apache.fineract;
 import com.google.gson.reflect.TypeToken;
 
 import org.apache.fineract.data.models.Authentication;
+import org.apache.fineract.data.models.accounts.LedgerPage;
 import org.apache.fineract.data.models.customer.Command;
 import org.apache.fineract.data.models.customer.Customer;
 import org.apache.fineract.data.models.customer.CustomerPage;
@@ -78,4 +79,9 @@ public class FakeRemoteDataSource {
         return testDataFactory.getObjectTypePojo(PlannedPaymentPage.class,
                 FakeJsonName.PLANNED_PAYMENT_PAGE);
     }
+
+    public static LedgerPage getLedgerPage() {
+        return testDataFactory.getObjectTypePojo(LedgerPage.class, FakeJsonName.LEDGER_PAGE);
+    }
+
 }
diff --git a/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt b/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt
new file mode 100644
index 0000000..8d96cc6
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerAccounting.kt
@@ -0,0 +1,31 @@
+package org.apache.fineract.data.datamanager
+
+import io.reactivex.Observable
+import io.reactivex.ObservableSource
+import io.reactivex.functions.Function
+import org.apache.fineract.data.local.PreferencesHelper
+import org.apache.fineract.data.remote.BaseApiManager
+import javax.inject.Inject
+import org.apache.fineract.FakeRemoteDataSource
+import org.apache.fineract.data.datamanager.api.DataManagerAuth
+import org.apache.fineract.data.datamanager.api.FineractBaseDataManager
+import org.apache.fineract.data.models.accounts.Ledger
+import org.apache.fineract.data.models.accounts.LedgerPage
+import javax.inject.Singleton
+
+@Singleton
+class DataManagerAccounting @Inject constructor(val baseManagerApi: BaseApiManager,
+                                                dataManagerAuth: DataManagerAuth,
+                                                val preferencesHelper: PreferencesHelper)
+    : FineractBaseDataManager(dataManagerAuth, preferencesHelper) {
+
+    fun fetchLedgers(): Observable<LedgerPage> =
+            baseManagerApi.accountingService.fetchLedgers()
+                    .onErrorResumeNext(Function<Throwable, ObservableSource<LedgerPage>>
+                    { Observable.just(FakeRemoteDataSource.getLedgerPage()) })
+
+    fun findLedger(identifier: String): Observable<Ledger> =
+            baseManagerApi.accountingService.findLedger(identifier)
+                    .onErrorResumeNext(Function<Throwable, ObservableSource<Ledger>>
+                    { Observable.just(FakeRemoteDataSource.getLedgerPage()!!.ledgers!![0]) })
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/data/models/accounts/AccountType.kt b/app/src/main/java/org/apache/fineract/data/models/accounts/AccountType.kt
new file mode 100644
index 0000000..f0495a2
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/models/accounts/AccountType.kt
@@ -0,0 +1,21 @@
+package org.apache.fineract.data.models.accounts
+
+import com.google.gson.annotations.SerializedName
+
+enum class AccountType {
+
+    @SerializedName("ASSET")
+    ASSET,
+
+    @SerializedName("LIABILITY")
+    LIABILITY,
+
+    @SerializedName("EQUITY")
+    EQUITY,
+
+    @SerializedName("REVENUE")
+    REVENUE,
+
+    @SerializedName("EXPENSE")
+    EXPENSE
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/data/models/accounts/Ledger.kt b/app/src/main/java/org/apache/fineract/data/models/accounts/Ledger.kt
new file mode 100644
index 0000000..b945674
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/models/accounts/Ledger.kt
@@ -0,0 +1,25 @@
+package org.apache.fineract.data.models.accounts
+
+import android.os.Parcelable
+import com.google.gson.annotations.SerializedName
+import kotlinx.android.parcel.Parcelize
+import java.math.BigDecimal
+
+@Parcelize
+data class Ledger(
+
+        @SerializedName("type") val type: AccountType,
+        @SerializedName("identifier") val identifier: String? = null,
+        @SerializedName("name") val name: String? = null,
+        @SerializedName("description") val description: String? = null,
+        @SerializedName("parentLedgerIdentifier") val parentLedgerIdentifier: String? = null,
+        @SerializedName("subLedgers") val subLedgers: List<Ledger>? = null,
+        @SerializedName("totalValue") val totalValue: BigDecimal? = null,
+        @SerializedName("createdOn") val createdOn: String? = null,
+        @SerializedName("createdBy") val createdBy: String? = null,
+        @SerializedName("lastModifiedOn") val lastModifiedOn: String? = null,
+        @SerializedName("lastModifiedBy") val lastModifiedBy: String? = null,
+        @SerializedName("showAccountsInChart") val showAccountsInChart: Boolean
+
+) : Parcelable
+
diff --git a/app/src/main/java/org/apache/fineract/data/models/accounts/LedgerPage.kt b/app/src/main/java/org/apache/fineract/data/models/accounts/LedgerPage.kt
new file mode 100644
index 0000000..3094be6
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/models/accounts/LedgerPage.kt
@@ -0,0 +1,9 @@
+package org.apache.fineract.data.models.accounts
+
+import com.google.gson.annotations.SerializedName
+
+data class LedgerPage(
+        @SerializedName("ledgers") val ledgers: List<Ledger>? = null,
+        @SerializedName("totalPages") val totalPages: Int? = null,
+        @SerializedName("totalElements") val totalElements: Long? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/data/remote/BaseApiManager.java b/app/src/main/java/org/apache/fineract/data/remote/BaseApiManager.java
index a757812..0b8e0de 100644
--- a/app/src/main/java/org/apache/fineract/data/remote/BaseApiManager.java
+++ b/app/src/main/java/org/apache/fineract/data/remote/BaseApiManager.java
@@ -2,6 +2,7 @@ package org.apache.fineract.data.remote;
 
 import android.content.Context;
 
+import org.apache.fineract.data.services.AccountingService;
 import org.apache.fineract.data.services.AnonymousService;
 import org.apache.fineract.data.services.AuthService;
 import org.apache.fineract.data.services.CustomerService;
@@ -33,7 +34,7 @@ public class BaseApiManager {
     private static IndividualLendingService individualLendingService;
     private static AnonymousService anonymousService;
     private static RolesService rolesService;
-
+    private static AccountingService accountingService;
 
     public BaseApiManager(Context context) {
         createService(context);
@@ -47,6 +48,7 @@ public class BaseApiManager {
         loanApi = createApi(LoanService.class);
         individualLendingService = createApi(IndividualLendingService.class);
         rolesService = createApi(RolesService.class);
+        accountingService = createApi(AccountingService.class);
     }
 
     private static void initAnonymous() {
@@ -115,4 +117,8 @@ public class BaseApiManager {
     public RolesService getRolesAndPermissionsService() {
         return rolesService;
     }
+
+    public  AccountingService getAccountingService() {
+        return accountingService;
+    }
 }
diff --git a/app/src/main/java/org/apache/fineract/data/remote/EndPoints.java b/app/src/main/java/org/apache/fineract/data/remote/EndPoints.java
index 8172ea0..4bd9a21 100644
--- a/app/src/main/java/org/apache/fineract/data/remote/EndPoints.java
+++ b/app/src/main/java/org/apache/fineract/data/remote/EndPoints.java
@@ -15,5 +15,6 @@ public class EndPoints {
     public static final String API_CUSTOMER_PATH = "/api/customer/v1";
     public static final String API_DEPOSIT_PATH = "/api/deposit/v1";
     public static final String API_PORTFOLIO_PATH = "/api/portfolio/v1";
+    public static final String API_ACCOUNTING_PATH = "/api/accounting/v1";
 
 }
diff --git a/app/src/main/java/org/apache/fineract/data/services/AccountingService.kt b/app/src/main/java/org/apache/fineract/data/services/AccountingService.kt
new file mode 100644
index 0000000..fa94fff
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/services/AccountingService.kt
@@ -0,0 +1,19 @@
+package org.apache.fineract.data.services
+
+import io.reactivex.Observable
+import org.apache.fineract.data.models.accounts.Ledger
+import org.apache.fineract.data.models.accounts.LedgerPage
+import org.apache.fineract.data.remote.EndPoints
+import retrofit2.http.GET
+import retrofit2.http.Path
+
+
+interface AccountingService {
+
+    @GET(EndPoints.API_ACCOUNTING_PATH + "/ledgers")
+    fun fetchLedgers(): Observable<LedgerPage>
+
+    @GET(EndPoints.API_ACCOUNTING_PATH + "/ledgers/{identifier}")
+    fun findLedger(@Path("identifier") identifier: String): Observable<Ledger>
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java b/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java
index a4dfd00..144a10a 100644
--- a/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java
+++ b/app/src/main/java/org/apache/fineract/injection/component/ActivityComponent.java
@@ -4,34 +4,44 @@ import org.apache.fineract.injection.PerActivity;
 import org.apache.fineract.injection.module.ActivityModule;
 import org.apache.fineract.ui.offline.CustomerPayloadFragment;
 import org.apache.fineract.ui.online.DashboardActivity;
-import org.apache.fineract.ui.online.customers.createcustomer.customeractivity.CreateCustomerActivity;
-import org.apache.fineract.ui.online.customers.createcustomer.formcustomeraddress.FormCustomerAddressFragment;
-
+import org.apache.fineract.ui.online.accounting.ledgers.LedgerFragment;
+import org.apache.fineract.ui.online.customers.createcustomer.customeractivity
+        .CreateCustomerActivity;
+import org.apache.fineract.ui.online.customers.createcustomer.formcustomeraddress
+        .FormCustomerAddressFragment;
 import org.apache.fineract.ui.online.customers.customeractivities.CustomerActivitiesFragment;
+import org.apache.fineract.ui.online.customers.customerdetails.CustomerDetailsFragment;
 import org.apache.fineract.ui.online.customers.customerlist.CustomersFragment;
-import org.apache.fineract.ui.online.customers.customerprofile.editcustomerprofilebottomsheet.EditCustomerProfileBottomSheet;
+import org.apache.fineract.ui.online.customers.customerprofile.editcustomerprofilebottomsheet
+        .EditCustomerProfileBottomSheet;
 import org.apache.fineract.ui.online.customers.customertasks.CustomerTasksBottomSheetFragment;
-import org.apache.fineract.ui.online.depositaccounts.createdepositaccount.FormDepositOverviewFragment;
-
-import org.apache.fineract.ui.online.depositaccounts.createdepositaccount.createdepositactivity.CreateDepositActivity;
-import org.apache.fineract.ui.online.depositaccounts.createdepositaccount.formdepositassignproduct.FormDepositAssignProductFragment;
+import org.apache.fineract.ui.online.depositaccounts.createdepositaccount
+        .FormDepositOverviewFragment;
+import org.apache.fineract.ui.online.depositaccounts.createdepositaccount.createdepositactivity
+        .CreateDepositActivity;
+import org.apache.fineract.ui.online.depositaccounts.createdepositaccount
+        .formdepositassignproduct.FormDepositAssignProductFragment;
+import org.apache.fineract.ui.online.depositaccounts.depositaccountdetails
+        .DepositAccountDetailsFragment;
 import org.apache.fineract.ui.online.depositaccounts.depositaccountslist.DepositAccountsFragment;
-import org.apache.fineract.ui.online.customers.customerdetails.CustomerDetailsFragment;
-import org.apache.fineract.ui.online.loanaccounts.loanaccountlist.LoanAccountsFragment;
-import org.apache.fineract.ui.online.loanaccounts.debtincomereport.DebtIncomeReportFragment;
-import org.apache.fineract.ui.online.depositaccounts.depositaccountdetails.DepositAccountDetailsFragment;
-import org.apache.fineract.ui.online.identification.createidentification.identificationactivity.CreateIdentificationActivity;
-import org.apache.fineract.ui.online.identification.identificationdetails.IdentificationDetailsFragment;
+import org.apache.fineract.ui.online.identification.createidentification.identificationactivity
+        .CreateIdentificationActivity;
+import org.apache.fineract.ui.online.identification.identificationdetails
+        .IdentificationDetailsFragment;
 import org.apache.fineract.ui.online.identification.identificationlist.IdentificationsFragment;
-import org.apache.fineract.ui.online.identification.uploadidentificationscan.UploadIdentificationCardBottomSheet;
+import org.apache.fineract.ui.online.identification.uploadidentificationscan
+        .UploadIdentificationCardBottomSheet;
 import org.apache.fineract.ui.online.launcher.LauncherActivity;
+import org.apache.fineract.ui.online.loanaccounts.debtincomereport.DebtIncomeReportFragment;
+import org.apache.fineract.ui.online.loanaccounts.loanaccountlist.LoanAccountsFragment;
 import org.apache.fineract.ui.online.loanaccounts.loanapplication.BaseFragmentDebtIncome;
-import org.apache.fineract.ui.online.loanaccounts.loanapplication.loanactivity.LoanApplicationActivity;
+import org.apache.fineract.ui.online.loanaccounts.loanapplication.loanactivity
+        .LoanApplicationActivity;
 import org.apache.fineract.ui.online.loanaccounts.loanapplication.loancosigner.LoanCoSignerFragment;
 import org.apache.fineract.ui.online.loanaccounts.loanapplication.loandetails.LoanDetailsFragment;
 import org.apache.fineract.ui.online.loanaccounts.loandetails.CustomerLoanDetailsFragment;
-import org.apache.fineract.ui.online.login.LoginActivity;
 import org.apache.fineract.ui.online.loanaccounts.plannedpayment.PlannedPaymentFragment;
+import org.apache.fineract.ui.online.login.LoginActivity;
 import org.apache.fineract.ui.online.roles.roleslist.RolesFragment;
 
 import dagger.Subcomponent;
@@ -101,4 +111,5 @@ public interface ActivityComponent {
 
     void inject(CustomerPayloadFragment customerPayloadFragment);
 
+    void inject(LedgerFragment ledgerFragment);
 }
diff --git a/app/src/main/java/org/apache/fineract/injection/component/ApplicationComponent.java b/app/src/main/java/org/apache/fineract/injection/component/ApplicationComponent.java
index 7a22b6e..c24b5a9 100644
--- a/app/src/main/java/org/apache/fineract/injection/component/ApplicationComponent.java
+++ b/app/src/main/java/org/apache/fineract/injection/component/ApplicationComponent.java
@@ -14,6 +14,7 @@ import org.apache.fineract.data.datamanager.api.DataManagerIndividualLending;
 import org.apache.fineract.data.datamanager.api.DataManagerLoans;
 import org.apache.fineract.data.datamanager.api.DataManagerRoles;
 import org.apache.fineract.data.datamanager.database.DbManagerCustomer;
+import org.apache.fineract.data.datamanager.DataManagerAccounting;
 import org.apache.fineract.data.local.PreferencesHelper;
 import org.apache.fineract.data.local.database.helpers.DatabaseHelperCustomer;
 import org.apache.fineract.data.remote.BaseApiManager;
@@ -44,6 +45,7 @@ public interface ApplicationComponent {
     DataManagerIndividualLending dataManagerIndividualLending();
     DataManagerAnonymous dataManagerAnonymous();
     DataManagerRoles dataManagerRolesAndPermissions();
+    DataManagerAccounting dataManagerAccounting();
     BaseApiManager baseApiManager();
     PreferencesHelper preferencesHelper();
 
diff --git a/app/src/main/java/org/apache/fineract/ui/adapters/LedgerAdapter.kt b/app/src/main/java/org/apache/fineract/ui/adapters/LedgerAdapter.kt
new file mode 100644
index 0000000..dccd522
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/adapters/LedgerAdapter.kt
@@ -0,0 +1,65 @@
+package org.apache.fineract.ui.adapters
+
+import android.content.Context
+import android.support.v7.widget.AppCompatImageView
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import kotlinx.android.synthetic.main.item_ledger.view.*
+import org.apache.fineract.R
+import org.apache.fineract.data.models.accounts.Ledger
+import org.apache.fineract.injection.ApplicationContext
+import org.apache.fineract.utils.DateUtils
+import org.apache.fineract.utils.StatusUtils
+import javax.inject.Inject
+
+class LedgerAdapter @Inject constructor(@ApplicationContext val context: Context)
+    : RecyclerView.Adapter<LedgerAdapter.ViewHolder>() {
+
+    private var ledgers: List<Ledger> = ArrayList()
+
+    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+
+        val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_ledger, parent, false)
+        return ViewHolder(view)
+    }
+
+    override fun getItemCount(): Int = ledgers.size
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+
+        val ledger = ledgers[position]
+
+        holder.tvLedgerIdentifier.text = ledger.identifier
+
+        val modifiedBy = context.getString(R.string.last_modified_by) + context.getString(
+                R.string.colon) + ledger.lastModifiedBy
+        holder.tvModifiedBy.text = modifiedBy
+
+        val lastModifiedOn = context.getString(R.string.last_modified_on) + context.getString(
+                R.string.colon) +
+                DateUtils.getDate(ledger.lastModifiedOn,
+                        DateUtils.INPUT_DATE_FORMAT, DateUtils.OUTPUT_DATE_FORMAT)
+
+        StatusUtils.setAccountType(ledger.type, holder?.ivAccountTypeIndicator, context)
+
+        holder.tvModifiedOn.text = lastModifiedOn
+        holder.tvTotalValue.text = ledger.totalValue.toString()
+    }
+
+    fun setLedgerList(ledgers: List<Ledger>) {
+        this.ledgers = ledgers
+        notifyDataSetChanged()
+    }
+
+    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+
+        val tvLedgerIdentifier: TextView = itemView.tv_ledger_identifier
+        val tvModifiedBy: TextView = itemView.tv_modified_by
+        val tvModifiedOn: TextView = itemView.tv_modified_on
+        val tvTotalValue: TextView = itemView.tv_total_value
+        val ivAccountTypeIndicator: AppCompatImageView = itemView.iv_type_indicator
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java b/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java
index f053318..2b782cb 100644
--- a/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java
+++ b/app/src/main/java/org/apache/fineract/ui/online/DashboardActivity.java
@@ -17,6 +17,7 @@ import org.apache.fineract.data.local.PreferencesHelper;
 import org.apache.fineract.jobs.StartSyncJob;
 import org.apache.fineract.ui.base.FineractBaseActivity;
 import org.apache.fineract.ui.offline.CustomerPayloadFragment;
+import org.apache.fineract.ui.online.accounting.ledgers.LedgerFragment;
 import org.apache.fineract.ui.online.customers.customerlist.CustomersFragment;
 import org.apache.fineract.ui.online.dashboard.DashboardFragment;
 import org.apache.fineract.ui.online.launcher.LauncherActivity;
@@ -113,6 +114,9 @@ public class DashboardActivity extends FineractBaseActivity implements
             case R.id.item_logout:
                 logout();
                 break;
+            case R.id.item_ledger:
+                replaceFragment(LedgerFragment.Companion.newInstance(), true, R.id.container);
+                break;
         }
         drawerLayout.closeDrawer(Gravity.START);
         setTitle(item.getTitle());
diff --git a/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerContract.kt b/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerContract.kt
new file mode 100644
index 0000000..e76cd28
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerContract.kt
@@ -0,0 +1,32 @@
+package org.apache.fineract.ui.online.accounting.accounts
+
+import org.apache.fineract.data.models.accounts.Ledger
+import org.apache.fineract.ui.base.MvpView
+
+interface LedgerContract {
+
+    interface View : MvpView {
+
+        fun showUserInterface()
+
+        fun showLedgers(ledgers: List<Ledger>)
+
+        fun showEmptyLedgers()
+
+        fun showRecyclerView(status: Boolean)
+
+        fun showProgressbar()
+
+        fun hideProgressbar()
+
+        fun searchedLedger(ledger: Ledger)
+
+    }
+
+    interface Presenter {
+
+        fun getLedgersPage()
+
+        fun searchLedger(identifier: String)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerFragment.kt b/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerFragment.kt
new file mode 100644
index 0000000..482eb6d
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerFragment.kt
@@ -0,0 +1,168 @@
+package org.apache.fineract.ui.online.accounting.ledgers
+
+
+import android.app.SearchManager
+import android.content.Context
+import android.os.Bundle
+import android.support.v4.widget.SwipeRefreshLayout
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.SearchView
+import android.text.TextUtils
+import android.view.*
+import kotlinx.android.synthetic.main.fragment_ledger.*
+import kotlinx.android.synthetic.main.layout_exception_handler.*
+import org.apache.fineract.R
+import org.apache.fineract.data.models.accounts.Ledger
+import org.apache.fineract.ui.adapters.LedgerAdapter
+import org.apache.fineract.ui.base.FineractBaseActivity
+import org.apache.fineract.ui.base.FineractBaseFragment
+import org.apache.fineract.ui.online.accounting.accounts.LedgerContract
+import java.util.*
+import javax.inject.Inject
+import kotlin.collections.ArrayList
+
+
+class LedgerFragment : FineractBaseFragment(), LedgerContract.View,
+        SwipeRefreshLayout.OnRefreshListener {
+
+    @Inject
+    lateinit var ledgerAdapter: LedgerAdapter
+
+    @Inject
+    lateinit var ledgerPresenter: LedgerPresenter
+
+    lateinit var ledgerList: List<Ledger>
+
+    companion object {
+        fun newInstance(): LedgerFragment = LedgerFragment()
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setHasOptionsMenu(true)
+        ledgerList = ArrayList()
+    }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+                              savedInstanceState: Bundle?): View? {
+
+        val rootView = inflater.inflate(R.layout.fragment_ledger, container, false)
+        (activity as FineractBaseActivity).activityComponent.inject(this)
+        ledgerPresenter.attachView(this)
+        initializeFineractUIErrorHandler(activity, rootView)
+
+        return rootView
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        showUserInterface()
+
+        btn_try_again.setOnClickListener {
+            layoutError.visibility = View.GONE
+            ledgerPresenter.getLedgersPage()
+        }
+
+        ledgerPresenter.getLedgersPage()
+    }
+
+    override fun showUserInterface() {
+
+        setToolbarTitle(getString(R.string.ledger))
+        val layoutManager = LinearLayoutManager(activity)
+        layoutManager.orientation = LinearLayoutManager.VERTICAL
+        rvLedger.layoutManager = layoutManager
+        rvLedger.setHasFixedSize(true)
+
+        rvLedger.adapter = ledgerAdapter
+
+        swipeContainer.setColorSchemeColors(*activity!!
+                .resources.getIntArray(R.array.swipeRefreshColors))
+        swipeContainer.setOnRefreshListener(this)
+    }
+
+    override fun onRefresh() {
+        ledgerPresenter.getLedgersPage()
+    }
+
+    override fun showLedgers(ledgers: List<Ledger>) {
+        showRecyclerView(true)
+        this.ledgerList = ledgers
+        ledgerAdapter.setLedgerList(ledgers)
+    }
+
+    override fun showEmptyLedgers() {
+        showRecyclerView(false)
+        showFineractEmptyUI(getString(R.string.ledger), getString(R.string.ledger),
+                R.drawable.ic_person_outline_black_24dp)
+    }
+
+    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+        super.onCreateOptionsMenu(menu, inflater)
+        inflater?.inflate(R.menu.menu_ledger_search, menu)
+        setUpSearchInterface(menu)
+    }
+
+    private fun setUpSearchInterface(menu: Menu?) {
+
+        val searchManager = activity?.getSystemService(Context.SEARCH_SERVICE) as? SearchManager
+        val searchView = menu?.findItem(R.id.ledger_search)?.actionView as? SearchView
+
+        searchView?.setSearchableInfo(searchManager?.getSearchableInfo(activity?.componentName))
+
+        searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+            override fun onQueryTextSubmit(query: String): Boolean {
+                ledgerPresenter.searchLedger(query)
+                return false
+            }
+
+            override fun onQueryTextChange(newText: String): Boolean {
+                if (TextUtils.isEmpty(newText)) {
+                    showRecyclerView(true)
+                    ledgerAdapter.setLedgerList(ledgerList)
+                }
+
+                return false
+            }
+        })
+
+    }
+
+    override fun searchedLedger(ledger: Ledger) {
+        showRecyclerView(true)
+        ledgerAdapter.setLedgerList(Collections.singletonList(ledger))
+    }
+
+    override fun showRecyclerView(status: Boolean) {
+        if (status) {
+            rvLedger.visibility = View.VISIBLE
+            layoutError.visibility = View.GONE
+        } else {
+            rvLedger.visibility = View.GONE
+            layoutError.visibility = View.VISIBLE
+        }
+    }
+
+    override fun showProgressbar() {
+        swipeContainer.isRefreshing = true
+    }
+
+    override fun hideProgressbar() {
+        swipeContainer.isRefreshing = false
+    }
+
+    override fun showNoInternetConnection() {
+        showRecyclerView(false)
+        showFineractNoInternetUI()
+    }
+
+    override fun showError(message: String) {
+        showRecyclerView(false)
+        showFineractErrorUI(getString(R.string.ledger))
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        ledgerPresenter.detachView()
+    }
+}
diff --git a/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerPresenter.kt b/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerPresenter.kt
new file mode 100644
index 0000000..5086b40
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/accounting/ledgers/LedgerPresenter.kt
@@ -0,0 +1,87 @@
+package org.apache.fineract.ui.online.accounting.ledgers
+
+import android.content.Context
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.observers.DisposableObserver
+import io.reactivex.schedulers.Schedulers
+import org.apache.fineract.R
+import org.apache.fineract.data.datamanager.DataManagerAccounting
+import org.apache.fineract.data.models.accounts.Ledger
+import org.apache.fineract.data.models.accounts.LedgerPage
+import org.apache.fineract.injection.ApplicationContext
+import org.apache.fineract.ui.base.BasePresenter
+import org.apache.fineract.ui.online.accounting.accounts.LedgerContract
+import javax.inject.Inject
+
+class LedgerPresenter @Inject constructor(@ApplicationContext context: Context,
+                                          val dataManagerAccounting: DataManagerAccounting)
+    : BasePresenter<LedgerContract.View>(context), LedgerContract.Presenter {
+
+    private val compositeDisposable = CompositeDisposable()
+
+    override fun getLedgersPage() {
+        checkViewAttached()
+        mvpView.showProgressbar()
+
+        compositeDisposable.add(dataManagerAccounting.fetchLedgers()
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribeWith(object : DisposableObserver<LedgerPage>() {
+                    override fun onComplete() {
+
+                    }
+
+                    override fun onNext(ledgerPage: LedgerPage) {
+
+                        mvpView.hideProgressbar()
+
+                        if (ledgerPage.ledgers != null) {
+
+                            if (ledgerPage.ledgers.isEmpty()) {
+                                mvpView.showLedgers(ledgerPage.ledgers)
+                            } else {
+                                mvpView.showEmptyLedgers()
+                            }
+                        }
+
+                    }
+
+                    override fun onError(throwable: Throwable) {
+                        mvpView.hideProgressbar()
+                        showExceptionError(throwable,
+                                context.getString(R.string.error_fetching_ledger))
+                    }
+                })
+        )
+    }
+
+    override fun searchLedger(identifier: String) {
+        checkViewAttached()
+        mvpView.showProgressbar()
+
+        compositeDisposable.add(dataManagerAccounting.findLedger(identifier)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribeWith(object : DisposableObserver<Ledger>() {
+                    override fun onComplete() {
+
+                    }
+
+                    override fun onNext(ledger: Ledger) {
+                        mvpView.hideProgressbar()
+                        mvpView.searchedLedger(ledger)
+
+                    }
+
+                    override fun onError(throwable: Throwable) {
+                        mvpView.hideProgressbar()
+                        showExceptionError(throwable,
+                                context.getString(R.string.error_fetching_ledger))
+                    }
+                })
+        )
+    }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/utils/StatusUtils.java b/app/src/main/java/org/apache/fineract/utils/StatusUtils.java
index 8ede644..4795aa9 100644
--- a/app/src/main/java/org/apache/fineract/utils/StatusUtils.java
+++ b/app/src/main/java/org/apache/fineract/utils/StatusUtils.java
@@ -8,6 +8,7 @@ import android.widget.ImageView;
 import com.google.gson.annotations.SerializedName;
 
 import org.apache.fineract.R;
+import org.apache.fineract.data.models.accounts.AccountType;
 import org.apache.fineract.data.models.customer.Command;
 import org.apache.fineract.data.models.customer.Customer;
 import org.apache.fineract.data.models.deposit.DepositAccount;
@@ -233,5 +234,32 @@ public class StatusUtils {
 
         }
     }
+
+    public static void setAccountType(AccountType action, ImageView imageView,
+            Context context) {
+        switch (action) {
+            case ASSET:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.status));
+                break;
+            case LIABILITY:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.red_dark));
+                break;
+            case EQUITY:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.blue));
+                break;
+            case REVENUE:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.green_dark));
+                break;
+            case EXPENSE:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.red_light));
+                break;
+
+        }
+    }
 }
 
diff --git a/app/src/main/res/layout/fragment_ledger.xml b/app/src/main/res/layout/fragment_ledger.xml
new file mode 100644
index 0000000..19ff350
--- /dev/null
+++ b/app/src/main/res/layout/fragment_ledger.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.design.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipeContainer"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent">
+
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/rvLedger"
+            android:layout_centerHorizontal="true"
+            android:layout_height="0dp"
+            android:layout_marginBottom="@dimen/layout_padding_30dp"
+            android:layout_weight="1"
+            android:layout_width="wrap_content"/>
+    </android.support.v4.widget.SwipeRefreshLayout>
+
+    <include
+        layout="@layout/layout_exception_handler"
+        android:id="@+id/layoutError"
+        android:visibility="gone"/>
+
+</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_ledger.xml b/app/src/main/res/layout/item_ledger.xml
new file mode 100644
index 0000000..c61fb82
--- /dev/null
+++ b/app/src/main/res/layout/item_ledger.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/ll_loan_accounts"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clickable="true"
+    android:foreground="?android:attr/selectableItemBackground"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/ll_ledger"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/iv_type_indicator"
+            android:layout_width="@dimen/side_bar_width"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="@dimen/default_margin"
+            android:layout_marginTop="@dimen/default_margin"
+            app:srcCompat="@drawable/round_corner" />
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:orientation="vertical"
+            android:padding="@dimen/layout_padding_24dp">
+
+            <TextView
+                android:id="@+id/tv_ledger_identifier"
+                style="@style/Base.TextAppearance.AppCompat.Medium"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:textColor="@color/black"
+                tools:text="Teller Identifier" />
+
+            <TextView
+                android:id="@+id/tv_modified_by"
+                style="@style/Base.TextAppearance.AppCompat.Small"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ellipsize="end"
+                android:lines="1"
+                tools:text="Last modified by: rajan" />
+
+            <TextView
+                android:id="@+id/tv_modified_on"
+                style="@style/Base.TextAppearance.AppCompat.Small"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                tools:text="Last modified on: 10 July 2018" />
+
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/tv_total_value"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginEnd="@dimen/layout_padding_24dp"
+            android:layout_marginRight="@dimen/layout_padding_24dp"
+            android:textSize="@dimen/text_medium"
+            tools:text="Total Value" />
+
+    </LinearLayout>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0.2dp"
+        android:background="#E7DFDF" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_ledger_search.xml b/app/src/main/res/menu/menu_ledger_search.xml
new file mode 100644
index 0000000..6ddfbd0
--- /dev/null
+++ b/app/src/main/res/menu/menu_ledger_search.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:app="http://schemas.android.com/apk/res-auto"
+      xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/ledger_search"
+        android:icon="@drawable/ic_search_black_24dp"
+        android:title="@string/ledger_search"
+        app:showAsAction="always"
+        app:actionViewClass="android.support.v7.widget.SearchView"/>
+
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_navigation_drawer.xml b/app/src/main/res/menu/menu_navigation_drawer.xml
index 0e289df..0d505c2 100644
--- a/app/src/main/res/menu/menu_navigation_drawer.xml
+++ b/app/src/main/res/menu/menu_navigation_drawer.xml
@@ -29,6 +29,13 @@
             android:id="@+id/item_customer_payload"
             android:title="Customer Payloads"/>
 
+        <item
+            android:checked="true"
+            android:icon="@drawable/ic_customer_black_24dp"
+            android:id="@+id/item_ledger"
+            android:title="@string/ledger"/>
+
+
     </group>
 
     <group
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7b01082..e81ddf5 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -82,6 +82,7 @@
     <string name="amount">Amount</string>
     <string name="description">Description</string>
     <string name="products">Products</string>
+    <string name="ledger">Ledgers</string>
     <string name="day">Day</string>
     <string name="in">In</string>
     <string name="required">Required</string>
@@ -171,6 +172,7 @@
     <string name="created_by">Created by</string>
     <string name="no_deposit_account">No deposit account</string>
     <string name="identification_search">Search identification card</string>
+    <string name="ledger_search">Ledger Search</string>
     <string name="loan_last_modified_by">%1$s %2$s</string>
     <string name="loan_created_by">%1$s %2$s</string>
     <string name="search_beneficiary">Search beneficiary</string>
@@ -265,6 +267,7 @@
     <string name="error_updating_deposit_account">Error updating deposit account</string>
     <string name="error_fetching_customer_activities">Error fetching customer activities</string>
     <string name="error_fetching_roles">Error fetching roles</string>
+    <string name="error_fetching_ledger">Error fetching ledger</string>
     <string name="error_sorry_not_able_to_load">Sorry we weren\'t able to load</string>
     <string name="error_fetching_customer_details">Failed to fetch customer details</string>
     <string name="error_fetching_deposit_product">Failed to fetch deposit product</string>
diff --git a/app/src/main/resources/ledgerPage.json b/app/src/main/resources/ledgerPage.json
new file mode 100644
index 0000000..139fc67
--- /dev/null
+++ b/app/src/main/resources/ledgerPage.json
@@ -0,0 +1,62 @@
+{
+  "ledgers": [
+    {
+      "type": "ASSET",
+      "identifier": "identifier1",
+      "name": "name",
+      "description": "description",
+      "parentLedgerIdentifier": "parentLedgerIdentifier",
+      "subLedgers": [],
+      "totalValue": 1200,
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy",
+      "showAccountsInChart": false
+    },
+    {
+      "type": "LIABILITY",
+      "identifier": "identifier2",
+      "name": "name",
+      "description": "description",
+      "parentLedgerIdentifier": "parentLedgerIdentifier",
+      "subLedgers": [],
+      "totalValue": 1500,
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy",
+      "showAccountsInChart": false
+    },
+    {
+      "type": "EQUITY",
+      "identifier": "identifier3",
+      "name": "name",
+      "description": "description",
+      "parentLedgerIdentifier": "parentLedgerIdentifier",
+      "subLedgers": [],
+      "totalValue": 1800,
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy",
+      "showAccountsInChart": false
+    },
+    {
+      "type": "REVENUE",
+      "identifier": "identifier4",
+      "name": "name",
+      "description": "description",
+      "parentLedgerIdentifier": "parentLedgerIdentifier",
+      "subLedgers": [],
+      "totalValue": 2100,
+      "createdOn": "createdOn",
+      "createdBy": "createdBy",
+      "lastModifiedOn": "lastModifiedOn",
+      "lastModifiedBy": "lastModifiedBy",
+      "showAccountsInChart": false
+    }
+  ],
+  "totalPages": 1,
+  "totalElements": 4
+}
\ No newline at end of file