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/08/21 10:59:03 UTC

[fineract-cn-mobile] branch development updated: feat : list and search tellers

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


The following commit(s) were added to refs/heads/development by this push:
     new 6f9edbe  feat : list and search tellers
6f9edbe is described below

commit 6f9edbef2398ba055b3598ba306983c79b6462de
Author: Mohak <mo...@gmail.com>
AuthorDate: Tue Jul 10 12:40:57 2018 +0530

    feat : list and search tellers
---
 .../java/org/apache/fineract/FakeJsonName.java     |   1 +
 .../org/apache/fineract/FakeRemoteDataSource.java  |   5 +
 .../fineract/data/datamanager/DataManagerTeller.kt |  30 ++++
 .../apache/fineract/data/models/teller/Teller.kt   |  44 ++++++
 .../fineract/data/remote/BaseApiManager.java       |   7 +
 .../org/apache/fineract/data/remote/EndPoints.java |   1 +
 .../fineract/data/services/TellersService.kt       |  17 +++
 .../injection/component/ActivityComponent.java     |   3 +
 .../injection/component/ApplicationComponent.java  |   2 +
 .../apache/fineract/ui/adapters/TellerAdapter.kt   |  67 +++++++++
 .../fineract/ui/online/DashboardActivity.java      |   4 +
 .../fineract/ui/online/teller/TellerContract.kt    |  29 ++++
 .../fineract/ui/online/teller/TellerFragment.kt    | 167 +++++++++++++++++++++
 .../fineract/ui/online/teller/TellerPresenter.kt   |  80 ++++++++++
 .../org/apache/fineract/utils/StatusUtils.java     |  25 ++-
 app/src/main/res/layout/fragment_teller.xml        |  24 +++
 app/src/main/res/layout/item_teller.xml            |  76 ++++++++++
 app/src/main/res/menu/menu_navigation_drawer.xml   |   5 +
 app/src/main/res/menu/menu_teller_search.xml       |  12 ++
 app/src/main/res/values/strings.xml                |   3 +
 app/src/main/resources/teller.json                 |  74 +++++++++
 21 files changed, 675 insertions(+), 1 deletion(-)

diff --git a/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java b/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
index 29c2de8..d8f1f46 100644
--- a/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
+++ b/app/src/commonTest/java/org/apache/fineract/FakeJsonName.java
@@ -19,4 +19,5 @@ public class FakeJsonName {
     public static final String ROLES = "role.json";
     public static final String LEDGER_PAGE = "ledgerPage.json";
     public static final String ACCOUNT_PAGE = "accountsPage.json";
+    public static final String TELLER = "teller.json";
 }
diff --git a/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java b/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
index c510bc1..70ccafb 100644
--- a/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
+++ b/app/src/commonTest/java/org/apache/fineract/FakeRemoteDataSource.java
@@ -15,6 +15,7 @@ import org.apache.fineract.data.models.loan.LoanAccount;
 import org.apache.fineract.data.models.loan.LoanAccountPage;
 import org.apache.fineract.data.models.payment.PlannedPaymentPage;
 import org.apache.fineract.data.models.rolesandpermission.Role;
+import org.apache.fineract.data.models.teller.Teller;
 
 import java.util.List;
 
@@ -89,4 +90,8 @@ public class FakeRemoteDataSource {
         return testDataFactory.getObjectTypePojo(AccountPage.class, FakeJsonName.ACCOUNT_PAGE);
     }
 
+    public static List<Teller> getTeller() {
+        return testDataFactory.getListTypePojo(new TypeToken<List<Teller>>() {
+        }, FakeJsonName.TELLER);
+    }
 }
