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:53 UTC

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

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