http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/TransactionConstants.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/TransactionConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/TransactionConstants.java
new file mode 100644
index 0000000..acfa73e
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/TransactionConstants.java
@@ -0,0 +1,43 @@
+/**
+ * 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.constants;
+
+public class TransactionConstants {
+
+    public static final int OFFICE_NAME_COL = 0;
+    public static final int CLIENT_NAME_COL = 1;
+    public static final int SAVINGS_ACCOUNT_NO_COL = 2;
+    public static final int PRODUCT_COL = 3;
+    public static final int OPENING_BALANCE_COL = 4;
+    public static final int TRANSACTION_TYPE_COL = 5;
+    public static final int AMOUNT_COL = 6;
+    public static final int TRANSACTION_DATE_COL = 7;
+    public static final int PAYMENT_TYPE_COL = 8;
+    public static final int ACCOUNT_NO_COL = 9;
+    public static final int CHECK_NO_COL = 10;
+    public static final int ROUTING_CODE_COL = 11;
+    public static final int RECEIPT_NO_COL = 12;
+    public static final int BANK_NO_COL = 13;
+    public static final int STATUS_COL = 14;
+    public static final int LOOKUP_CLIENT_NAME_COL = 15;
+    public static final int LOOKUP_ACCOUNT_NO_COL = 16;
+    public static final int LOOKUP_PRODUCT_COL = 17;
+    public static final int LOOKUP_OPENING_BALANCE_COL = 18;
+    public static final int LOOKUP_SAVINGS_ACTIVATION_DATE_COL = 19;
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/UserConstants.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/UserConstants.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/UserConstants.java
new file mode 100644
index 0000000..b9b6c4c
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/constants/UserConstants.java
@@ -0,0 +1,34 @@
+/**
+ * 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.constants;
+
+public class UserConstants {
+    public static final int OFFICE_NAME_COL=0;
+    public static final int STAFF_NAME_COL=1;
+    public static final int USER_NAME_COL=2;
+    public static final int FIRST_NAME_COL=3;
+    public static final int LAST_NAME_COL=4;
+    public static final int EMAIL_COL=5;
+    public static final int AUTO_GEN_PW_COL=6;
+    public static final int OVERRIDE_PW_EXPIRY_POLICY_COL=7;
+    public static final int STATUS_COL=8;
+    public static final int ROLE_NAME_START_COL=9;
+    public static final int ROLE_NAME_END_COL=14;
+
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/BulkImportEvent.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/BulkImportEvent.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/BulkImportEvent.java
new file mode 100644
index 0000000..0a49366
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/BulkImportEvent.java
@@ -0,0 +1,71 @@
+/**
+ * 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.data;
+
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.context.ApplicationEvent;
+
+public class BulkImportEvent extends ApplicationEvent {
+
+    private final String tenantIdentifier;
+
+    private final Workbook workbook;
+
+    private final Long importId;
+
+    private final String locale;
+
+    private final String dateFormat;
+
+    private BulkImportEvent(final String tenantIdentifier, final Workbook 
workbook,
+            final Long importId, final String locale, final String dateFormat) 
{
+        super(BulkImportEvent.class);
+        this.tenantIdentifier = tenantIdentifier;
+        this.workbook = workbook;
+        this.importId = importId;
+        this.locale = locale;
+        this.dateFormat = dateFormat;
+    }
+
+    public static BulkImportEvent instance(final String tenantIdentifier, 
final Workbook workbook,
+            final Long importId, final String locale, final String dateFormat) 
{
+        return new BulkImportEvent(tenantIdentifier, workbook, importId, 
locale, dateFormat);
+    }
+
+    public String getTenantIdentifier() {
+        return tenantIdentifier;
+    }
+
+    public Workbook getWorkbook() {
+        return workbook;
+    }
+
+    public Long getImportId() {
+        return importId;
+    }
+
+    public String getDateFormat() {
+        return dateFormat;
+    }
+
+    public String getLocale() {
+        return locale;
+    }
+
+}
\ 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/data/Count.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/Count.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/Count.java
new file mode 100644
index 0000000..c4926c1
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/Count.java
@@ -0,0 +1,45 @@
+/**
+ * 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.data;
+
+public class Count {
+
+    private Integer successCount;
+    private Integer errorCount;
+
+    public static Count instance(final Integer successCount,
+            final Integer errorCount) {
+        return new Count(successCount, errorCount);
+    }
+
+    private Count(final Integer successCount,
+            final Integer errorCount) {
+        this.successCount  = successCount;
+        this.errorCount = errorCount;
+    }
+
+    public Integer getSuccessCount() {
+        return successCount;
+    }
+
+    public Integer getErrorCount() {
+        return errorCount;
+    }
+
+}
\ 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/data/GlobalEntityType.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/GlobalEntityType.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/GlobalEntityType.java
new file mode 100644
index 0000000..bb99a54
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/GlobalEntityType.java
@@ -0,0 +1,118 @@
+/**
+ * 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.data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum GlobalEntityType {
+
+
+    INVALID(0, "invalid"),
+    CLIENTS_PERSON(1, "clients.person"),
+    CLIENTS_ENTTTY(2,"clients.entity"),
+    GROUPS(3, "groups"),
+    CENTERS(4, "centers"),
+    OFFICES(5, "offices"),
+    STAFF(6, "staff"),
+    USERS(7, "users"),
+    SMS(8, "sms"),
+    DOCUMENTS(9, "documents"),
+    TEMPLATES(10, "templates"),
+    NOTES(11, "templates"),
+    CALENDAR(12, "calendar"),
+    MEETINGS(13, "meetings"),
+    HOLIDAYS(14, "holidays"),
+    LOANS(15, "loans"),
+    LOAN_PRODUCTS(16,"loancharges"),
+    LOAN_TRANSACTIONS(18, "loantransactions"),
+    GUARANTORS(19, "guarantors"),
+    COLLATERALS(20, "collaterals"),
+    FUNDS(21, "funds"),
+    CURRENCY(22, "currencies"),
+    SAVINGS_ACCOUNT(23, "savingsaccount"),
+    SAVINGS_CHARGES(24, "savingscharges"),
+    SAVINGS_TRANSACTIONS(25, "savingstransactions"),
+    SAVINGS_PRODUCTS(26, "savingsproducts"),
+    GL_JOURNAL_ENTRIES(27, "gljournalentries"),
+    CODE_VALUE(28, "codevalue"),
+    CODE(29, "code"),
+    CHART_OF_ACCOUNTS(30,"chartofaccounts"),
+    FIXED_DEPOSIT_ACCOUNTS(31,"fixeddepositaccounts"),
+    FIXED_DEPOSIT_TRANSACTIONS(32,"fixeddeposittransactions"),
+    SHARE_ACCOUNTS(33,"shareaccounts"),
+    RECURRING_DEPOSIT_ACCOUNTS(34,"recurringdeposits"),
+    
RECURRING_DEPOSIT_ACCOUNTS_TRANSACTIONS(35,"recurringdepositstransactions"),
+    CLIENT(36,"client");
+
+    private final Integer value;
+    private final String code;
+
+    private static final Map<Integer, GlobalEntityType> intToEnumMap = new 
HashMap<>();
+    private static final Map<String, GlobalEntityType> stringToEnumMap = new 
HashMap<>();
+    private static int minValue;
+    private static int maxValue;
+
+    static {
+        int i = 0;
+        for (final GlobalEntityType entityType : GlobalEntityType.values()) {
+            if (i == 0) {
+                minValue = entityType.value;
+            }
+            intToEnumMap.put(entityType.value, entityType);
+            stringToEnumMap.put(entityType.code, entityType);
+            if (minValue >= entityType.value) {
+                minValue = entityType.value;
+            }
+            if (maxValue < entityType.value) {
+                maxValue = entityType.value;
+            }
+            i = i + 1;
+        }
+    }
+
+    private GlobalEntityType(final Integer value, final String code) {
+        this.value = value;
+        this.code = code;
+    }
+
+    public Integer getValue() {
+        return this.value;
+    }
+
+    public String getCode() {
+        return this.code;
+    }
+
+    public static GlobalEntityType fromInt(final int i) {
+        final GlobalEntityType entityType = 
intToEnumMap.get(Integer.valueOf(i));
+        return entityType;
+    }
+
+    public static GlobalEntityType fromCode(final String key) {
+        final GlobalEntityType entityType = stringToEnumMap.get(key);
+        return entityType;
+    }
+
+    @Override
+    public String toString() {
+        return name().toString();
+    }
+
+}
\ 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/data/ImportData.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java
new file mode 100644
index 0000000..635a6a9
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java
@@ -0,0 +1,80 @@
+/**
+ * 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.data;
+
+import org.joda.time.LocalDate;
+
+public class ImportData {
+
+    @SuppressWarnings("unused")
+    private Long importId;
+    @SuppressWarnings("unused")
+    private Long documentId;
+    @SuppressWarnings("unused")
+    private String name;
+    @SuppressWarnings("unused")
+    private LocalDate importTime;
+    @SuppressWarnings("unused")
+    private LocalDate endTime;
+    @SuppressWarnings("unused")
+    private Boolean completed;
+    @SuppressWarnings("unused")
+    private Long createdBy;
+    @SuppressWarnings("unused")
+    private Integer totalRecords;
+    @SuppressWarnings("unused")
+    private Integer successCount;
+    @SuppressWarnings("unused")
+    private Integer failureCount;
+
+    public static ImportData instance(final Long importId, final Long 
documentId,
+                                      final LocalDate importTime, final 
LocalDate endTime,
+                                      final Boolean completed, final String 
name,
+                                      final Long createdBy, final Integer 
totalRecords, final Integer successCount,
+                                      final Integer failureCount) {
+        return new ImportData(importId, documentId, importTime, endTime,
+                completed, name, createdBy, totalRecords, successCount,
+                failureCount);
+    }
+
+    public  static ImportData instance(final Long importId){
+        return new ImportData(importId,null,null,
+                null,null,null,null,null,
+                null,null);
+    }
+
+    private ImportData(final Long importId, final Long documentId,
+                       final LocalDate importTime, final LocalDate endTime,
+                       final Boolean completed, final String name,
+                       final Long createdBy, final Integer totalRecords, final 
Integer successCount,
+                       final Integer failureCount) {
+        this.importId = importId;
+        this.documentId = documentId;
+        this.name = name;
+        this.importTime = importTime;
+        this.endTime = endTime;
+        this.completed = completed;
+        this.createdBy = createdBy;
+        this.totalRecords = totalRecords;
+        this.successCount = successCount;
+        this.failureCount = failureCount;
+    }
+
+
+}
\ 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/data/ImportFormatType.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportFormatType.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportFormatType.java
new file mode 100644
index 0000000..29bbe61
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportFormatType.java
@@ -0,0 +1,49 @@
+/**
+ * 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.data;
+
+import 
org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
+
+public enum ImportFormatType {
+
+    XLSX ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
+    XLS ("application/vnd.ms-excel"),
+    ODS ("application/vnd.oasis.opendocument.spreadsheet");
+
+
+    private final String format;
+
+    private ImportFormatType(String format) {
+        this.format= format;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    public static ImportFormatType of(String name) {
+        for(ImportFormatType type : ImportFormatType.values()) {
+            if(type.name().equalsIgnoreCase(name)) {
+                return type;
+            }
+        }
+        throw new 
GeneralPlatformDomainRuleException("error.msg.invalid.file.extension",
+                "Uploaded file extension is not recognized.");
+    }
+}
\ 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/domain/ImportDocument.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/domain/ImportDocument.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/domain/ImportDocument.java
new file mode 100644
index 0000000..5e65be2
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/domain/ImportDocument.java
@@ -0,0 +1,124 @@
+/**
+ * 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.domain;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import 
org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.apache.fineract.infrastructure.documentmanagement.domain.Document;
+import org.apache.fineract.useradministration.domain.AppUser;
+import org.joda.time.LocalDate;
+import org.joda.time.LocalDateTime;
+
+@Entity
+@Table(name = "m_import_document")
+public class ImportDocument extends AbstractPersistableCustom<Long>{
+
+    @OneToOne
+    @JoinColumn(name = "document_id")
+    private Document document;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "import_time")
+    private Date importTime;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "end_time")
+    private Date endTime;
+
+    @Column(name = "completed", nullable = false)
+    private Boolean completed;
+
+    @Column(name = "entity_type")
+    private Integer entity_type;
+
+    @ManyToOne
+    @JoinColumn(name = "createdby_id")
+    private AppUser createdBy;
+
+    @Column(name = "total_records", nullable = true)
+    private Integer totalRecords;
+
+    @Column(name = "success_count", nullable = true)
+    private Integer successCount;
+
+    @Column(name = "failure_count", nullable = true)
+    private Integer failureCount;
+
+    protected ImportDocument() {
+
+    }
+
+    public static ImportDocument instance(final Document document, final 
LocalDateTime importTime,
+            final Integer entity_type, final AppUser createdBy, final Integer 
totalRecords) {
+
+        final Boolean completed = Boolean.FALSE;
+        final Integer successCount = 0;
+        final Integer failureCount = 0;
+        final LocalDateTime endTime = LocalDateTime.now();
+
+        return new ImportDocument(document, importTime, endTime, completed, 
entity_type,
+                createdBy, totalRecords, successCount, failureCount);
+    }
+
+    private ImportDocument(final Document document, final LocalDateTime 
importTime,
+            final LocalDateTime endTime, Boolean completed, final Integer 
entity_type,
+            final AppUser createdBy, final Integer totalRecords, final Integer 
successCount,
+            final Integer failureCount) {
+        this.document = document;
+        this.importTime = importTime.toDate();
+        this.endTime = endTime.toDate();
+        this.completed = completed;
+        this.entity_type = entity_type;
+        this.createdBy = createdBy;
+        this.totalRecords = totalRecords;
+        this.successCount = successCount;
+        this.failureCount = failureCount;
+
+    }
+
+    public void update(final LocalDateTime endTime, final Integer successCount,
+            final Integer errorCount) {
+        this.endTime = endTime.toDate();
+        this.completed = Boolean.TRUE;
+        this.successCount = successCount;
+        this.failureCount = errorCount;
+    }
+
+    public Document getDocument() {
+        return this.document;
+    }
+
+    public Integer getEntityType() {
+        return this.entity_type;
+    }
+
+
+
+
+}
\ 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/domain/ImportDocumentRepository.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/domain/ImportDocumentRepository.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/domain/ImportDocumentRepository.java
new file mode 100644
index 0000000..18e0d3d
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/domain/ImportDocumentRepository.java
@@ -0,0 +1,27 @@
+/**
+ * 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.domain;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+public interface ImportDocumentRepository
+        extends JpaRepository<ImportDocument, Long>, 
JpaSpecificationExecutor<ImportDocument> {
+    // no added behaviour
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/exceptions/ImportTypeNotFoundException.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/exceptions/ImportTypeNotFoundException.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/exceptions/ImportTypeNotFoundException.java
new file mode 100644
index 0000000..2754c2a
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/exceptions/ImportTypeNotFoundException.java
@@ -0,0 +1,29 @@
+/**
+ * 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.exceptions;
+
+import 
org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
+
+public class ImportTypeNotFoundException extends 
AbstractPlatformResourceNotFoundException {
+
+    public ImportTypeNotFoundException(final String entityType) {
+        super("error.msg.entity.type.invalid", "Entity type " + entityType + " 
does not exist", entityType);
+    }
+
+}
\ 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/importhandler/ImportHandler.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandler.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandler.java
new file mode 100644
index 0000000..e185d38
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandler.java
@@ -0,0 +1,27 @@
+/**
+ * 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.importhandler;
+
+import org.apache.fineract.infrastructure.bulkimport.data.Count;
+import org.apache.poi.ss.usermodel.Workbook;
+
+public interface ImportHandler {
+    public Count process(Workbook workbook, String locale, String dateFormat);
+}
+

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java
new file mode 100644
index 0000000..36bd1d8
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java
@@ -0,0 +1,355 @@
+/**
+ * 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 from 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.importhandler;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import 
org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.*;
+import org.apache.poi.ss.usermodel.*;
+import org.joda.time.LocalDate;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+public class ImportHandlerUtils {
+
+    public static Integer getNumberOfRows(Sheet sheet, int primaryColumn) {
+        Integer noOfEntries = 0;
+        // getLastRowNum and getPhysicalNumberOfRows showing false values
+        // sometimes
+        while (sheet.getRow(noOfEntries+1) !=null && 
sheet.getRow(noOfEntries+1).getCell(primaryColumn) != null) {
+            noOfEntries++;
+        }
+
+        return noOfEntries;
+    }
+
+    public static boolean isNotImported(Row row, int statusColumn) {
+        if (readAsString(statusColumn,row)!=null) {
+            return !readAsString(statusColumn, 
row).equals(TemplatePopulateImportConstants.STATUS_CELL_IMPORTED);
+        }else {
+            return true;
+        }
+    }
+
+    public static Long readAsLong(int colIndex, Row row) {
+        Cell c = row.getCell(colIndex);
+        if (c == null || c.getCellType() == Cell.CELL_TYPE_BLANK)
+            return null;
+        FormulaEvaluator eval = 
row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+        if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
+            if(eval!=null) {
+                CellValue val = eval.evaluate(c);
+                return ((Double) val.getNumberValue()).longValue();
+            }
+        }
+        else if (c.getCellType()==Cell.CELL_TYPE_NUMERIC){
+            return ((Double) c.getNumericCellValue()).longValue();
+        }
+        else {
+            return Long.parseLong(row.getCell(colIndex).getStringCellValue());
+        }
+        return null;
+    }
+
+
+    public static String readAsString(int colIndex, Row row) {
+
+        Cell c = row.getCell(colIndex);
+        if (c == null || c.getCellType() == Cell.CELL_TYPE_BLANK)
+            return null;
+        FormulaEvaluator eval = 
row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+        if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
+            if (eval!=null) {
+                CellValue val = eval.evaluate(c);
+                String res = trimEmptyDecimalPortion(val.getStringValue());
+                if (res!=null) {
+                    if (!res.equals("")) {
+                        return res.trim();
+                    } else {
+                        return null;
+                    }
+                }else {
+                    return null;
+                }
+            }else {
+                return null;
+            }
+        }else if(c.getCellType()==Cell.CELL_TYPE_STRING) {
+            String res = 
trimEmptyDecimalPortion(c.getStringCellValue().trim());
+            return res.trim();
+
+        }else if(c.getCellType()==Cell.CELL_TYPE_NUMERIC) {
+            return ((Double) 
row.getCell(colIndex).getNumericCellValue()).intValue() + "";
+        }else if (c.getCellType()==Cell.CELL_TYPE_BOOLEAN){
+            return c.getBooleanCellValue()+"";
+        }else {
+            return null;
+        }
+    }
+
+
+    public static String trimEmptyDecimalPortion(String result) {
+        if(result != null && result.endsWith(".0"))
+            return     result.split("\\.")[0];
+        else
+            return result;
+    }
+
+    public static LocalDate readAsDate(int colIndex, Row row) {
+        Cell c = row.getCell(colIndex);
+        if(c == null || c.getCellType() == Cell.CELL_TYPE_BLANK)
+            return null;
+
+        LocalDate localDate=new LocalDate(c.getDateCellValue());
+        return localDate;
+    }
+
+    public static Boolean readAsBoolean(int colIndex, Row row) {
+            Cell c = row.getCell(colIndex);
+            if(c == null || c.getCellType() == Cell.CELL_TYPE_BLANK)
+                return false;
+            FormulaEvaluator eval = 
row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+            if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
+                if(eval!=null) {
+                    CellValue val = eval.evaluate(c);
+                    return val.getBooleanValue();
+                }
+                return false;
+            }else if(c.getCellType()==Cell.CELL_TYPE_BOOLEAN)
+                return c.getBooleanCellValue();
+            else {
+                String booleanString = 
row.getCell(colIndex).getStringCellValue().trim();
+                if (booleanString.equalsIgnoreCase("TRUE"))
+                    return true;
+                else
+                    return false;
+            }
+        }
+
+    public static Integer readAsInt(int colIndex, Row row) {
+            Cell c = row.getCell(colIndex);
+            if (c == null || c.getCellType() == Cell.CELL_TYPE_BLANK)
+                return null;
+            FormulaEvaluator eval = 
row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+            if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
+                if(eval!=null) {
+                   CellValue val = eval.evaluate(c);
+                    return ((Double) val.getNumberValue()).intValue();
+                }
+                return null;
+            }else if (c.getCellType()==Cell.CELL_TYPE_NUMERIC) {
+                return ((Double) c.getNumericCellValue()).intValue();
+            }else {
+                return 
Integer.parseInt(row.getCell(colIndex).getStringCellValue());
+            }
+    }
+
+    public static Double readAsDouble(int colIndex, Row row) {
+        Cell c = row.getCell(colIndex);
+        if (c == null || c.getCellType() == Cell.CELL_TYPE_BLANK)
+            return 0.0;
+        FormulaEvaluator eval = 
row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+        if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
+                if (eval!=null) {
+                    CellValue val = eval.evaluate(c);
+                    return val.getNumberValue();
+                }else {
+                    return 0.0;
+                }
+        } else if (c.getCellType()==Cell.CELL_TYPE_NUMERIC) {
+            return row.getCell(colIndex).getNumericCellValue();
+        }else {
+            return 
Double.parseDouble(row.getCell(colIndex).getStringCellValue());
+        }
+    }
+
+    public static void writeString(int colIndex, Row row, String value) {
+        if(value!=null)
+            row.createCell(colIndex).setCellValue(value);
+    }
+
+    public static CellStyle getCellStyle(Workbook workbook, IndexedColors 
color) {
+        CellStyle style = workbook.createCellStyle();
+        style.setFillForegroundColor(color.getIndex());
+        style.setFillPattern(CellStyle.SOLID_FOREGROUND);
+        return style;
+    }
+
+    public static String getDefaultUserMessages(List<ApiParameterError> 
ApiParameterErrorList){
+        StringBuffer defaultUserMessages=new StringBuffer();
+        for (ApiParameterError error:ApiParameterErrorList) {
+            
defaultUserMessages=defaultUserMessages.append(error.getDefaultUserMessage()+'\t');
+        }
+        return defaultUserMessages.toString();
+    }
+    public static String getErrorList(List<String> errorList){
+        StringBuffer errors=new StringBuffer();
+        for (String error: errorList) {
+                errors=errors.append(error);
+        }
+        return errors.toString();
+    }
+
+    public static void writeErrorMessage(Sheet sheet,Integer rowIndex,String 
errorMessage,int statusColumn){
+        Cell statusCell = sheet.getRow(rowIndex).createCell(statusColumn);
+        statusCell.setCellValue(errorMessage);
+        statusCell.setCellStyle(getCellStyle(sheet.getWorkbook(), 
IndexedColors.RED));
+    }
+
+    public static String getErrorMessage(RuntimeException re) {
+        if (re instanceof AbstractPlatformDomainRuleException){
+            AbstractPlatformDomainRuleException 
abstractPlatformDomainRuleException= (AbstractPlatformDomainRuleException) re;
+            return abstractPlatformDomainRuleException.getDefaultUserMessage();
+        }else if (re instanceof AbstractPlatformResourceNotFoundException){
+            AbstractPlatformResourceNotFoundException 
abstractPlatformResourceNotFoundException= 
(AbstractPlatformResourceNotFoundException) re;
+            return  
abstractPlatformResourceNotFoundException.getDefaultUserMessage();
+        }else if (re instanceof AbstractPlatformServiceUnavailableException) {
+            AbstractPlatformServiceUnavailableException 
abstractPlatformServiceUnavailableException = 
(AbstractPlatformServiceUnavailableException) re;
+            return 
abstractPlatformServiceUnavailableException.getDefaultUserMessage();
+        }else if (re instanceof PlatformDataIntegrityException){
+            PlatformDataIntegrityException platformDataIntegrityException= 
(PlatformDataIntegrityException) re;
+            return platformDataIntegrityException.getDefaultUserMessage();
+        }else if (re instanceof PlatformApiDataValidationException){
+            PlatformApiDataValidationException 
platformApiDataValidationException=(PlatformApiDataValidationException) re;
+            return 
getDefaultUserMessages(platformApiDataValidationException.getErrors());
+        }else if (re instanceof UnsupportedParameterException ){
+            UnsupportedParameterException unsupportedParameterException= 
(UnsupportedParameterException) re;
+            return  
getErrorList(unsupportedParameterException.getUnsupportedParameters());
+        }else {
+            if (re.getMessage()!=null) {
+                return re.getMessage();
+            }else {
+                return re.getClass().getCanonicalName();
+            }
+        }
+    }
+
+    public static Long getIdByName (Sheet sheet, String name) {
+        String sheetName = sheet.getSheetName();
+        
if(!sheetName.equals(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME)) {
+            for (Row row : sheet) {
+                for (Cell cell : row) {
+                    if(name!=null) {
+                        if (cell.getCellType() == Cell.CELL_TYPE_STRING && 
cell.getRichStringCellValue().getString().trim().equals(name)) {
+                            if 
(sheetName.equals(TemplatePopulateImportConstants.OFFICE_SHEET_NAME) ||
+                                    
sheetName.equals(TemplatePopulateImportConstants.GL_ACCOUNTS_SHEET_NAME) ||
+                                    
sheetName.equals(TemplatePopulateImportConstants.EXTRAS_SHEET_NAME) ||
+                                    
sheetName.equals(TemplatePopulateImportConstants.SHARED_PRODUCTS_SHEET_NAME)||
+                                    
sheetName.equals(TemplatePopulateImportConstants.ROLES_SHEET_NAME)) {
+                                if (row.getCell(cell.getColumnIndex() - 
1).getCellType() == Cell.CELL_TYPE_NUMERIC)
+                                    return ((Double) 
row.getCell(cell.getColumnIndex() - 1).getNumericCellValue()).longValue();
+                                return 0L;
+                            } else if 
(sheetName.equals(TemplatePopulateImportConstants.CLIENT_SHEET_NAME) ||
+                                    
sheetName.equals(TemplatePopulateImportConstants.CENTER_SHEET_NAME) ||
+                                    
sheetName.equals(TemplatePopulateImportConstants.GROUP_SHEET_NAME) ||
+                                    
sheetName.equals(TemplatePopulateImportConstants.STAFF_SHEET_NAME))
+                                if (row.getCell(cell.getColumnIndex() + 
1).getCellType() == Cell.CELL_TYPE_NUMERIC)
+                                    return ((Double) 
row.getCell(cell.getColumnIndex() + 1).getNumericCellValue()).longValue();
+                            return 0L;
+                        }
+                    }else {
+                        return 0L;
+                    }
+                }
+            }
+        } else if 
(sheetName.equals(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME)) {
+            for(Row row : sheet) {
+                for(int i = 0; i < 2; i++) {
+                    if (name != null) {
+                        Cell cell = row.getCell(i);
+                        if (cell.getCellType() == Cell.CELL_TYPE_STRING && 
cell.getRichStringCellValue().getString().trim().equals(name)) {
+                            return ((Double) row.getCell(cell.getColumnIndex() 
- 1).getNumericCellValue()).longValue();
+                        }
+                    }else {
+                        return 0L;
+                    }
+                }
+            }
+        }
+        return 0L;
+    }
+    public static String getCodeByName(Sheet sheet, String name) {
+        String sheetName = sheet.getSheetName();
+        sheetName.equals(TemplatePopulateImportConstants.EXTRAS_SHEET_NAME);
+        {
+            for (Row row : sheet) {
+                for (Cell cell : row) {
+                    if (name!=null) {
+                        if (cell.getCellType() == Cell.CELL_TYPE_STRING
+                                && 
cell.getRichStringCellValue().getString().trim()
+                                .equals(name)) {
+                            return row.getCell(cell.getColumnIndex() - 1)
+                                    .getStringCellValue().toString();
+
+                        }
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    public static String getFrequencyId(String frequency) {
+        if (frequency!=null) {
+            if 
(frequency.equalsIgnoreCase(TemplatePopulateImportConstants.FREQUENCY_DAILY))
+                frequency = "1";
+            else if 
(frequency.equalsIgnoreCase(TemplatePopulateImportConstants.FREQUENCY_WEEKLY))
+                frequency = "2";
+            else if 
(frequency.equalsIgnoreCase(TemplatePopulateImportConstants.FREQUENCY_MONTHLY))
+                frequency = "3";
+            else if 
(frequency.equalsIgnoreCase(TemplatePopulateImportConstants.FREQUENCY_YEARLY))
+                frequency = "4";
+            return frequency;
+        }else {
+            return null;
+        }
+    }
+
+    public static String getRepeatsOnDayId(String repeatsOnDay) {
+        if (repeatsOnDay!=null) {
+            if 
(repeatsOnDay.equalsIgnoreCase(TemplatePopulateImportConstants.MONDAY))
+                repeatsOnDay = "1";
+            else if 
(repeatsOnDay.equalsIgnoreCase(TemplatePopulateImportConstants.TUESDAY))
+                repeatsOnDay = "2";
+            else if 
(repeatsOnDay.equalsIgnoreCase(TemplatePopulateImportConstants.WEDNESDAY))
+                repeatsOnDay = "3";
+            else if 
(repeatsOnDay.equalsIgnoreCase(TemplatePopulateImportConstants.THURSDAY))
+                repeatsOnDay = "4";
+            else if 
(repeatsOnDay.equalsIgnoreCase(TemplatePopulateImportConstants.FRIDAY))
+                repeatsOnDay = "5";
+
+            else if 
(repeatsOnDay.equalsIgnoreCase(TemplatePopulateImportConstants.SATURDAY))
+                repeatsOnDay = "6";
+            else if 
(repeatsOnDay.equalsIgnoreCase(TemplatePopulateImportConstants.SUNDAY))
+                repeatsOnDay = "7";
+            return repeatsOnDay;
+        }else {
+            return null;
+        }
+    }
+}
\ 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/importhandler/center/CenterImportHandler.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/center/CenterImportHandler.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/center/CenterImportHandler.java
new file mode 100644
index 0000000..958f1dd
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/center/CenterImportHandler.java
@@ -0,0 +1,259 @@
+/**
+ * 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.importhandler.center;
+
+import com.google.common.reflect.TypeToken;
+import com.google.gson.GsonBuilder;
+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.constants.CenterConstants;
+import 
org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
+import org.apache.fineract.infrastructure.bulkimport.data.Count;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandler;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandlerUtils;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.helper.DateSerializer;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.helper.EnumOptionDataValueSerializer;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.helper.GroupIdSerializer;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.apache.fineract.infrastructure.core.exception.*;
+import org.apache.fineract.portfolio.calendar.data.CalendarData;
+import org.apache.fineract.portfolio.group.data.CenterData;
+import org.apache.fineract.portfolio.group.data.GroupGeneralData;
+import org.apache.poi.ss.usermodel.*;
+import org.joda.time.LocalDate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@Service
+public class CenterImportHandler implements ImportHandler {
+
+
+    private List<CenterData> centers;
+    private List<CalendarData> meetings;
+    private List<String>statuses;
+    private Workbook workbook;
+
+    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+
+    @Autowired
+    public CenterImportHandler(final PortfolioCommandSourceWritePlatformService
+            commandsSourceWritePlatformService) {
+        this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+    }
+
+    @Override
+    public Count process(Workbook workbook, String locale, String dateFormat) {
+        this.centers=new ArrayList<>();
+        this.meetings=new ArrayList<>();
+        this.statuses=new ArrayList<>();
+        this.workbook=workbook;
+        readExcelFile(locale, dateFormat);
+        return importEntity(dateFormat);
+    }
+
+    public void readExcelFile(final String locale, final String dateFormat) {
+
+        Sheet centersSheet = 
workbook.getSheet(TemplatePopulateImportConstants.CENTER_SHEET_NAME);
+        Integer noOfEntries = ImportHandlerUtils.getNumberOfRows(centersSheet, 
TemplatePopulateImportConstants.FIRST_COLUMN_INDEX);
+        for (int rowIndex = 1; rowIndex <=noOfEntries; rowIndex++) {
+            Row row;
+                row = centersSheet.getRow(rowIndex);
+                if(ImportHandlerUtils.isNotImported(row, 
CenterConstants.STATUS_COL)) {
+                    centers.add(readCenter(row,locale,dateFormat));
+                    meetings.add(readMeeting(row,locale,dateFormat));
+                }
+        }
+    }
+
+    private CalendarData readMeeting(Row row,final String locale, final String 
dateFormat) {
+        LocalDate meetingStartDate = 
ImportHandlerUtils.readAsDate(CenterConstants.MEETING_START_DATE_COL, row);
+        Boolean isRepeating = 
ImportHandlerUtils.readAsBoolean(CenterConstants.IS_REPEATING_COL, row);
+        String frequency = 
ImportHandlerUtils.readAsString(CenterConstants.FREQUENCY_COL, row);
+        EnumOptionData frequencyEnum=new 
EnumOptionData(null,null,ImportHandlerUtils.getFrequencyId(frequency));
+        Integer interval = 
ImportHandlerUtils.readAsInt(CenterConstants.INTERVAL_COL, row);
+        String repeatsOnDay = 
ImportHandlerUtils.readAsString(CenterConstants.REPEATS_ON_DAY_COL, row);
+        EnumOptionData repeatsOnDayEnum=new 
EnumOptionData(null,null,ImportHandlerUtils.getRepeatsOnDayId(repeatsOnDay));
+        if(meetingStartDate==null)
+            return null;
+        else {
+            if(repeatsOnDay==null)
+                return 
CalendarData.importInstanceNoRepeatsOnDay(meetingStartDate, isRepeating,
+                        frequencyEnum, interval, 
row.getRowNum(),locale,dateFormat);
+            else
+                return 
CalendarData.importInstanceWithRepeatsOnDay(meetingStartDate, isRepeating,
+                        frequencyEnum, interval, repeatsOnDayEnum, 
row.getRowNum(),locale,dateFormat);
+        }
+    }
+
+    private CenterData readCenter(Row row,final String locale, final String 
dateFormat) {
+        String status = 
ImportHandlerUtils.readAsString(CenterConstants.STATUS_COL, row);
+        String officeName = 
ImportHandlerUtils.readAsString(CenterConstants.OFFICE_NAME_COL, row);
+        Long officeId = 
ImportHandlerUtils.getIdByName(workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME),
 officeName);
+        String staffName = 
ImportHandlerUtils.readAsString(CenterConstants.STAFF_NAME_COL, row);
+        Long staffId = 
ImportHandlerUtils.getIdByName(workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME),
 staffName);
+
+        String externalId = 
ImportHandlerUtils.readAsString(CenterConstants.EXTERNAL_ID_COL, row);
+        Boolean active = 
ImportHandlerUtils.readAsBoolean(CenterConstants.ACTIVE_COL, row);
+        LocalDate 
submittedOn=ImportHandlerUtils.readAsDate(CenterConstants.SUBMITTED_ON_DATE_COL,row);
+        LocalDate activationDate = null;
+        if (active){
+            
activationDate=ImportHandlerUtils.readAsDate(CenterConstants.ACTIVATION_DATE_COL,
 row);
+        }else {
+            activationDate=submittedOn;
+        }
+        String centerName = 
ImportHandlerUtils.readAsString(CenterConstants.CENTER_NAME_COL, row);
+        if(centerName==null||centerName.equals("")) {
+            throw new IllegalArgumentException("Name is blank");
+        }
+        List<GroupGeneralData> groupMembers = new 
ArrayList<GroupGeneralData>();
+        for (int cellNo =CenterConstants. GROUP_NAMES_STARTING_COL; cellNo < 
CenterConstants.GROUP_NAMES_ENDING_COL; cellNo++) {
+            String groupName = ImportHandlerUtils.readAsString(cellNo, row);
+            if (groupName==null||groupName.equals(""))
+                break;
+            Long groupId = 
ImportHandlerUtils.getIdByName(workbook.getSheet(TemplatePopulateImportConstants.GROUP_SHEET_NAME),
 groupName);
+            GroupGeneralData group = new GroupGeneralData(groupId);
+            if (!containsGroupId(groupMembers,groupId)) {
+                groupMembers.add(group);
+            }
+        }
+
+        statuses.add(status);
+        return 
CenterData.importInstance(centerName,groupMembers,activationDate, 
active,submittedOn, externalId,
+                officeId, staffId, row.getRowNum(),dateFormat,locale);
+    }
+
+    private boolean containsGroupId(List<GroupGeneralData> groupMembers,Long 
groupId){
+        for (GroupGeneralData group: groupMembers) {
+            if (group.getId()==groupId){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Count importEntity(String dateFormat) {
+        Sheet centerSheet = 
workbook.getSheet(TemplatePopulateImportConstants.CENTER_SHEET_NAME);
+        int progressLevel = 0;
+        String centerId = "";
+        int successCount = 0;
+        int errorCount = 0;
+        String errorMessage = "";
+        for (int i = 0; i < centers.size(); i++) {
+            Row row = centerSheet.getRow(centers.get(i).getRowIndex());
+            Cell errorReportCell = row.createCell(CenterConstants.FAILURE_COL);
+            Cell statusCell = row.createCell(CenterConstants.STATUS_COL);
+            CommandProcessingResult result = null;
+            try {
+                String status = statuses.get(i);
+                progressLevel = getProgressLevel(status);
+
+                if (progressLevel == 0) {
+                    result = importCenter(i, dateFormat);
+                    centerId = result.getGroupId().toString();
+                    progressLevel = 1;
+                } else
+                    centerId = 
ImportHandlerUtils.readAsInt(CenterConstants.CENTER_ID_COL, 
centerSheet.getRow(centers.get(i).getRowIndex())).toString();
+
+                if (meetings.get(i) != null)
+                    progressLevel = importCenterMeeting(result, i, dateFormat);
+                successCount++;
+                
statusCell.setCellValue(TemplatePopulateImportConstants.STATUS_CELL_IMPORTED);
+                
statusCell.setCellStyle(ImportHandlerUtils.getCellStyle(workbook, 
IndexedColors.LIGHT_GREEN));
+            }catch (RuntimeException ex){
+                errorCount++;
+                ex.printStackTrace();
+                errorMessage=ImportHandlerUtils.getErrorMessage(ex);
+                
writeCenterErrorMessage(centerId,errorMessage,progressLevel,statusCell,errorReportCell,row);
+            }
+        }
+        setReportHeaders(centerSheet);
+        return Count.instance(successCount, errorCount);
+    }
+
+    private void writeCenterErrorMessage(String centerId,String 
errorMessage,int progressLevel,Cell statusCell,Cell errorReportCell,Row row){
+        String status = "";
+        if (progressLevel == 0)
+            status = TemplatePopulateImportConstants.STATUS_CREATION_FAILED;
+        else if (progressLevel == 1)
+            status = TemplatePopulateImportConstants.STATUS_MEETING_FAILED;
+        statusCell.setCellValue(status);
+        statusCell.setCellStyle(ImportHandlerUtils.getCellStyle(workbook, 
IndexedColors.RED));
+
+        if (progressLevel > 0)
+            
row.createCell(CenterConstants.CENTER_ID_COL).setCellValue(Integer.parseInt(centerId));
+        errorReportCell.setCellValue(errorMessage);
+    }
+
+    private int getProgressLevel(String status) {
+
+        if(status==null || 
status.equals(TemplatePopulateImportConstants.STATUS_CREATION_FAILED))
+            return 0;
+        else 
if(status.equals(TemplatePopulateImportConstants.STATUS_MEETING_FAILED))
+            return 1;
+        return 0;
+    }
+    private CommandProcessingResult importCenter(int rowIndex,String 
dateFormat) {
+        GsonBuilder gsonBuilder = new GsonBuilder();
+        gsonBuilder.registerTypeAdapter(LocalDate.class, new 
DateSerializer(dateFormat));
+        Type groupCollectionType = new 
TypeToken<Collection<GroupGeneralData>>() {}.getType();
+        gsonBuilder.registerTypeAdapter(groupCollectionType,new 
GroupIdSerializer());
+        String payload= gsonBuilder.create().toJson(centers.get(rowIndex));;
+        final CommandWrapper commandRequest = new CommandWrapperBuilder() //
+                .createCenter() //
+                .withJson(payload) //
+                .build(); //
+        final CommandProcessingResult result = 
commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return result;
+    }
+
+    private void setReportHeaders(Sheet sheet) {
+        ImportHandlerUtils.writeString(CenterConstants.STATUS_COL, 
sheet.getRow(0), TemplatePopulateImportConstants.STATUS_COL_REPORT_HEADER);
+        ImportHandlerUtils.writeString(CenterConstants.CENTER_ID_COL, 
sheet.getRow(0), TemplatePopulateImportConstants.CENTERID_COL_REPORT_HEADER);
+        ImportHandlerUtils.writeString(CenterConstants.FAILURE_COL, 
sheet.getRow(0), TemplatePopulateImportConstants.FAILURE_COL_REPORT_HEADER);
+    }
+
+    private Integer importCenterMeeting(CommandProcessingResult result, int 
rowIndex,String dateFormat) {
+        CalendarData calendarData=meetings.get(rowIndex);
+        calendarData.setTitle("centers_" + result.getGroupId().toString() + 
"_CollectionMeeting");
+        GsonBuilder gsonBuilder = new GsonBuilder();
+        gsonBuilder.registerTypeAdapter(LocalDate.class, new 
DateSerializer(dateFormat));
+        gsonBuilder.registerTypeAdapter(EnumOptionData.class,new 
EnumOptionDataValueSerializer());
+
+        String payload = gsonBuilder.create().toJson(calendarData);
+        CommandWrapper commandWrapper=new 
CommandWrapper(result.getOfficeId(),result.getGroupId(),result.getClientId(),
+                result.getLoanId(),result.getSavingsId(),null,null,null,null,
+                
null,payload,result.getTransactionId(),result.getProductId(),null,null,
+                null);
+        final CommandWrapper commandRequest = new CommandWrapperBuilder() //
+                
.createCalendar(commandWrapper,TemplatePopulateImportConstants.CENTER_ENTITY_TYPE,result.getGroupId())
 //
+                .withJson(payload) //
+                .build(); //
+        final CommandProcessingResult meetingresult = 
commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return 2;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/chartofaccounts/ChartOfAccountsImportHandler.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/chartofaccounts/ChartOfAccountsImportHandler.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/chartofaccounts/ChartOfAccountsImportHandler.java
new file mode 100644
index 0000000..c31099a
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/chartofaccounts/ChartOfAccountsImportHandler.java
@@ -0,0 +1,143 @@
+/**
+ * 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.importhandler.chartofaccounts;
+
+import com.google.gson.GsonBuilder;
+import org.apache.fineract.accounting.glaccount.data.GLAccountData;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountUsage;
+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.constants.ChartOfAcountsConstants;
+import 
org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
+import org.apache.fineract.infrastructure.bulkimport.data.Count;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandler;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandlerUtils;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.helper.CodeValueDataIdSerializer;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.helper.EnumOptionDataIdSerializer;
+import org.apache.fineract.infrastructure.codes.data.CodeValueData;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.apache.fineract.infrastructure.core.exception.*;
+import org.apache.poi.ss.usermodel.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+@Service
+public class ChartOfAccountsImportHandler implements ImportHandler {
+    private  List<GLAccountData> glAccounts;
+    private  Workbook workbook;
+
+    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+
+    @Autowired
+    public ChartOfAccountsImportHandler(final 
PortfolioCommandSourceWritePlatformService
+            commandsSourceWritePlatformService) {
+        this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+    }
+
+    @Override
+    public Count process(Workbook workbook, String locale, String dateFormat) {
+        this.glAccounts=new ArrayList<>();
+        this.workbook=workbook;
+        readExcelFile();
+        return importEntity();
+    }
+
+    public void readExcelFile() {
+
+        Sheet 
chartOfAccountsSheet=workbook.getSheet(TemplatePopulateImportConstants.CHART_OF_ACCOUNTS_SHEET_NAME);
+        Integer noOfEntries= 
ImportHandlerUtils.getNumberOfRows(chartOfAccountsSheet,TemplatePopulateImportConstants.FIRST_COLUMN_INDEX);
+        for (int rowIndex=1;rowIndex<=noOfEntries;rowIndex++){
+            Row row;
+                row=chartOfAccountsSheet.getRow(rowIndex);
+                if (ImportHandlerUtils.isNotImported(row, 
ChartOfAcountsConstants.STATUS_COL)){
+                    glAccounts.add(readGlAccounts(row));
+                }
+        }
+    }
+
+    private GLAccountData readGlAccounts(Row row) {
+        String 
accountType=ImportHandlerUtils.readAsString(ChartOfAcountsConstants.ACCOUNT_TYPE_COL,row);
+        EnumOptionData accountTypeEnum=GLAccountType.fromString(accountType);
+        String 
accountName=ImportHandlerUtils.readAsString(ChartOfAcountsConstants.ACCOUNT_NAME_COL,row);
+        String 
usage=ImportHandlerUtils.readAsString(ChartOfAcountsConstants.ACCOUNT_USAGE_COL,row);
+        Long usageId=null;
+        EnumOptionData usageEnum=null;
+        if (usage!=null&& usage.equals(GLAccountUsage.DETAIL.toString())){
+            usageId=1L;
+            usageEnum=new EnumOptionData(usageId,null,null);
+        }else if (usage!=null&&usage.equals(GLAccountUsage.HEADER.toString())){
+            usageId=2L;
+            usageEnum=new EnumOptionData(usageId,null,null);
+        }
+        Boolean 
manualEntriesAllowed=ImportHandlerUtils.readAsBoolean(ChartOfAcountsConstants.MANUAL_ENTRIES_ALLOWED_COL,row);
+        Long parentId=null;
+        if 
(ImportHandlerUtils.readAsString(ChartOfAcountsConstants.PARENT_ID_COL,row)!=null)
 {
+            parentId = 
Long.parseLong(ImportHandlerUtils.readAsString(ChartOfAcountsConstants.PARENT_ID_COL,row));
+        }
+        String 
glCode=ImportHandlerUtils.readAsString(ChartOfAcountsConstants.GL_CODE_COL,row);
+        Long tagId=null;
+        
if(ImportHandlerUtils.readAsString(ChartOfAcountsConstants.TAG_ID_COL,row)!=null)
+            
tagId=Long.parseLong(ImportHandlerUtils.readAsString(ChartOfAcountsConstants.TAG_ID_COL,row));
+        CodeValueData tagIdCodeValueData=new CodeValueData(tagId);
+        String 
description=ImportHandlerUtils.readAsString(ChartOfAcountsConstants.DESCRIPTION_COL,row);
+        return 
GLAccountData.importInstance(accountName,parentId,glCode,manualEntriesAllowed,accountTypeEnum,
+                usageEnum,description,tagIdCodeValueData,row.getRowNum());
+    }
+
+    public Count importEntity() {
+        Sheet 
chartOfAccountsSheet=workbook.getSheet(TemplatePopulateImportConstants.CHART_OF_ACCOUNTS_SHEET_NAME);
+
+        GsonBuilder gsonBuilder = new GsonBuilder();
+        gsonBuilder.registerTypeAdapter(EnumOptionData.class, new 
EnumOptionDataIdSerializer());
+        gsonBuilder.registerTypeAdapter(CodeValueData.class, new 
CodeValueDataIdSerializer());
+        int successCount = 0;
+        int errorCount = 0;
+        String errorMessage = "";
+        for (GLAccountData glAccount: glAccounts) {
+            try {
+                String payload=gsonBuilder.create().toJson(glAccount);
+                final CommandWrapper commandRequest = new 
CommandWrapperBuilder() //
+                        .createGLAccount() //
+                        .withJson(payload) //
+                        .build(); //
+                final CommandProcessingResult result = 
commandsSourceWritePlatformService.logCommandSource(commandRequest);
+                successCount++;
+                Cell statusCell = 
chartOfAccountsSheet.getRow(glAccount.getRowIndex()).createCell(ChartOfAcountsConstants.STATUS_COL);
+                
statusCell.setCellValue(TemplatePopulateImportConstants.STATUS_CELL_IMPORTED);
+                
statusCell.setCellStyle(ImportHandlerUtils.getCellStyle(workbook, 
IndexedColors.LIGHT_GREEN));
+            }catch (RuntimeException ex){
+                errorCount++;
+                ex.printStackTrace();
+                errorMessage=ImportHandlerUtils.getErrorMessage(ex);
+                
ImportHandlerUtils.writeErrorMessage(chartOfAccountsSheet,glAccount.getRowIndex(),errorMessage,ChartOfAcountsConstants.STATUS_COL);
+            }
+        }
+        
chartOfAccountsSheet.setColumnWidth(ChartOfAcountsConstants.STATUS_COL, 
TemplatePopulateImportConstants.SMALL_COL_SIZE);
+        ImportHandlerUtils.writeString(ChartOfAcountsConstants.STATUS_COL, 
chartOfAccountsSheet.getRow(TemplatePopulateImportConstants.ROWHEADER_INDEX),
+                TemplatePopulateImportConstants.STATUS_COLUMN_HEADER);
+        return Count.instance(successCount,errorCount);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/fineract/blob/210647d4/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/client/ClientEntityImportHandler.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/client/ClientEntityImportHandler.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/client/ClientEntityImportHandler.java
new file mode 100644
index 0000000..36fb4cd
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/client/ClientEntityImportHandler.java
@@ -0,0 +1,212 @@
+/**
+ * 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.importhandler.client;
+
+import com.google.gson.GsonBuilder;
+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.constants.ClientEntityConstants;
+import 
org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
+import org.apache.fineract.infrastructure.bulkimport.data.Count;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandler;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandlerUtils;
+import 
org.apache.fineract.infrastructure.bulkimport.importhandler.helper.DateSerializer;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.exception.*;
+import org.apache.fineract.portfolio.address.data.AddressData;
+import org.apache.fineract.portfolio.client.data.ClientData;
+import org.apache.fineract.portfolio.client.data.ClientNonPersonData;
+import org.apache.poi.ss.usermodel.*;
+import org.joda.time.LocalDate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+@Service
+public class ClientEntityImportHandler implements ImportHandler {
+
+    private Workbook workbook;
+    private List<ClientData> clients;
+
+    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+
+    @Autowired
+    public ClientEntityImportHandler(final 
PortfolioCommandSourceWritePlatformService
+            commandsSourceWritePlatformService) {
+        this.commandsSourceWritePlatformService = 
commandsSourceWritePlatformService;
+    }
+
+    @Override
+    public Count process(Workbook workbook, String locale, String dateFormat) {
+        this.workbook = workbook;
+        this.clients=new ArrayList<>();
+        readExcelFile(locale,dateFormat);
+        return importEntity(dateFormat);
+    }
+
+    public void readExcelFile(final String locale, final String dateFormat) {
+        Sheet 
clientSheet=workbook.getSheet(TemplatePopulateImportConstants.CLIENT_ENTITY_SHEET_NAME);
+        Integer noOfEntries= ImportHandlerUtils.getNumberOfRows(clientSheet,0);
+        for (int rowIndex=1;rowIndex<=noOfEntries;rowIndex++){
+            Row row;
+                row=clientSheet.getRow(rowIndex);
+                if (ImportHandlerUtils.isNotImported(row, 
ClientEntityConstants.STATUS_COL)){
+                    clients.add(readClient(row,locale,dateFormat));
+                }
+        }
+    }
+
+    private ClientData readClient(Row row,final String locale, final String 
dateFormat) {
+        Long legalFormId=2L;
+        String name = 
ImportHandlerUtils.readAsString(ClientEntityConstants.NAME_COL, row);
+        String officeName = 
ImportHandlerUtils.readAsString(ClientEntityConstants.OFFICE_NAME_COL, row);
+        Long officeId = 
ImportHandlerUtils.getIdByName(workbook.getSheet(TemplatePopulateImportConstants.OFFICE_SHEET_NAME),
 officeName);
+        String staffName = 
ImportHandlerUtils.readAsString(ClientEntityConstants.STAFF_NAME_COL, row);
+        Long staffId = 
ImportHandlerUtils.getIdByName(workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME),
 staffName);
+        LocalDate 
incorportionDate=ImportHandlerUtils.readAsDate(ClientEntityConstants.INCOPORATION_DATE_COL,row);
+        LocalDate 
incorporationTill=ImportHandlerUtils.readAsDate(ClientEntityConstants.INCOPORATION_VALID_TILL_COL,row);
+        String mobileNo=null;
+        if (ImportHandlerUtils.readAsLong(ClientEntityConstants.MOBILE_NO_COL, 
row)!=null)
+         mobileNo = 
ImportHandlerUtils.readAsLong(ClientEntityConstants.MOBILE_NO_COL, 
row).toString();
+
+        String 
clientType=ImportHandlerUtils.readAsString(ClientEntityConstants.CLIENT_TYPE_COL,
 row);
+        Long clientTypeId = null;
+        if (clientType!=null) {
+            String clientTypeAr[] =clientType .split("-");
+            if (clientTypeAr[1] != null) {
+                clientTypeId = Long.parseLong(clientTypeAr[1]);
+            }
+        }
+        String clientClassification= 
ImportHandlerUtils.readAsString(ClientEntityConstants.CLIENT_CLASSIFICATION_COL,
 row);
+        Long clientClassicationId = null;
+        if (clientClassification!=null) {
+            String clientClassificationAr[] =clientClassification.split("-");
+            if (clientClassificationAr[1] != null)
+                clientClassicationId = 
Long.parseLong(clientClassificationAr[1]);
+        }
+        String 
incorporationNo=ImportHandlerUtils.readAsString(ClientEntityConstants.INCOPORATION_NUMBER_COL,row);
+
+        String 
mainBusinessLine=ImportHandlerUtils.readAsString(ClientEntityConstants.MAIN_BUSINESS_LINE,row);
+        Long mainBusinessId = null;
+        if (mainBusinessLine!=null) {
+            String mainBusinessLineAr[] = 
ImportHandlerUtils.readAsString(ClientEntityConstants.MAIN_BUSINESS_LINE, 
row).split("-");
+            if (mainBusinessLineAr[1] != null)
+                mainBusinessId = Long.parseLong(mainBusinessLineAr[1]);
+        }
+        String constitution= 
ImportHandlerUtils.readAsString(ClientEntityConstants.CONSTITUTION_COL,row);
+        Long constitutionId = null;
+        if (constitution!=null) {
+            String constitutionAr[] = constitution.split("-");
+            if (constitutionAr[1] != null)
+                constitutionId = Long.parseLong(constitutionAr[1]);
+        }
+        String remarks = 
ImportHandlerUtils.readAsString(ClientEntityConstants.REMARKS_COL, row);
+
+        ClientNonPersonData clientNonPersonData= 
ClientNonPersonData.importInstance(incorporationNo,incorporationTill,remarks,
+                mainBusinessId,constitutionId,locale,dateFormat);
+
+        String externalId= 
ImportHandlerUtils.readAsString(ClientEntityConstants.EXTERNAL_ID_COL, row);
+
+        Boolean active = 
ImportHandlerUtils.readAsBoolean(ClientEntityConstants.ACTIVE_COL, row);
+
+        LocalDate 
submittedOn=ImportHandlerUtils.readAsDate(ClientEntityConstants.SUBMITTED_ON_COL,row);
+
+        LocalDate activationDate = 
ImportHandlerUtils.readAsDate(ClientEntityConstants.ACTIVATION_DATE_COL, row);
+        if (!active){
+            activationDate=submittedOn;
+        }
+        AddressData addressDataObj=null;
+        if 
(ImportHandlerUtils.readAsBoolean(ClientEntityConstants.ADDRESS_ENABLED,row)) {
+            String addressType = 
ImportHandlerUtils.readAsString(ClientEntityConstants.ADDRESS_TYPE_COL, row);
+            Long addressTypeId = null;
+            if (addressType!=null) {
+                String addressTypeAr[] = addressType.split("-");
+                if (addressTypeAr[1] != null)
+                    addressTypeId = Long.parseLong(addressTypeAr[1]);
+            }
+            String street = 
ImportHandlerUtils.readAsString(ClientEntityConstants.STREET_COL, row);
+            String addressLine1 = 
ImportHandlerUtils.readAsString(ClientEntityConstants.ADDRESS_LINE_1_COL, row);
+            String addressLine2 = 
ImportHandlerUtils.readAsString(ClientEntityConstants.ADDRESS_LINE_2_COL, row);
+            String addressLine3 = 
ImportHandlerUtils.readAsString(ClientEntityConstants.ADDRESS_LINE_3_COL, row);
+            String city = 
ImportHandlerUtils.readAsString(ClientEntityConstants.CITY_COL, row);
+
+            String postalCode = 
ImportHandlerUtils.readAsString(ClientEntityConstants.POSTAL_CODE_COL, row);
+            Boolean isActiveAddress = 
ImportHandlerUtils.readAsBoolean(ClientEntityConstants.IS_ACTIVE_ADDRESS_COL, 
row);
+
+            String 
stateProvince=ImportHandlerUtils.readAsString(ClientEntityConstants.STATE_PROVINCE_COL,
 row);
+            Long stateProvinceId = null;
+            if (stateProvince!=null) {
+                String stateProvinceAr[] = stateProvince.split("-");
+                if (stateProvinceAr[1] != null)
+                    stateProvinceId = Long.parseLong(stateProvinceAr[1]);
+            }
+            String country= 
ImportHandlerUtils.readAsString(ClientEntityConstants.COUNTRY_COL, row);
+            Long countryId = null;
+            if (country!=null) {
+                String countryAr[] = country.split("-");
+                if (countryAr[1] != null)
+                    countryId = Long.parseLong(countryAr[1]);
+            }
+            addressDataObj = new AddressData(addressTypeId, street, 
addressLine1, addressLine2, addressLine3,
+                    city, postalCode, isActiveAddress, stateProvinceId, 
countryId);
+        }
+        return 
ClientData.importClientEntityInstance(legalFormId,row.getRowNum(),name,officeId,clientTypeId,clientClassicationId,
+                staffId,active,activationDate,submittedOn, 
externalId,incorportionDate,mobileNo,clientNonPersonData,addressDataObj,locale,dateFormat);
+    }
+
+    public Count importEntity(String dateFormat) {
+        Sheet 
clientSheet=workbook.getSheet(TemplatePopulateImportConstants.CLIENT_ENTITY_SHEET_NAME);
+
+        int successCount = 0;
+        int errorCount = 0;
+        String errorMessage = "";
+
+        GsonBuilder gsonBuilder = new GsonBuilder();
+        gsonBuilder.registerTypeAdapter(LocalDate.class, new 
DateSerializer(dateFormat));
+
+        for (ClientData client: clients) {
+            try {
+                String payload=gsonBuilder.create().toJson(client);
+                final CommandWrapper commandRequest = new 
CommandWrapperBuilder() //
+                        .createClient() //
+                        .withJson(payload) //
+                        .build(); //
+                final CommandProcessingResult result = 
commandsSourceWritePlatformService.logCommandSource(commandRequest);
+                successCount++;
+                Cell statusCell = 
clientSheet.getRow(client.getRowIndex()).createCell(ClientEntityConstants.STATUS_COL);
+                
statusCell.setCellValue(TemplatePopulateImportConstants.STATUS_CELL_IMPORTED);
+                
statusCell.setCellStyle(ImportHandlerUtils.getCellStyle(workbook, 
IndexedColors.LIGHT_GREEN));
+            }catch (RuntimeException ex){
+                errorCount++;
+                ex.printStackTrace();
+                errorMessage=ImportHandlerUtils.getErrorMessage(ex);
+                
ImportHandlerUtils.writeErrorMessage(clientSheet,client.getRowIndex(),errorMessage,ClientEntityConstants.STATUS_COL);
+            }
+        }
+        clientSheet.setColumnWidth(ClientEntityConstants.STATUS_COL, 
TemplatePopulateImportConstants.SMALL_COL_SIZE);
+        ImportHandlerUtils.writeString(ClientEntityConstants.STATUS_COL, 
clientSheet.getRow(TemplatePopulateImportConstants.ROWHEADER_INDEX),
+                TemplatePopulateImportConstants.STATUS_COLUMN_HEADER);
+
+        return Count.instance(successCount,errorCount);
+    }
+
+
+}

Reply via email to