diff --git a/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerTeller.kt b/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerTeller.kt
new file mode 100644
index 0000000..898ad3b
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/datamanager/DataManagerTeller.kt
@@ -0,0 +1,30 @@
+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.models.teller.Teller
+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 javax.inject.Singleton
+
+@Singleton
+class DataManagerTeller @Inject constructor(val baseManagerApi: BaseApiManager,
+                                            dataManagerAuth: DataManagerAuth,
+                                            val preferencesHelper: PreferencesHelper)
+    : FineractBaseDataManager(dataManagerAuth, preferencesHelper) {
+
+    fun getTellers(): Observable<List<Teller>> =
+            baseManagerApi.tellerService.getTellerList(preferencesHelper.tenantIdentifier)
+                    .onErrorResumeNext(Function<Throwable, ObservableSource<List<Teller>>>
+                    { Observable.just(FakeRemoteDataSource.getTeller()) })
+
+    fun findTeller(tellerCode: String): Observable<Teller> = baseManagerApi.tellerService
+            .searchTeller(preferencesHelper.tenantIdentifier, tellerCode)
+            .onErrorResumeNext(Function<Throwable, ObservableSource<Teller>>
+            { Observable.just(FakeRemoteDataSource.getTeller()[0]) })
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/apache/fineract/data/models/teller/Teller.kt b/app/src/main/java/org/apache/fineract/data/models/teller/Teller.kt
new file mode 100644
index 0000000..61bb53e
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/models/teller/Teller.kt
@@ -0,0 +1,44 @@
+package org.apache.fineract.data.models.teller
+
+import android.os.Parcelable
+import com.google.gson.annotations.SerializedName
+import kotlinx.android.parcel.Parcelize
+import java.math.BigDecimal
+
+@Parcelize
+data class Teller(
+
+        @SerializedName("code") val code: String? = null,
+        @SerializedName("password") val password: String? = null,
+        @SerializedName("cashdrawLimit") val cashdrawLimit: BigDecimal? = null,
+        @SerializedName("tellerAccountIdentifier") val tellerAccountIdentifier: String? = null,
+        @SerializedName("vaultAccountIdentifier") val vaultAccountIdentifier: String? = null,
+        @SerializedName("chequesReceivableAccount") val chequesReceivableAccount: String? = null,
+        @SerializedName("cashOverShortAccount") val cashOverShortAccount: String? = null,
+        @SerializedName("denominationRequired") val denominationRequired: Boolean = false,
+        @SerializedName("assignedEmployee") val assignedEmployee: String? = null,
+        @SerializedName("state") val state: State? = null,
+        @SerializedName("createdBy") val createdBy: String? = null,
+        @SerializedName("createdOn") val createdOn: String? = null,
+        @SerializedName("lastModifiedBy") val lastModifiedBy: String? = null,
+        @SerializedName("lastModifiedOn") val lastModifiedOn: String? = null,
+        @SerializedName("lastOpenedBy") val lastOpenedBy: String? = null,
+        @SerializedName("lastOpenedOn") val lastOpenedOn: String? = null
+
+) : Parcelable {
+
+    enum class State {
+
+        @SerializedName("ACTIVE")
+        ACTIVE,
+
+        @SerializedName("CLOSED")
+        CLOSED,
+
+        @SerializedName("OPEN")
+        OPEN,
+
+        @SerializedName("PAUSED")
+        PAUSED
+    }
+}
\ 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 0b8e0de..74616c4 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
@@ -10,6 +10,7 @@ import org.apache.fineract.data.services.DepositService;
 import org.apache.fineract.data.services.IndividualLendingService;
 import org.apache.fineract.data.services.LoanService;
 import org.apache.fineract.data.services.RolesService;
+import org.apache.fineract.data.services.TellersService;
 
 import okhttp3.OkHttpClient;
 import okhttp3.logging.HttpLoggingInterceptor;
@@ -35,6 +36,7 @@ public class BaseApiManager {
     private static AnonymousService anonymousService;
     private static RolesService rolesService;
     private static AccountingService accountingService;
+    private static TellersService tellerService;
 
     public BaseApiManager(Context context) {
         createService(context);
@@ -49,6 +51,7 @@ public class BaseApiManager {
         individualLendingService = createApi(IndividualLendingService.class);
         rolesService = createApi(RolesService.class);
         accountingService = createApi(AccountingService.class);
+        tellerService = createApi(TellersService.class);
     }
 
     private static void initAnonymous() {
@@ -121,4 +124,8 @@ public class BaseApiManager {
     public  AccountingService getAccountingService() {
         return accountingService;
     }
+
+    public TellersService getTellerService() {
+        return tellerService;
+    }
 }
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 4bd9a21..0e29bd0 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
@@ -16,5 +16,6 @@ public class EndPoints {
     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";
+    public static final String API_TELLER_PATH = "/api/teller/v1";
 
 }
diff --git a/app/src/main/java/org/apache/fineract/data/services/TellersService.kt b/app/src/main/java/org/apache/fineract/data/services/TellersService.kt
new file mode 100644
index 0000000..08b6213
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/data/services/TellersService.kt
@@ -0,0 +1,17 @@
+package org.apache.fineract.data.services
+
+import io.reactivex.Observable
+import org.apache.fineract.data.models.teller.Teller
+import org.apache.fineract.data.remote.EndPoints
+import retrofit2.http.GET
+import retrofit2.http.Path
+
+interface TellersService {
+
+    @GET(EndPoints.API_TELLER_PATH + "/offices/{officeIdentifier}/teller")
+    fun getTellerList(@Path("officeIdentifier") officeIdentifier: String): Observable<List<Teller>>
+
+    @GET(EndPoints.API_TELLER_PATH + "/offices/{officeIdentifier}/teller/{tellerCode}")
+    fun searchTeller(@Path("officeIdentifier") officeIdentifier: String,
+                     @Path("tellerCode") tellerCode: String): Observable<Teller>
+}
\ 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 09e014e..e3cecba 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
@@ -44,6 +44,7 @@ import org.apache.fineract.ui.online.loanaccounts.plannedpayment.PlannedPaymentF
 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 org.apache.fineract.ui.online.teller.TellerFragment;
 
 import dagger.Subcomponent;
 
@@ -115,4 +116,6 @@ public interface ActivityComponent {
     void inject(LedgerFragment ledgerFragment);
 
     void inject(AccountsFragment accountsFragment);
+
+    void inject(TellerFragment tellerFragment);
 }
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 c24b5a9..635cfe0 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
@@ -15,6 +15,7 @@ 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.datamanager.DataManagerTeller;
 import org.apache.fineract.data.local.PreferencesHelper;
 import org.apache.fineract.data.local.database.helpers.DatabaseHelperCustomer;
 import org.apache.fineract.data.remote.BaseApiManager;
@@ -46,6 +47,7 @@ public interface ApplicationComponent {
     DataManagerAnonymous dataManagerAnonymous();
     DataManagerRoles dataManagerRolesAndPermissions();
     DataManagerAccounting dataManagerAccounting();
+    DataManagerTeller dataManagerTeller();
     BaseApiManager baseApiManager();
     PreferencesHelper preferencesHelper();
 
diff --git a/app/src/main/java/org/apache/fineract/ui/adapters/TellerAdapter.kt b/app/src/main/java/org/apache/fineract/ui/adapters/TellerAdapter.kt
new file mode 100644
index 0000000..7eb2015
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/adapters/TellerAdapter.kt
@@ -0,0 +1,67 @@
+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_teller.view.*
+import org.apache.fineract.R
+import org.apache.fineract.data.models.teller.Teller
+import org.apache.fineract.injection.ApplicationContext
+import org.apache.fineract.utils.DateUtils
+import org.apache.fineract.utils.StatusUtils
+import javax.inject.Inject
+
+class TellerAdapter @Inject constructor(@ApplicationContext val context: Context)
+    : RecyclerView.Adapter<TellerAdapter.ViewHolder>() {
+
+    var tellers: List<Teller> = ArrayList()
+
+    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+        val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_teller,
+                parent, false)
+        return ViewHolder(view)
+    }
+
+    override fun getItemCount(): Int = tellers.size
+
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+
+        val teller = tellers[position]
+
+        holder.tellerIdentifier.text = teller.tellerAccountIdentifier
+
+        val modifiedBy = context.getString(R.string.last_modified_by) + context.getString(
+                R.string.colon) + teller.lastModifiedBy
+        holder.tvModifiedBy.text = modifiedBy
+
+        val lastModifiedOn = context.getString(R.string.last_modified_on) + context.getString(
+                R.string.colon) +
+                DateUtils.getDate(teller.lastModifiedOn,
+                        DateUtils.INPUT_DATE_FORMAT, DateUtils.OUTPUT_DATE_FORMAT)
+
+        StatusUtils.setTellerStatus(teller.state, holder.statusIndicator, context)
+
+        holder.tvModifiedOn.text = lastModifiedOn
+        holder.withDrawLimit.text = tellers[position].cashdrawLimit.toString()
+    }
+
+    fun setTellerList(tellers: List<Teller>) {
+        this.tellers = tellers
+        notifyDataSetChanged()
+    }
+
+    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+
+        val tellerIdentifier: TextView = itemView.tv_teller_identifier
+        val tvModifiedBy: TextView = itemView.tv_modified_by
+        val tvModifiedOn: TextView = itemView.tv_modified_on
+        val withDrawLimit: TextView = itemView.tv_cashWithdraw_limit
+        val statusIndicator: AppCompatImageView = itemView.iv_status_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 fe07f9d..c3c401e 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
@@ -23,6 +23,7 @@ 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;
 import org.apache.fineract.ui.online.roles.roleslist.RolesFragment;
+import org.apache.fineract.ui.online.teller.TellerFragment;
 import org.apache.fineract.utils.MaterialDialog;
 
 import javax.inject.Inject;
@@ -120,6 +121,9 @@ public class DashboardActivity extends FineractBaseActivity implements
                 break;
             case R.id.item_accounts:
                 replaceFragment(AccountsFragment.Companion.newInstance(), true, R.id.container);
+            case R.id.item_teller:
+                replaceFragment(TellerFragment.Companion.newInstance(), true, R.id.container);
+                break;
         }
 
         drawerLayout.closeDrawer(Gravity.START);
diff --git a/app/src/main/java/org/apache/fineract/ui/online/teller/TellerContract.kt b/app/src/main/java/org/apache/fineract/ui/online/teller/TellerContract.kt
new file mode 100644
index 0000000..58d3821
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/teller/TellerContract.kt
@@ -0,0 +1,29 @@
+package org.apache.fineract.ui.online.teller
+
+import org.apache.fineract.data.models.teller.Teller
+import org.apache.fineract.ui.base.MvpView
+
+interface TellerContract {
+
+    interface View : MvpView {
+
+        fun showUserInterface()
+
+        fun showTellers(tellers: List<Teller>)
+
+        fun showEmptyTellers()
+
+        fun showRecyclerView(status: Boolean)
+
+        fun showProgressbar()
+
+        fun hideProgressbar()
+
+        fun searchedTeller(teller: Teller)
+    }
+
+    interface Presenter {
+
+        fun fetchTellers()
+    }
+}
diff --git a/app/src/main/java/org/apache/fineract/ui/online/teller/TellerFragment.kt b/app/src/main/java/org/apache/fineract/ui/online/teller/TellerFragment.kt
new file mode 100644
index 0000000..a5799f6
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/teller/TellerFragment.kt
@@ -0,0 +1,167 @@
+package org.apache.fineract.ui.online.teller
+
+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_teller.*
+import kotlinx.android.synthetic.main.layout_exception_handler.*
+import org.apache.fineract.R
+import org.apache.fineract.data.models.teller.Teller
+import org.apache.fineract.ui.adapters.TellerAdapter
+import org.apache.fineract.ui.base.FineractBaseActivity
+import org.apache.fineract.ui.base.FineractBaseFragment
+import java.util.*
+import javax.inject.Inject
+
+
+class TellerFragment : FineractBaseFragment(), TellerContract.View, SwipeRefreshLayout.OnRefreshListener {
+
+    @Inject
+    lateinit var tellPresenter: TellerPresenter
+
+    @Inject
+    lateinit var tellerAdapter: TellerAdapter
+
+    lateinit var tellerList: List<Teller>
+
+    companion object {
+        fun newInstance(): TellerFragment = TellerFragment().apply {
+            val args = Bundle()
+            this.arguments = args
+        }
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setHasOptionsMenu(true)
+        tellerList = ArrayList()
+    }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+                              savedInstanceState: Bundle?): View? {
+
+        val rootView = inflater.inflate(R.layout.fragment_teller, container, false)
+
+        (activity as FineractBaseActivity).activityComponent.inject(this)
+        tellPresenter.attachView(this)
+        initializeFineractUIErrorHandler(activity, rootView)
+
+        return rootView
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        showUserInterface()
+        tellPresenter.fetchTellers()
+
+        btn_try_again.setOnClickListener {
+            layoutError.visibility = View.GONE
+            tellPresenter.fetchTellers()
+        }
+    }
+
+    override fun showUserInterface() {
+
+        setToolbarTitle(getString(R.string.teller))
+        val llManager = LinearLayoutManager(activity)
+        llManager.orientation = LinearLayoutManager.VERTICAL
+        rvTellers.layoutManager = llManager
+        rvTellers.setHasFixedSize(true)
+        rvTellers.adapter = tellerAdapter
+
+        swipeContainer.setColorSchemeColors(*activity!!
+                .resources.getIntArray(R.array.swipeRefreshColors))
+        swipeContainer.setOnRefreshListener(this)
+    }
+
+    override fun showTellers(tellers: List<Teller>) {
+        showRecyclerView(true)
+        tellerList = tellers
+        tellerAdapter.setTellerList(tellers)
+    }
+
+    override fun onRefresh() {
+        tellPresenter.fetchTellers()
+    }
+
+    override fun showEmptyTellers() {
+        showRecyclerView(false)
+        showFineractEmptyUI(getString(R.string.teller), getString(R.string.teller),
+                R.drawable.ic_person_outline_black_24dp)
+    }
+
+    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+        super.onCreateOptionsMenu(menu, inflater)
+        inflater?.inflate(R.menu.menu_teller_search, menu)
+        setUpSearchInterface(menu)
+    }
+
+    private fun setUpSearchInterface(menu: Menu?) {
+
+        val searchManager = activity?.getSystemService(Context.SEARCH_SERVICE) as? SearchManager
+        val searchView = menu?.findItem(R.id.teller_search)?.actionView as? SearchView
+
+        searchView?.setSearchableInfo(searchManager?.getSearchableInfo(activity?.componentName))
+
+        searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+            override fun onQueryTextSubmit(query: String): Boolean {
+                tellPresenter.searchTeller(query)
+                return false
+            }
+
+            override fun onQueryTextChange(newText: String): Boolean {
+                if (TextUtils.isEmpty(newText)) {
+                    showRecyclerView(true)
+                    tellerAdapter.setTellerList(tellerList)
+                }
+
+                return false
+            }
+        })
+
+    }
+
+    override fun searchedTeller(teller: Teller) {
+        showRecyclerView(true)
+        tellerAdapter.setTellerList(Collections.singletonList(teller))
+    }
+
+    override fun showRecyclerView(status: Boolean) {
+        if (status) {
+            rvTellers.visibility = View.VISIBLE
+            layoutError.visibility = View.GONE
+        } else {
+            rvTellers.visibility = View.GONE
+            layoutError.visibility = View.VISIBLE
+        }
+    }
+
+    override fun showProgressbar() {
+        swipeContainer.isRefreshing = true
+    }
+
+    override fun hideProgressbar() {
+        swipeContainer.isRefreshing = false
+    }
+
+    override fun showError(message: String) {
+        showRecyclerView(false)
+        showFineractErrorUI(getString(R.string.teller))
+    }
+
+    override fun showNoInternetConnection() {
+        showRecyclerView(false)
+        showFineractNoInternetUI()
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        tellPresenter.detachView()
+    }
+}
diff --git a/app/src/main/java/org/apache/fineract/ui/online/teller/TellerPresenter.kt b/app/src/main/java/org/apache/fineract/ui/online/teller/TellerPresenter.kt
new file mode 100644
index 0000000..ab2de29
--- /dev/null
+++ b/app/src/main/java/org/apache/fineract/ui/online/teller/TellerPresenter.kt
@@ -0,0 +1,80 @@
+package org.apache.fineract.ui.online.teller
+
+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.DataManagerTeller
+import org.apache.fineract.data.models.teller.Teller
+import org.apache.fineract.injection.ApplicationContext
+import org.apache.fineract.ui.base.BasePresenter
+import javax.inject.Inject
+
+class TellerPresenter @Inject constructor(@ApplicationContext context: Context,
+                                          private val dataManagerTeller: DataManagerTeller) :
+        BasePresenter<TellerContract.View>(context), TellerContract.Presenter {
+
+    val compositeDisposable = CompositeDisposable()
+
+    override fun fetchTellers() {
+
+        checkViewAttached()
+        mvpView.showProgressbar()
+
+        compositeDisposable.add(dataManagerTeller.getTellers()
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribeWith(object : DisposableObserver<List<Teller>>() {
+                    override fun onComplete() {
+
+                    }
+
+                    override fun onNext(tellerList: List<Teller>) {
+                        mvpView.hideProgressbar()
+
+                        if (!tellerList.isEmpty()) {
+                            mvpView.showTellers(tellerList)
+                        } else {
+                            mvpView.showEmptyTellers()
+                        }
+                    }
+
+                    override fun onError(throwable: Throwable) {
+                        mvpView.hideProgressbar()
+                        showExceptionError(throwable,
+                                context.getString(R.string.error_fetching_teller))
+                    }
+                }))
+    }
+
+    fun searchTeller(query: String) {
+
+        checkViewAttached()
+        mvpView.showProgressbar()
+
+        compositeDisposable.add(dataManagerTeller.findTeller(query)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribeWith(object : DisposableObserver<Teller>() {
+                    override fun onComplete() {
+
+                    }
+
+                    override fun onNext(teller: Teller) {
+                        mvpView.hideProgressbar()
+                        mvpView.searchedTeller(teller)
+
+                    }
+
+                    override fun onError(throwable: Throwable) {
+                        mvpView.hideProgressbar()
+                        showExceptionError(throwable,
+                                context.getString(R.string.error_fetching_teller))
+                    }
+                }))
+    }
+
+
+}
\ 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 4795aa9..374b508 100644
--- a/app/src/main/java/org/apache/fineract/utils/StatusUtils.java
+++ b/app/src/main/java/org/apache/fineract/utils/StatusUtils.java
@@ -13,10 +13,11 @@ import org.apache.fineract.data.models.customer.Command;
 import org.apache.fineract.data.models.customer.Customer;
 import org.apache.fineract.data.models.deposit.DepositAccount;
 import org.apache.fineract.data.models.loan.LoanAccount;
