http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorServiceImpl.java
new file mode 100644
index 0000000..c329ef4
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorServiceImpl.java
@@ -0,0 +1,674 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.bulkimport.service;
+
+import org.apache.fineract.accounting.glaccount.data.GLAccountData;
+import 
org.apache.fineract.accounting.glaccount.service.GLAccountReadPlatformService;
+import 
org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
+import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
+import org.apache.fineract.infrastructure.bulkimport.populator.*;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.centers.CentersWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.chartofaccounts.ChartOfAccountsWorkbook;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.client.ClientEntityWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.client.ClientPersonWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.fixeddeposits.FixedDepositTransactionWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.fixeddeposits.FixedDepositWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.group.GroupsWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.guarantor.GuarantorWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.journalentry.JournalEntriesWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.loan.LoanWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.loanrepayment.LoanRepaymentWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.office.OfficeWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.recurringdeposit.RecurringDepositTransactionWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.recurringdeposit.RecurringDepositWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.savings.SavingsTransactionsWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.savings.SavingsWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.shareaccount.SharedAccountWorkBookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.staff.StaffWorkbookPopulator;
+import 
org.apache.fineract.infrastructure.bulkimport.populator.users.UserWorkbookPopulator;
+import org.apache.fineract.infrastructure.codes.data.CodeValueData;
+import 
org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
+import 
org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
+import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.infrastructure.core.service.Page;
+import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.apache.fineract.organisation.monetary.data.CurrencyData;
+import 
org.apache.fineract.organisation.monetary.service.CurrencyReadPlatformService;
+import org.apache.fineract.organisation.office.data.OfficeData;
+import 
org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
+import org.apache.fineract.organisation.staff.data.StaffData;
+import org.apache.fineract.organisation.staff.service.StaffReadPlatformService;
+import org.apache.fineract.portfolio.charge.data.ChargeData;
+import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
+import org.apache.fineract.portfolio.client.data.ClientData;
+import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
+import org.apache.fineract.portfolio.fund.data.FundData;
+import org.apache.fineract.portfolio.fund.service.FundReadPlatformService;
+import org.apache.fineract.portfolio.group.api.GroupingTypesApiConstants;
+import org.apache.fineract.portfolio.group.data.CenterData;
+import org.apache.fineract.portfolio.group.data.GroupGeneralData;
+import org.apache.fineract.portfolio.group.service.CenterReadPlatformService;
+import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
+import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
+import 
org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
+import org.apache.fineract.portfolio.loanproduct.data.LoanProductData;
+import 
org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService;
+import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
+import 
org.apache.fineract.portfolio.paymenttype.service.PaymentTypeReadPlatformService;
+import org.apache.fineract.portfolio.products.data.ProductData;
+import 
org.apache.fineract.portfolio.products.service.ProductReadPlatformService;
+import org.apache.fineract.portfolio.savings.DepositAccountType;
+import org.apache.fineract.portfolio.savings.data.*;
+import 
org.apache.fineract.portfolio.savings.service.DepositProductReadPlatformService;
+import 
org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
+import 
org.apache.fineract.portfolio.savings.service.SavingsProductReadPlatformService;
+import org.apache.fineract.portfolio.shareproducts.data.ShareProductData;
+import org.apache.fineract.useradministration.data.RoleData;
+import org.apache.fineract.useradministration.service.RoleReadPlatformService;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class BulkImportWorkbookPopulatorServiceImpl implements 
BulkImportWorkbookPopulatorService {
+
+  private final PlatformSecurityContext context;
+  private final OfficeReadPlatformService officeReadPlatformService;
+  private final StaffReadPlatformService staffReadPlatformService;
+  private final ClientReadPlatformService clientReadPlatformService;
+  private final CenterReadPlatformService centerReadPlatformService;
+  private final GroupReadPlatformService groupReadPlatformService;
+  private final FundReadPlatformService fundReadPlatformService;
+  private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
+  private final LoanProductReadPlatformService loanProductReadPlatformService;
+  private final CurrencyReadPlatformService currencyReadPlatformService;
+  private final LoanReadPlatformService loanReadPlatformService;
+  private final GLAccountReadPlatformService glAccountReadPlatformService;
+  private final SavingsAccountReadPlatformService 
savingsAccountReadPlatformService;
+  private final CodeValueReadPlatformService codeValueReadPlatformService;
+  private final SavingsProductReadPlatformService 
savingsProductReadPlatformService;
+  private final ProductReadPlatformService productReadPlatformService;
+  private final ChargeReadPlatformService chargeReadPlatformService;
+  private final DepositProductReadPlatformService 
depositProductReadPlatformService;
+  private final RoleReadPlatformService roleReadPlatformService;
+  
+  @Autowired
+  public BulkImportWorkbookPopulatorServiceImpl(final PlatformSecurityContext 
context,
+      final OfficeReadPlatformService officeReadPlatformService,
+      final StaffReadPlatformService staffReadPlatformService,
+      final ClientReadPlatformService clientReadPlatformService,
+      final CenterReadPlatformService centerReadPlatformService,
+      final GroupReadPlatformService groupReadPlatformService,
+      final FundReadPlatformService fundReadPlatformService,
+      final PaymentTypeReadPlatformService paymentTypeReadPlatformService,
+      final LoanProductReadPlatformService loanProductReadPlatformService,
+      final CurrencyReadPlatformService currencyReadPlatformService,
+      final LoanReadPlatformService loanReadPlatformService,
+      final GLAccountReadPlatformService glAccountReadPlatformService,
+      final SavingsAccountReadPlatformService 
savingsAccountReadPlatformService,
+               final CodeValueReadPlatformService codeValueReadPlatformService,
+               final SavingsProductReadPlatformService 
savingsProductReadPlatformService,
+                 final ProductReadPlatformService productReadPlatformService,
+                 final ChargeReadPlatformService chargeReadPlatformService,
+                 final DepositProductReadPlatformService 
depositProductReadPlatformService,
+                 final RoleReadPlatformService roleReadPlatformService) {
+    this.officeReadPlatformService = officeReadPlatformService;
+    this.staffReadPlatformService = staffReadPlatformService;
+    this.context = context;
+    this.clientReadPlatformService=clientReadPlatformService;
+    this.centerReadPlatformService=centerReadPlatformService;
+    this.groupReadPlatformService=groupReadPlatformService;
+    this.fundReadPlatformService=fundReadPlatformService;
+    this.paymentTypeReadPlatformService=paymentTypeReadPlatformService;
+    this.loanProductReadPlatformService=loanProductReadPlatformService;
+    this.currencyReadPlatformService=currencyReadPlatformService;
+    this.loanReadPlatformService=loanReadPlatformService;
+    this.glAccountReadPlatformService=glAccountReadPlatformService;
+    this.savingsAccountReadPlatformService=savingsAccountReadPlatformService;
+    this.codeValueReadPlatformService=codeValueReadPlatformService;
+    this.savingsProductReadPlatformService=savingsProductReadPlatformService;
+    this.productReadPlatformService=productReadPlatformService;
+    this.chargeReadPlatformService=chargeReadPlatformService;
+    this.depositProductReadPlatformService=depositProductReadPlatformService;
+    this.roleReadPlatformService=roleReadPlatformService;
+  }
+
+       @Override
+       public Response getTemplate(String entityType, Long officeId, Long 
staffId,final String dateFormat) {
+               WorkbookPopulator populator=null;
+               final Workbook workbook=new HSSFWorkbook();
+               if(entityType!=null){
+                       if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.CLIENTS_PERSON.toString())||
+                                       
entityType.trim().equalsIgnoreCase(GlobalEntityType.CLIENTS_ENTTTY.toString())) 
{
+                               populator = 
populateClientWorkbook(entityType,officeId, staffId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.CENTERS.toString())) {
+                               
populator=populateCenterWorkbook(officeId,staffId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.GROUPS.toString())) {
+                               populator = populateGroupsWorkbook(officeId, 
staffId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.LOANS.toString())) {
+                               populator = populateLoanWorkbook(officeId, 
staffId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.LOAN_TRANSACTIONS.toString()))
 {
+                               populator = 
populateLoanRepaymentWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.GL_JOURNAL_ENTRIES.toString()))
 {
+                               populator = 
populateJournalEntriesWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.GUARANTORS.toString())) {
+                               populator = populateGuarantorWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.OFFICES.toString())) {
+                               populator=populateOfficeWorkbook();
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.CHART_OF_ACCOUNTS.toString()))
 {
+                               populator=populateChartOfAccountsWorkbook();
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.STAFF.toString())) {
+                               populator=populateStaffWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.SHARE_ACCOUNTS.toString()))
 {
+                               
populator=populateSharedAcountsWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.SAVINGS_ACCOUNT.toString()))
 {
+                               
populator=populateSavingsAccountWorkbook(officeId,staffId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.SAVINGS_TRANSACTIONS.toString()))
 {
+                               
populator=populateSavingsTransactionWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.RECURRING_DEPOSIT_ACCOUNTS.toString()))
 {
+                               
populator=populateRecurringDepositWorkbook(officeId,staffId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.RECURRING_DEPOSIT_ACCOUNTS_TRANSACTIONS.toString()))
 {
+                               
populator=populateRecurringDepositTransactionWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.FIXED_DEPOSIT_ACCOUNTS.toString()))
 {
+                               populator = 
populateFixedDepositWorkbook(officeId, staffId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.FIXED_DEPOSIT_TRANSACTIONS.toString())){
+                               
populator=populateFixedDepositTransactionsWorkbook(officeId);
+                       }else if 
(entityType.trim().equalsIgnoreCase(GlobalEntityType.USERS.toString())){
+                               
populator=populateUserWorkbook(officeId,staffId);
+                       }else {
+                               throw new 
GeneralPlatformDomainRuleException("error.msg.unable.to.find.resource",
+                                               "Unable to find requested 
resource");
+                       }
+                       populator.populate(workbook,dateFormat);
+                       return buildResponse(workbook, entityType);
+               }else {
+                       throw new 
GeneralPlatformDomainRuleException("error.msg.given.entity.type.null",
+                                       "Given Entity type is null");
+               }
+       }
+
+
+       private WorkbookPopulator populateClientWorkbook(final String 
entityType ,final Long officeId, final Long staffId) {
+    
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+    
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+    List<OfficeData> offices = fetchOffices(officeId);
+    List<StaffData> staff = fetchStaff(staffId);
+    List<CodeValueData> clientTypeCodeValues 
=fetchCodeValuesByCodeName("ClientType");
+       List<CodeValueData> 
clientClassification=fetchCodeValuesByCodeName("ClientClassification");
+       List<CodeValueData> 
addressTypesCodeValues=fetchCodeValuesByCodeName("ADDRESS_TYPE");
+       List<CodeValueData> 
stateProvinceCodeValues=fetchCodeValuesByCodeName("STATE");
+       List<CodeValueData> 
countryCodeValues=fetchCodeValuesByCodeName("COUNTRY");
+       
if(entityType.trim().equalsIgnoreCase(GlobalEntityType.CLIENTS_PERSON.toString()))
 {
+               List<CodeValueData> genderCodeValues = 
fetchCodeValuesByCodeName("Gender");
+               return new ClientPersonWorkbookPopulator(new 
OfficeSheetPopulator(offices),
+                               new PersonnelSheetPopulator(staff, offices), 
clientTypeCodeValues, genderCodeValues, clientClassification
+                               , addressTypesCodeValues, 
stateProvinceCodeValues, countryCodeValues);
+       }else 
if(entityType.trim().equalsIgnoreCase(GlobalEntityType.CLIENTS_ENTTTY.toString())){
+               List<CodeValueData> 
constitutionCodeValues=fetchCodeValuesByCodeName("Constitution");
+               List<CodeValueData> 
mainBusinessline=fetchCodeValuesByCodeName("Main Business Line");
+               return new ClientEntityWorkbookPopulator(new 
OfficeSheetPopulator(offices),
+                               new PersonnelSheetPopulator(staff, offices), 
clientTypeCodeValues, constitutionCodeValues,mainBusinessline,
+                               clientClassification, addressTypesCodeValues, 
stateProvinceCodeValues, countryCodeValues);
+       }
+         return null;
+  }
+
+  private Response buildResponse(final Workbook workbook, final String entity) 
{
+    String filename = entity + DateUtils.getLocalDateOfTenant().toString() + 
".xls";
+    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    try {
+      workbook.write(baos);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    final ResponseBuilder response = Response.ok(baos.toByteArray());
+    response.header("Content-Disposition", "attachment; filename=\"" + 
filename + "\"");
+    response.header("Content-Type", "application/vnd.ms-excel");
+    return response.build();
+  }
+
+  @SuppressWarnings("unchecked")
+  private List<OfficeData> fetchOffices(final Long officeId) {
+    List<OfficeData> offices = null;
+    if (officeId == null) {
+      Boolean includeAllOffices = Boolean.TRUE;
+      offices = (List) 
this.officeReadPlatformService.retrieveAllOffices(includeAllOffices, null);
+    } else {
+      offices = new ArrayList<>();
+      offices.add(this.officeReadPlatformService.retrieveOffice(officeId));
+    }
+    return offices;
+  }
+
+  @SuppressWarnings("unchecked")
+  private List<StaffData> fetchStaff(final Long staffId) {
+    List<StaffData> staff = null;
+    if (staffId == null){
+      staff =
+          (List) this.staffReadPlatformService.retrieveAllStaff(null, null, 
Boolean.FALSE, null);
+    //System.out.println("Staff List size : "+staff.size());
+    }else {
+      staff = new ArrayList<>();
+      staff.add(this.staffReadPlatformService.retrieveStaff(staffId));
+    }
+    return staff;
+  }
+  private List<CodeValueData> fetchCodeValuesByCodeName(String codeName){
+       List<CodeValueData> codeValues=null;
+       if (codeName!=null){
+               
codeValues=(List)codeValueReadPlatformService.retrieveCodeValuesByCode(codeName);
+       }else {
+               throw new NullPointerException();
+       }
+       return codeValues;
+  }
+  private List<SavingsProductData>fetchSavingsProducts(){
+       List<SavingsProductData> 
savingsProducts=(List)savingsProductReadPlatformService.retrieveAll();
+       return savingsProducts;
+  }
+
+private WorkbookPopulator populateCenterWorkbook(Long officeId,Long staffId){
+        
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+        
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+       
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.GROUP_ENTITY_TYPE);
+        List<OfficeData> offices = fetchOffices(officeId);
+       List<StaffData> staff = fetchStaff(staffId);
+       List<GroupGeneralData> groups = fetchGroups(officeId);
+       return new CentersWorkbookPopulator(new OfficeSheetPopulator(offices),
+               new PersonnelSheetPopulator(staff, offices),new 
GroupSheetPopulator(groups,offices));
+}
+
+       private WorkbookPopulator populateGroupsWorkbook(Long officeId, Long 
staffId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CENTER_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<StaffData> staff = fetchStaff(staffId);
+               List<CenterData> centers = fetchCenters(officeId);
+               List<ClientData> clients = fetchClients(officeId);
+               return new GroupsWorkbookPopulator(new 
OfficeSheetPopulator(offices),
+                               new PersonnelSheetPopulator(staff, offices), 
new CenterSheetPopulator(centers, offices),
+                               new ClientSheetPopulator(clients, offices));
+       }
+       private List<CenterData> fetchCenters(Long officeId) {
+               List<CenterData>centers=null;
+               if (officeId==null) {
+                       centers=(List<CenterData>) 
this.centerReadPlatformService.retrieveAll(null, null);
+               } else {
+                       SearchParameters searchParameters = 
SearchParameters.from(null, officeId, null, null, null);
+                       centers = 
(List<CenterData>)centerReadPlatformService.retrieveAll(searchParameters,null);
+               }
+               
+               return centers;
+       }
+       private List<ClientData> fetchClients(Long officeId) {
+               List<ClientData> clients=null;
+               if (officeId==null) {
+                       Page<ClientData> clientDataPage 
=this.clientReadPlatformService.retrieveAll(null);
+                       if (clientDataPage!=null){
+                               clients=new ArrayList<>();
+                               for (ClientData client: 
clientDataPage.getPageItems()) {
+                                       clients.add(client);
+                               }
+                       }
+               } else {
+                       SearchParameters searchParameters = 
SearchParameters.from(null, officeId, null, null, null);
+                       Page<ClientData> clientDataPage 
=this.clientReadPlatformService.retrieveAll(searchParameters);
+                       if (clientDataPage!=null){
+                               clients=new ArrayList<>();
+                               for (ClientData client: 
clientDataPage.getPageItems()) {
+                                       clients.add(client);
+                               }
+                       }
+               }
+               return clients;
+       }
+
+
+       private WorkbookPopulator populateLoanWorkbook(Long officeId, Long 
staffId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.GROUP_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.LOAN_PRODUCT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.FUNDS_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.PAYMENT_TYPE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CURRENCY_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<StaffData> staff = fetchStaff(staffId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<GroupGeneralData> groups = fetchGroups(officeId);
+               List<LoanProductData> loanproducts = fetchLoanProducts();
+               List<FundData> funds = fetchFunds();
+               List<PaymentTypeData> paymentTypes = fetchPaymentTypes();
+               List<CurrencyData> currencies = fetchCurrencies();
+               return new LoanWorkbookPopulator(new 
OfficeSheetPopulator(offices), new ClientSheetPopulator(clients, offices),
+                               new GroupSheetPopulator(groups, offices), new 
PersonnelSheetPopulator(staff, offices),
+                               new LoanProductSheetPopulator(loanproducts), 
new ExtrasSheetPopulator(funds, paymentTypes, currencies));
+       }
+
+       private List<CurrencyData> fetchCurrencies() {
+               List<CurrencyData> currencies =(List<CurrencyData>) 
this.currencyReadPlatformService.
+                               retrieveAllPlatformCurrencies();
+               return currencies;
+       }
+
+       private List<PaymentTypeData> fetchPaymentTypes() {
+               List<PaymentTypeData> paymentTypeData =(List<PaymentTypeData>) 
this.paymentTypeReadPlatformService
+                               .retrieveAllPaymentTypes();
+               return paymentTypeData;
+       }
+
+       private List<FundData> fetchFunds() {
+               List<FundData> funds =(List<FundData>) 
this.fundReadPlatformService.retrieveAllFunds();
+               return funds;
+       }
+
+       private List<LoanProductData> fetchLoanProducts() {
+               List<LoanProductData>loanproducts =(List<LoanProductData>) 
this.loanProductReadPlatformService
+                               .retrieveAllLoanProducts();
+               return loanproducts;
+       }
+
+       private List<GroupGeneralData> fetchGroups(Long officeId) {
+               List<GroupGeneralData> groups = null;
+               if (officeId == null) {
+                       groups = (List<GroupGeneralData>) 
this.groupReadPlatformService.retrieveAll(null, null);
+               } else {
+                       SearchParameters searchParameters = 
SearchParameters.from(null, officeId, null, null, null);
+                       groups = 
(List<GroupGeneralData>)groupReadPlatformService.retrieveAll(searchParameters,null);
+               }
+
+               return groups;
+       }
+
+       private WorkbookPopulator populateLoanRepaymentWorkbook(Long officeId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.FUNDS_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.PAYMENT_TYPE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CURRENCY_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<FundData> funds = fetchFunds();
+               List<PaymentTypeData> paymentTypes = fetchPaymentTypes();
+               List<CurrencyData> currencies = fetchCurrencies();
+               List<LoanAccountData> loans = fetchLoanAccounts(officeId);
+               return new LoanRepaymentWorkbookPopulator(loans, new 
OfficeSheetPopulator(offices),
+                               new ClientSheetPopulator(clients, offices), new 
ExtrasSheetPopulator(funds, paymentTypes, currencies));
+       }
+
+       private List<LoanAccountData> fetchLoanAccounts(final Long officeId) {
+               List<LoanAccountData> loanAccounts = null;
+               if(officeId==null){
+                       loanAccounts= 
loanReadPlatformService.retrieveAll(null).getPageItems();
+               }else {
+                       SearchParameters searchParameters = 
SearchParameters.from(null, officeId, null, null, null);
+                       loanAccounts = 
loanReadPlatformService.retrieveAll(searchParameters).getPageItems();
+               }
+               return loanAccounts;
+       }
+
+       private WorkbookPopulator populateJournalEntriesWorkbook(Long officeId) 
{
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.GL_ACCOUNT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.FUNDS_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.PAYMENT_TYPE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CURRENCY_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<GLAccountData> glAccounts = fetchGLAccounts();
+               List<FundData> funds = fetchFunds();
+               List<PaymentTypeData> paymentTypes = fetchPaymentTypes();
+               List<CurrencyData> currencies = fetchCurrencies();
+               return new JournalEntriesWorkbookPopulator(new 
OfficeSheetPopulator(offices),
+                               new GlAccountSheetPopulator(glAccounts), new 
ExtrasSheetPopulator(funds, paymentTypes, currencies));
+       }
+
+       private List<GLAccountData> fetchGLAccounts() {
+               List<GLAccountData> glaccounts = (List<GLAccountData>) 
this.glAccountReadPlatformService.
+                               retrieveAllGLAccounts(null, null, null,
+                                       null, null, null);
+               return glaccounts;
+       }
+
+       private WorkbookPopulator populateGuarantorWorkbook(Long officeId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<ClientData>clients=fetchClients(officeId);
+               List<LoanAccountData> loans = fetchLoanAccounts(officeId);
+               List<SavingsAccountData> savingsaccounts = 
fetchSavingsAccounts(officeId);
+               List<CodeValueData> 
guarantorRelationshipTypes=fetchCodeValuesByCodeName("GuarantorRelationship");
+               return new GuarantorWorkbookPopulator(new 
OfficeSheetPopulator(offices),
+                               new ClientSheetPopulator(clients, 
offices),loans,savingsaccounts,guarantorRelationshipTypes);
+       }
+
+       private List<SavingsAccountData> fetchSavingsAccounts(Long officeId) {
+               List<SavingsAccountData> savingsAccounts=null;
+               if (officeId!=null) {
+                       String activeAccounts="sa.status_enum = 300";
+                       SearchParameters searchParameters = 
SearchParameters.from(activeAccounts, officeId, null, null, null);
+                       savingsAccounts = 
savingsAccountReadPlatformService.retrieveAll(searchParameters).getPageItems();;
+               }else {
+                       savingsAccounts= 
savingsAccountReadPlatformService.retrieveAll(null).getPageItems();
+               }
+               return savingsAccounts;
+       }
+
+
+       private WorkbookPopulator populateOfficeWorkbook() {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(null);
+               return new OfficeWorkbookPopulator(offices);
+       }
+
+
+
+
+       private WorkbookPopulator populateChartOfAccountsWorkbook() {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.GL_ACCOUNT_ENTITY_TYPE);
+               List<GLAccountData> glAccounts = fetchGLAccounts();
+               return new ChartOfAccountsWorkbook(glAccounts);
+       }
+
+
+       private WorkbookPopulator populateStaffWorkbook(Long officeId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               List<OfficeData> offices=fetchOffices(officeId);
+               return new StaffWorkbookPopulator(new 
OfficeSheetPopulator(offices));
+       }
+
+
+
+       private WorkbookPopulator populateSharedAcountsWorkbook(Long officeId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.SHARED_ACCOUNT_ENTITY_TYPE);
+               List<ShareProductData> 
shareProductDataList=fetchSharedProducts();
+               List<ChargeData> chargesForShares=fetchChargesForShares();
+               List<ClientData> clientDataList=fetchClients(officeId);
+               List<OfficeData>officeDataList=fetchOffices(officeId);
+               List<SavingsAccountData> savingsAccounts = 
fetchSavingsAccounts(officeId);
+               return new SharedAccountWorkBookPopulator(new 
SharedProductsSheetPopulator(shareProductDataList,chargesForShares),
+                               new 
ClientSheetPopulator(clientDataList,officeDataList),new 
SavingsAccountSheetPopulator(savingsAccounts));
+       }
+
+       private List<ChargeData> fetchChargesForShares() {
+               List<ChargeData>chargesForShares=(List<ChargeData>) 
chargeReadPlatformService.retrieveSharesApplicableCharges();
+               return chargesForShares;
+       }
+
+       private List<ShareProductData> fetchSharedProducts() {
+               List<ProductData> productDataList = 
productReadPlatformService.retrieveAllProducts(0,50).getPageItems() ;
+               List<ShareProductData> sharedProductDataList=new ArrayList<>();
+               if(productDataList!=null) {
+                       for (ProductData data : productDataList) {
+                               ShareProductData shareProduct = 
(ShareProductData) data;
+                               sharedProductDataList.add(shareProduct);
+                       }
+               }
+               return sharedProductDataList;
+       }
+
+
+       private WorkbookPopulator populateSavingsAccountWorkbook(Long officeId, 
Long staffId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.GROUP_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.SAVINGS_PRODUCT_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<StaffData> staff = fetchStaff(staffId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<GroupGeneralData> groups = fetchGroups(officeId);
+               List<SavingsProductData> savingsProducts=fetchSavingsProducts();
+               return new SavingsWorkbookPopulator(new 
OfficeSheetPopulator(offices), new ClientSheetPopulator(clients, offices),
+                               new GroupSheetPopulator(groups, offices), new 
PersonnelSheetPopulator(staff, offices),
+                               new 
SavingsProductSheetPopulator(savingsProducts));
+       }
+
+
+
+       private WorkbookPopulator populateSavingsTransactionWorkbook(Long 
officeId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.FUNDS_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.PAYMENT_TYPE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CURRENCY_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<FundData> funds = fetchFunds();
+               List<PaymentTypeData> paymentTypes = fetchPaymentTypes();
+               List<CurrencyData> currencies = fetchCurrencies();
+               List<SavingsAccountData> 
savingsAccounts=fetchSavingsAccounts(officeId);
+               return new SavingsTransactionsWorkbookPopulator(new 
OfficeSheetPopulator(offices), new ClientSheetPopulator(clients, offices),
+                                new ExtrasSheetPopulator(funds, paymentTypes, 
currencies),savingsAccounts);
+       }
+
+
+       private WorkbookPopulator populateRecurringDepositWorkbook(Long 
officeId,Long staffId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.RECURRING_DEPOSIT_PRODUCT_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<StaffData> staff = fetchStaff(staffId);
+               List<RecurringDepositProductData> recurringDepositProducts = 
fetchRecurringDepositProducts();
+               return new RecurringDepositWorkbookPopulator(new 
OfficeSheetPopulator(offices), new ClientSheetPopulator(clients, offices),
+                               new PersonnelSheetPopulator(staff,offices),new 
RecurringDepositProductSheetPopulator(recurringDepositProducts));
+       }
+
+       private List<RecurringDepositProductData> 
fetchRecurringDepositProducts() {
+               List<DepositProductData> 
depositProducts=(List<DepositProductData>)depositProductReadPlatformService
+                               
.retrieveAll(DepositAccountType.RECURRING_DEPOSIT);
+               List<RecurringDepositProductData> recurringDepositProducts=new 
ArrayList<>();
+               for (DepositProductData depositproduct: depositProducts) {
+                       RecurringDepositProductData recurringDepositProduct= 
(RecurringDepositProductData) depositproduct;
+                       recurringDepositProducts.add(recurringDepositProduct);
+               }
+               return recurringDepositProducts;
+       }
+
+
+
+       private WorkbookPopulator 
populateRecurringDepositTransactionWorkbook(Long officeId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.FUNDS_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.PAYMENT_TYPE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CURRENCY_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<FundData> funds = fetchFunds();
+               List<PaymentTypeData> paymentTypes = fetchPaymentTypes();
+               List<CurrencyData> currencies = fetchCurrencies();
+               List<SavingsAccountData> 
savingsAccounts=fetchSavingsAccounts(officeId);
+               return new RecurringDepositTransactionWorkbookPopulator(new 
OfficeSheetPopulator(offices), new ClientSheetPopulator(clients, offices),
+                               new ExtrasSheetPopulator(funds, paymentTypes, 
currencies),savingsAccounts);
+       }
+
+       private WorkbookPopulator populateFixedDepositWorkbook(Long officeId, 
Long staffId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.STAFF_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.FIXED_DEPOSIT_PRODUCT_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<StaffData> staff = fetchStaff(staffId);
+               List<FixedDepositProductData> fixedDepositProducts = 
fetchFixedDepositProducts();
+               return new FixedDepositWorkbookPopulator(new 
OfficeSheetPopulator(offices), new ClientSheetPopulator(clients, offices),
+                               new PersonnelSheetPopulator(staff,offices),new 
FixedDepositProductSheetPopulator(fixedDepositProducts));
+
+
+       }
+
+       private List<FixedDepositProductData> fetchFixedDepositProducts() {
+               List<DepositProductData> 
depositProducts=(List<DepositProductData>)depositProductReadPlatformService
+                               .retrieveAll(DepositAccountType.FIXED_DEPOSIT);
+               List<FixedDepositProductData> fixedDepositProducts=new 
ArrayList<>();
+               for (DepositProductData depositproduct: depositProducts) {
+                       FixedDepositProductData fixedDepositProduct= 
(FixedDepositProductData) depositproduct;
+                       fixedDepositProducts.add(fixedDepositProduct);
+               }
+               return fixedDepositProducts;
+
+       }
+
+       private WorkbookPopulator populateUserWorkbook(Long officeId, Long 
staffId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.USER_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<StaffData> staff = fetchStaff(staffId);
+               List<RoleData> roles=fetchRoles();
+               return new UserWorkbookPopulator(new 
OfficeSheetPopulator(offices), new PersonnelSheetPopulator(staff,offices),
+                               new RoleSheetPopulator(roles));
+       }
+
+       private List<RoleData> fetchRoles() {
+               List<RoleData> rolesList= (List<RoleData>) 
roleReadPlatformService.retrieveAllActiveRoles();
+               return rolesList;
+       }
+
+       private WorkbookPopulator populateFixedDepositTransactionsWorkbook(Long 
officeId) {
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.OFFICE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CLIENT_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.FUNDS_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.PAYMENT_TYPE_ENTITY_TYPE);
+               
this.context.authenticatedUser().validateHasReadPermission(TemplatePopulateImportConstants.CURRENCY_ENTITY_TYPE);
+               List<OfficeData> offices = fetchOffices(officeId);
+               List<ClientData> clients = fetchClients(officeId);
+               List<FundData> funds = fetchFunds();
+               List<PaymentTypeData> paymentTypes = fetchPaymentTypes();
+               List<CurrencyData> currencies = fetchCurrencies();
+               List<SavingsAccountData> 
savingsAccounts=fetchSavingsAccounts(officeId);
+               return new FixedDepositTransactionWorkbookPopulator(new 
OfficeSheetPopulator(offices), new ClientSheetPopulator(clients, offices),
+                               new ExtrasSheetPopulator(funds, paymentTypes, 
currencies),savingsAccounts);
+       }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java
new file mode 100644
index 0000000..c0ce1a9
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.bulkimport.service;
+
+import com.sun.jersey.core.header.FormDataContentDisposition;
+import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
+import org.apache.fineract.infrastructure.bulkimport.data.ImportData;
+import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData;
+
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.util.Collection;
+
+public interface BulkImportWorkbookService {
+
+    public Long importWorkbook(String entityType, InputStream inputStream, 
FormDataContentDisposition fileDetail,
+            final String locale, final String dateFormat);
+    public Collection<ImportData> getImports(GlobalEntityType type);
+
+    public DocumentData getOutputTemplateLocation(String importDocumentId);
+
+    public Response getOutputTemplate(String importDocumentId);
+
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookServiceImpl.java
new file mode 100644
index 0000000..b8f199c
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookServiceImpl.java
@@ -0,0 +1,296 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE multipartFile
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this multipartFile
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this multipartFile except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.bulkimport.service;
+
+import com.google.common.io.Files;
+import com.sun.jersey.core.header.FormDataContentDisposition;
+import org.apache.fineract.infrastructure.bulkimport.data.BulkImportEvent;
+import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
+import org.apache.fineract.infrastructure.bulkimport.data.ImportData;
+import org.apache.fineract.infrastructure.bulkimport.data.ImportFormatType;
+import org.apache.fineract.infrastructure.bulkimport.domain.ImportDocument;
+import 
org.apache.fineract.infrastructure.bulkimport.domain.ImportDocumentRepository;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandler;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandlerUtils;
+import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
+import 
org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
+import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData;
+import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
+import 
org.apache.fineract.infrastructure.documentmanagement.domain.DocumentRepository;
+import 
org.apache.fineract.infrastructure.documentmanagement.service.DocumentWritePlatformService;
+import 
org.apache.fineract.infrastructure.documentmanagement.service.DocumentWritePlatformServiceJpaRepositoryImpl;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.tika.Tika;
+import org.apache.tika.io.IOUtils;
+import org.apache.tika.io.TikaInputStream;
+import org.joda.time.LocalDate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+import javax.ws.rs.core.Response;
+import java.io.*;
+import java.net.URLConnection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+
+@Service
+public class BulkImportWorkbookServiceImpl implements 
BulkImportWorkbookService {
+    private final ApplicationContext applicationContext;
+    private final PlatformSecurityContext securityContext;
+    private final DocumentWritePlatformService documentWritePlatformService;
+    private final DocumentRepository documentRepository;
+    private final ImportDocumentRepository importDocumentRepository;
+    private final JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    public BulkImportWorkbookServiceImpl(final ApplicationContext 
applicationContext,
+            final PlatformSecurityContext securityContext,
+            final DocumentWritePlatformService documentWritePlatformService,
+            final DocumentRepository documentRepository,
+            final ImportDocumentRepository importDocumentRepository, final 
RoutingDataSource dataSource) {
+        this.applicationContext = applicationContext;
+        this.securityContext = securityContext;
+        this.documentWritePlatformService = documentWritePlatformService;
+        this.documentRepository = documentRepository;
+        this.importDocumentRepository = importDocumentRepository;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+    }
+
+    @Override
+    public Long importWorkbook(String entity, InputStream inputStream, 
FormDataContentDisposition fileDetail,
+            final String locale, final String dateFormat) {
+        try {
+            if (entity !=null && inputStream!=null 
&&fileDetail!=null&&locale!=null&&dateFormat!=null) {
+
+                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                IOUtils.copy(inputStream, baos);
+                final byte[] bytes = baos.toByteArray();
+                InputStream clonedInputStream = new 
ByteArrayInputStream(bytes);
+                InputStream clonedInputStreamWorkbook =new 
ByteArrayInputStream(bytes);
+                final Tika tika = new Tika();
+                final TikaInputStream tikaInputStream = 
TikaInputStream.get(clonedInputStream);
+                final String fileType = tika.detect(tikaInputStream);
+                final String fileExtension = 
Files.getFileExtension(fileDetail.getFileName()).toLowerCase();
+                ImportFormatType format = ImportFormatType.of(fileExtension);
+                if (!fileType.contains("msoffice")) {
+                    throw new 
GeneralPlatformDomainRuleException("error.msg.invalid.file.extension",
+                            "Uploaded file extension is not recognized.");
+                }
+                Workbook workbook = new 
HSSFWorkbook(clonedInputStreamWorkbook);
+                GlobalEntityType entityType=null;
+                int primaryColumn=0;
+                ImportHandler importHandler = null;
+                if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.CLIENTS_PERSON.toString())) {
+                    entityType = GlobalEntityType.CLIENTS_PERSON;
+                    primaryColumn = 0;
+                }else 
if(entity.trim().equalsIgnoreCase(GlobalEntityType.CLIENTS_ENTTTY.toString())){
+                    entityType = GlobalEntityType.CLIENTS_ENTTTY;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.CENTERS.toString())) {
+                    entityType = GlobalEntityType.CENTERS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.GROUPS.toString())) {
+                    entityType = GlobalEntityType.GROUPS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.LOANS.toString())) {
+                    entityType = GlobalEntityType.LOANS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.LOAN_TRANSACTIONS.toString())) 
{
+                    entityType = GlobalEntityType.LOAN_TRANSACTIONS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.GUARANTORS.toString())) {
+                    entityType = GlobalEntityType.GUARANTORS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.OFFICES.toString())) {
+                    entityType = GlobalEntityType.OFFICES;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.CHART_OF_ACCOUNTS.toString())) 
{
+                    entityType = GlobalEntityType.CHART_OF_ACCOUNTS;
+                    primaryColumn = 0;
+                }else  if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.GL_JOURNAL_ENTRIES.toString()))
 {
+                    entityType = GlobalEntityType.GL_JOURNAL_ENTRIES;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.STAFF.toString())) {
+                    entityType = GlobalEntityType.STAFF;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.SHARE_ACCOUNTS.toString())) {
+                    entityType = GlobalEntityType.SHARE_ACCOUNTS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.SAVINGS_ACCOUNT.toString())) {
+                    entityType = GlobalEntityType.SAVINGS_ACCOUNT;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.SAVINGS_TRANSACTIONS.toString()))
 {
+                    entityType = GlobalEntityType.SAVINGS_TRANSACTIONS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.RECURRING_DEPOSIT_ACCOUNTS.toString()))
 {
+                    entityType = GlobalEntityType.RECURRING_DEPOSIT_ACCOUNTS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.RECURRING_DEPOSIT_ACCOUNTS_TRANSACTIONS.toString()))
 {
+                    entityType = 
GlobalEntityType.RECURRING_DEPOSIT_ACCOUNTS_TRANSACTIONS;
+                    primaryColumn = 0;
+                }else if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.FIXED_DEPOSIT_ACCOUNTS.toString()))
 {
+                    entityType = GlobalEntityType.FIXED_DEPOSIT_ACCOUNTS;
+                    primaryColumn = 0;
+                }else  if 
(entity.trim().equalsIgnoreCase(GlobalEntityType.FIXED_DEPOSIT_TRANSACTIONS.toString())){
+                    entityType = GlobalEntityType.FIXED_DEPOSIT_TRANSACTIONS;
+                    primaryColumn = 0;
+                }else 
if(entity.trim().equalsIgnoreCase(GlobalEntityType.USERS.toString())){
+                    entityType = GlobalEntityType.USERS;
+                    primaryColumn = 0;
+                }else{
+                    throw new 
GeneralPlatformDomainRuleException("error.msg.unable.to.find.resource",
+                            "Unable to find requested resource");
+                }
+                return publishEvent(primaryColumn, fileDetail, 
clonedInputStreamWorkbook, entityType,
+                        workbook, locale, dateFormat);
+            }else {
+                throw new 
GeneralPlatformDomainRuleException("error.msg.null","One or more of the given 
parameters not found");
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new 
GeneralPlatformDomainRuleException("error.msg.io.exception","IO exception 
occured with "+fileDetail.getFileName()+" "+e.getMessage());
+
+        }
+    }
+
+
+    private Long publishEvent(final Integer primaryColumn,
+            final FormDataContentDisposition fileDetail, final InputStream 
clonedInputStreamWorkbook,
+            final GlobalEntityType entityType, final Workbook workbook,
+            final String locale, final String dateFormat) {
+
+        final String fileName = fileDetail.getFileName();
+
+        
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
+
+        final Long documentId = 
this.documentWritePlatformService.createInternalDocument(
+                
DocumentWritePlatformServiceJpaRepositoryImpl.DOCUMENT_MANAGEMENT_ENTITY.IMPORT.name(),
+                this.securityContext.authenticatedUser().getId(), null, 
clonedInputStreamWorkbook,
+                URLConnection.guessContentTypeFromName(fileName), fileName, 
null, fileName);
+        final Document document = this.documentRepository.findOne(documentId);
+
+        final ImportDocument importDocument = ImportDocument.instance(document,
+                DateUtils.getLocalDateTimeOfTenant(), entityType.getValue(),
+                this.securityContext.authenticatedUser(),
+                ImportHandlerUtils.getNumberOfRows(workbook.getSheetAt(0),
+                        primaryColumn));
+        this.importDocumentRepository.saveAndFlush(importDocument);
+        BulkImportEvent event = 
BulkImportEvent.instance(ThreadLocalContextUtil.getTenant()
+                .getTenantIdentifier(), workbook, importDocument.getId(), 
locale, dateFormat);
+        applicationContext.publishEvent(event);
+        return importDocument.getId();
+    }
+    @Override
+    public Collection<ImportData> getImports(GlobalEntityType type) {
+        this.securityContext.authenticatedUser();
+
+        final ImportMapper rm = new ImportMapper();
+        final String sql = "select " + rm.schema() + " order by i.id desc";
+
+        return this.jdbcTemplate.query(sql, rm, new Object[] 
{type.getValue()});
+    }
+
+
+
+    private static final class ImportMapper implements RowMapper<ImportData> {
+
+        public String schema() {
+            final StringBuilder sql = new StringBuilder();
+            sql.append("i.id as id, i.document_id as documentId, d.name as 
name, i.import_time as importTime, i.end_time as endTime, ")
+                    .append("i.completed as completed, i.total_records as 
totalRecords, i.success_count as successCount, ")
+                    .append("i.failure_count as failureCount, i.createdby_id 
as createdBy ")
+                    .append("from m_import_document i inner join m_document d 
on i.document_id=d.id ")
+                    .append("where i.entity_type= ? ");
+            return sql.toString();
+        }
+
+        @Override
+        public ImportData mapRow(final ResultSet rs, 
@SuppressWarnings("unused") final int rowNum) throws SQLException {
+
+            final Long id = rs.getLong("id");
+            final Long documentId = rs.getLong("documentId");
+            final String name = rs.getString("name");
+            final LocalDate importTime = JdbcSupport.getLocalDate(rs, 
"importTime");
+            final LocalDate endTime = JdbcSupport.getLocalDate(rs, "endTime");
+            final Boolean completed = rs.getBoolean("completed");
+            final Integer totalRecords = JdbcSupport.getInteger(rs, 
"totalRecords");
+            final Integer successCount = JdbcSupport.getInteger(rs, 
"successCount");
+            final Integer failureCount = JdbcSupport.getInteger(rs, 
"failureCount");
+            final Long createdBy = rs.getLong("createdBy");
+
+            return ImportData.instance(id, documentId, importTime, endTime, 
completed,
+                    name, createdBy, totalRecords, successCount, failureCount);
+        }
+    }
+
+    @Override
+    public DocumentData getOutputTemplateLocation(String importDocumentId) {
+        this.securityContext.authenticatedUser();
+        final ImportTemplateLocationMapper importTemplateLocationMapper=new 
ImportTemplateLocationMapper();
+        final String sql = "select " + importTemplateLocationMapper.schema();
+
+        return this.jdbcTemplate.queryForObject(sql, 
importTemplateLocationMapper, new Object[] {importDocumentId});
+    }
+
+    @Override
+    public Response getOutputTemplate(String importDocumentId) {
+        this.securityContext.authenticatedUser();
+        final ImportTemplateLocationMapper importTemplateLocationMapper=new 
ImportTemplateLocationMapper();
+        final String sql = "select " + importTemplateLocationMapper.schema();
+        DocumentData documentData= this.jdbcTemplate.queryForObject(sql, 
importTemplateLocationMapper, new Object[] {importDocumentId});
+        return buildResponse(documentData);
+    }
+
+    private Response buildResponse(DocumentData documentData) {
+        String fileName="Output"+documentData.fileName();
+        String fileLocation=documentData.fileLocation();
+        File file=new File(fileLocation);
+        final Response.ResponseBuilder response = Response.ok((Object)file);
+        response.header("Content-Disposition", "attachment; filename=\"" + 
fileName + "\"");
+        response.header("Content-Type", "application/vnd.ms-excel");
+        return response.build();
+    }
+
+    private static final class ImportTemplateLocationMapper implements 
RowMapper<DocumentData> {
+        public String schema() {
+            final StringBuilder sql = new StringBuilder();
+            sql.append("d.location,d.file_name ")
+                    .append("from m_import_document i inner join m_document d 
on i.document_id=d.id ")
+                    .append("where i.id= ? ");
+            return sql.toString();
+        }
+            @Override
+            public DocumentData mapRow (ResultSet rs,int rowNum) throws 
SQLException {
+                final String location = rs.getString("location");
+                final String fileName=rs.getString("file_name");
+                return new DocumentData(null,null,null,null,fileName,
+                        null,null,null,location,null);
+            }
+    }
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/data/CodeValueData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/data/CodeValueData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/data/CodeValueData.java
index 8b3a819..d7a5ca0 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/data/CodeValueData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/data/CodeValueData.java
@@ -37,6 +37,15 @@ public class CodeValueData implements Serializable {
     private final boolean active;
     private final boolean mandatory;
 
+    public CodeValueData( final Long id){
+        this.id = id;
+        this.name = null;
+        this.position = null;
+        this.description = null;
+        this.active = false;
+        this.mandatory = false;
+    }
+
     public static CodeValueData instance(final Long id, final String name, 
final Integer position, 
             final boolean isActive, final boolean mandatory) {
         String description = null;

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
index c1edb48..e5c6748 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
@@ -33,27 +33,24 @@ public class PaginationParametersDataValidator {
     private final Set<String> sortOrderValues = new 
HashSet<>(Arrays.asList("ASC", "DESC"));
 
     public void validateParameterValues(PaginationParameters parameters, final 
Set<String> supportedOrdeByValues, final String resourceName) {
-
         final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
-
-        if (parameters.isOrderByRequested() && 
!supportedOrdeByValues.contains(parameters.getOrderBy())) {
-            final String defaultUserMessage = "The orderBy value '" + 
parameters.getOrderBy()
-                    + "' is not supported. The supported orderBy values are " 
+ supportedOrdeByValues.toString();
-            final ApiParameterError error = 
ApiParameterError.parameterError("validation.msg." + resourceName
-                    + ".orderBy.value.is.not.supported", defaultUserMessage, 
"orderBy", parameters.getOrderBy(),
-                    supportedOrdeByValues.toString());
-            dataValidationErrors.add(error);
-        }
-
-        if (parameters.isSortOrderProvided() && 
!sortOrderValues.contains(parameters.getSortOrder().toUpperCase())) {
-            final String defaultUserMessage = "The sortOrder value '" + 
parameters.getSortOrder()
-                    + "' is not supported. The supported sortOrder values are 
" + sortOrderValues.toString();
-            final ApiParameterError error = 
ApiParameterError.parameterError("validation.msg." + resourceName
-                    + ".sortOrder.value.is.not.supported", defaultUserMessage, 
"sortOrder", parameters.getSortOrder(),
-                    sortOrderValues.toString());
-            dataValidationErrors.add(error);
-        }
-
+            if (parameters.isOrderByRequested() && 
!supportedOrdeByValues.contains(parameters.getOrderBy())) {
+                final String defaultUserMessage = "The orderBy value '" + 
parameters.getOrderBy()
+                        + "' is not supported. The supported orderBy values 
are " + supportedOrdeByValues.toString();
+                final ApiParameterError error = 
ApiParameterError.parameterError("validation.msg." + resourceName
+                                + ".orderBy.value.is.not.supported", 
defaultUserMessage, "orderBy", parameters.getOrderBy(),
+                        supportedOrdeByValues.toString());
+                dataValidationErrors.add(error);
+            }
+
+            if (parameters.isSortOrderProvided() && 
!sortOrderValues.contains(parameters.getSortOrder().toUpperCase())) {
+                final String defaultUserMessage = "The sortOrder value '" + 
parameters.getSortOrder()
+                        + "' is not supported. The supported sortOrder values 
are " + sortOrderValues.toString();
+                final ApiParameterError error = 
ApiParameterError.parameterError("validation.msg." + resourceName
+                                + ".sortOrder.value.is.not.supported", 
defaultUserMessage, "sortOrder", parameters.getSortOrder(),
+                        sortOrderValues.toString());
+                dataValidationErrors.add(error);
+            }
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java
index 0e08deb..fdf72a8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java
@@ -35,4 +35,9 @@ public interface DocumentWritePlatformService {
     @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_DOCUMENT')")
     CommandProcessingResult deleteDocument(DocumentCommand documentCommand);
 
+    @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_DOCUMENT')")
+    Long createInternalDocument(String entityType, Long entityId,
+            Long fileSize, InputStream inputStream, String mimeType,
+            String name, String description, String fileName);
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
index b229db5..1ddd86d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java
@@ -89,6 +89,22 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl 
implements DocumentWr
 
     @Transactional
     @Override
+    public Long createInternalDocument(final String entityType, final Long 
entityId,
+            final Long fileSize, final InputStream inputStream, final String 
mimeType,
+            final String name, final String description, final String 
fileName) {
+
+
+        final DocumentCommand documentCommand = new DocumentCommand(null, 
null, entityType, entityId, name, fileName,
+                fileSize, mimeType, description, null);
+
+        final Long documentId = createDocument(documentCommand, inputStream);
+
+        return documentId;
+
+    }
+
+    @Transactional
+    @Override
     public CommandProcessingResult updateDocument(final DocumentCommand 
documentCommand, final InputStream inputStream) {
         try {
             this.context.authenticatedUser();
@@ -161,7 +177,7 @@ public class DocumentWritePlatformServiceJpaRepositoryImpl 
implements DocumentWr
 
     /*** Entities for document Management **/
     public static enum DOCUMENT_MANAGEMENT_ENTITY {
-        CLIENTS, CLIENT_IDENTIFIERS, STAFF, LOANS, SAVINGS, GROUPS;
+        CLIENTS, CLIENT_IDENTIFIERS, STAFF, LOANS, SAVINGS, GROUPS,IMPORT;
 
         @Override
         public String toString() {

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
index 217e096..c3c8750 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
@@ -37,6 +37,16 @@ public class CurrencyData {
         return new CurrencyData("", "", 0, 0, "", "");
     }
 
+    public CurrencyData(String code) {
+        this.code = code;
+        this.name = null;
+        this.decimalPlaces =0;
+        this.inMultiplesOf = null;
+        this.displaySymbol = null;
+        this.nameCode = null;
+        this.displayLabel = null;
+    }
+
     public CurrencyData(final String code, final String name, final int 
decimalPlaces, final Integer inMultiplesOf,
             final String displaySymbol, final String nameCode) {
         this.code = code;
@@ -83,4 +93,8 @@ public class CurrencyData {
 
         return builder.toString();
     }
+
+    public String getName() {
+        return name;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/organisation/office/api/OfficesApiResource.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/api/OfficesApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/api/OfficesApiResource.java
index 9f0b109..f2c52da 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/api/OfficesApiResource.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/api/OfficesApiResource.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.organisation.office.api;
 
+import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
@@ -34,11 +35,17 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
+import com.sun.jersey.core.header.FormDataContentDisposition;
+import com.sun.jersey.multipart.FormDataParam;
 import org.apache.fineract.commands.domain.CommandWrapper;
 import org.apache.fineract.commands.service.CommandWrapperBuilder;
 import 
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
+import 
org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookPopulatorService;
+import 
org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookService;
 import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import 
org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
@@ -70,16 +77,23 @@ public class OfficesApiResource {
     private final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer;
     private final ApiRequestParameterHelper apiRequestParameterHelper;
     private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+    private final BulkImportWorkbookService bulkImportWorkbookService;
+    private final BulkImportWorkbookPopulatorService 
bulkImportWorkbookPopulatorService;
+
 
     @Autowired
     public OfficesApiResource(final PlatformSecurityContext context, final 
OfficeReadPlatformService readPlatformService,
             final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer, 
final ApiRequestParameterHelper apiRequestParameterHelper,
-            final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService) {
+            final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService,
+            final BulkImportWorkbookService bulkImportWorkbookService,
+            final BulkImportWorkbookPopulatorService 
bulkImportWorkbookPopulatorService) {
         this.context = context;
         this.readPlatformService = readPlatformService;
         this.toApiJsonSerializer = toApiJsonSerializer;
         this.apiRequestParameterHelper = apiRequestParameterHelper;
         this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+        this.bulkImportWorkbookService=bulkImportWorkbookService;
+        
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
     }
 
     @GET
@@ -165,4 +179,22 @@ public class OfficesApiResource {
 
         return this.toApiJsonSerializer.serialize(result);
     }
+
+    @GET
+    @Path("downloadtemplate")
+    @Produces("application/vnd.ms-excel")
+    public Response getOfficeTemplate(@QueryParam("dateFormat") final String 
dateFormat) {
+        return 
bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.OFFICES.toString(),
 null,null,dateFormat);
+    }
+
+    @POST
+    @Path("uploadtemplate")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    public String postOfficeTemplate(@FormDataParam("file") InputStream 
uploadedInputStream,
+            @FormDataParam("file") FormDataContentDisposition fileDetail,
+            @FormDataParam("locale") final String locale, 
@FormDataParam("dateFormat") final String dateFormat){
+        final Long importDocumentId = 
this.bulkImportWorkbookService.importWorkbook(GlobalEntityType.OFFICES.toString(),
+                uploadedInputStream,fileDetail, locale,dateFormat);
+        return this.toApiJsonSerializer.serialize(importDocumentId);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/organisation/office/data/OfficeData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/data/OfficeData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/data/OfficeData.java
index 3ea04ee..6668807 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/data/OfficeData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/data/OfficeData.java
@@ -22,6 +22,7 @@ import java.io.Serializable;
 import java.util.Collection;
 import java.util.List;
 
+import 
org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
 import org.joda.time.LocalDate;
 
 /**
@@ -40,6 +41,36 @@ public class OfficeData implements Serializable {
     @SuppressWarnings("unused")
     private final Collection<OfficeData> allowedParents;
 
+    //import fields
+    private transient Integer rowIndex;
+    private String locale;
+    private String dateFormat;
+
+    public static OfficeData importInstance(final String name, final Long 
parentId, final LocalDate openingDate,final String externalId) {
+        return new OfficeData(null, name, null, externalId, openingDate, null, 
parentId, null, null);
+    }
+    public void setImportFields(final Integer rowIndex, final String locale, 
final String dateFormat) {
+        this.rowIndex = rowIndex;
+        this.locale = locale;
+        this.dateFormat = dateFormat;
+    }
+    public static OfficeData testInstance(final Long id,final String name){
+        return new OfficeData(id,name,null,null,
+                null,null,null,null,
+                null);
+    }
+    public LocalDate getOpeningDate() {
+        return openingDate;
+    }
+
+    public Integer getRowIndex() {
+        return rowIndex;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
     public static OfficeData dropdown(final Long id, final String name, final 
String nameDecorated) {
         return new OfficeData(id, name, nameDecorated, null, null, null, null, 
null, null);
     }

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
index 79bd1a8..769b2a1 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
@@ -156,17 +156,17 @@ public class OfficeReadPlatformServiceImpl implements 
OfficeReadPlatformService
         sqlBuilder.append("select ");
         sqlBuilder.append(rm.officeSchema());
         sqlBuilder.append(" where o.hierarchy like ? ");
+        if(searchParameters!=null) {
+            if (searchParameters.isOrderByRequested()) {
+                sqlBuilder.append("order by 
").append(searchParameters.getOrderBy());
 
-        if (searchParameters.isOrderByRequested()) {
-            sqlBuilder.append("order by 
").append(searchParameters.getOrderBy());
-
-            if (searchParameters.isSortOrderProvided()) {
-                sqlBuilder.append(' ').append(searchParameters.getSortOrder());
+                if (searchParameters.isSortOrderProvided()) {
+                    sqlBuilder.append(' 
').append(searchParameters.getSortOrder());
+                }
+            } else {
+                sqlBuilder.append("order by o.hierarchy");
             }
-        } else {
-            sqlBuilder.append("order by o.hierarchy");
         }
-
         return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] 
{ hierarchySearchString });
     }
 

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/api/StaffApiResource.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/api/StaffApiResource.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/api/StaffApiResource.java
index c857874..d9ec511 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/api/StaffApiResource.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/api/StaffApiResource.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.organisation.staff.api;
 
+import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
@@ -34,11 +35,17 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
+import com.sun.jersey.core.header.FormDataContentDisposition;
+import com.sun.jersey.multipart.FormDataParam;
 import org.apache.fineract.commands.domain.CommandWrapper;
 import org.apache.fineract.commands.service.CommandWrapperBuilder;
 import 
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
+import 
org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookPopulatorService;
+import 
org.apache.fineract.infrastructure.bulkimport.service.BulkImportWorkbookService;
 import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import 
org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
@@ -72,18 +79,25 @@ public class StaffApiResource {
     private final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer;
     private final ApiRequestParameterHelper apiRequestParameterHelper;
     private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+    private final BulkImportWorkbookService bulkImportWorkbookService;
+    private final BulkImportWorkbookPopulatorService 
bulkImportWorkbookPopulatorService;
+
 
     @Autowired
     public StaffApiResource(final PlatformSecurityContext context, final 
StaffReadPlatformService readPlatformService,
             final OfficeReadPlatformService officeReadPlatformService, final 
DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer,
             final ApiRequestParameterHelper apiRequestParameterHelper,
-            final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService) {
+            final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService,
+            final BulkImportWorkbookService bulkImportWorkbookService,
+            final BulkImportWorkbookPopulatorService 
bulkImportWorkbookPopulatorService) {
         this.context = context;
         this.readPlatformService = readPlatformService;
         this.officeReadPlatformService = officeReadPlatformService;
         this.toApiJsonSerializer = toApiJsonSerializer;
         this.apiRequestParameterHelper = apiRequestParameterHelper;
         this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+        this.bulkImportWorkbookService=bulkImportWorkbookService;
+        
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
     }
 
     @GET
@@ -150,4 +164,24 @@ public class StaffApiResource {
 
         return this.toApiJsonSerializer.serialize(result);
     }
+
+    @GET
+    @Path("downloadtemplate")
+    @Produces("application/vnd.ms-excel")
+    public Response getStaffTemplate(@QueryParam("officeId")final Long 
officeId,
+            @QueryParam("dateFormat") final String dateFormat) {
+        return 
bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.STAFF.toString(),
 officeId,null,dateFormat);
+    }
+
+    @POST
+    @Path("uploadtemplate")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    public String postStaffTemplate(@FormDataParam("file") InputStream 
uploadedInputStream,
+            @FormDataParam("file") FormDataContentDisposition fileDetail,
+            @FormDataParam("locale") final String locale,
+            @FormDataParam("dateFormat") final String dateFormat){
+        final Long importDocumentId = this. 
bulkImportWorkbookService.importWorkbook(GlobalEntityType.STAFF.toString(), 
uploadedInputStream,
+                fileDetail,locale,dateFormat);
+        return this.toApiJsonSerializer.serialize(importDocumentId);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/data/StaffData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/data/StaffData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/data/StaffData.java
index 45f0dbd..265b671 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/data/StaffData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/data/StaffData.java
@@ -20,6 +20,7 @@ package org.apache.fineract.organisation.staff.data;
 
 import java.util.Collection;
 
+import 
org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
 import org.apache.fineract.organisation.office.data.OfficeData;
 import org.joda.time.LocalDate;
 
@@ -40,6 +41,41 @@ public class StaffData {
     private final Boolean isActive;
     private final LocalDate joiningDate;
 
+    //import fields
+    private transient Integer rowIndex;
+    private String dateFormat;
+    private String locale;
+
+    public static StaffData importInstance(String externalId, String 
firstName, String lastName, String mobileNo, Long officeId, Boolean 
isLoanOfficer,
+            Boolean isActive, LocalDate joinedOnDate, Integer rowIndex,String 
locale, String dateFormat){
+        return  new 
StaffData(externalId,firstName,lastName,mobileNo,officeId,isLoanOfficer,isActive,
+                joinedOnDate,rowIndex,locale,dateFormat);
+
+    }
+    private StaffData(String externalId, String firstname, String lastname, 
String mobileNo, Long officeId, Boolean isLoanOfficer,
+            Boolean isActive, LocalDate joiningDate, Integer rowIndex,String 
locale, String dateFormat) {
+
+        this.externalId = externalId;
+        this.firstname = firstname;
+        this.lastname = lastname;
+        this.mobileNo = mobileNo;
+        this.officeId = officeId;
+        this.isLoanOfficer = isLoanOfficer;
+        this.isActive = isActive;
+        this.joiningDate = joiningDate;
+        this.rowIndex = rowIndex;
+        this.dateFormat= dateFormat;
+        this.locale= locale;
+        this.allowedOffices = null;
+        this.id = null;
+        this.officeName = null;
+        this.displayName = null;
+    }
+
+    public Integer getRowIndex() {
+        return rowIndex;
+    }
+
     @SuppressWarnings("unused")
     private final Collection<OfficeData> allowedOffices;
 

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffReadPlatformServiceImpl.java
index ed675a1..37c869c 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffReadPlatformServiceImpl.java
@@ -241,14 +241,16 @@ public class StaffReadPlatformServiceImpl implements 
StaffReadPlatformService {
         }
         // Passing status parameter to get ACTIVE (By Default), INACTIVE or ALL
         // (Both active and Inactive) employees
-        if (status.equalsIgnoreCase("active")) {
-            extraCriteria.append(" and s.is_active = 1 ");
-        } else if (status.equalsIgnoreCase("inActive")) {
-            extraCriteria.append(" and s.is_active = 0 ");
-        } else if (status.equalsIgnoreCase("all")) {} else {
-            throw new UnrecognizedQueryParamException("status", status, new 
Object[] { "all", "active", "inactive" });
+        if (status!=null) {
+            if (status.equalsIgnoreCase("active")) {
+                extraCriteria.append(" and s.is_active = 1 ");
+            } else if (status.equalsIgnoreCase("inActive")) {
+                extraCriteria.append(" and s.is_active = 0 ");
+            } else if (status.equalsIgnoreCase("all")) {
+            } else {
+                throw new UnrecognizedQueryParamException("status", status, 
new Object[]{"all", "active", "inactive"});
+            }
         }
-        
         //adding the Authorization criteria so that a user cannot see an 
employee who does not belong to his office or         a sub office for his 
office.
         
         extraCriteria.append(" and o.hierarchy like ? ");

Reply via email to