@Override
  public CustomerDetailsDto createNewCenter(
      CenterCreationDetail createCenterDetail, MeetingDto meetingDto) {

    MifosUser user =
        (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    UserContext userContext = toUserContext(user);

    OfficeBO userOffice = this.officeDao.findOfficeById(userContext.getBranchId());
    userContext.setBranchGlobalNum(userOffice.getGlobalOfficeNum());

    String centerName = createCenterDetail.getDisplayName();
    String externalId = createCenterDetail.getExternalId();
    AddressDto addressDto = createCenterDetail.getAddressDto();
    Address centerAddress =
        new Address(
            addressDto.getLine1(),
            addressDto.getLine2(),
            addressDto.getLine3(),
            addressDto.getCity(),
            addressDto.getState(),
            addressDto.getCountry(),
            addressDto.getZip(),
            addressDto.getPhoneNumber());
    PersonnelBO loanOfficer =
        this.personnelDao.findPersonnelById(createCenterDetail.getLoanOfficerId());
    OfficeBO centerOffice = this.officeDao.findOfficeById(createCenterDetail.getOfficeId());

    List<AccountFeesEntity> feesForCustomerAccount =
        createAccountFeeEntities(createCenterDetail.getFeesToApply());

    DateTime mfiJoiningDate = null;
    if (createCenterDetail.getMfiJoiningDate() != null) {
      mfiJoiningDate = createCenterDetail.getMfiJoiningDate().toDateMidnight().toDateTime();
    }

    MeetingBO meeting = new MeetingFactory().create(meetingDto);
    meeting.setUserContext(userContext);

    CenterBO center =
        CenterBO.createNew(
            userContext,
            centerName,
            mfiJoiningDate,
            meeting,
            loanOfficer,
            centerOffice,
            centerAddress,
            externalId,
            new DateMidnight().toDateTime());

    this.customerService.createCenter(center, meeting, feesForCustomerAccount);

    return new CustomerDetailsDto(center.getCustomerId(), center.getGlobalCustNum());
  }
  @Override
  public ParsedClientsDto save(ParsedClientsDto parsedClientsDto) {
    MifosUser user =
        (MifosUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    UserContext userContext = toUserContext(user);

    OfficeBO userOffice = this.officeDao.findOfficeById(userContext.getBranchId());
    userContext.setBranchGlobalNum(userOffice.getGlobalOfficeNum());

    DateTimeService dateTimeService = new DateTimeService();

    /* Construct ClientBO objects */
    List<NewClientDto> newClients = new ArrayList<NewClientDto>();

    for (ImportedClientDetail importedClient : parsedClientsDto.getSuccessfullyParsedRows()) {
      String secondMiddleName = null;
      ClientCreationDetail clientCreationDetail = importedClient.getClientCreationDetail();

      PersonnelBO formedBy = null;

      /* Client name details */
      ClientNameDetailDto clientNameDetails = clientCreationDetail.getClientNameDetailDto();
      ClientNameDetailEntity clientNameDetailEntity =
          new ClientNameDetailEntity(null, secondMiddleName, clientNameDetails);

      ClientDetailEntity clientDetailEntity = new ClientDetailEntity();
      clientDetailEntity.updateClientDetails(clientCreationDetail.getClientPersonalDetailDto());

      String clientFirstName = clientNameDetails.getFirstName();
      String clientLastName = clientNameDetails.getLastName();
      String secondLastName = clientNameDetails.getSecondLastName();

      /* Spouse/father name details */
      ClientNameDetailEntity spouseFatherNameDetailEntity = null;
      if (clientCreationDetail.getSpouseFatherName() != null) {
        spouseFatherNameDetailEntity =
            new ClientNameDetailEntity(
                null, secondMiddleName, clientCreationDetail.getSpouseFatherName());
      }
      /* Data conversion */
      DateTime dateOfBirth = new DateTime(clientCreationDetail.getDateOfBirth());
      DateTime mfiJoiningDate = new DateTime(clientCreationDetail.getMfiJoiningDate());
      DateTime trainedDateTime = null;
      if (clientCreationDetail.getTrainedDate() != null) {
        trainedDateTime = new DateTime(clientCreationDetail.getTrainedDate());
      }
      /* Status */
      CustomerStatus clientStatus = CustomerStatus.fromInt(clientCreationDetail.getClientStatus());
      CustomerStatus finalStatus = clientStatus;
      if (clientStatus == CustomerStatus.CLIENT_ACTIVE
          && clientCreationDetail.getActivationDate() == null) {
        clientStatus = CustomerStatus.CLIENT_PENDING;
      }
      /* Address */
      Address address = null;
      if (clientCreationDetail.getAddress() != null) {
        AddressDto dto = clientCreationDetail.getAddress();
        address =
            new Address(
                dto.getLine1(),
                dto.getLine2(),
                dto.getLine3(),
                dto.getCity(),
                dto.getState(),
                dto.getCountry(),
                dto.getZip(),
                dto.getPhoneNumber());
      }
      // empty list
      List<ClientInitialSavingsOfferingEntity> associatedOfferings =
          new ArrayList<ClientInitialSavingsOfferingEntity>();
      // client object
      ClientBO client;
      if (clientCreationDetail.getGroupFlag() == 1) {
        CustomerBO group =
            customerDao.findCustomerBySystemId(clientCreationDetail.getParentGroupId());

        if (clientCreationDetail.getFormedBy() != null) {
          formedBy = this.personnelDao.findPersonnelById(clientCreationDetail.getFormedBy());
        } else {
          formedBy = group.getPersonnel();
        }

        client =
            ClientBO.createNewInGroupHierarchy(
                userContext,
                clientCreationDetail.getClientName(),
                clientStatus,
                mfiJoiningDate,
                group,
                formedBy,
                clientNameDetailEntity,
                dateOfBirth,
                clientCreationDetail.getGovernmentId(),
                clientCreationDetail.isTrained(),
                trainedDateTime,
                clientCreationDetail.getGroupFlag(),
                clientFirstName,
                clientLastName,
                secondLastName,
                spouseFatherNameDetailEntity,
                clientDetailEntity,
                associatedOfferings,
                clientCreationDetail.getExternalId(),
                address,
                clientCreationDetail.getActivationDate());
      } else {
        Short officeId = clientCreationDetail.getOfficeId();
        Short officerId = clientCreationDetail.getLoanOfficerId();

        PersonnelBO loanOfficer = personnelDao.findPersonnelById(officerId);
        OfficeBO office = this.officeDao.findOfficeById(officeId);

        if (clientCreationDetail.getFormedBy() != null) {
          formedBy = this.personnelDao.findPersonnelById(clientCreationDetail.getFormedBy());
        } else {
          formedBy = loanOfficer;
        }

        int lastSearchIdCustomerValue =
            customerDao.retrieveLastSearchIdValueForNonParentCustomersInOffice(officeId);

        /* meeting */
        final MeetingDto meetingDto = importedClient.getMeeting();
        MeetingBO clientMeeting = null;
        if (meetingDto != null) {
          clientMeeting = new MeetingFactory().create(meetingDto);
          clientMeeting.setUserContext(userContext);
        }

        client =
            ClientBO.createNewOutOfGroupHierarchy(
                userContext,
                clientCreationDetail.getClientName(),
                clientStatus,
                mfiJoiningDate,
                office,
                loanOfficer,
                clientMeeting,
                formedBy,
                clientNameDetailEntity,
                dateOfBirth,
                clientCreationDetail.getGovernmentId(),
                clientCreationDetail.isTrained(),
                trainedDateTime,
                clientCreationDetail.getGroupFlag(),
                clientFirstName,
                clientLastName,
                secondLastName,
                spouseFatherNameDetailEntity,
                clientDetailEntity,
                associatedOfferings,
                clientCreationDetail.getExternalId(),
                address,
                lastSearchIdCustomerValue);

        if (clientCreationDetail.getActivationDate() != null) {
          client.setCustomerActivationDate(
              clientCreationDetail.getActivationDate().toDateMidnight().toDate());
        }
      }
      // global id
      if (importedClient.getClientGlobalNum() != null) {
        client.setGlobalCustNum(importedClient.getClientGlobalNum());
      }

      NewClientDto newClient = new NewClientDto(client, finalStatus);

      newClients.add(newClient);
    }

    /* Validate client data */
    for (NewClientDto newClient : newClients) {
      ClientBO client = newClient.getClientBO();
      try {
        client.validate();
        customerDao.validateClientForDuplicateNameOrGovtId(
            client.getDisplayName(), client.getDateOfBirth(), client.getGovernmentId());
      } catch (CustomerException ex) {
        throw new MifosRuntimeException(ex);
      }
    }

    /* Save clients */
    List<AccountFeesEntity> accountFees = new ArrayList<AccountFeesEntity>(); // empty list
    try {
      hibernateTransactionHelper.startTransaction();
      for (NewClientDto newClient : newClients) {

        ClientBO client = newClient.getClientBO();
        CustomerStatus finalStatus = newClient.getCustomerStatus();
        // status to pending approval if active

        MeetingBO meeting = client.getCustomerMeetingValue();

        customerDao.save(client);
        hibernateTransactionHelper.flushSession();

        CalendarEvent applicableCalendarEvents =
            holidayDao.findCalendarEventsForThisYearAndNext(client.getOfficeId());
        CustomerAccountBO customerAccount =
            customerAccountFactory.create(client, accountFees, meeting, applicableCalendarEvents);
        client.addAccount(customerAccount);
        customerDao.save(client);
        hibernateTransactionHelper.flushSession();

        if (client.getParentCustomer() != null) {
          customerDao.save(client.getParentCustomer());
        }

        if (client.getGlobalCustNum() == null) {
          client.generateGlobalCustomerNumber();
        }
        client.generateSearchId();
        customerDao.save(client);
        hibernateTransactionHelper.flushSession();

        if (client.getParentCustomer() != null) {
          customerDao.save(client.getParentCustomer());
        }

        /* activate client */
        if (finalStatus == CustomerStatus.CLIENT_ACTIVE) {
          hibernateTransactionHelper.flushSession();
          hibernateTransactionHelper.beginAuditLoggingFor(client);
          client.clearCustomerFlagsIfApplicable(client.getStatus(), finalStatus);

          client.updateCustomerStatus(finalStatus);
          // changeStatus(client, oldStatus, newStatus);
          if (client.getParentCustomer() != null) {
            CustomerHierarchyEntity hierarchy =
                new CustomerHierarchyEntity(client, client.getParentCustomer());
            client.addCustomerHierarchy(hierarchy);
          }

          if (client.getCustomerActivationDate() != null) {
            client.setCustomerActivationDate(client.getCustomerActivationDate());
          } else {
            client.setCustomerActivationDate(dateTimeService.getCurrentJavaDateTime());
          }
          customerAccount.createSchedulesAndFeeSchedulesForFirstTimeActiveCustomer(
              client,
              accountFees,
              meeting,
              applicableCalendarEvents,
              new DateTime(client.getCustomerActivationDate()));

          customerDao.save(client);
        }
      }
      hibernateTransactionHelper.commitTransaction();
    } catch (Exception ex) {
      hibernateTransactionHelper.rollbackTransaction();
      throw new MifosRuntimeException(ex);
    }

    return parsedClientsDto;
  }