+import org.apache.fineract.data.models.teller.Teller;
 
 /**
  * @author Rajan Maurya
- *         On 05/08/17.
+ * On 05/08/17.
  */
 public class StatusUtils {
 
@@ -42,6 +43,28 @@ public class StatusUtils {
         }
     }
 
+    public static void setTellerStatus(Teller.State state, AppCompatImageView imageView,
+            Context context) {
+        switch (state) {
+            case ACTIVE:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.deposit_green));
+                break;
+            case CLOSED:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.red_dark));
+                break;
+            case OPEN:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.blue));
+                break;
+            case PAUSED:
+                imageView.setColorFilter(
+                        ContextCompat.getColor(context, R.color.light_yellow));
+                break;
+        }
+    }
+
     public static void setCustomerStatusIcon(Customer.State state, ImageView imageView,
             Context context) {
         switch (state) {
diff --git a/app/src/main/res/layout/fragment_teller.xml b/app/src/main/res/layout/fragment_teller.xml
new file mode 100644
index 0000000..cc01983
--- /dev/null
+++ b/app/src/main/res/layout/fragment_teller.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.design.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipeContainer"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/rvTellers"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+    </android.support.v4.widget.SwipeRefreshLayout>
+
+    <include
+        android:id="@+id/layoutError"
+        layout="@layout/layout_exception_handler"
+        android:visibility="gone" />
+
+</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_teller.xml b/app/src/main/res/layout/item_teller.xml
new file mode 100644
index 0000000..38bacab
--- /dev/null
+++ b/app/src/main/res/layout/item_teller.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_teller"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/iv_status_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_teller_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_cashWithdraw_limit"
+            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="Withdraw Limit" />
+
+    </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_navigation_drawer.xml b/app/src/main/res/menu/menu_navigation_drawer.xml
index 086432f..d32c652 100644
--- a/app/src/main/res/menu/menu_navigation_drawer.xml
+++ b/app/src/main/res/menu/menu_navigation_drawer.xml
@@ -40,6 +40,11 @@
             android:icon="@drawable/ic_customer_black_24dp"
             android:id="@+id/item_accounts"
             android:title="@string/accounts"/>
+        <item
+            android:checked="true"
+            android:icon="@drawable/ic_customer_black_24dp"
+            android:id="@+id/item_teller"
+            android:title="@string/teller"/>
 
     </group>
 
diff --git a/app/src/main/res/menu/menu_teller_search.xml b/app/src/main/res/menu/menu_teller_search.xml
new file mode 100644
index 0000000..751de05
--- /dev/null
+++ b/app/src/main/res/menu/menu_teller_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/teller_search"
+        android:icon="@drawable/ic_search_black_24dp"
+        android:title="@string/teller_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/values/strings.xml b/app/src/main/res/values/strings.xml
index 737d1ae..034ec59 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -174,6 +174,7 @@
     <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="teller_search">Search teller</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>
@@ -182,6 +183,7 @@
     <string name="activities_created_by_on">%1$s, %2$s</string>
     <string name="logout">Logout</string>
     <string name="manage_roles">Manage roles</string>
+    <string name="teller">Tellers</string>
     <string name="try_again">Try Again</string>
     <string name="retry">Retry</string>
     <string name="oh_no">Oh no!</string>
@@ -270,6 +272,7 @@
     <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_fetching_teller">Error fetching teller</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/teller.json b/app/src/main/resources/teller.json
new file mode 100644
index 0000000..2083e44
--- /dev/null
+++ b/app/src/main/resources/teller.json
@@ -0,0 +1,74 @@
+[
+  {
+    "code": "code1",
+    "password": "password1",
+    "cashdrawLimit": 1000,
+    "tellerAccountIdentifier": "tellerAccountIdentifier1",
+    "vaultAccountIdentifier": "vaultAccountIdentifier",
+    "chequesReceivableAccount": "chequesReceivableAccount",
+    "cashOverShortAccount": "cashOverShortAccount",
+    "denominationRequired": false,
+    "assignedEmployee": "assignedEmployee",
+    "state": "ACTIVE",
+    "createdBy": "createdBy",
+    "createdOn": "createdOn",
+    "lastModifiedBy": "lastModifiedBy",
+    "lastModifiedOn": "lastModifiedOn",
+    "lastOpenedBy": "lastOpenedBy",
+    "lastOpenedOn": "lastOpenedOn"
+  },
+  {
+    "code": "code2",
+    "password": "password2",
+    "cashdrawLimit": 1500,
+    "tellerAccountIdentifier": "tellerAccountIdentifier2",
+    "vaultAccountIdentifier": "vaultAccountIdentifier",
+    "chequesReceivableAccount": "chequesReceivableAccount",
+    "cashOverShortAccount": "cashOverShortAccount",
+    "denominationRequired": false,
+    "assignedEmployee": "assignedEmployee",
+    "state": "CLOSED",
+    "createdBy": "createdBy",
+    "createdOn": "createdOn",
+    "lastModifiedBy": "lastModifiedBy",
+    "lastModifiedOn": "lastModifiedOn",
+    "lastOpenedBy": "lastOpenedBy",
+    "lastOpenedOn": "lastOpenedOn"
+  },
+  {
+    "code": "code3",
+    "password": "password3",
+    "cashdrawLimit": 2000,
+    "tellerAccountIdentifier": "tellerAccountIdentifier3",
+    "vaultAccountIdentifier": "vaultAccountIdentifier",
+    "chequesReceivableAccount": "chequesReceivableAccount",
+    "cashOverShortAccount": "cashOverShortAccount",
+    "denominationRequired": false,
+    "assignedEmployee": "assignedEmployee",
+    "state": "PAUSED",
+    "createdBy": "createdBy",
+    "createdOn": "createdOn",
+    "lastModifiedBy": "lastModifiedBy",
+    "lastModifiedOn": "lastModifiedOn",
+    "lastOpenedBy": "lastOpenedBy",
+    "lastOpenedOn": "lastOpenedOn"
+  },
+  {
+    "code": "code4",
+    "password": "password4",
+    "cashdrawLimit": 2500,
+    "tellerAccountIdentifier": "tellerAccountIdentifier4",
+    "vaultAccountIdentifier": "vaultAccountIdentifier",
+    "chequesReceivableAccount": "chequesReceivableAccount",
+    "cashOverShortAccount": "cashOverShortAccount",
+    "denominationRequired": false,
+    "assignedEmployee": "assignedEmployee",
+    "state": "OPEN",
+    "createdBy": "createdBy",
+    "createdOn": "createdOn",
+    "lastModifiedBy": "lastModifiedBy",
+    "lastModifiedOn": "lastModifiedOn",
+    "lastOpenedBy": "lastOpenedBy",
+    "lastOpenedOn": "lastOpenedOn"
+  }
+]