You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2023/06/12 09:24:40 UTC

[fineract] branch develop updated: FINERACT-1926: External owner accounting

This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 582f36ad3 FINERACT-1926: External owner accounting
582f36ad3 is described below

commit 582f36ad343f47d6f6e718a9e8b1d1a19eaae2e4
Author: Adam Saghy <ad...@gmail.com>
AuthorDate: Fri Jun 9 12:06:54 2023 +0200

    FINERACT-1926: External owner accounting
---
 custom/acme/note/starter/dependencies.gradle       |   1 +
 fineract-core/dependencies.gradle                  |   7 +
 .../closure/api/GLClosureJsonInputParams.java      |   0
 .../closure/api/GLClosuresApiResource.java         |   0
 .../closure/api/GLClosuresApiResourceSwagger.java  |   0
 .../closure/command/GLClosureCommand.java          |   0
 .../accounting/closure/data/GLClosureData.java     |   0
 .../accounting/closure/domain/GLClosure.java       |   0
 .../closure/domain/GLClosureRepository.java        |   0
 .../exception/GLClosureDuplicateException.java     |   0
 .../exception/GLClosureInvalidDeleteException.java |   0
 .../exception/GLClosureInvalidException.java       |   0
 .../exception/GLClosureNotFoundException.java      |   0
 .../handler/CreateGLClosureCommandHandler.java     |   0
 .../handler/DeleteGLClosureCommandHandler.java     |   0
 .../handler/UpdateGLClosureCommandHandler.java     |   0
 .../GLClosureCommandFromApiJsonDeserializer.java   |   3 +-
 .../service/GLClosureReadPlatformService.java      |   0
 .../service/GLClosureReadPlatformServiceImpl.java  |   0
 .../service/GLClosureWritePlatformService.java     |   0
 ...osureWritePlatformServiceJpaRepositoryImpl.java |   0
 .../AccountingDropdownReadPlatformService.java     |   0
 .../api/FinancialActivityAccountsApiResource.java  |   0
 ...inancialActivityAccountsApiResourceSwagger.java |   0
 .../api/FinancialActivityAccountsConstants.java    |   0
 .../FinancialActivityAccountsJsonInputParams.java  |   0
 .../data/FinancialActivityAccountData.java         |   0
 .../domain/FinancialActivityAccount.java           |   0
 .../domain/FinancialActivityAccountRepository.java |   0
 .../FinancialActivityAccountRepositoryWrapper.java |   0
 ...cateFinancialActivityAccountFoundException.java |   0
 .../FinancialActivityAccountInvalidException.java  |   0
 .../FinancialActivityAccountNotFoundException.java |   0
 .../CreateFinancialActivityAccountHandler.java     |   0
 ...leteFinancialActivityAccountCommandHandler.java |   0
 ...dateFinancialActivityAccountCommandHandler.java |   0
 .../FinancialActivityAccountDataValidator.java     |   0
 ...inancialActivityAccountReadPlatformService.java |   0
 ...cialActivityAccountReadPlatformServiceImpl.java |   0
 ...nancialActivityAccountWritePlatformService.java |   0
 ...ialActivityAccountWritePlatformServiceImpl.java |   0
 .../glaccount/api/GLAccountsApiResource.java       |   0
 .../api/GLAccountsApiResourceSwagger.java          |   0
 .../glaccount/command/GLAccountCommand.java        |   0
 .../glaccount/data/GLAccountDataForLookup.java     |   0
 .../glaccount/domain/GLAccountRepository.java      |   0
 .../domain/GLAccountRepositoryWrapper.java         |   0
 .../accounting/glaccount/domain/TrialBalance.java  |   0
 .../glaccount/domain/TrialBalanceRepository.java   |   0
 .../domain/TrialBalanceRepositoryWrapper.java      |   0
 .../exception/GLAccountDisableException.java       |   0
 .../exception/GLAccountDuplicateException.java     |   0
 .../GLAccountInvalidClassificationException.java   |   0
 .../exception/GLAccountInvalidDeleteException.java |   0
 .../exception/GLAccountInvalidParentException.java |   0
 .../exception/GLAccountInvalidUpdateException.java |   0
 .../exception/GLAccountInvalidUsageException.java  |   0
 .../exception/GLAccountNotFoundException.java      |   0
 .../InvalidParentGLAccountHeadException.java       |   0
 .../handler/CreateGLAccountCommandHandler.java     |   0
 .../handler/DeleteGLAccountCommandHandler.java     |   0
 .../handler/UpdateGLAccountCommandHandler.java     |   0
 .../UpdateTrialBalanceDetailsConfig.java           |   0
 .../UpdateTrialBalanceDetailsTasklet.java          |   0
 .../GLAccountCommandFromApiJsonDeserializer.java   |   3 +-
 .../service/GLAccountReadPlatformService.java      |   0
 .../service/GLAccountReadPlatformServiceImpl.java  |   0
 .../service/GLAccountWritePlatformService.java     |   0
 ...countWritePlatformServiceJpaRepositoryImpl.java |  13 +-
 .../journalentry/JournalEntryMapper.java           | 106 ++++++
 .../accounting/journalentry/data/CreditDebit.java  |   0
 .../JournalEntryAssociationParametersData.java     |   0
 .../journalentry/data/JournalEntryData.java        | 116 +++---
 .../journalentry/data/TransactionDetailData.java   |   0
 .../journalentry/data/TransactionTypeEnumData.java |   0
 .../journalentry/domain/JournalEntry.java          | 126 ++-----
 .../domain/JournalEntryRepository.java             |  14 +-
 .../exception/JournalEntriesNotFoundException.java |   0
 .../exception/JournalEntryInvalidException.java    |   0
 .../exception/JournalEntryNotFoundException.java   |   0
 .../exception/JournalEntryRuntimeException.java    |   0
 .../exception/TrialBalanceNotFoundException.java   |   0
 .../fineract/batch/api/BatchApiResource.java       |   0
 .../batch/api/BatchApiResourceSwagger.java         |   0
 .../fineract/batch/command/CommandContext.java     |   0
 .../fineract/batch/command/CommandStrategy.java    |   0
 .../batch/command/CommandStrategyProvider.java     |   0
 .../batch/command/CommandStrategyUtils.java        |   0
 .../command/internal/UnknownCommandStrategy.java   |   0
 .../apache/fineract/batch/domain/BatchRequest.java |   0
 .../fineract/batch/domain/BatchResponse.java       |   0
 .../org/apache/fineract/batch/domain/Header.java   |   0
 .../exception/ClientDetailsNotFoundException.java  |   0
 .../fineract/batch/exception/ErrorHandler.java     | 114 ++++++
 .../apache/fineract/batch/exception/ErrorInfo.java |   0
 .../serialization/BatchRequestJsonHelper.java      |   0
 .../fineract/batch/service/BatchApiService.java    |   0
 .../batch/service/BatchApiServiceImpl.java         |   0
 .../batch/service/BatchExecutionException.java     |   0
 .../fineract/batch/service/ResolutionHelper.java   |   0
 .../BusinessStepNotBelongsToJobException.java      |   0
 .../domain/CommandProcessingResultType.java        |   0
 .../fineract/commands/domain/CommandSource.java    |   0
 .../commands/domain/CommandSourceRepository.java   |   0
 .../CommandNotAwaitingApprovalException.java       |   0
 .../exception/CommandNotFoundException.java        |   0
 ...onAsCommandIsNotApprovedByCheckerException.java |   0
 .../exception/UnsupportedCommandException.java     |   0
 .../jobs/PurgeProcessedCommandsConfig.java         |   0
 .../jobs/PurgeProcessedCommandsTasklet.java        |   0
 .../commands/provider/CommandHandlerProvider.java  |   0
 .../commands/service/CommandProcessingService.java |   0
 .../commands/service/CommandSourceService.java     |   0
 .../commands/service/IdempotencyKeyGenerator.java  |   0
 .../commands/service/IdempotencyKeyResolver.java   |   0
 ...folioCommandSourceWritePlatformServiceImpl.java |   0
 .../SynchronousCommandProcessingService.java       |   0
 .../bulkimport/data/GlobalEntityType.java          |   0
 .../infrastructure/bulkimport/data/ImportData.java |   0
 .../BulkImportWorkbookPopulatorService.java        |   0
 .../service/BulkImportWorkbookService.java         |   0
 .../businessdate/api/BusinessDateApiResource.java  |   0
 .../api/BusinessDateApiResourceSwagger.java        |   0
 .../businessdate/data/BusinessDateData.java        |   0
 .../businessdate/domain/BusinessDate.java          |   0
 .../domain/BusinessDateRepository.java             |   0
 .../exception/BusinessDateActionException.java     |   0
 .../exception/BusinessDateNotFoundException.java   |   0
 .../handler/BusinessDateUpdateHandler.java         |   0
 .../businessdate/mapper/BusinessDateMapper.java    |   0
 .../service/BusinessDateReadPlatformService.java   |   0
 .../BusinessDateReadPlatformServiceImpl.java       |   0
 .../service/BusinessDateWritePlatformService.java  |   0
 .../BusinessDateWritePlatformServiceImpl.java      |   0
 .../BusinessDateDataParserAndValidator.java        |   0
 .../infrastructure/cache/CacheApiConstants.java    |   0
 .../infrastructure/cache/CacheEnumerations.java    |   0
 .../cache/PlatformCacheConfiguration.java          |   0
 .../infrastructure/cache/api/CacheApiResource.java |   0
 .../cache/api/CacheApiResourceSwagger.java         |   0
 .../cache/command/UpdateCacheCommandHandler.java   |   0
 .../infrastructure/cache/data/CacheData.java       |   0
 .../infrastructure/cache/domain/PlatformCache.java |   0
 .../cache/domain/PlatformCacheRepository.java      |   0
 .../cache/service/CacheWritePlatformService.java   |   0
 ...CacheWritePlatformServiceJpaRepositoryImpl.java |   0
 .../service/RuntimeDelegatingCacheManager.java     |   0
 .../codes/domain/CodeRepository.java               |   0
 .../codes/domain/CodeValueRepository.java          |   0
 .../codes/domain/CodeValueRepositoryWrapper.java   |   0
 .../codes/exception/CodeNotFoundException.java     |   0
 .../exception/CodeValueNotFoundException.java      |   0
 .../service/CodeValueReadPlatformService.java      |   0
 .../infrastructure/core/api/JsonQuery.java         |   0
 .../infrastructure/core/api/MutableUriInfo.java    |   0
 .../infrastructure/core/boot/FineractProfiles.java |   0
 .../EnableFineractEventListenerCondition.java      |   0
 .../condition/EnableFineractEventsCondition.java   |   0
 .../FineractLiquibaseOnlyApplicationCondition.java |   0
 .../condition/FineractModeValidationCondition.java |   0
 ...eractPartitionJobConfigValidationCondition.java |   0
 .../FineractRemoteJobMessageHandlerCondition.java  |   0
 .../condition/FineractValidationCondition.java     |   0
 .../condition/FineractWebApplicationCondition.java |   0
 .../core/condition/ProfileCondition.java           |   0
 .../core/condition/PropertiesCondition.java        |   0
 .../core/condition/SpringPropertiesFactory.java    |   0
 .../config/AbstractFineractModuleProperties.java   |   0
 .../ExplicitConfigurationPropertiesFactory.java    |   0
 .../core/config/FineractProperties.java            |   4 +-
 .../core/data/ApiGlobalErrorResponse.java          |   0
 .../core/data/PaginationParameters.java            |   0
 .../data/PaginationParametersDataValidator.java    |   0
 .../infrastructure/core/data/UploadRequest.java    |   0
 .../diagnostics/performance/MeasuringUtil.java     |   0
 .../core/domain/BatchRequestContextHolder.java     |   2 +-
 .../infrastructure/core/domain/ContextHolder.java  |   0
 .../infrastructure/core/domain/FineractEvent.java  |   0
 .../core/domain/FineractRequestContextHolder.java  |   0
 .../infrastructure/core/domain/JdbcSupport.java    |   0
 .../AbstractIdempotentCommandException.java        |   0
 ...bstractPlatformServiceUnavailableException.java |   0
 .../IdempotentCommandProcessFailedException.java   |   0
 .../IdempotentCommandProcessSucceedException.java  |   0
 ...tentCommandProcessUnderProcessingException.java |   0
 .../core/exception/MultiException.java             |   0
 ...ormRequestBodyItemLimitValidationException.java |   0
 .../PlatformServiceUnavailableException.java       |   0
 .../AccessDeniedExceptionMapper.java               |   0
 .../BadCredentialsExceptionMapper.java             |   0
 .../BusinessStepExceptionMapper.java               |   0
 ...BusinessStepNotBelongsToJobExceptionMapper.java |   0
 ...mpotentCommandProcessFailedExceptionMapper.java |   0
 ...potentCommandProcessSucceedExceptionMapper.java |   0
 ...mmandProcessUnderProcessingExceptionMapper.java |   0
 .../InvalidInstanceTypeMethodExceptionMapper.java  |   0
 .../InvalidJsonExceptionMapper.java                |   0
 .../InvalidTenantIdentifierExceptionMapper.java    |   0
 .../exceptionmapper/JsonSyntaxExceptionMapper.java |   0
 .../MalformedJsonExceptionMapper.java              |   0
 .../NoAuthorizationExceptionMapper.java            |   0
 .../exceptionmapper/OAuth2ExceptionEntryPoint.java |   0
 .../PlatformApiDataValidationExceptionMapper.java  |   0
 .../PlatformDataIntegrityExceptionMapper.java      |   0
 .../PlatformDomainRuleExceptionMapper.java         |   0
 .../PlatformInternalServerExceptionMapper.java     |   0
 ...uestBodyItemLimitValidationExceptionMapper.java |   0
 .../PlatformResourceNotFoundExceptionMapper.java   |   0
 .../PlatformServiceUnavailableExceptionMapper.java |   0
 .../UnAuthenticatedUserExceptionMapper.java        |   0
 .../UnrecognizedQueryParamExceptionMapper.java     |   0
 .../UnsupportedCommandExceptionMapper.java         |   0
 .../UnsupportedParameterExceptionMapper.java       |   0
 .../core/filters/BatchCallHandler.java             |   0
 .../infrastructure/core/filters/BatchFilter.java   |   0
 .../core/filters/BatchFilterChain.java             |   0
 .../core/filters/BatchRequestPreprocessor.java     |   0
 .../core/filters/CorrelationHeaderFilter.java      |   0
 .../core/filters/IdempotencyStoreBatchFilter.java  |   0
 .../core/filters/IdempotencyStoreFilter.java       |   0
 .../core/filters/IdempotencyStoreHelper.java       |   0
 .../core/filters/RequestResponseFilter.java        |   0
 .../core/filters/ResponseCorsFilter.java           |   0
 .../AbstractFromApiJsonDeserializer.java           |   0
 .../serialization/FromApiJsonDeserializer.java     |   0
 .../infrastructure/core/service/MDCWrapper.java    |   0
 .../core/service/PaginationHelper.java             |   0
 .../DataSourcePerTenantServiceFactory.java         |   0
 .../database/DatabaseIndependentQueryService.java  |   0
 .../core/service/database/DatabaseIndexMapper.java |   0
 .../database/DatabasePasswordEncryptor.java        |   0
 .../service/database/DatabaseQueryService.java     |   0
 .../database/DatabaseSpecificSQLGenerator.java     |   0
 .../core/service/database/DatabaseType.java        |   0
 .../service/database/DatabaseTypeResolver.java     |   0
 .../service/database/HikariDataSourceFactory.java  |   0
 .../core/service/database/IndexDetail.java         |   0
 .../core/service/database/MySQLQueryService.java   |   0
 .../service/database/PostgreSQLQueryService.java   |   0
 .../core/service/database/RoutingDataSource.java   |   0
 .../service/database/RoutingDataSourceService.java |   0
 .../database/RoutingDataSourceServiceFactory.java  |   0
 .../TomcatJdbcDataSourcePerTenantService.java      |   0
 .../service/migration/TenantDataSourceFactory.java |   0
 .../service/tenant/JdbcTenantDetailsService.java   |   0
 .../core/service/tenant/TenantDetailsService.java  |   0
 .../core/service/tenant/TenantMapper.java          |   0
 .../documentmanagement/data/DocumentData.java      |   0
 .../event/business/BusinessEventListener.java      |   0
 .../business/domain/AbstractBusinessEvent.java     |   0
 .../event/business/domain/BulkBusinessEvent.java   |   0
 .../event/business/domain/BusinessEvent.java       |   0
 .../event/business/domain/NoExternalEvent.java     |   6 +-
 .../journalentry/JournalEntryBusinessEvent.java    |  19 +-
 .../service/BusinessEventNotifierService.java      |   0
 .../service/BusinessEventNotifierServiceImpl.java  |   4 +-
 .../api/ExternalEventConfigurationApiResource.java |   0
 ...ternalEventConfigurationApiResourceSwagger.java |   0
 .../command/ExternalEventConfigurationCommand.java |   0
 .../config/EnableExternalEventQueueCondition.java  |   0
 .../config/EnableExternalEventTopicCondition.java  |   0
 .../data/ExternalEventConfigurationData.java       |   0
 .../data/ExternalEventConfigurationItemData.java   |   0
 .../exception/AcknowledgementTimeoutException.java |   0
 ...xternalEventConfigurationNotFoundException.java |   0
 .../ExternalEventConfigurationUpdateHandler.java   |   0
 .../external/jobs/PurgeExternalEventsConfig.java   |   0
 .../external/jobs/PurgeExternalEventsTasklet.java  |   0
 .../jobs/SendAsynchronousEventsConfig.java         |   0
 .../jobs/SendAsynchronousEventsTasklet.java        |   0
 .../external/producer/ExternalEventProducer.java   |   0
 .../producer/NoopExternalEventProducer.java        |   0
 ...CustomExternalEventConfigurationRepository.java |   0
 ...omExternalEventConfigurationRepositoryImpl.java |   0
 .../ExternalEventConfigurationRepository.java      |   0
 .../repository/ExternalEventRepository.java        |   0
 .../external/repository/domain/ExternalEvent.java  |   0
 .../domain/ExternalEventConfiguration.java         |   0
 .../repository/domain/ExternalEventStatus.java     |   0
 .../repository/domain/ExternalEventView.java       |   0
 ...onfigurationCommandFromApiJsonDeserializer.java |   0
 ...ernalEventConfigurationReadPlatformService.java |   0
 ...lEventConfigurationReadPlatformServiceImpl.java |   0
 ...xternalEventConfigurationValidationService.java |   5 +-
 ...rnalEventConfigurationWritePlatformService.java |   0
 ...EventConfigurationWritePlatformServiceImpl.java |   0
 .../external/service/ExternalEventService.java     |   0
 .../service/ExternalEventsConfigurationMapper.java |   0
 .../external/service/JdbcTemplateFactory.java      |   0
 ...efaultExternalEventIdempotencyKeyGenerator.java |   0
 .../ExternalEventIdempotencyKeyGenerator.java      |   0
 .../service/message/BulkMessageItemFactory.java    |   0
 .../external/service/message/MessageFactory.java   |   0
 .../service/message/domain/BulkMessageData.java    |   0
 .../message/domain/MessageBusinessDate.java        |   0
 .../service/message/domain/MessageCategory.java    |   0
 .../service/message/domain/MessageCreatedAt.java   |   0
 .../service/message/domain/MessageData.java        |   0
 .../service/message/domain/MessageDataSchema.java  |   0
 .../external/service/message/domain/MessageId.java |   0
 .../message/domain/MessageIdempotencyKey.java      |   0
 .../service/message/domain/MessageSource.java      |   0
 .../service/message/domain/MessageType.java        |   0
 .../generic/CommandProcessingResultMapper.java     |   0
 .../mapper/generic/CurrencyDataMapper.java         |   0
 .../mapper/support/AvroMapperConfig.java           |   0
 .../mapper/support/AvroMonthDayMapper.java         |   0
 .../serializer/BusinessEventSerializer.java        |   0
 .../serializer/BusinessEventSerializerFactory.java |   0
 .../service/support/ByteBufferConverter.java       |   0
 .../validation/ExternalEventSourceData.java        |   0
 .../validation/ExternalEventSourceProvider.java    |   0
 .../ExternalEventSourceProviderConfig.java         |   0
 .../validation/ExternalEventSourceService.java     |   0
 .../SimpleExternalEventSourceProvider.java         |   0
 .../infrastructure/hooks/event/HookEvent.java      |   0
 .../hooks/event/HookEventSource.java               |   0
 .../api/FineractInstanceModeConstants.java         |   0
 .../infrastructure/jobs/data/JobDetailData.java    |   0
 .../jobs/data/JobDetailHistoryData.java            |   0
 .../jobs/exception/JobExecutionException.java      |   0
 .../infrastructure/jobs/service/JobName.java       |   0
 .../service/SchedulerJobRunnerReadService.java     |   0
 .../infrastructure/jobs/service/StepName.java      |   0
 .../InvalidInstanceTypeMethodException.java        |   0
 .../InvalidTenantIdentifierException.java          |   0
 .../security/service/PasswordEncryptor.java        |   0
 .../security/service/PlatformSecurityContext.java  |   0
 .../service/PlatformUserDetailsService.java        |   0
 .../security/utils/ColumnValidator.java            |   0
 .../security/utils/EncryptionUtil.java             |   0
 .../security/utils/LogParameterEscapeUtil.java     |   0
 .../infrastructure/security/utils/SQLBuilder.java  |   0
 .../security/utils/SQLInjectionException.java      |   0
 .../security/utils/SQLInjectionValidator.java      |   0
 .../office/data/OfficeTransactionData.java         |   0
 .../office/domain/OfficeRepository.java            |   0
 .../office/domain/OfficeRepositoryWrapper.java     |   0
 .../office/exception/OfficeNotFoundException.java  |   0
 .../office/service/OfficeReadPlatformService.java  |   0
 .../portfolio/charge/domain/ChargeRepository.java  |   0
 .../charge/domain/ChargeRepositoryWrapper.java     |   0
 .../exception/ChargeIsNotActiveException.java      |   0
 .../charge/exception/ChargeNotFoundException.java  |   0
 .../fineract/portfolio/note/data/NoteData.java     |   0
 .../paymentdetail/domain/PaymentDetail.java        |  14 +-
 .../paymenttype/domain/PaymentTypeRepository.java  |   0
 .../domain/PaymentTypeRepositoryWrapper.java       |   0
 .../exception/PaymentTypeNotFoundException.java    |   0
 .../constants/ShareProductApiConstants.java        |   0
 .../useradministration/data/AppUserData.java       |   0
 .../exception/UnAuthenticatedUserException.java    |   0
 .../src/docs/en/chapters/architecture/design.adoc  |   4 +-
 .../architecture/reliable-event-framework.adoc     |   6 +-
 .../src/docs/en/chapters/resilience/command.adoc   |   4 +-
 .../src/docs/en/chapters/resilience/intro.adoc     |   2 +-
 .../service/InvestorAccountingHelper.java          | 140 +++++++
 .../api/ExternalAssetOwnersApiResource.java        |  55 ++-
 .../loan/LoanAccountOwnerTransferBusinessStep.java |   9 +-
 .../config/InvestorModuleIsEnabledCondition.java   |   7 +-
 ...ata.java => ExternalOwnerJournalEntryData.java} |   8 +-
 ... => ExternalOwnerTransferJournalEntryData.java} |   8 +-
 .../investor/data/ExternalTransferData.java        |   2 +-
 ...pingData.java => ExternalTransferLoanData.java} |   2 +-
 .../ExternalAssetOwnerJournalEntryMapping.java     |  36 +-
 ...nalAssetOwnerJournalEntryMappingRepository.java |  14 +-
 ...ernalAssetOwnerTransferJournalEntryMapping.java |  36 +-
 ...OwnerTransferJournalEntryMappingRepository.java |  13 +-
 ...nalAssetOwnerTransferLoanMappingRepository.java |  12 +
 .../investor/internal/InternalAPIForTesting.java   |   6 +-
 ...nersReadService.java => AccountingService.java} |  11 +-
 .../investor/service/AccountingServiceImpl.java    | 197 ++++++++++
 .../ExternalAssetOwnerJournalEntryService.java     |   6 +-
 .../ExternalAssetOwnerJournalEntryServiceImpl.java |  71 ++++
 .../service/ExternalAssetOwnersReadService.java    |   8 +
 .../ExternalAssetOwnersReadServiceImpl.java        |  75 +++-
 .../service/ExternalAssetOwnersTransferMapper.java |   3 +-
 .../ExternalAssetOwnersWriteServiceImpl.java       |   2 -
 .../module/investor/module-changelog-master.xml    |   1 +
 .../module/investor/parts/0008_add_mappings.xml    | 160 ++++++++
 .../main/resources/jpa/investor/persistence.xml    |   1 +
 .../LoanAccountOwnerTransferBusinessStepTest.java  |   5 +-
 fineract-loan/dependencies.gradle                  |   1 +
 .../domain/ProductToGLAccountMapping.java          |   0
 .../ProductToGLAccountMappingRepository.java       |   0
 .../ProductToGLAccountMappingInvalidException.java |   0
 ...ProductToGLAccountMappingNotFoundException.java |   0
 ...tToGLAccountMappingFromApiJsonDeserializer.java |   0
 .../LoanProductToGLAccountMappingHelper.java       |   0
 .../service/ProductToGLAccountMappingHelper.java   |   0
 ...oductToGLAccountMappingReadPlatformService.java |   0
 ...tToGLAccountMappingReadPlatformServiceImpl.java |   0
 ...ductToGLAccountMappingWritePlatformService.java |   0
 ...ToGLAccountMappingWritePlatformServiceImpl.java |   0
 .../SavingsProductToGLAccountMappingHelper.java    |   0
 .../ShareProductToGLAccountMappingHelper.java      |   0
 .../LoanAccountLockCannotBeOverruledException.java |   0
 .../core/exception/ErrorHandlerRegister.java       |  41 +++
 ...ccountLockCannotBeOverruledExceptionMapper.java |   0
 .../LoanJournalEntryCreatedBusinessEvent.java      |  23 +-
 .../jobs/exception/LoanIdsHardLockedException.java |   0
 .../data/LoanScheduleDelinquencyData.java          |   0
 .../loanaccount/data/UnpaidChargeData.java         |   0
 .../domain/LoanTransactionRepository.java          |   9 +-
 .../exception/LinkedAccountRequiredException.java  |   0
 .../src/main/resources/jpa/loan/persistence.xml    |   1 +
 .../domain/JournalEntryRepositoryCustom.java       |  26 --
 .../domain/JournalEntryRepositoryImpl.java         |  39 --
 .../service/AccountingProcessorHelper.java         | 160 +++-----
 ...EntryWritePlatformServiceJpaRepositoryImpl.java |  64 ++--
 .../fineract/batch/exception/ErrorHandler.java     | 117 ------
 .../service/TellerWritePlatformServiceJpaImpl.java |  19 +-
 .../src/main/resources/application.properties      |   2 +-
 .../src/main/resources/jpa/persistence.xml         |   3 +
 .../src/test/resources/application-test.properties |   2 +
 .../common/ExternalAssetOwnerHelper.java           |  36 +-
 .../accounting/FinancialActivityAccountHelper.java |  18 +-
 .../InitiateExternalAssetOwnerTransferTest.java    | 401 ++++++++++++++++-----
 418 files changed, 1673 insertions(+), 750 deletions(-)

diff --git a/custom/acme/note/starter/dependencies.gradle b/custom/acme/note/starter/dependencies.gradle
index 7cf50805b..71bce3e81 100644
--- a/custom/acme/note/starter/dependencies.gradle
+++ b/custom/acme/note/starter/dependencies.gradle
@@ -21,6 +21,7 @@ dependencies {
     implementation(project(':custom:acme:note:service'))
     implementation('org.springframework.boot:spring-boot-starter')
     testImplementation(project(':fineract-core'))
+    testImplementation(project(':fineract-loan'))
     testImplementation(project(':fineract-provider'))
     testImplementation('org.springframework.boot:spring-boot-starter-jdbc')
     testImplementation('org.springframework.boot:spring-boot-starter-data-jpa')
diff --git a/fineract-core/dependencies.gradle b/fineract-core/dependencies.gradle
index 6e95a3628..c94a32a0e 100644
--- a/fineract-core/dependencies.gradle
+++ b/fineract-core/dependencies.gradle
@@ -23,6 +23,9 @@ dependencies {
     // Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library.
     // We also (normally should have) no need to ever use 'compileOnly'.
 
+    implementation(
+            project(path: ':fineract-avro-schemas')
+            )
 
     // implementation dependencies are directly used (compiled against) in src/main (and src/test)
     //
@@ -30,8 +33,11 @@ dependencies {
             'org.springframework.boot:spring-boot-starter-web',
             'org.springframework.boot:spring-boot-starter-security',
             'org.springframework.boot:spring-boot-starter-validation',
+            'org.springframework.boot:spring-boot-starter-batch',
+            'org.springframework.batch:spring-batch-integration',
             'jakarta.ws.rs:jakarta.ws.rs-api',
             'org.glassfish.jersey.media:jersey-media-multipart',
+            'org.apache.avro:avro',
 
             'com.google.guava:guava',
             'com.google.code.gson:gson',
@@ -49,6 +55,7 @@ dependencies {
             'org.mapstruct:mapstruct',
 
             'io.github.resilience4j:resilience4j-spring-boot2',
+            'org.apache.httpcomponents:httpcore',
             )
     implementation ('org.springframework.boot:spring-boot-starter-data-jpa') {
         exclude group: 'org.hibernate'
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/api/GLClosureJsonInputParams.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosureJsonInputParams.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/api/GLClosureJsonInputParams.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosureJsonInputParams.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResourceSwagger.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResourceSwagger.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResourceSwagger.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResourceSwagger.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/command/GLClosureCommand.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/command/GLClosureCommand.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/command/GLClosureCommand.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/command/GLClosureCommand.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/data/GLClosureData.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/data/GLClosureData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/data/GLClosureData.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/data/GLClosureData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosure.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosure.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosure.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosure.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureDuplicateException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureDuplicateException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureDuplicateException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureDuplicateException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidDeleteException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidDeleteException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidDeleteException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidDeleteException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureInvalidException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/exception/GLClosureNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/handler/CreateGLClosureCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/handler/CreateGLClosureCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/handler/CreateGLClosureCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/handler/CreateGLClosureCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/handler/DeleteGLClosureCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/handler/DeleteGLClosureCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/handler/DeleteGLClosureCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/handler/DeleteGLClosureCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/handler/UpdateGLClosureCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/handler/UpdateGLClosureCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/handler/UpdateGLClosureCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/handler/UpdateGLClosureCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/serialization/GLClosureCommandFromApiJsonDeserializer.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/serialization/GLClosureCommandFromApiJsonDeserializer.java
similarity index 94%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/serialization/GLClosureCommandFromApiJsonDeserializer.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/serialization/GLClosureCommandFromApiJsonDeserializer.java
index 5d13a3fb9..d3951ce73 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/serialization/GLClosureCommandFromApiJsonDeserializer.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/serialization/GLClosureCommandFromApiJsonDeserializer.java
@@ -32,11 +32,10 @@ import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
 import org.apache.fineract.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
 import org.apache.fineract.infrastructure.core.serialization.FromApiJsonDeserializer;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
-import org.apache.fineract.portfolio.loanaccount.guarantor.command.GuarantorCommand;
 import org.springframework.stereotype.Component;
 
 /**
- * Implementation of {@link FromApiJsonDeserializer} for {@link GuarantorCommand}'s.
+ * Implementation of {@link FromApiJsonDeserializer}
  */
 @Component
 @RequiredArgsConstructor
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureReadPlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformService.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformServiceJpaRepositoryImpl.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformServiceJpaRepositoryImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformServiceJpaRepositoryImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/closure/service/GLClosureWritePlatformServiceJpaRepositoryImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/common/AccountingDropdownReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResource.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResource.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResourceSwagger.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResourceSwagger.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResourceSwagger.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsApiResourceSwagger.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsConstants.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsConstants.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsConstants.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsConstants.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsJsonInputParams.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsJsonInputParams.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsJsonInputParams.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/api/FinancialActivityAccountsJsonInputParams.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/data/FinancialActivityAccountData.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/data/FinancialActivityAccountData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/data/FinancialActivityAccountData.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/data/FinancialActivityAccountData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepositoryWrapper.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepositoryWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepositoryWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepositoryWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/DuplicateFinancialActivityAccountFoundException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/DuplicateFinancialActivityAccountFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/DuplicateFinancialActivityAccountFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/DuplicateFinancialActivityAccountFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountInvalidException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountInvalidException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountInvalidException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountInvalidException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/exception/FinancialActivityAccountNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/CreateFinancialActivityAccountHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/CreateFinancialActivityAccountHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/CreateFinancialActivityAccountHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/CreateFinancialActivityAccountHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/DeleteFinancialActivityAccountCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/DeleteFinancialActivityAccountCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/DeleteFinancialActivityAccountCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/DeleteFinancialActivityAccountCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/UpdateFinancialActivityAccountCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/UpdateFinancialActivityAccountCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/UpdateFinancialActivityAccountCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/handler/UpdateFinancialActivityAccountCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/serialization/FinancialActivityAccountDataValidator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountReadPlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformService.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResourceSwagger.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResourceSwagger.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResourceSwagger.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResourceSwagger.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/command/GLAccountCommand.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/command/GLAccountCommand.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/command/GLAccountCommand.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/command/GLAccountCommand.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/data/GLAccountDataForLookup.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/data/GLAccountDataForLookup.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/data/GLAccountDataForLookup.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/data/GLAccountDataForLookup.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepository.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepositoryWrapper.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepositoryWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepositoryWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountRepositoryWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalance.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalance.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalance.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalance.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java
similarity index 100%
copy from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java
copy to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepositoryWrapper.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepositoryWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepositoryWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepositoryWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDisableException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDisableException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDisableException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDisableException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDuplicateException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDuplicateException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDuplicateException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountDuplicateException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidClassificationException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidClassificationException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidClassificationException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidClassificationException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidDeleteException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidDeleteException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidDeleteException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidDeleteException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidParentException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidParentException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidParentException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidParentException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUpdateException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUpdateException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUpdateException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUpdateException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUsageException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUsageException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUsageException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountInvalidUsageException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/GLAccountNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/InvalidParentGLAccountHeadException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/InvalidParentGLAccountHeadException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/exception/InvalidParentGLAccountHeadException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/exception/InvalidParentGLAccountHeadException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/handler/CreateGLAccountCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/handler/CreateGLAccountCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/handler/CreateGLAccountCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/handler/CreateGLAccountCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/handler/DeleteGLAccountCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/handler/DeleteGLAccountCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/handler/DeleteGLAccountCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/handler/DeleteGLAccountCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/handler/UpdateGLAccountCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/handler/UpdateGLAccountCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/handler/UpdateGLAccountCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/handler/UpdateGLAccountCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsConfig.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/jobs/updatetrialbalancedetails/UpdateTrialBalanceDetailsTasklet.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java
similarity index 95%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java
index d4b5a1f1c..5695a3e40 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/serialization/GLAccountCommandFromApiJsonDeserializer.java
@@ -31,11 +31,10 @@ import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
 import org.apache.fineract.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
 import org.apache.fineract.infrastructure.core.serialization.FromApiJsonDeserializer;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
-import org.apache.fineract.portfolio.loanaccount.guarantor.command.GuarantorCommand;
 import org.springframework.stereotype.Component;
 
 /**
- * Implementation of {@link FromApiJsonDeserializer} for {@link GuarantorCommand}'s.
+ * Implementation of {@link FromApiJsonDeserializer}
  */
 @Component
 @RequiredArgsConstructor
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformService.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
similarity index 96%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
index 5168a65f9..daa3f3798 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -18,7 +18,6 @@
  */
 package org.apache.fineract.accounting.glaccount.service;
 
-import java.util.List;
 import java.util.Map;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.accounting.common.AccountingConstants;
@@ -37,7 +36,6 @@ import org.apache.fineract.accounting.glaccount.exception.GLAccountInvalidUpdate
 import org.apache.fineract.accounting.glaccount.exception.GLAccountNotFoundException;
 import org.apache.fineract.accounting.glaccount.exception.InvalidParentGLAccountHeadException;
 import org.apache.fineract.accounting.glaccount.serialization.GLAccountCommandFromApiJsonDeserializer;
-import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
 import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
 import org.apache.fineract.infrastructure.codes.domain.CodeValue;
 import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
@@ -148,9 +146,9 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
              **/
             if (changesOnly.containsKey(GLAccountJsonInputParams.USAGE.getValue())) {
                 if (glAccount.isHeaderAccount()) {
-                    final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository
-                            .findFirstJournalEntryForAccount(glAccountId);
-                    if (journalEntriesForAccount.size() > 0) {
+                    final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
+                            .exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
+                    if (journalEntriesForAccountExist) {
                         throw new GLAccountInvalidUpdateException(GlAccountInvalidUpdateReason.TRANSANCTIONS_LOGGED, glAccountId);
                     }
                 }
@@ -193,8 +191,9 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
         }
 
         // does this account have transactions logged against it
-        final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository.findFirstJournalEntryForAccount(glAccountId);
-        if (journalEntriesForAccount.size() > 0) {
+        final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
+                .exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
+        if (journalEntriesForAccountExist) {
             throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.TRANSANCTIONS_LOGGED, glAccountId);
         }
         this.glAccountRepository.delete(glAccount);
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/JournalEntryMapper.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/JournalEntryMapper.java
new file mode 100644
index 000000000..9ef238e01
--- /dev/null
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/JournalEntryMapper.java
@@ -0,0 +1,106 @@
+/**
+ * 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.accounting.journalentry;
+
+import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
+import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
+import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.apache.fineract.organisation.monetary.data.CurrencyData;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Named;
+
+@Mapper(config = MapstructMapperConfig.class)
+public interface JournalEntryMapper {
+
+    @Mapping(target = "id", source = "id")
+    @Mapping(target = "officeId", source = "office.id")
+    @Mapping(target = "officeName", source = "office.name")
+    @Mapping(target = "glAccountId", source = "glAccount.id")
+    @Mapping(target = "glAccountCode", source = "glAccount.glCode")
+    @Mapping(target = "glAccountName", source = "glAccount.name")
+    @Mapping(target = "glAccountType", source = "glAccount.type", qualifiedByName = "glAccountType")
+    @Mapping(target = "transactionDate", source = "transactionDate")
+    @Mapping(target = "entryType", source = "type", qualifiedByName = "journalEntryType")
+    @Mapping(target = "amount", source = "amount")
+    @Mapping(target = "entityType", source = "entityType", qualifiedByName = "entityType")
+    @Mapping(target = "entityId", source = "entityId")
+    @Mapping(target = "submittedOnDate", source = "submittedOnDate")
+    @Mapping(target = "transactionId", source = "transactionId")
+    @Mapping(target = "currency", source = "currencyCode")
+    @Mapping(target = "manualEntry", source = "manualEntry")
+    @Mapping(target = "reversed", source = "reversed")
+    @Mapping(target = "referenceNumber", source = "referenceNumber")
+    @Mapping(target = "paymentTypeId", source = "paymentDetail.paymentType.id")
+    @Mapping(target = "accountNumber", source = "paymentDetail.accountNumber")
+    @Mapping(target = "checkNumber", source = "paymentDetail.checkNumber")
+    @Mapping(target = "routingCode", source = "paymentDetail.routingCode")
+    @Mapping(target = "receiptNumber", source = "paymentDetail.receiptNumber")
+    @Mapping(target = "bankNumber", source = "paymentDetail.bankNumber")
+    @Mapping(target = "createdDate", ignore = true)
+    @Mapping(target = "createdByUserId", ignore = true)
+    @Mapping(target = "createdByUserName", ignore = true)
+    @Mapping(target = "comments", ignore = true)
+    @Mapping(target = "officeRunningBalance", ignore = true)
+    @Mapping(target = "organizationRunningBalance", ignore = true)
+    @Mapping(target = "runningBalanceComputed", ignore = true)
+    @Mapping(target = "rowIndex", ignore = true)
+    @Mapping(target = "dateFormat", ignore = true)
+    @Mapping(target = "locale", ignore = true)
+    @Mapping(target = "credits", ignore = true)
+    @Mapping(target = "debits", ignore = true)
+    @Mapping(target = "transactionDetails", ignore = true)
+    @Mapping(target = "savingTransactionId", ignore = true)
+    JournalEntryData map(JournalEntry journalEntry);
+
+    @Named("entityType")
+    default PortfolioProductType mapEntityType(Integer entityTypeId) {
+        return PortfolioProductType.fromInt(entityTypeId);
+    }
+
+    @Named("glAccountType")
+    default GLAccountType mapGlAccountType(Integer typeId) {
+        return GLAccountType.fromInt(typeId);
+    }
+
+    @Named("journalEntryType")
+    default JournalEntryType mapJournalEntryType(Integer typeId) {
+        return JournalEntryType.fromInt(typeId);
+    }
+
+    default EnumOptionData mapGlAccountType(GLAccountType accountType) {
+        return new EnumOptionData((long) accountType.getValue(), accountType.getCode(), accountType.name());
+    }
+
+    default EnumOptionData mapJournalEntryType(JournalEntryType journalEntryType) {
+        return new EnumOptionData((long) journalEntryType.getValue(), journalEntryType.getCode(), journalEntryType.name());
+    }
+
+    default EnumOptionData mapEntityType(PortfolioProductType entityType) {
+        return new EnumOptionData((long) entityType.getValue(), entityType.getCode(), entityType.name());
+    }
+
+    default CurrencyData mapCurrency(String currencyCode) {
+        return new CurrencyData(currencyCode);
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/CreditDebit.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/CreditDebit.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/CreditDebit.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/CreditDebit.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryAssociationParametersData.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryAssociationParametersData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryAssociationParametersData.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryAssociationParametersData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryData.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryData.java
similarity index 90%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryData.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryData.java
index 5c4acc155..c22e09616 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryData.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/JournalEntryData.java
@@ -21,7 +21,7 @@ package org.apache.fineract.accounting.journalentry.data;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.List;
-import lombok.Getter;
+import lombok.Data;
 import org.apache.fineract.accounting.glaccount.data.GLAccountData;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
@@ -31,55 +31,55 @@ import org.apache.fineract.organisation.monetary.data.CurrencyData;
  *
  * Note: no getter/setters required as google will produce json from fields of object.
  */
-@Getter
+@Data
 public class JournalEntryData {
 
-    private final Long id;
-    private final Long officeId;
+    private Long id;
+    private Long officeId;
     @SuppressWarnings("unused")
-    private final String officeName;
+    private String officeName;
     @SuppressWarnings("unused")
-    private final String glAccountName;
-    private final Long glAccountId;
+    private String glAccountName;
+    private Long glAccountId;
     @SuppressWarnings("unused")
-    private final String glAccountCode;
-    private final EnumOptionData glAccountType;
+    private String glAccountCode;
+    private EnumOptionData glAccountType;
     @SuppressWarnings("unused")
-    private final LocalDate transactionDate;
-    private final EnumOptionData entryType;
-    private final BigDecimal amount;
+    private LocalDate transactionDate;
+    private EnumOptionData entryType;
+    private BigDecimal amount;
     @SuppressWarnings("unused")
-    private final CurrencyData currency;
-    private final String transactionId;
+    private CurrencyData currency;
+    private String transactionId;
     @SuppressWarnings("unused")
-    private final Boolean manualEntry;
+    private Boolean manualEntry;
     @SuppressWarnings("unused")
-    private final EnumOptionData entityType;
+    private EnumOptionData entityType;
     @SuppressWarnings("unused")
-    private final Long entityId;
+    private Long entityId;
     @SuppressWarnings("unused")
-    private final Long createdByUserId;
+    private Long createdByUserId;
     @SuppressWarnings("unused")
-    private final LocalDate createdDate;
+    private LocalDate createdDate;
     @SuppressWarnings("unused")
-    private final String createdByUserName;
+    private String createdByUserName;
     @SuppressWarnings("unused")
-    private final String comments;
+    private String comments;
     @SuppressWarnings("unused")
-    private final Boolean reversed;
+    private Boolean reversed;
     @SuppressWarnings("unused")
-    private final String referenceNumber;
+    private String referenceNumber;
     @SuppressWarnings("unused")
-    private final BigDecimal officeRunningBalance;
+    private BigDecimal officeRunningBalance;
     @SuppressWarnings("unused")
-    private final BigDecimal organizationRunningBalance;
+    private BigDecimal organizationRunningBalance;
     @SuppressWarnings("unused")
-    private final Boolean runningBalanceComputed;
+    private Boolean runningBalanceComputed;
 
     @SuppressWarnings("unused")
-    private final TransactionDetailData transactionDetails;
+    private TransactionDetailData transactionDetails;
     @SuppressWarnings("unused")
-    private final LocalDate submittedOnDate;
+    private LocalDate submittedOnDate;
 
     // import fields
     private transient Integer rowIndex;
@@ -96,6 +96,8 @@ public class JournalEntryData {
     private String bankNumber;
     private transient Long savingTransactionId;
 
+    public JournalEntryData() {}
+
     // for opening bal bulk import
     public JournalEntryData(Long officeId, LocalDate transactionDate, String currencyCode, List<CreditDebit> credits,
             List<CreditDebit> debits, String locale, String dateFormat) {
@@ -139,18 +141,6 @@ public class JournalEntryData {
         this.submittedOnDate = null;
     }
 
-    public static JournalEntryData importInstance(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId,
-            Integer rowIndex, List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber,
-            String routingCode, String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
-        return new JournalEntryData(officeId, transactionDate, currencyCode, paymentTypeId, rowIndex, credits, debits, accountNumber,
-                checkNumber, routingCode, receiptNumber, bankNumber, comments, locale, dateFormat);
-    }
-
-    public static JournalEntryData importInstance1(Long officeId, LocalDate transactionDate, String currencyCode, List<CreditDebit> credits,
-            List<CreditDebit> debits, String locale, String dateFormat) {
-        return new JournalEntryData(officeId, transactionDate, currencyCode, credits, debits, locale, dateFormat);
-    }
-
     private JournalEntryData(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId, Integer rowIndex,
             List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber, String routingCode,
             String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
@@ -195,23 +185,6 @@ public class JournalEntryData {
         this.transactionDetails = null;
     }
 
-    public Integer getRowIndex() {
-        return rowIndex;
-    }
-
-    public LocalDate getTransactionDate() {
-        return transactionDate;
-    }
-
-    public void addDebits(CreditDebit debit) {
-
-        this.debits.add(debit);
-    }
-
-    public void addCredits(CreditDebit credit) {
-        this.credits.add(credit);
-    }
-
     public JournalEntryData(final Long id, final Long officeId, final String officeName, final String glAccountName, final Long glAccountId,
             final String glAccountCode, final EnumOptionData glAccountClassification, final LocalDate transactionDate,
             final EnumOptionData entryType, final BigDecimal amount, final String transactionId, final Boolean manualEntry,
@@ -247,6 +220,18 @@ public class JournalEntryData {
         this.currency = currency;
     }
 
+    public static JournalEntryData importInstance(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId,
+            Integer rowIndex, List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber,
+            String routingCode, String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
+        return new JournalEntryData(officeId, transactionDate, currencyCode, paymentTypeId, rowIndex, credits, debits, accountNumber,
+                checkNumber, routingCode, receiptNumber, bankNumber, comments, locale, dateFormat);
+    }
+
+    public static JournalEntryData importInstance1(Long officeId, LocalDate transactionDate, String currencyCode, List<CreditDebit> credits,
+            List<CreditDebit> debits, String locale, String dateFormat) {
+        return new JournalEntryData(officeId, transactionDate, currencyCode, credits, debits, locale, dateFormat);
+    }
+
     public static JournalEntryData fromGLAccountData(final GLAccountData glAccountData) {
 
         final Long id = null;
@@ -279,4 +264,21 @@ public class JournalEntryData {
                 createdByUserName, comments, reversed, referenceNumber, officeRunningBalance, organizationRunningBalance,
                 runningBalanceComputed, transactionDetailData, currency);
     }
+
+    public Integer getRowIndex() {
+        return rowIndex;
+    }
+
+    public LocalDate getTransactionDate() {
+        return transactionDate;
+    }
+
+    public void addDebits(CreditDebit debit) {
+
+        this.debits.add(debit);
+    }
+
+    public void addCredits(CreditDebit credit) {
+        this.credits.add(credit);
+    }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionDetailData.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionDetailData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionDetailData.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionDetailData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionTypeEnumData.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionTypeEnumData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionTypeEnumData.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/data/TransactionTypeEnumData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
similarity index 67%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
index 55ca63117..1feaf76e8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntry.java
@@ -26,17 +26,16 @@ import jakarta.persistence.ManyToOne;
 import jakarta.persistence.Table;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import lombok.Getter;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.accounting.glaccount.domain.GLAccount;
 import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.organisation.office.domain.Office;
-import org.apache.fineract.portfolio.client.domain.ClientTransaction;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
 import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
-import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
 
 @Entity
+@Getter
 @Table(name = "acc_gl_journal_entry")
 public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
 
@@ -62,17 +61,14 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
     @Column(name = "transaction_id", nullable = false, length = 50)
     private String transactionId;
 
-    @ManyToOne
-    @JoinColumn(name = "loan_transaction_id", nullable = false)
-    private LoanTransaction loanTransaction;
+    @Column(name = "loan_transaction_id")
+    private Long loanTransactionId;
 
-    @ManyToOne
-    @JoinColumn(name = "savings_transaction_id", nullable = false)
-    private SavingsAccountTransaction savingsTransaction;
+    @Column(name = "savings_transaction_id")
+    private Long savingsTransactionId;
 
-    @ManyToOne
-    @JoinColumn(name = "client_transaction_id", nullable = false)
-    private ClientTransaction clientTransaction;
+    @Column(name = "client_transaction_id")
+    private Long clientTransactionId;
 
     @Column(name = "share_transaction_id")
     private Long shareTransactionId;
@@ -107,16 +103,6 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
     @Column(name = "submitted_on_date", nullable = false)
     private LocalDate submittedOnDate;
 
-    public static JournalEntry createNew(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount,
-            final String currencyCode, final String transactionId, final boolean manualEntry, final LocalDate transactionDate,
-            final JournalEntryType journalEntryType, final BigDecimal amount, final String description, final Integer entityType,
-            final Long entityId, final String referenceNumber, final LoanTransaction loanTransaction,
-            final SavingsAccountTransaction savingsTransaction, final ClientTransaction clientTransaction, Long shareTransactionId) {
-        return new JournalEntry(office, paymentDetail, glAccount, currencyCode, transactionId, manualEntry, transactionDate,
-                journalEntryType.getValue(), amount, description, entityType, entityId, referenceNumber, loanTransaction,
-                savingsTransaction, clientTransaction, shareTransactionId);
-    }
-
     protected JournalEntry() {
         //
     }
@@ -124,8 +110,7 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
     public JournalEntry(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount, final String currencyCode,
             final String transactionId, final boolean manualEntry, final LocalDate transactionDate, final Integer type,
             final BigDecimal amount, final String description, final Integer entityType, final Long entityId, final String referenceNumber,
-            final LoanTransaction loanTransaction, final SavingsAccountTransaction savingsTransaction,
-            final ClientTransaction clientTransaction, final Long shareTransactionId) {
+            final Long loanTransactionId, final Long savingsTransactionId, final Long clientTransactionId, final Long shareTransactionId) {
         this.office = office;
         this.glAccount = glAccount;
         this.reversalJournalEntry = null;
@@ -140,40 +125,26 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
         this.entityId = entityId;
         this.referenceNumber = referenceNumber;
         this.currencyCode = currencyCode;
-        this.loanTransaction = loanTransaction;
-        this.savingsTransaction = savingsTransaction;
-        this.clientTransaction = clientTransaction;
+        this.loanTransactionId = loanTransactionId;
+        this.savingsTransactionId = savingsTransactionId;
+        this.clientTransactionId = clientTransactionId;
         this.paymentDetail = paymentDetail;
         this.shareTransactionId = shareTransactionId;
         this.submittedOnDate = DateUtils.getBusinessLocalDate();
     }
 
-    public boolean isDebitEntry() {
-        return JournalEntryType.DEBIT.getValue().equals(this.type);
-    }
-
-    public Integer getType() {
-        return this.type;
-    }
-
-    public Office getOffice() {
-        return this.office;
-    }
-
-    public GLAccount getGlAccount() {
-        return this.glAccount;
-    }
-
-    public LocalDate getTransactionDate() {
-        return this.transactionDate;
-    }
-
-    public BigDecimal getAmount() {
-        return this.amount;
+    public static JournalEntry createNew(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount,
+            final String currencyCode, final String transactionId, final boolean manualEntry, final LocalDate transactionDate,
+            final JournalEntryType journalEntryType, final BigDecimal amount, final String description, final Integer entityType,
+            final Long entityId, final String referenceNumber, final Long loanTransaction, final Long savingsTransaction,
+            final Long clientTransaction, Long shareTransactionId) {
+        return new JournalEntry(office, paymentDetail, glAccount, currencyCode, transactionId, manualEntry, transactionDate,
+                journalEntryType.getValue(), amount, description, entityType, entityId, referenceNumber, loanTransaction,
+                savingsTransaction, clientTransaction, shareTransactionId);
     }
 
-    public void setAmount(BigDecimal amount) {
-        this.amount = amount;
+    public boolean isDebitEntry() {
+        return JournalEntryType.DEBIT.getValue().equals(this.type);
     }
 
     public void setReversalJournalEntry(final JournalEntry reversalJournalEntry) {
@@ -183,57 +154,4 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
     public void setReversed(final boolean reversed) {
         this.reversed = reversed;
     }
-
-    public String getReferenceNumber() {
-        return this.referenceNumber;
-    }
-
-    public String getCurrencyCode() {
-        return this.currencyCode;
-    }
-
-    public LoanTransaction getLoanTransaction() {
-        return this.loanTransaction;
-    }
-
-    public SavingsAccountTransaction getSavingsTransaction() {
-        return this.savingsTransaction;
-    }
-
-    public PaymentDetail getPaymentDetails() {
-        return this.paymentDetail;
-    }
-
-    public String getTransactionId() {
-        return transactionId;
-    }
-
-    public ClientTransaction getClientTransaction() {
-        return this.clientTransaction;
-    }
-
-    public Long getEntityId() {
-        return this.entityId;
-    }
-
-    public Integer getEntityType() {
-        return this.entityType;
-    }
-
-    public Long getShareTransactionId() {
-        return this.shareTransactionId;
-    }
-
-    public boolean isReversed() {
-        return this.reversed;
-    }
-
-    public String getDescription() {
-        return this.description;
-    }
-
-    public LocalDate getSubmittedOnDate() {
-        return this.submittedOnDate;
-    }
-
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java
similarity index 76%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java
index 7064f8313..4f737e1b2 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java
@@ -24,8 +24,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
 
-public interface JournalEntryRepository
-        extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry>, JournalEntryRepositoryCustom {
+public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry> {
 
     @Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.manualEntry=true")
     List<JournalEntry> findUnReversedManualJournalEntriesByTransactionId(@Param("transactionId") String transactionId);
@@ -42,15 +41,4 @@ public interface JournalEntryRepository
     @Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.entityType = :entityType")
     List<JournalEntry> findJournalEntries(@Param("transactionId") String transactionId, @Param("entityType") Integer entityType);
 
-    /*
-     * @Query("select journalEntry from JournalEntry journalEntry where glAccount.id= :accountId and transactionId= :transactionId and transactionDate= :transactionDate"
-     * +
-     * " and type= :journalEntryType and entityType=1 and entityId= :loanId and loanTransaction.id= :loanTransactionId"
-     * ) JournalEntry findLOANJournalEntryWith(@Param("accountId") Long accountId, @Param("transactionId") String
-     * transactionId,
-     *
-     * @Param("transactionDate") Date transactionDate, @Param("journalEntryType") Integer journalEntryType,
-     *
-     * @Param("loanId") Long loanId, @Param("loanTransactionId") Long loanTransactionId);
-     */
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntriesNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntriesNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntriesNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntriesNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryInvalidException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryInvalidException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryInvalidException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryInvalidException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryRuntimeException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryRuntimeException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryRuntimeException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/exception/JournalEntryRuntimeException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/trialbalance/exception/TrialBalanceNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/accounting/trialbalance/exception/TrialBalanceNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/trialbalance/exception/TrialBalanceNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/accounting/trialbalance/exception/TrialBalanceNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java b/fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/api/BatchApiResourceSwagger.java b/fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResourceSwagger.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/api/BatchApiResourceSwagger.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResourceSwagger.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandContext.java b/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandContext.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandContext.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/command/CommandContext.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategy.java b/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategy.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategy.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategy.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java b/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyUtils.java b/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyUtils.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyUtils.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyUtils.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/UnknownCommandStrategy.java b/fineract-core/src/main/java/org/apache/fineract/batch/command/internal/UnknownCommandStrategy.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/UnknownCommandStrategy.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/command/internal/UnknownCommandStrategy.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/domain/BatchRequest.java b/fineract-core/src/main/java/org/apache/fineract/batch/domain/BatchRequest.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/domain/BatchRequest.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/domain/BatchRequest.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/domain/BatchResponse.java b/fineract-core/src/main/java/org/apache/fineract/batch/domain/BatchResponse.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/domain/BatchResponse.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/domain/BatchResponse.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/domain/Header.java b/fineract-core/src/main/java/org/apache/fineract/batch/domain/Header.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/domain/Header.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/domain/Header.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ClientDetailsNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/batch/exception/ClientDetailsNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/exception/ClientDetailsNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/exception/ClientDetailsNotFoundException.java
diff --git a/fineract-core/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java b/fineract-core/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java
new file mode 100644
index 000000000..cc6adce36
--- /dev/null
+++ b/fineract-core/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java
@@ -0,0 +1,114 @@
+/**
+ * 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.batch.exception;
+
+import com.google.gson.Gson;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Function;
+import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
+import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
+import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.exception.PlatformInternalServerException;
+import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
+import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformApiDataValidationExceptionMapper;
+import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformDataIntegrityExceptionMapper;
+import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformDomainRuleExceptionMapper;
+import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformInternalServerExceptionMapper;
+import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformResourceNotFoundExceptionMapper;
+import org.apache.fineract.infrastructure.core.exceptionmapper.UnsupportedParameterExceptionMapper;
+import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
+import org.apache.http.HttpStatus;
+import org.springframework.dao.NonTransientDataAccessException;
+import org.springframework.transaction.TransactionException;
+
+/**
+ * Provides an Error Handler method that returns an object of type {@link ErrorInfo} to the CommandStrategy which raised
+ * the exception. This class uses various subclasses of RuntimeException to check the kind of exception raised and
+ * provide appropriate status and error codes for each one of the raised exception.
+ *
+ * @author Rishabh Shukla
+ * @see org.apache.fineract.batch.command.CommandStrategy
+ */
+public final class ErrorHandler {
+
+    private static final Gson JSON_HELPER = GoogleGsonSerializerHelper.createGsonBuilder(true).create();
+
+    private static final LinkedHashMap<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> EXCEPTION_HANDLERS = new LinkedHashMap<>();
+    private static final Map.Entry<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> DEFAULT_ERROR_HANDLER = Map.entry(
+            RuntimeException.class,
+            runtimeException -> new ErrorInfo(500, 9999, "{\"Exception\": %s}".formatted(runtimeException.getMessage())));
+
+    static {
+        EXCEPTION_HANDLERS.put(AbstractPlatformResourceNotFoundException.class,
+                runtimeException -> handleException(runtimeException, new PlatformResourceNotFoundExceptionMapper(), 1001));
+        EXCEPTION_HANDLERS.put(UnsupportedParameterException.class,
+                runtimeException -> handleException(runtimeException, new UnsupportedParameterExceptionMapper(), 2001));
+        EXCEPTION_HANDLERS.put(PlatformApiDataValidationException.class,
+                runtimeException -> handleException(runtimeException, new PlatformApiDataValidationExceptionMapper(), 2002));
+        EXCEPTION_HANDLERS.put(PlatformDataIntegrityException.class,
+                runtimeException -> handleException(runtimeException, new PlatformDataIntegrityExceptionMapper(), 3001));
+        EXCEPTION_HANDLERS.put(AbstractPlatformDomainRuleException.class,
+                runtimeException -> handleException(runtimeException, new PlatformDomainRuleExceptionMapper(), 9999));
+        EXCEPTION_HANDLERS.put(TransactionException.class, runtimeException -> new ErrorInfo(HttpStatus.SC_BAD_REQUEST, 4001,
+                "{\"Exception\": %s}".formatted(runtimeException.getMessage())));
+        EXCEPTION_HANDLERS.put(PlatformInternalServerException.class,
+                runtimeException -> handleException(runtimeException, new PlatformInternalServerExceptionMapper(), 5001));
+        EXCEPTION_HANDLERS.put(NonTransientDataAccessException.class, runtimeException -> new ErrorInfo(HttpStatus.SC_BAD_REQUEST, 4002,
+                "{\"Exception\": %s}".formatted(runtimeException.getMessage())));
+        EXCEPTION_HANDLERS.put(DEFAULT_ERROR_HANDLER.getKey(), DEFAULT_ERROR_HANDLER.getValue());
+    }
+
+    private ErrorHandler() {}
+
+    public static void registerNewErrorHandler(final Class<? extends RuntimeException> exceptionClass, final ExceptionMapper mapper,
+            int errorCode) {
+        LinkedHashMap<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> newHandlers = new LinkedHashMap<>();
+        newHandlers.put(exceptionClass, runtimeException -> handleException(runtimeException, mapper, errorCode));
+        EXCEPTION_HANDLERS.forEach(newHandlers::putIfAbsent);
+    }
+
+    public static void registerNewErrorHandler(final Class<? extends RuntimeException> exceptionClass,
+            Function<RuntimeException, ErrorInfo> function) {
+        LinkedHashMap<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> newHandlers = new LinkedHashMap<>();
+        newHandlers.put(exceptionClass, function);
+        EXCEPTION_HANDLERS.forEach(newHandlers::putIfAbsent);
+    }
+
+    private static ErrorInfo handleException(final RuntimeException exception, final ExceptionMapper mapper, final int errorCode) {
+        final Response response = mapper.toResponse(exception);
+        final String errorBody = JSON_HELPER.toJson(response.getEntity());
+        return new ErrorInfo(response.getStatus(), errorCode, errorBody);
+    }
+
+    /**
+     * Returns an object of ErrorInfo type containing the information regarding the raised error.
+     *
+     * @param exception
+     * @return ErrorInfo
+     */
+    public static ErrorInfo handler(final RuntimeException exception) {
+        Map.Entry<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> errorhandler = EXCEPTION_HANDLERS.entrySet().stream()
+                .filter(e -> e.getKey().isAssignableFrom(exception.getClass())).findFirst().orElse(DEFAULT_ERROR_HANDLER);
+        return errorhandler.getValue().apply(exception);
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorInfo.java b/fineract-core/src/main/java/org/apache/fineract/batch/exception/ErrorInfo.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorInfo.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/exception/ErrorInfo.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/serialization/BatchRequestJsonHelper.java b/fineract-core/src/main/java/org/apache/fineract/batch/serialization/BatchRequestJsonHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/serialization/BatchRequestJsonHelper.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/serialization/BatchRequestJsonHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiService.java b/fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiService.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchExecutionException.java b/fineract-core/src/main/java/org/apache/fineract/batch/service/BatchExecutionException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchExecutionException.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/service/BatchExecutionException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java b/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
rename to fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/exceptions/BusinessStepNotBelongsToJobException.java b/fineract-core/src/main/java/org/apache/fineract/cob/exceptions/BusinessStepNotBelongsToJobException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/cob/exceptions/BusinessStepNotBelongsToJobException.java
rename to fineract-core/src/main/java/org/apache/fineract/cob/exceptions/BusinessStepNotBelongsToJobException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandProcessingResultType.java b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandProcessingResultType.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandProcessingResultType.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandProcessingResultType.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSource.java b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSource.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSourceRepository.java b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSourceRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSourceRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSourceRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/exception/CommandNotAwaitingApprovalException.java b/fineract-core/src/main/java/org/apache/fineract/commands/exception/CommandNotAwaitingApprovalException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/exception/CommandNotAwaitingApprovalException.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/exception/CommandNotAwaitingApprovalException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/exception/CommandNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/commands/exception/CommandNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/exception/CommandNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/exception/CommandNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/exception/RollbackTransactionAsCommandIsNotApprovedByCheckerException.java b/fineract-core/src/main/java/org/apache/fineract/commands/exception/RollbackTransactionAsCommandIsNotApprovedByCheckerException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/exception/RollbackTransactionAsCommandIsNotApprovedByCheckerException.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/exception/RollbackTransactionAsCommandIsNotApprovedByCheckerException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/exception/UnsupportedCommandException.java b/fineract-core/src/main/java/org/apache/fineract/commands/exception/UnsupportedCommandException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/exception/UnsupportedCommandException.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/exception/UnsupportedCommandException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsConfig.java b/fineract-core/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsConfig.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsConfig.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsConfig.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsTasklet.java b/fineract-core/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsTasklet.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsTasklet.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/jobs/PurgeProcessedCommandsTasklet.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java b/fineract-core/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandProcessingService.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandProcessingService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandProcessingService.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/service/CommandProcessingService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandSourceService.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandSourceService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandSourceService.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/service/CommandSourceService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyGenerator.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyGenerator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyGenerator.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyGenerator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyResolver.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyResolver.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyResolver.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/service/IdempotencyKeyResolver.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
rename to fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/GlobalEntityType.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/GlobalEntityType.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/GlobalEntityType.java
rename to fineract-core/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/ImportData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookPopulatorService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResource.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResourceSwagger.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResourceSwagger.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResourceSwagger.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResourceSwagger.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/data/BusinessDateData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/data/BusinessDateData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/data/BusinessDateData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/data/BusinessDateData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDate.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDate.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDate.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDate.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateRepository.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateActionException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateActionException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateActionException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateActionException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/exception/BusinessDateNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/handler/BusinessDateUpdateHandler.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/handler/BusinessDateUpdateHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/handler/BusinessDateUpdateHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/handler/BusinessDateUpdateHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/mapper/BusinessDateMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/mapper/BusinessDateMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/mapper/BusinessDateMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/mapper/BusinessDateMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateReadPlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/validator/BusinessDateDataParserAndValidator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/validator/BusinessDateDataParserAndValidator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/validator/BusinessDateDataParserAndValidator.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/validator/BusinessDateDataParserAndValidator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/CacheApiConstants.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/CacheApiConstants.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/CacheApiConstants.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/CacheApiConstants.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/CacheEnumerations.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/CacheEnumerations.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/CacheEnumerations.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/CacheEnumerations.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/PlatformCacheConfiguration.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/PlatformCacheConfiguration.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/PlatformCacheConfiguration.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/PlatformCacheConfiguration.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResource.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResourceSwagger.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResourceSwagger.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResourceSwagger.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/api/CacheApiResourceSwagger.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/command/UpdateCacheCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/command/UpdateCacheCommandHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/command/UpdateCacheCommandHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/command/UpdateCacheCommandHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/data/CacheData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/data/CacheData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/data/CacheData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/data/CacheData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java
similarity index 100%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java
copy to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCacheRepository.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCacheRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCacheRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCacheRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformServiceJpaRepositoryImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformServiceJpaRepositoryImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformServiceJpaRepositoryImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/CacheWritePlatformServiceJpaRepositoryImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeRepository.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepository.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepositoryWrapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepositoryWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepositoryWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValueRepositoryWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeValueNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeValueNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeValueNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/exception/CodeValueNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeValueReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeValueReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeValueReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeValueReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonQuery.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonQuery.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/JsonQuery.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonQuery.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/MutableUriInfo.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/MutableUriInfo.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/api/MutableUriInfo.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/MutableUriInfo.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractProfiles.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractProfiles.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractProfiles.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/boot/FineractProfiles.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventListenerCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventListenerCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventListenerCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventListenerCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventsCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventsCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventsCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/EnableFineractEventsCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractLiquibaseOnlyApplicationCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractLiquibaseOnlyApplicationCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractLiquibaseOnlyApplicationCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractLiquibaseOnlyApplicationCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractModeValidationCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractModeValidationCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractModeValidationCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractModeValidationCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractPartitionJobConfigValidationCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractPartitionJobConfigValidationCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractPartitionJobConfigValidationCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractPartitionJobConfigValidationCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractRemoteJobMessageHandlerCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractRemoteJobMessageHandlerCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractRemoteJobMessageHandlerCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractRemoteJobMessageHandlerCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractValidationCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractValidationCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractValidationCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractValidationCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractWebApplicationCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractWebApplicationCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractWebApplicationCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/FineractWebApplicationCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/ProfileCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/ProfileCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/ProfileCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/ProfileCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/PropertiesCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/PropertiesCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/PropertiesCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/PropertiesCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/SpringPropertiesFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/SpringPropertiesFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/condition/SpringPropertiesFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/condition/SpringPropertiesFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/AbstractFineractModuleProperties.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/AbstractFineractModuleProperties.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/AbstractFineractModuleProperties.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/AbstractFineractModuleProperties.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/ExplicitConfigurationPropertiesFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/ExplicitConfigurationPropertiesFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/ExplicitConfigurationPropertiesFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/ExplicitConfigurationPropertiesFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
similarity index 98%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
index 2b0452665..8f15543a6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
@@ -410,12 +410,12 @@ public class FineractProperties {
     @Setter
     public static class FineractModulesProperties {
 
-        private FineractExternalAssetOwnerModuleProperties externalAssetOwner;
+        private FineractInvestorModuleProperties investor;
     }
 
     @Getter
     @Setter
-    public static class FineractExternalAssetOwnerModuleProperties extends AbstractFineractModuleProperties {
+    public static class FineractInvestorModuleProperties extends AbstractFineractModuleProperties {
 
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/ApiGlobalErrorResponse.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/ApiGlobalErrorResponse.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/ApiGlobalErrorResponse.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/ApiGlobalErrorResponse.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParameters.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParameters.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParameters.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParameters.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/PaginationParametersDataValidator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/UploadRequest.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/UploadRequest.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/UploadRequest.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/data/UploadRequest.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/diagnostics/performance/MeasuringUtil.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/diagnostics/performance/MeasuringUtil.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/diagnostics/performance/MeasuringUtil.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/diagnostics/performance/MeasuringUtil.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/BatchRequestContextHolder.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/BatchRequestContextHolder.java
similarity index 98%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/BatchRequestContextHolder.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/BatchRequestContextHolder.java
index a807a70d9..3776fb3de 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/BatchRequestContextHolder.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/BatchRequestContextHolder.java
@@ -84,7 +84,7 @@ public final class BatchRequestContextHolder {
     /**
      * Set the enclosing transaction flag for the current thread.
      *
-     * @param isEnclosingTransaction
+     * @param enclosingTransaction
      */
     public static void setEnclosingTransaction(Optional<TransactionStatus> enclosingTransaction) {
         BatchRequestContextHolder.enclosingTransaction.set(enclosingTransaction);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/ContextHolder.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/ContextHolder.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/ContextHolder.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/ContextHolder.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractEvent.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractEvent.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractEvent.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractEvent.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractRequestContextHolder.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractRequestContextHolder.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractRequestContextHolder.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractRequestContextHolder.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractIdempotentCommandException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractIdempotentCommandException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractIdempotentCommandException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractIdempotentCommandException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractPlatformServiceUnavailableException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractPlatformServiceUnavailableException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractPlatformServiceUnavailableException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/AbstractPlatformServiceUnavailableException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessSucceedException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessSucceedException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessSucceedException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessSucceedException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessUnderProcessingException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessUnderProcessingException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessUnderProcessingException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessUnderProcessingException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformRequestBodyItemLimitValidationException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformRequestBodyItemLimitValidationException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformRequestBodyItemLimitValidationException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformRequestBodyItemLimitValidationException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformServiceUnavailableException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformServiceUnavailableException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformServiceUnavailableException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/PlatformServiceUnavailableException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessFailedExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessFailedExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessFailedExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessFailedExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessSucceedExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessSucceedExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessSucceedExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessSucceedExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessUnderProcessingExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessUnderProcessingExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessUnderProcessingExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandProcessUnderProcessingExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchCallHandler.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchCallHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchCallHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchCallHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilter.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilter.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilter.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilterChain.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilterChain.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilterChain.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchFilterChain.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchRequestPreprocessor.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchRequestPreprocessor.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchRequestPreprocessor.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/BatchRequestPreprocessor.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/CorrelationHeaderFilter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/CorrelationHeaderFilter.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/CorrelationHeaderFilter.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/CorrelationHeaderFilter.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreBatchFilter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreBatchFilter.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreBatchFilter.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreBatchFilter.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreFilter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreFilter.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreFilter.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreFilter.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreHelper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreHelper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/IdempotencyStoreHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/RequestResponseFilter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/RequestResponseFilter.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/RequestResponseFilter.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/RequestResponseFilter.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/ResponseCorsFilter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/ResponseCorsFilter.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/filters/ResponseCorsFilter.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/filters/ResponseCorsFilter.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/serialization/AbstractFromApiJsonDeserializer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/AbstractFromApiJsonDeserializer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/serialization/AbstractFromApiJsonDeserializer.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/AbstractFromApiJsonDeserializer.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromApiJsonDeserializer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromApiJsonDeserializer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromApiJsonDeserializer.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/FromApiJsonDeserializer.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DataSourcePerTenantServiceFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndexMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndexMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndexMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndexMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabasePasswordEncryptor.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabasePasswordEncryptor.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabasePasswordEncryptor.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabasePasswordEncryptor.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
similarity index 100%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
copy to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/HikariDataSourceFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/HikariDataSourceFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/HikariDataSourceFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/HikariDataSourceFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/IndexDetail.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/IndexDetail.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/IndexDetail.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/IndexDetail.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/PostgreSQLQueryService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/PostgreSQLQueryService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/PostgreSQLQueryService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/PostgreSQLQueryService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSource.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceServiceFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceServiceFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceServiceFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/RoutingDataSourceServiceFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDataSourceFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDataSourceFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDataSourceFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantDataSourceFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantDetailsService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantDetailsService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantDetailsService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantDetailsService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/TenantMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/BusinessEventListener.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/BusinessEventListener.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/BusinessEventListener.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/BusinessEventListener.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java
similarity index 100%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java
copy to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BulkBusinessEvent.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BulkBusinessEvent.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BulkBusinessEvent.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BulkBusinessEvent.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BusinessEvent.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BusinessEvent.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BusinessEvent.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BusinessEvent.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/NoExternalEvent.java
similarity index 87%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
copy to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/NoExternalEvent.java
index 6b3954d33..0706e75ec 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/NoExternalEvent.java
@@ -16,8 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service.database;
+package org.apache.fineract.infrastructure.event.business.domain;
 
-public enum DatabaseType {
-    MYSQL, POSTGRESQL
-}
+public interface NoExternalEvent {}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/journalentry/JournalEntryBusinessEvent.java
similarity index 65%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java
copy to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/journalentry/JournalEntryBusinessEvent.java
index 741a92664..3aeaa7b3b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/journalentry/JournalEntryBusinessEvent.java
@@ -16,17 +16,22 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.event.business.domain;
+package org.apache.fineract.infrastructure.event.business.domain.journalentry;
 
-import lombok.RequiredArgsConstructor;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.infrastructure.event.business.domain.AbstractBusinessEvent;
 
-@RequiredArgsConstructor
-public abstract class AbstractBusinessEvent<T> implements BusinessEvent<T> {
+public abstract class JournalEntryBusinessEvent extends AbstractBusinessEvent<JournalEntry> {
 
-    private final T value;
+    private static final String CATEGORY = "Accounting";
+
+    public JournalEntryBusinessEvent(JournalEntry value) {
+        super(value);
+    }
 
     @Override
-    public T get() {
-        return value;
+    public String getCategory() {
+        return CATEGORY;
     }
+
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierServiceImpl.java
similarity index 96%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierServiceImpl.java
index dca732ad9..ba1c85a29 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierServiceImpl.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/service/BusinessEventNotifierServiceImpl.java
@@ -28,6 +28,7 @@ import org.apache.fineract.infrastructure.core.config.FineractProperties;
 import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
 import org.apache.fineract.infrastructure.event.business.domain.BulkBusinessEvent;
 import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
+import org.apache.fineract.infrastructure.event.business.domain.NoExternalEvent;
 import org.apache.fineract.infrastructure.event.external.repository.ExternalEventConfigurationRepository;
 import org.apache.fineract.infrastructure.event.external.service.ExternalEventService;
 import org.springframework.beans.factory.InitializingBean;
@@ -82,13 +83,14 @@ public class BusinessEventNotifierServiceImpl implements BusinessEventNotifierSe
     @Override
     public void notifyPostBusinessEvent(BusinessEvent<?> businessEvent) {
         throwExceptionIfBulkEvent(businessEvent);
+        boolean isExternalEvent = !(businessEvent instanceof NoExternalEvent);
         List<BusinessEventListener> businessEventListeners = postListeners.get(businessEvent.getClass());
         if (businessEventListeners != null) {
             for (BusinessEventListener eventListener : businessEventListeners) {
                 eventListener.onBusinessEvent(businessEvent);
             }
         }
-        if (isExternalEventPostingEnabled()) {
+        if (isExternalEvent && isExternalEventPostingEnabled()) {
             // we only want to create external events for operations that were successful, hence the post listener
             if (isExternalEventConfiguredForPosting(businessEvent.getType())) {
                 if (isExternalEventRecordingEnabled()) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResourceSwagger.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResourceSwagger.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResourceSwagger.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/api/ExternalEventConfigurationApiResourceSwagger.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalEventConfigurationCommand.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalEventConfigurationCommand.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalEventConfigurationCommand.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/command/ExternalEventConfigurationCommand.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventQueueCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventQueueCondition.java
similarity index 100%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventQueueCondition.java
copy to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventQueueCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventTopicCondition.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventTopicCondition.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventTopicCondition.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventTopicCondition.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/data/ExternalEventConfigurationItemData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/exception/AcknowledgementTimeoutException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/exception/AcknowledgementTimeoutException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/exception/AcknowledgementTimeoutException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/exception/AcknowledgementTimeoutException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/exception/ExternalEventConfigurationNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/exception/ExternalEventConfigurationNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/exception/ExternalEventConfigurationNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/exception/ExternalEventConfigurationNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/handler/ExternalEventConfigurationUpdateHandler.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsConfig.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsConfig.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsConfig.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsConfig.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsTasklet.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsTasklet.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsTasklet.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/PurgeExternalEventsTasklet.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsConfig.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsConfig.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsConfig.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsConfig.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/ExternalEventProducer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/producer/ExternalEventProducer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/ExternalEventProducer.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/producer/ExternalEventProducer.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/NoopExternalEventProducer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/producer/NoopExternalEventProducer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/NoopExternalEventProducer.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/producer/NoopExternalEventProducer.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepository.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepositoryImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepositoryImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepositoryImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/CustomExternalEventConfigurationRepositoryImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventConfigurationRepository.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventConfigurationRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventConfigurationRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventConfigurationRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventRepository.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/ExternalEventRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEvent.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventConfiguration.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventConfiguration.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventConfiguration.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventConfiguration.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventStatus.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventStatus.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventStatus.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventStatus.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventView.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventView.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventView.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/repository/domain/ExternalEventView.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/serialization/ExternalEventConfigurationCommandFromApiJsonDeserializer.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationReadPlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
similarity index 94%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
index 79dabacc7..30af0a0f8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationService.java
@@ -32,6 +32,7 @@ import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
 import org.apache.fineract.infrastructure.event.business.domain.BulkBusinessEvent;
 import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
+import org.apache.fineract.infrastructure.event.business.domain.NoExternalEvent;
 import org.apache.fineract.infrastructure.event.external.exception.ExternalEventConfigurationNotFoundException;
 import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventSourceService;
 import org.springframework.beans.factory.InitializingBean;
@@ -102,8 +103,8 @@ public class ExternalEventConfigurationValidationService implements Initializing
         try (ScanResult scanResult = new ClassGraph().enableAllInfo().acceptPackages(sourcePackages.toArray(sourcePackagesForScan))
                 .scan()) {
             ClassInfoList businessEventClasses = scanResult.getClassesImplementing(EXTERNAL_EVENT_BUSINESS_INTERFACE)
-                    .filter(classInfo -> (!classInfo.isInterface() && !classInfo.isAbstract()
-                            && !classInfo.getName().equalsIgnoreCase(BULK_BUSINESS_EVENT)));
+                    .filter(classInfo -> (!classInfo.implementsInterface(NoExternalEvent.class) && !classInfo.isInterface()
+                            && !classInfo.isAbstract() && !classInfo.getName().equalsIgnoreCase(BULK_BUSINESS_EVENT)));
             return businessEventClasses.stream().map(classInfo -> classInfo.getSimpleName()).collect(Collectors.toList());
         }
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventsConfigurationMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/JdbcTemplateFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/JdbcTemplateFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/JdbcTemplateFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/JdbcTemplateFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/DefaultExternalEventIdempotencyKeyGenerator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/DefaultExternalEventIdempotencyKeyGenerator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/DefaultExternalEventIdempotencyKeyGenerator.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/DefaultExternalEventIdempotencyKeyGenerator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/ExternalEventIdempotencyKeyGenerator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/ExternalEventIdempotencyKeyGenerator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/ExternalEventIdempotencyKeyGenerator.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/idempotency/ExternalEventIdempotencyKeyGenerator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/BulkMessageItemFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/BulkMessageItemFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/BulkMessageItemFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/BulkMessageItemFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/MessageFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/MessageFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/MessageFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/MessageFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/BulkMessageData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/BulkMessageData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/BulkMessageData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/BulkMessageData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageBusinessDate.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageBusinessDate.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageBusinessDate.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageBusinessDate.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCategory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCategory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCategory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCategory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCreatedAt.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCreatedAt.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCreatedAt.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageCreatedAt.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageDataSchema.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageDataSchema.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageDataSchema.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageDataSchema.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageId.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageId.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageId.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageId.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageIdempotencyKey.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageIdempotencyKey.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageIdempotencyKey.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageIdempotencyKey.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageSource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageSource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageSource.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageSource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageType.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageType.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageType.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/message/domain/MessageType.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CommandProcessingResultMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CommandProcessingResultMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CommandProcessingResultMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CommandProcessingResultMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CurrencyDataMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CurrencyDataMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CurrencyDataMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CurrencyDataMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMapperConfig.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMapperConfig.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMapperConfig.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMapperConfig.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMonthDayMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMonthDayMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMonthDayMapper.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/support/AvroMonthDayMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializerFactory.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializerFactory.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializerFactory.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializerFactory.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/support/ByteBufferConverter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/support/ByteBufferConverter.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/support/ByteBufferConverter.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/support/ByteBufferConverter.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProvider.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProvider.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProvider.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProvider.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProviderConfig.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProviderConfig.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProviderConfig.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceProviderConfig.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/ExternalEventSourceService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/SimpleExternalEventSourceProvider.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/SimpleExternalEventSourceProvider.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/SimpleExternalEventSourceProvider.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/validation/SimpleExternalEventSourceProvider.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEvent.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEvent.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEvent.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEvent.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEventSource.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEventSource.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEventSource.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/hooks/event/HookEventSource.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/instancemode/api/FineractInstanceModeConstants.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/instancemode/api/FineractInstanceModeConstants.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/instancemode/api/FineractInstanceModeConstants.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/instancemode/api/FineractInstanceModeConstants.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailHistoryData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailHistoryData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailHistoryData.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/data/JobDetailHistoryData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/StepName.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/service/StepName.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/StepName.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/jobs/service/StepName.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidInstanceTypeMethodException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidInstanceTypeMethodException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidInstanceTypeMethodException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidInstanceTypeMethodException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidTenantIdentifierException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidTenantIdentifierException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidTenantIdentifierException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/exception/InvalidTenantIdentifierException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/PasswordEncryptor.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/service/PasswordEncryptor.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/PasswordEncryptor.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/service/PasswordEncryptor.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformSecurityContext.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformSecurityContext.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformSecurityContext.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformSecurityContext.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformUserDetailsService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformUserDetailsService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformUserDetailsService.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/service/PlatformUserDetailsService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/EncryptionUtil.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/EncryptionUtil.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/EncryptionUtil.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/EncryptionUtil.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/LogParameterEscapeUtil.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/LogParameterEscapeUtil.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/LogParameterEscapeUtil.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/LogParameterEscapeUtil.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLBuilder.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLBuilder.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLBuilder.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLBuilder.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionException.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidator.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidator.java
rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidator.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/data/OfficeTransactionData.java b/fineract-core/src/main/java/org/apache/fineract/organisation/office/data/OfficeTransactionData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/organisation/office/data/OfficeTransactionData.java
rename to fineract-core/src/main/java/org/apache/fineract/organisation/office/data/OfficeTransactionData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepository.java b/fineract-core/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepositoryWrapper.java b/fineract-core/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepositoryWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepositoryWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/organisation/office/domain/OfficeRepositoryWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/exception/OfficeNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/organisation/office/exception/OfficeNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/organisation/office/exception/OfficeNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/organisation/office/exception/OfficeNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformService.java b/fineract-core/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformService.java
rename to fineract-core/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepository.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepositoryWrapper.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepositoryWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepositoryWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/charge/domain/ChargeRepositoryWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeIsNotActiveException.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeIsNotActiveException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeIsNotActiveException.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeIsNotActiveException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/charge/exception/ChargeNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/data/NoteData.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/note/data/NoteData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/note/data/NoteData.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/note/data/NoteData.java
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java
index 4b8e85ff8..46de7071e 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java
@@ -24,6 +24,7 @@ import jakarta.persistence.JoinColumn;
 import jakarta.persistence.ManyToOne;
 import jakarta.persistence.Table;
 import java.util.Map;
+import lombok.Getter;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
@@ -33,6 +34,7 @@ import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
 import org.apache.fineract.portfolio.paymenttype.domain.PaymentType;
 
 @Entity
+@Getter
 @Table(name = "m_payment_detail")
 public final class PaymentDetail extends AbstractPersistableCustom {
 
@@ -109,16 +111,4 @@ public final class PaymentDetail extends AbstractPersistableCustom {
                 this.routingCode, this.receiptNumber, this.bankNumber);
         return paymentDetailData;
     }
-
-    public PaymentType getPaymentType() {
-        return this.paymentType;
-    }
-
-    public String getReceiptNumber() {
-        return this.receiptNumber;
-    }
-
-    public String getRoutingCode() {
-        return routingCode;
-    }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepository.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepository.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepositoryWrapper.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepositoryWrapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepositoryWrapper.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentTypeRepositoryWrapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/exception/PaymentTypeNotFoundException.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/paymenttype/exception/PaymentTypeNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/exception/PaymentTypeNotFoundException.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/paymenttype/exception/PaymentTypeNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/constants/ShareProductApiConstants.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/shareproducts/constants/ShareProductApiConstants.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/constants/ShareProductApiConstants.java
rename to fineract-core/src/main/java/org/apache/fineract/portfolio/shareproducts/constants/ShareProductApiConstants.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/data/AppUserData.java b/fineract-core/src/main/java/org/apache/fineract/useradministration/data/AppUserData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/useradministration/data/AppUserData.java
rename to fineract-core/src/main/java/org/apache/fineract/useradministration/data/AppUserData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/exception/UnAuthenticatedUserException.java b/fineract-core/src/main/java/org/apache/fineract/useradministration/exception/UnAuthenticatedUserException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/useradministration/exception/UnAuthenticatedUserException.java
rename to fineract-core/src/main/java/org/apache/fineract/useradministration/exception/UnAuthenticatedUserException.java
diff --git a/fineract-doc/src/docs/en/chapters/architecture/design.adoc b/fineract-doc/src/docs/en/chapters/architecture/design.adoc
index ce68dc22c..1a332c0b1 100644
--- a/fineract-doc/src/docs/en/chapters/architecture/design.adoc
+++ b/fineract-doc/src/docs/en/chapters/architecture/design.adoc
@@ -24,13 +24,13 @@ include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/useradmin
 .Create a CommandWrapper object that represents this create user command and JSON request body. Pass off responsiblity for processing to PortfolioCommandSourceWritePlatformService.logCommandSource
 [source,java]
 ----
-include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java[lines=69..129]
+include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java[lines=69..129]
 ----
 
 .Check user has permission for this action. if ok, a) parse the json request body, b) create a JsonCommand object to wrap the command details, c) use CommandProcessingService to handle command
 [source,java]
 ----
-include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java[lines=84..150]
+include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java[lines=84..150]
 ----
 
 NOTE: if a RollbackTransactionAsCommandIsNotApprovedByCheckerException occurs at this point. The original transaction will of been aborted and we only log an entry for the command in the audit table setting its status as 'Pending'.
diff --git a/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc b/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc
index 5416b0f31..8a6bdcb10 100644
--- a/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc
+++ b/fineract-doc/src/docs/en/chapters/architecture/reliable-event-framework.adoc
@@ -343,7 +343,7 @@ The interface looks the following:
 .`BusinessEvent.java`
 [source,java]
 ----
-include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BusinessEvent.java[lines=21..]
+include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/business/domain/BusinessEvent.java[lines=21..]
 ----
 
 Quite simple. The `get` method should return the data you want to pass within the event instance. The `getType` method returns the name of the business event that's gonna be saved as the `type` into the database.
@@ -358,7 +358,7 @@ The serializer has a special interface, `BusinessEventSerializer`.
 .`BusinessEventSerializer.java`
 [source,java]
 ----
-include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java[lines=25..]
+include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/BusinessEventSerializer.java[lines=25..]
 ----
 
 An implementation of this interface shall be registered as a Spring bean, and it'll be picked up automatically by the framework.
@@ -439,4 +439,4 @@ NOTE: All the default serializers are having `Ordered.LOWEST_PRECEDENCE`.
 |`false`
 |Whether the external event sending is enabled or disabled.
 
-|===
\ No newline at end of file
+|===
diff --git a/fineract-doc/src/docs/en/chapters/resilience/command.adoc b/fineract-doc/src/docs/en/chapters/resilience/command.adoc
index c1fd0784f..cf8b7a303 100644
--- a/fineract-doc/src/docs/en/chapters/resilience/command.adoc
+++ b/fineract-doc/src/docs/en/chapters/resilience/command.adoc
@@ -7,13 +7,13 @@ TBD
 .Retry-able service function `executeCommand`
 [source,java]
 ----
-include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java[lines=73..151]
+include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java[lines=73..151]
 ----
 
 .Fallback function `fallbackExecuteCommand`
 [source,java]
 ----
-include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java[lines=166..174]
+include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java[lines=166..174]
 ----
 
 .Retry configuration for `executeCommand`
diff --git a/fineract-doc/src/docs/en/chapters/resilience/intro.adoc b/fineract-doc/src/docs/en/chapters/resilience/intro.adoc
index 6efa6e850..225291a7b 100644
--- a/fineract-doc/src/docs/en/chapters/resilience/intro.adoc
+++ b/fineract-doc/src/docs/en/chapters/resilience/intro.adoc
@@ -80,5 +80,5 @@ For better code quality and readability we introduced https://resilience4j.readm
 .Annotation based retry
 [source,java]
 ----
-include::{rootdir}/fineract-provider/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java[lines=49..76]
+include::{rootdir}/fineract-core/src/main/java/org/apache/fineract/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java[lines=49..76]
 ----
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/accounting/journalentry/service/InvestorAccountingHelper.java b/fineract-investor/src/main/java/org/apache/fineract/investor/accounting/journalentry/service/InvestorAccountingHelper.java
new file mode 100644
index 000000000..5ab1dd267
--- /dev/null
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/accounting/journalentry/service/InvestorAccountingHelper.java
@@ -0,0 +1,140 @@
+/**
+ * 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.investor.accounting.journalentry.service;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import lombok.RequiredArgsConstructor;
+import org.apache.fineract.accounting.closure.domain.GLClosure;
+import org.apache.fineract.accounting.closure.domain.GLClosureRepository;
+import org.apache.fineract.accounting.common.AccountingConstants;
+import org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
+import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount;
+import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
+import org.apache.fineract.accounting.glaccount.domain.GLAccount;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
+import org.apache.fineract.accounting.journalentry.exception.JournalEntryInvalidException;
+import org.apache.fineract.accounting.journalentry.exception.JournalEntryInvalidException.GlJournalEntryInvalidReason;
+import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
+import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
+import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
+import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
+import org.apache.fineract.organisation.office.domain.Office;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class InvestorAccountingHelper {
+
+    public static final String INVESTOR_TRANSFER_IDENTIFIER = "I";
+
+    private final JournalEntryRepository glJournalEntryRepository;
+    private final ProductToGLAccountMappingRepository accountMappingRepository;
+    private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository;
+    private final GLClosureRepository closureRepository;
+
+    /**
+     * @param officeId
+     * @param transactionDate
+     */
+    public void checkForBranchClosures(Long officeId, final LocalDate transactionDate) {
+        /**
+         * check if an accounting closure has happened for this branch after the transaction Date
+         **/
+        GLClosure gLClosure = getLatestClosureByBranch(officeId);
+        if (gLClosure != null) {
+            if (gLClosure.getClosingDate().isAfter(transactionDate) || gLClosure.getClosingDate().isEqual(transactionDate)) {
+                throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, gLClosure.getClosingDate(), null,
+                        null);
+            }
+        }
+    }
+
+    public JournalEntry createDebitJournalEntryOrReversalForInvestor(final Office office, final String currencyCode,
+            final int accountMappingTypeId, final Long loanProductId, final Long loanId, final Long transactionId,
+            final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversalOrder) {
+        final GLAccount account = getLinkedGLAccountForLoanProduct(loanProductId, accountMappingTypeId);
+        if (isReversalOrder) {
+            return createCreditJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
+        } else {
+            return createDebitJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
+        }
+    }
+
+    public JournalEntry createCreditJournalEntryOrReversalForInvestor(final Office office, final String currencyCode, final Long loanId,
+            final Long transactionId, final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversalOrder,
+            final GLAccount account) {
+        if (isReversalOrder) {
+            return createDebitJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
+        } else {
+            return createCreditJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
+        }
+    }
+
+    private JournalEntry createCreditJournalEntryForInvestor(final Office office, final String currencyCode, final GLAccount account,
+            final Long loanId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
+        final boolean manualEntry = false;
+        final String modifiedTransactionId = INVESTOR_TRANSFER_IDENTIFIER + transactionId;
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null, null, null,
+                null, null);
+        return this.glJournalEntryRepository.saveAndFlush(journalEntry);
+    }
+
+    private JournalEntry createDebitJournalEntryForInvestor(final Office office, final String currencyCode, final GLAccount account,
+            final Long loanId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
+        final boolean manualEntry = false;
+        String modifiedTransactionId = INVESTOR_TRANSFER_IDENTIFIER + transactionId;
+
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null, null, null, null,
+                null);
+        return this.glJournalEntryRepository.saveAndFlush(journalEntry);
+    }
+
+    public GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId) {
+        GLAccount glAccount;
+        if (isOrganizationAccount(accountMappingTypeId)) {
+            FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
+                    .findByFinancialActivityTypeWithNotFoundDetection(accountMappingTypeId);
+            glAccount = financialActivityAccount.getGlAccount();
+        } else {
+            ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(loanProductId,
+                    PortfolioProductType.LOAN.getValue(), accountMappingTypeId);
+
+            if (accountMapping == null) {
+                throw new ProductToGLAccountMappingNotFoundException(PortfolioProductType.LOAN, loanProductId,
+                        AccountingConstants.AccrualAccountsForLoan.fromInt(accountMappingTypeId).toString());
+            }
+            glAccount = accountMapping.getGlAccount();
+        }
+        return glAccount;
+    }
+
+    private boolean isOrganizationAccount(final int accountMappingTypeId) {
+        return FinancialActivity.fromInt(accountMappingTypeId) != null;
+    }
+
+    public GLClosure getLatestClosureByBranch(final long officeId) {
+        return this.closureRepository.getLatestGLClosureByBranch(officeId);
+    }
+
+}
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/api/ExternalAssetOwnersApiResource.java b/fineract-investor/src/main/java/org/apache/fineract/investor/api/ExternalAssetOwnersApiResource.java
index a495433ef..c8e2da270 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/api/ExternalAssetOwnersApiResource.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/api/ExternalAssetOwnersApiResource.java
@@ -40,17 +40,19 @@ import lombok.RequiredArgsConstructor;
 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.core.api.ApiRequestParameterHelper;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
 import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
 import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
 import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext;
+import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
+import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
+import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
 import org.apache.fineract.investor.data.ExternalTransferData;
 import org.apache.fineract.investor.data.ExternalTransferResponseData;
 import org.apache.fineract.investor.service.ExternalAssetOwnersReadService;
 import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Conditional;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Component;
 
@@ -58,13 +60,11 @@ import org.springframework.stereotype.Component;
 @Component
 @Tag(name = "External Asset Owners", description = "External Asset Owners")
 @RequiredArgsConstructor
-@ConditionalOnProperty(value = "fineract.module.external-asset-owner.enabled", havingValue = "true")
+@Conditional(InvestorModuleIsEnabledCondition.class)
 public class ExternalAssetOwnersApiResource {
 
     private final PlatformUserRightsContext platformUserRightsContext;
     private final ExternalAssetOwnersReadService externalAssetOwnersReadService;
-    private final ApiRequestParameterHelper apiRequestParameterHelper;
-    private final DefaultToApiJsonSerializer<ExternalTransferData> apiJsonSerializerService;
     private final DefaultToApiJsonSerializer<ExternalTransferResponseData> postApiJsonSerializerService;
     private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
     private final LoanReadPlatformServiceCommon loanReadPlatformService;
@@ -106,7 +106,7 @@ public class ExternalAssetOwnersApiResource {
     @Produces({ MediaType.APPLICATION_JSON })
     @Operation(tags = {
             "External Asset Owners" }, summary = "Retrieve External Asset Owner Transfers", description = "Retrieve External Asset Owner Transfer items by transferExternalId, loanId or loanExternalId")
-    public Page<ExternalTransferData> getTransfer(
+    public Page<ExternalTransferData> getTransfers(
             @QueryParam("transferExternalId") @Parameter(description = "transferExternalId") final String transferExternalId,
             @QueryParam("loanId") @Parameter(description = "loanId") final Long loanId,
             @QueryParam("loanExternalId") @Parameter(description = "loanExternalId") final String loanExternalId,
@@ -117,6 +117,49 @@ public class ExternalAssetOwnersApiResource {
 
     }
 
+    @GET
+    @Path("/transfers/active-transfer")
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(tags = {
+            "External Asset Owners" }, summary = "Retrieve Active Asset Owner Transfer", description = "Retrieve Active External Asset Owner Transfer by transferExternalId, loanId or loanExternalId")
+    public ExternalTransferData getActiveTransfer(
+            @QueryParam("transferExternalId") @Parameter(description = "transferExternalId") final String transferExternalId,
+            @QueryParam("loanId") @Parameter(description = "loanId") final Long loanId,
+            @QueryParam("loanExternalId") @Parameter(description = "loanExternalId") final String loanExternalId,
+            @Context final UriInfo uriInfo) {
+        platformUserRightsContext.isAuthenticated();
+        return externalAssetOwnersReadService.retrieveActiveTransferData(loanId, loanExternalId, transferExternalId);
+
+    }
+
+    @GET
+    @Path("/transfers/{transferId}/journal-entries")
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(tags = {
+            "External Asset Owners" }, summary = "Retrieve Journal Entries of Transfer", description = "Retrieve Journal entries of transfer by transferId")
+    public ExternalOwnerTransferJournalEntryData getJournalEntriesOfTransfer(
+            @PathParam("transferId") @Parameter(description = "transferId") final Long transferId,
+            @QueryParam("offset") @Parameter(description = "offset") final Integer offset,
+            @QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) {
+        platformUserRightsContext.isAuthenticated();
+        return externalAssetOwnersReadService.retrieveJournalEntriesOfTransfer(transferId, offset, limit);
+
+    }
+
+    @GET
+    @Path("/owners/external-id/{ownerExternalId}/journal-entries")
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(tags = {
+            "External Asset Owners" }, summary = "Retrieve Journal Entries of Owner", description = "Retrieve Journal entries of owner by owner externalId")
+    public ExternalOwnerJournalEntryData getJournalEntriesOfOwner(
+            @PathParam("ownerExternalId") @Parameter(description = "ownerExternalId") final String ownerExternalId,
+            @QueryParam("offset") @Parameter(description = "offset") final Integer offset,
+            @QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) {
+        platformUserRightsContext.isAuthenticated();
+        return externalAssetOwnersReadService.retrieveJournalEntriesOfOwner(ownerExternalId, offset, limit);
+
+    }
+
     private String getResult(Long loanId, String apiRequestBodyAsJson, String commandParam) {
         final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
         CommandWrapper commandRequest = null;
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java b/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
index 57c098bfd..34752d86a 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
@@ -26,6 +26,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.cob.loan.LoanCOBBusinessStep;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
 import org.apache.fineract.investor.data.ExternalTransferStatus;
 import org.apache.fineract.investor.data.ExternalTransferSubStatus;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
@@ -33,18 +34,22 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferDetails;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMapping;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
+import org.apache.fineract.investor.service.AccountingService;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.springframework.context.annotation.Conditional;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Component;
 
 @Component
 @RequiredArgsConstructor
 @Slf4j
+@Conditional(InvestorModuleIsEnabledCondition.class)
 public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep {
 
     public static final LocalDate FUTURE_DATE_9999_12_31 = LocalDate.of(9999, 12, 31);
     private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
     private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
+    private final AccountingService accountingService;
 
     @Override
     public Loan execute(Loan loan) {
@@ -109,7 +114,7 @@ public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep
         externalAssetOwnerTransferRepository.save(activeExternalAssetOwnerTransfer);
         buybackExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository.save(buybackExternalAssetOwnerTransfer);
         externalAssetOwnerTransferLoanMappingRepository.deleteByLoanIdAndOwnerTransfer(loan.getId(), activeExternalAssetOwnerTransfer);
-        // TODO: create asset ownership accounting entries
+        accountingService.createJournalEntriesForBuybackAssetTransfer(loan, buybackExternalAssetOwnerTransfer);
         return buybackExternalAssetOwnerTransfer;
     }
 
@@ -121,7 +126,7 @@ public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep
             createActiveMapping(loan.getId(), newExternalAssetOwnerTransfer);
             newExternalAssetOwnerTransfer
                     .setExternalAssetOwnerTransferDetails(createAssetOwnerTransferDetails(loan, newExternalAssetOwnerTransfer));
-            // TODO: create asset ownership accounting entries
+            accountingService.createJournalEntriesForSaleAssetTransfer(loan, newExternalAssetOwnerTransfer);
         } else {
             ExternalTransferSubStatus subStatus = ExternalTransferSubStatus.BALANCE_ZERO;
             if (loan.getTotalOverpaid().compareTo(BigDecimal.ZERO) > 0) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventQueueCondition.java b/fineract-investor/src/main/java/org/apache/fineract/investor/config/InvestorModuleIsEnabledCondition.java
similarity index 77%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventQueueCondition.java
rename to fineract-investor/src/main/java/org/apache/fineract/investor/config/InvestorModuleIsEnabledCondition.java
index b3f7182fc..afea92a5f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/config/EnableExternalEventQueueCondition.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/config/InvestorModuleIsEnabledCondition.java
@@ -16,16 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.event.external.config;
+package org.apache.fineract.investor.config;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.infrastructure.core.condition.PropertiesCondition;
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
 
-public class EnableExternalEventQueueCondition extends PropertiesCondition {
+public class InvestorModuleIsEnabledCondition extends PropertiesCondition {
 
     @Override
     protected boolean matches(FineractProperties properties) {
-        return StringUtils.isNotBlank(properties.getEvents().getExternal().getProducer().getJms().getEventQueueName());
+        return properties.getModule().getInvestor().isEnabled();
     }
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalOwnerJournalEntryData.java
similarity index 76%
copy from fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java
copy to fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalOwnerJournalEntryData.java
index 0dfd8fa8d..c2958bdd0 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalOwnerJournalEntryData.java
@@ -19,10 +19,12 @@
 package org.apache.fineract.investor.data;
 
 import lombok.Data;
+import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
+import org.springframework.data.domain.Page;
 
 @Data
-public class ExternalTransferLoanMappingData {
+public class ExternalOwnerJournalEntryData {
 
-    private final Long loanId;
-    private final String externalId;
+    private ExternalTransferOwnerData ownerData;
+    private Page<JournalEntryData> journalEntryData;
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalOwnerTransferJournalEntryData.java
similarity index 76%
copy from fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java
copy to fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalOwnerTransferJournalEntryData.java
index 0dfd8fa8d..047f41a8d 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalOwnerTransferJournalEntryData.java
@@ -19,10 +19,12 @@
 package org.apache.fineract.investor.data;
 
 import lombok.Data;
+import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
+import org.springframework.data.domain.Page;
 
 @Data
-public class ExternalTransferLoanMappingData {
+public class ExternalOwnerTransferJournalEntryData {
 
-    private final Long loanId;
-    private final String externalId;
+    private ExternalTransferData transferData;
+    private Page<JournalEntryData> journalEntryData;
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferData.java b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferData.java
index 9cbb0a539..54bbf5a85 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferData.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferData.java
@@ -26,7 +26,7 @@ public class ExternalTransferData {
 
     private Long transferId;
     private ExternalTransferOwnerData owner;
-    private ExternalTransferLoanMappingData loan;
+    private ExternalTransferLoanData loan;
     private ExternalTransferDataDetails details;
     private String transferExternalId;
     private String purchasePriceRatio;
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanData.java
similarity index 95%
rename from fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java
rename to fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanData.java
index 0dfd8fa8d..92f599916 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanMappingData.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/data/ExternalTransferLoanData.java
@@ -21,7 +21,7 @@ package org.apache.fineract.investor.data;
 import lombok.Data;
 
 @Data
-public class ExternalTransferLoanMappingData {
+public class ExternalTransferLoanData {
 
     private final Long loanId;
     private final String externalId;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerJournalEntryMapping.java
similarity index 57%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java
copy to fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerJournalEntryMapping.java
index af57933ab..3e1ef837d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerJournalEntryMapping.java
@@ -16,38 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.cache.domain;
+package org.apache.fineract.investor.domain;
 
-import jakarta.persistence.Column;
 import jakarta.persistence.Entity;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToOne;
 import jakarta.persistence.Table;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
-import lombok.experimental.Accessors;
-import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
 
-@Entity
-@Table(name = "c_cache")
 @Getter
 @Setter
+@Table(name = "m_external_asset_owner_journal_entry_mapping")
 @NoArgsConstructor
-@Accessors(chain = true)
-public class PlatformCache extends AbstractPersistableCustom {
-
-    @Column(name = "cache_type_enum")
-    private Integer cacheType;
-
-    public boolean isNoCachedEnabled() {
-        return CacheType.fromInt(this.cacheType).isNoCache();
-    }
+@Entity
+public class ExternalAssetOwnerJournalEntryMapping extends AbstractAuditableWithUTCDateTimeCustom {
 
-    public boolean isEhcacheEnabled() {
-        return CacheType.fromInt(this.cacheType).isEhcache();
-    }
+    @OneToOne
+    @JoinColumn(name = "journal_entry_id", nullable = false)
+    private JournalEntry journalEntry;
 
-    public boolean isDistributedCacheEnabled() {
-        return CacheType.fromInt(this.cacheType).isDistributedCache();
-    }
+    @ManyToOne
+    @JoinColumn(name = "owner_id", nullable = false)
+    private ExternalAssetOwner owner;
 
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerJournalEntryMappingRepository.java
similarity index 59%
copy from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java
copy to fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerJournalEntryMappingRepository.java
index f49e8b5d4..d4338cbc8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerJournalEntryMappingRepository.java
@@ -16,16 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.accounting.glaccount.domain;
+package org.apache.fineract.investor.domain;
 
-import java.util.List;
+import org.apache.fineract.infrastructure.core.domain.ExternalId;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
 
-public interface TrialBalanceRepository extends JpaRepository<TrialBalance, Long>, JpaSpecificationExecutor<TrialBalance> {
+public interface ExternalAssetOwnerJournalEntryMappingRepository extends JpaRepository<ExternalAssetOwnerJournalEntryMapping, Long>,
+        JpaSpecificationExecutor<ExternalAssetOwnerJournalEntryMapping> {
 
-    @Query(value = "select * from m_trial_balance where office_id=:officeId and account_id=:accountId and closing_balance is null order by created_date, entry_date", nativeQuery = true)
-    List<TrialBalance> findNewByOfficeAndAccount(@Param("officeId") Long officeId, @Param("accountId") Long accountId);
+    @Query("SELECT mapping FROM ExternalAssetOwnerJournalEntryMapping mapping WHERE mapping.owner.externalId = :ownerExternalId")
+    Page<ExternalAssetOwnerJournalEntryMapping> findByExternalOwnerId(@Param("ownerExternalId") ExternalId ownerExternalId,
+            PageRequest pageRequest);
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferJournalEntryMapping.java
similarity index 57%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java
rename to fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferJournalEntryMapping.java
index af57933ab..888a4fd3d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferJournalEntryMapping.java
@@ -16,38 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.cache.domain;
+package org.apache.fineract.investor.domain;
 
-import jakarta.persistence.Column;
 import jakarta.persistence.Entity;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToOne;
 import jakarta.persistence.Table;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
-import lombok.experimental.Accessors;
-import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
 
-@Entity
-@Table(name = "c_cache")
 @Getter
 @Setter
+@Table(name = "m_external_asset_owner_transfer_journal_entry_mapping")
 @NoArgsConstructor
-@Accessors(chain = true)
-public class PlatformCache extends AbstractPersistableCustom {
-
-    @Column(name = "cache_type_enum")
-    private Integer cacheType;
-
-    public boolean isNoCachedEnabled() {
-        return CacheType.fromInt(this.cacheType).isNoCache();
-    }
+@Entity
+public class ExternalAssetOwnerTransferJournalEntryMapping extends AbstractAuditableWithUTCDateTimeCustom {
 
-    public boolean isEhcacheEnabled() {
-        return CacheType.fromInt(this.cacheType).isEhcache();
-    }
+    @OneToOne
+    @JoinColumn(name = "journal_entry_id", nullable = false)
+    private JournalEntry journalEntry;
 
-    public boolean isDistributedCacheEnabled() {
-        return CacheType.fromInt(this.cacheType).isDistributedCache();
-    }
+    @ManyToOne
+    @JoinColumn(name = "owner_transfer_id", nullable = false)
+    private ExternalAssetOwnerTransfer ownerTransfer;
 
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferJournalEntryMappingRepository.java
similarity index 61%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java
rename to fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferJournalEntryMappingRepository.java
index f49e8b5d4..9f72b37c7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/TrialBalanceRepository.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferJournalEntryMappingRepository.java
@@ -16,16 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.accounting.glaccount.domain;
+package org.apache.fineract.investor.domain;
 
-import java.util.List;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
 
-public interface TrialBalanceRepository extends JpaRepository<TrialBalance, Long>, JpaSpecificationExecutor<TrialBalance> {
+public interface ExternalAssetOwnerTransferJournalEntryMappingRepository
+        extends JpaRepository<ExternalAssetOwnerTransferJournalEntryMapping, Long>,
+        JpaSpecificationExecutor<ExternalAssetOwnerTransferJournalEntryMapping> {
 
-    @Query(value = "select * from m_trial_balance where office_id=:officeId and account_id=:accountId and closing_balance is null order by created_date, entry_date", nativeQuery = true)
-    List<TrialBalance> findNewByOfficeAndAccount(@Param("officeId") Long officeId, @Param("accountId") Long accountId);
+    @Query("SELECT mapping FROM ExternalAssetOwnerTransferJournalEntryMapping mapping WHERE mapping.ownerTransfer.id =:transferId")
+    Page<ExternalAssetOwnerTransferJournalEntryMapping> findByTransferId(@Param("transferId") Long transferId, PageRequest pageable);
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMappingRepository.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMappingRepository.java
index e7b28b4d8..f6b238bd6 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMappingRepository.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMappingRepository.java
@@ -18,11 +18,23 @@
  */
 package org.apache.fineract.investor.domain;
 
+import java.util.Optional;
+import org.apache.fineract.infrastructure.core.domain.ExternalId;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 
 public interface ExternalAssetOwnerTransferLoanMappingRepository extends JpaRepository<ExternalAssetOwnerTransferLoanMapping, Long>,
         JpaSpecificationExecutor<ExternalAssetOwnerTransferLoanMapping> {
 
     void deleteByLoanIdAndOwnerTransfer(Long loanId, ExternalAssetOwnerTransfer externalAssetOwnerTransfer);
+
+    Optional<ExternalAssetOwnerTransferLoanMapping> findByLoanId(Long loanId);
+
+    @Query("SELECT mapping FROM ExternalAssetOwnerTransferLoanMapping mapping WHERE mapping.ownerTransfer.externalLoanId =:externalLoanId")
+    Optional<ExternalAssetOwnerTransferLoanMapping> findByLoanExternalId(@Param("externalLoanId") ExternalId externalLoanId);
+
+    @Query("SELECT mapping FROM ExternalAssetOwnerTransferLoanMapping mapping WHERE mapping.ownerTransfer.externalId =:externalTransferId")
+    Optional<ExternalAssetOwnerTransferLoanMapping> findByTransferExternalId(@Param("externalTransferId") ExternalId externalTransferId);
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java b/fineract-investor/src/main/java/org/apache/fineract/investor/internal/InternalAPIForTesting.java
similarity index 87%
copy from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
copy to fineract-investor/src/main/java/org/apache/fineract/investor/internal/InternalAPIForTesting.java
index 6b3954d33..fc10dbc2a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/internal/InternalAPIForTesting.java
@@ -16,8 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service.database;
+package org.apache.fineract.investor.internal;
 
-public enum DatabaseType {
-    MYSQL, POSTGRESQL
-}
+public class InternalAPIForTesting {}
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadService.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingService.java
old mode 100644
new mode 100755
similarity index 69%
copy from fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadService.java
copy to fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingService.java
index 6d98a6c11..437211da0
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadService.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingService.java
@@ -18,11 +18,12 @@
  */
 package org.apache.fineract.investor.service;
 
-import org.apache.fineract.investor.data.ExternalTransferData;
-import org.springframework.data.domain.Page;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 
-public interface ExternalAssetOwnersReadService {
+public interface AccountingService {
 
-    Page<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId, Integer offset,
-            Integer limit);
+    void createJournalEntriesForSaleAssetTransfer(Loan loan, ExternalAssetOwnerTransfer transfer);
+
+    void createJournalEntriesForBuybackAssetTransfer(Loan loan, ExternalAssetOwnerTransfer transfer);
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingServiceImpl.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingServiceImpl.java
new file mode 100644
index 000000000..f85f3eab0
--- /dev/null
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingServiceImpl.java
@@ -0,0 +1,197 @@
+/**
+ * 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.investor.service;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import lombok.RequiredArgsConstructor;
+import org.apache.fineract.accounting.common.AccountingConstants;
+import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount;
+import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
+import org.apache.fineract.accounting.glaccount.domain.GLAccount;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
+import org.apache.fineract.investor.accounting.journalentry.service.InvestorAccountingHelper;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMappingRepository;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMappingRepository;
+import org.apache.fineract.organisation.office.domain.Office;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class AccountingServiceImpl implements AccountingService {
+
+    private final InvestorAccountingHelper helper;
+    private final ExternalAssetOwnerTransferJournalEntryMappingRepository externalAssetOwnerTransferJournalEntryMappingRepository;
+    private final ExternalAssetOwnerJournalEntryMappingRepository externalAssetOwnerJournalEntryMappingRepository;
+    private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository;
+
+    private static boolean participateInTransfer(FinancialActivityAccount financialActivityAccount, JournalEntry journalEntry,
+            JournalEntryType filterType) {
+        return filterType.getValue().equals(journalEntry.getType())
+                && !Objects.equals(financialActivityAccount.getGlAccount().getId(), journalEntry.getGlAccount().getId());
+    }
+
+    @Override
+    public void createJournalEntriesForSaleAssetTransfer(final Loan loan, final ExternalAssetOwnerTransfer transfer) {
+        List<JournalEntry> journalEntryList = createJournalEntries(loan, transfer, true);
+        createMappingToTransfer(transfer, journalEntryList);
+        createMappingToOwner(transfer, journalEntryList, JournalEntryType.DEBIT);
+    }
+
+    @Override
+    public void createJournalEntriesForBuybackAssetTransfer(final Loan loan, final ExternalAssetOwnerTransfer transfer) {
+        List<JournalEntry> journalEntryList = createJournalEntries(loan, transfer, false);
+        createMappingToTransfer(transfer, journalEntryList);
+        createMappingToOwner(transfer, journalEntryList, JournalEntryType.CREDIT);
+    }
+
+    @NotNull
+    private List<JournalEntry> createJournalEntries(Loan loan, ExternalAssetOwnerTransfer transfer, boolean isReversalOrder) {
+        this.helper.checkForBranchClosures(loan.getOffice().getId(), transfer.getSettlementDate());
+        // loan properties
+        final Long loanProductId = loan.getLoanProduct().getId();
+        final Long loanId = loan.getId();
+        final Office office = loan.getOffice();
+        final String currencyCode = loan.getCurrencyCode();
+        // transaction properties
+        final Long transactionId = transfer.getId();
+        final LocalDate transactionDate = transfer.getSettlementDate();
+        final BigDecimal principalAmount = loan.getLoanSummary().getTotalPrincipalOutstanding();
+        final BigDecimal interestAmount = loan.getLoanSummary().getTotalInterestOutstanding();
+        final BigDecimal feesAmount = loan.getLoanSummary().getTotalFeeChargesOutstanding();
+        final BigDecimal penaltiesAmount = loan.getLoanSummary().getTotalPenaltyChargesOutstanding();
+        final BigDecimal overPaymentAmount = loan.getTotalOverpaid();
+
+        // Moving money to asset transfer account
+        List<JournalEntry> journalEntryList = createJournalEntries(loanProductId, loanId, office, currencyCode, transactionId,
+                transactionDate, principalAmount, interestAmount, feesAmount, penaltiesAmount, overPaymentAmount, !isReversalOrder);
+        // Moving money from asset transfer account
+        journalEntryList.addAll(createJournalEntries(loanProductId, loanId, office, currencyCode, transactionId, transactionDate,
+                principalAmount, interestAmount, feesAmount, penaltiesAmount, overPaymentAmount, isReversalOrder));
+        return journalEntryList;
+    }
+
+    private void createMappingToOwner(ExternalAssetOwnerTransfer transfer, List<JournalEntry> journalEntryList,
+            JournalEntryType filterType) {
+        FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
+                .findByFinancialActivityTypeWithNotFoundDetection(AccountingConstants.FinancialActivity.ASSET_TRANSFER.getValue());
+        journalEntryList.forEach(journalEntry -> {
+            if (participateInTransfer(financialActivityAccount, journalEntry, filterType)) {
+                ExternalAssetOwnerJournalEntryMapping mapping = new ExternalAssetOwnerJournalEntryMapping();
+                mapping.setJournalEntry(journalEntry);
+                mapping.setOwner(transfer.getOwner());
+                externalAssetOwnerJournalEntryMappingRepository.saveAndFlush(mapping);
+            }
+        });
+    }
+
+    private void createMappingToTransfer(ExternalAssetOwnerTransfer transfer, List<JournalEntry> journalEntryList) {
+        journalEntryList.forEach(journalEntry -> {
+            ExternalAssetOwnerTransferJournalEntryMapping mapping = new ExternalAssetOwnerTransferJournalEntryMapping();
+            mapping.setJournalEntry(journalEntry);
+            mapping.setOwnerTransfer(transfer);
+            externalAssetOwnerTransferJournalEntryMappingRepository.saveAndFlush(mapping);
+        });
+    }
+
+    private List<JournalEntry> createJournalEntries(Long loanProductId, Long loanId, Office office, String currencyCode, Long transactionId,
+            LocalDate transactionDate, BigDecimal principalAmount, BigDecimal interestAmount, BigDecimal feesAmount,
+            BigDecimal penaltiesAmount, BigDecimal overPaymentAmount, boolean isReversalOrder) {
+        List<JournalEntry> journalEntryList = new ArrayList<>();
+        BigDecimal totalDebitAmount = BigDecimal.ZERO;
+        Map<GLAccount, BigDecimal> accountMap = new LinkedHashMap<>();
+        // principal entry
+        if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
+            totalDebitAmount = totalDebitAmount.add(principalAmount);
+            GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
+                    AccountingConstants.AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue());
+            accountMap.put(account, principalAmount);
+        }
+        // interest entry
+        if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
+            totalDebitAmount = totalDebitAmount.add(interestAmount);
+            GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
+                    AccountingConstants.AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue());
+            if (accountMap.containsKey(account)) {
+                BigDecimal amount = accountMap.get(account).add(interestAmount);
+                accountMap.put(account, amount);
+            } else {
+                accountMap.put(account, interestAmount);
+            }
+        }
+        // fee entry
+        if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
+            totalDebitAmount = totalDebitAmount.add(feesAmount);
+            GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
+                    AccountingConstants.AccrualAccountsForLoan.FEES_RECEIVABLE.getValue());
+            if (accountMap.containsKey(account)) {
+                BigDecimal amount = accountMap.get(account).add(feesAmount);
+                accountMap.put(account, amount);
+            } else {
+                accountMap.put(account, feesAmount);
+            }
+        }
+        // penalty entry
+        if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
+            totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
+            GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
+                    AccountingConstants.AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue());
+            if (accountMap.containsKey(account)) {
+                BigDecimal amount = accountMap.get(account).add(penaltiesAmount);
+                accountMap.put(account, amount);
+            } else {
+                accountMap.put(account, penaltiesAmount);
+            }
+        }
+        // overpaid entry
+        if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
+            totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
+            GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
+                    AccountingConstants.AccrualAccountsForLoan.OVERPAYMENT.getValue());
+            if (accountMap.containsKey(account)) {
+                BigDecimal amount = accountMap.get(account).add(overPaymentAmount);
+                accountMap.put(account, amount);
+            } else {
+                accountMap.put(account, overPaymentAmount);
+            }
+        }
+        // asset transfer entry
+        for (Map.Entry<GLAccount, BigDecimal> entry : accountMap.entrySet()) {
+            journalEntryList.add(this.helper.createCreditJournalEntryOrReversalForInvestor(office, currencyCode, loanId, transactionId,
+                    transactionDate, entry.getValue(), isReversalOrder, entry.getKey()));
+        }
+        if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
+            journalEntryList.add(this.helper.createDebitJournalEntryOrReversalForInvestor(office, currencyCode,
+                    AccountingConstants.FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId, loanId, transactionId, transactionDate,
+                    totalDebitAmount, isReversalOrder));
+        }
+        return journalEntryList;
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryService.java
similarity index 87%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
rename to fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryService.java
index 6b3954d33..a2a06c877 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryService.java
@@ -16,8 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.core.service.database;
+package org.apache.fineract.investor.service;
 
-public enum DatabaseType {
-    MYSQL, POSTGRESQL
-}
+public interface ExternalAssetOwnerJournalEntryService {}
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryServiceImpl.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryServiceImpl.java
new file mode 100644
index 000000000..14d8e9398
--- /dev/null
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryServiceImpl.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.investor.service;
+
+import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
+import org.apache.fineract.infrastructure.event.business.domain.journalentry.LoanJournalEntryCreatedBusinessEvent;
+import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
+import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMappingRepository;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+@Conditional(InvestorModuleIsEnabledCondition.class)
+public class ExternalAssetOwnerJournalEntryServiceImpl implements ExternalAssetOwnerJournalEntryService {
+
+    private final BusinessEventNotifierService businessEventNotifierService;
+    private final ExternalAssetOwnerJournalEntryMappingRepository externalAssetOwnerJournalEntryMappingRepository;
+    private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
+    private final LoanTransactionRepository loanTransactionRepository;
+
+    @PostConstruct
+    public void addListeners() {
+        businessEventNotifierService.addPostBusinessEventListener(LoanJournalEntryCreatedBusinessEvent.class,
+                new HandleLoanJournalEntryCreatedBusinessEvent());
+    }
+
+    private class HandleLoanJournalEntryCreatedBusinessEvent implements BusinessEventListener<LoanJournalEntryCreatedBusinessEvent> {
+
+        @Override
+        public void onBusinessEvent(LoanJournalEntryCreatedBusinessEvent event) {
+            JournalEntry journalEntry = event.get();
+            createMapping(journalEntry);
+        }
+
+        private void createMapping(JournalEntry journalEntry) {
+            Long loanId = loanTransactionRepository.findLoanIdById(journalEntry.getLoanTransactionId()).orElseThrow();
+            externalAssetOwnerTransferLoanMappingRepository.findByLoanId(loanId).ifPresent(transferLoanMapping -> {
+                ExternalAssetOwnerJournalEntryMapping mapping = new ExternalAssetOwnerJournalEntryMapping();
+                mapping.setJournalEntry(journalEntry);
+                mapping.setOwner(transferLoanMapping.getOwnerTransfer().getOwner());
+                externalAssetOwnerJournalEntryMappingRepository.saveAndFlush(mapping);
+            });
+        }
+    }
+}
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadService.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadService.java
index 6d98a6c11..d6a8c33da 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadService.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadService.java
@@ -18,6 +18,8 @@
  */
 package org.apache.fineract.investor.service;
 
+import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
+import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
 import org.apache.fineract.investor.data.ExternalTransferData;
 import org.springframework.data.domain.Page;
 
@@ -25,4 +27,10 @@ public interface ExternalAssetOwnersReadService {
 
     Page<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId, Integer offset,
             Integer limit);
+
+    ExternalTransferData retrieveActiveTransferData(Long loanId, String externalLoanId, String transferExternalId);
+
+    ExternalOwnerTransferJournalEntryData retrieveJournalEntriesOfTransfer(Long transferId, Integer offset, Integer limit);
+
+    ExternalOwnerJournalEntryData retrieveJournalEntriesOfOwner(String ownerExternalId, Integer offset, Integer limit);
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadServiceImpl.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadServiceImpl.java
index 257227987..bf619e275 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadServiceImpl.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersReadServiceImpl.java
@@ -18,10 +18,20 @@
  */
 package org.apache.fineract.investor.service;
 
+import java.util.Optional;
 import lombok.RequiredArgsConstructor;
+import org.apache.fineract.accounting.journalentry.JournalEntryMapper;
 import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
+import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
+import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
 import org.apache.fineract.investor.data.ExternalTransferData;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMappingRepository;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMappingRepository;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMapping;
+import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
@@ -35,19 +45,17 @@ import org.springframework.transaction.annotation.Transactional;
 public class ExternalAssetOwnersReadServiceImpl implements ExternalAssetOwnersReadService {
 
     private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
+    private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
+    private final ExternalAssetOwnerTransferJournalEntryMappingRepository externalAssetOwnerTransferJournalEntryMappingRepository;
+    private final ExternalAssetOwnerJournalEntryMappingRepository externalAssetOwnerJournalEntryMappingRepository;
     private final ExternalAssetOwnersTransferMapper mapper;
+    private final JournalEntryMapper journalEntryMapper;
 
     @Override
     public Page<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId, Integer offset,
             Integer limit) {
         Page<ExternalAssetOwnerTransfer> result;
-        if (offset == null) {
-            offset = 0;
-        }
-        if (limit == null) {
-            limit = 100;
-        }
-        PageRequest pageRequest = PageRequest.of(offset, limit, Sort.by("id"));
+        PageRequest pageRequest = getPageRequest(offset, limit);
         if (loanId != null) {
             result = externalAssetOwnerTransferRepository.findAllByLoanId(loanId, pageRequest);
         } else if (externalLoanId != null) {
@@ -61,4 +69,57 @@ public class ExternalAssetOwnersReadServiceImpl implements ExternalAssetOwnersRe
         return result.map(mapper::mapTransfer);
     }
 
+    @Override
+    public ExternalTransferData retrieveActiveTransferData(Long loanId, String externalLoanId, String transferExternalId) {
+        Optional<ExternalAssetOwnerTransferLoanMapping> result;
+        if (loanId != null) {
+            result = externalAssetOwnerTransferLoanMappingRepository.findByLoanId(loanId);
+        } else if (externalLoanId != null) {
+            result = externalAssetOwnerTransferLoanMappingRepository.findByLoanExternalId(ExternalIdFactory.produce(externalLoanId));
+        } else if (transferExternalId != null) {
+            result = externalAssetOwnerTransferLoanMappingRepository
+                    .findByTransferExternalId(ExternalIdFactory.produce(transferExternalId));
+        } else {
+            throw new IllegalArgumentException(
+                    "At least one of the following parameters must be provided: loanId, externalLoanId, transferExternalId");
+        }
+        return result.map(transferLoanMapping -> mapper.mapTransfer(transferLoanMapping.getOwnerTransfer())).orElse(null);
+    }
+
+    @Override
+    public ExternalOwnerTransferJournalEntryData retrieveJournalEntriesOfTransfer(Long transferId, Integer offset, Integer limit) {
+        PageRequest pageRequest = getPageRequest(offset, limit);
+        Page<ExternalAssetOwnerTransferJournalEntryMapping> result = externalAssetOwnerTransferJournalEntryMappingRepository
+                .findByTransferId(transferId, pageRequest);
+        ExternalOwnerTransferJournalEntryData mappedResult = new ExternalOwnerTransferJournalEntryData();
+        if (result.hasContent()) {
+            mappedResult.setJournalEntryData(result.map(entry -> journalEntryMapper.map(entry.getJournalEntry())));
+            mappedResult.setTransferData(mapper.mapTransfer(result.stream().findFirst().get().getOwnerTransfer()));
+        }
+        return mappedResult;
+    }
+
+    @Override
+    public ExternalOwnerJournalEntryData retrieveJournalEntriesOfOwner(String ownerExternalId, Integer offset, Integer limit) {
+        PageRequest pageRequest = getPageRequest(offset, limit);
+        Page<ExternalAssetOwnerJournalEntryMapping> result = externalAssetOwnerJournalEntryMappingRepository
+                .findByExternalOwnerId(ExternalIdFactory.produce(ownerExternalId), pageRequest);
+        ExternalOwnerJournalEntryData mappedResult = new ExternalOwnerJournalEntryData();
+        if (result.hasContent()) {
+            mappedResult.setJournalEntryData(result.map(entry -> journalEntryMapper.map(entry.getJournalEntry())));
+            mappedResult.setOwnerData(mapper.mapOwner(result.stream().findFirst().get().getOwner()));
+        }
+        return mappedResult;
+    }
+
+    private PageRequest getPageRequest(Integer offset, Integer limit) {
+        if (offset == null) {
+            offset = 0;
+        }
+        if (limit == null) {
+            limit = 100;
+        }
+        return PageRequest.of(offset, limit, Sort.by("id"));
+    }
+
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersTransferMapper.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersTransferMapper.java
index 094a60459..61491ac65 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersTransferMapper.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersTransferMapper.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.investor.service;
 
+import org.apache.fineract.accounting.journalentry.JournalEntryMapper;
 import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
 import org.apache.fineract.investor.data.ExternalTransferData;
 import org.apache.fineract.investor.data.ExternalTransferDataDetails;
@@ -28,7 +29,7 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferDetails;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 
-@Mapper(config = MapstructMapperConfig.class)
+@Mapper(config = MapstructMapperConfig.class, uses = JournalEntryMapper.class)
 public interface ExternalAssetOwnersTransferMapper {
 
     @Mapping(target = "transferId", source = "id")
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java
index e32f15802..270d08729 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnersWriteServiceImpl.java
@@ -51,7 +51,6 @@ import org.apache.fineract.investor.data.ExternalTransferStatus;
 import org.apache.fineract.investor.domain.ExternalAssetOwner;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerRepository;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
-import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
 import org.apache.fineract.investor.exception.ExternalAssetOwnerInitiateTransferException;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
@@ -70,7 +69,6 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
     private static final List<ExternalTransferStatus> BUYBACK_READY_STATUSES = List.of(ExternalTransferStatus.PENDING,
             ExternalTransferStatus.ACTIVE);
     private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
-    private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
     private final ExternalAssetOwnerRepository externalAssetOwnerRepository;
     private final FromJsonHelper fromApiJsonHelper;
     private final LoanRepository loanRepository;
diff --git a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
index e8df64dc0..a6cb411e3 100644
--- a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
+++ b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
@@ -29,4 +29,5 @@
   <include relativeToChangelogFile="true" file="parts/0005_add_sale_and_buyback_command.xml"/>
   <include relativeToChangelogFile="true" file="parts/0006_asset_schemas.xml"/>
   <include relativeToChangelogFile="true" file="parts/0007_add_external_asset_owner_transfer_details.xml"/>
+  <include relativeToChangelogFile="true" file="parts/0008_add_mappings.xml"/>
 </databaseChangeLog>
diff --git a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0008_add_mappings.xml b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0008_add_mappings.xml
new file mode 100644
index 000000000..dac832f3e
--- /dev/null
+++ b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0008_add_mappings.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
+
+    <!-- Create table m_external_asset_owner_transfer_journal_entry_mapping -->
+    <changeSet author="fineract" id="1" context="mysql">
+        <createTable tableName="m_external_asset_owner_transfer_journal_entry_mapping">
+            <column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
+                <constraints nullable="false" primaryKey="true"/>
+            </column>
+            <column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
+                <constraints nullable="false"/>
+            </column>
+            <column name="owner_transfer_id" type="bigint" remarks="Owner transfer">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_by" type="bigint" remarks=""/>
+            <column name="created_on_utc" type="DATETIME" remarks=""/>
+            <column name="last_modified_by" type="bigint" remarks=""/>
+            <column name="last_modified_on_utc" type="DATETIME" remarks=""/>
+        </createTable>
+    </changeSet>
+
+    <changeSet author="fineract" id="1" context="postgresql">
+        <createTable tableName="m_external_asset_owner_transfer_journal_entry_mapping">
+            <column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
+                <constraints nullable="false" primaryKey="true"/>
+            </column>
+            <column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
+                <constraints nullable="false"/>
+            </column>
+            <column name="owner_transfer_id" type="bigint" remarks="Owner transfer">
+            </column>
+            <column name="created_by" type="bigint" remarks=""/>
+            <column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
+            <column name="last_modified_by" type="bigint" remarks=""/>
+            <column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
+        </createTable>
+    </changeSet>
+
+    <changeSet author="fineract" id="2">
+        <addForeignKeyConstraint baseColumnNames="created_by"
+                                 baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_transfer_je_mapping_created_by" deferrable="false"
+                                 initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="m_appuser" validate="true"/>
+        <addForeignKeyConstraint baseColumnNames="last_modified_by"
+                                 baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_transfer_je_mapping_modified_by" deferrable="false"
+                                 initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="m_appuser" validate="true"/>
+
+        <addForeignKeyConstraint baseColumnNames="journal_entry_id"
+                                 baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_transfer_je_mapping_journal_entry_id" deferrable="false"
+                                 initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="acc_gl_journal_entry" validate="true"/>
+        <addForeignKeyConstraint baseColumnNames="owner_transfer_id"
+                                 baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_transfer_je_mapping_owner_transfer_id"
+                                 deferrable="false" initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="m_external_asset_owner_transfer" validate="true"/>
+    </changeSet>
+
+    <!-- Create table m_external_asset_owner_journal_entry_mapping -->
+    <changeSet author="fineract" id="3" context="mysql">
+        <createTable tableName="m_external_asset_owner_journal_entry_mapping">
+            <column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
+                <constraints nullable="false" primaryKey="true"/>
+            </column>
+            <column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
+                <constraints nullable="false"/>
+            </column>
+            <column name="owner_id" type="bigint" remarks="Owner">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_by" type="bigint" remarks=""/>
+            <column name="created_on_utc" type="DATETIME" remarks=""/>
+            <column name="last_modified_by" type="bigint" remarks=""/>
+            <column name="last_modified_on_utc" type="DATETIME" remarks=""/>
+        </createTable>
+    </changeSet>
+
+    <changeSet author="fineract" id="3" context="postgresql">
+        <createTable tableName="m_external_asset_owner_journal_entry_mapping">
+            <column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
+                <constraints nullable="false" primaryKey="true"/>
+            </column>
+            <column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
+                <constraints nullable="false"/>
+            </column>
+            <column name="owner_id" type="bigint" remarks="Owner">
+            </column>
+            <column name="created_by" type="bigint" remarks=""/>
+            <column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
+            <column name="last_modified_by" type="bigint" remarks=""/>
+            <column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
+        </createTable>
+    </changeSet>
+
+    <changeSet author="fineract" id="4">
+        <addForeignKeyConstraint baseColumnNames="created_by"
+                                 baseTableName="m_external_asset_owner_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_je_mapping_created_by" deferrable="false"
+                                 initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="m_appuser" validate="true"/>
+        <addForeignKeyConstraint baseColumnNames="last_modified_by"
+                                 baseTableName="m_external_asset_owner_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_je_mapping_modified_by" deferrable="false"
+                                 initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="m_appuser" validate="true"/>
+
+        <addForeignKeyConstraint baseColumnNames="journal_entry_id"
+                                 baseTableName="m_external_asset_owner_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_je_mapping_journal_entry_id" deferrable="false"
+                                 initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="acc_gl_journal_entry" validate="true"/>
+        <addForeignKeyConstraint baseColumnNames="owner_id"
+                                 baseTableName="m_external_asset_owner_journal_entry_mapping"
+                                 constraintName="FK_ext_asset_owner_je_mapping_owner_id"
+                                 deferrable="false" initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
+                                 referencedTableName="m_external_asset_owner" validate="true"/>
+    </changeSet>
+    <!-- Add index to m_external_asset_owner_transfer_loan_mapping of loan_id -->
+    <changeSet id="5" author="fineract">
+        <createIndex tableName="m_external_asset_owner_transfer_loan_mapping"
+                     indexName="IND_m_ext_asset_owner_transfer_loan_mapping_loan_id">
+            <column name="loan_id"/>
+        </createIndex>
+    </changeSet>
+</databaseChangeLog>
diff --git a/fineract-investor/src/main/resources/jpa/investor/persistence.xml b/fineract-investor/src/main/resources/jpa/investor/persistence.xml
index f1c5a63c7..2b5752f6c 100644
--- a/fineract-investor/src/main/resources/jpa/investor/persistence.xml
+++ b/fineract-investor/src/main/resources/jpa/investor/persistence.xml
@@ -30,6 +30,7 @@
     <persistence-unit name="jpa-pu" transaction-type="RESOURCE_LOCAL">
         <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
         <class>org.apache.fineract.accounting.glaccount.domain.GLAccount</class>
+        <class>org.apache.fineract.accounting.journalentry.domain.JournalEntry</class>
         <class>org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom</class>
         <class>org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom</class>
         <class>org.apache.fineract.infrastructure.codes.domain.Code</class>
diff --git a/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java b/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
index a492ac953..171b0bbb5 100644
--- a/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
+++ b/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
@@ -44,6 +44,7 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMapping;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
+import org.apache.fineract.investor.service.AccountingService;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
 import org.junit.jupiter.api.BeforeEach;
@@ -65,6 +66,8 @@ public class LoanAccountOwnerTransferBusinessStepTest {
     private ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
     @Mock
     private ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
+    @Mock
+    private AccountingService accountingService;
     private LoanAccountOwnerTransferBusinessStep underTest;
 
     @BeforeEach
@@ -73,7 +76,7 @@ public class LoanAccountOwnerTransferBusinessStepTest {
         ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
         ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, actualDate)));
         underTest = new LoanAccountOwnerTransferBusinessStep(externalAssetOwnerTransferRepository,
-                externalAssetOwnerTransferLoanMappingRepository);
+                externalAssetOwnerTransferLoanMappingRepository, accountingService);
     }
 
     @Test
diff --git a/fineract-loan/dependencies.gradle b/fineract-loan/dependencies.gradle
index e0b745e3e..d76999691 100644
--- a/fineract-loan/dependencies.gradle
+++ b/fineract-loan/dependencies.gradle
@@ -48,6 +48,7 @@ dependencies {
             'org.mapstruct:mapstruct',
 
             'io.github.resilience4j:resilience4j-spring-boot2',
+            'org.apache.httpcomponents:httpcore',
             )
     compileOnly 'org.projectlombok:lombok'
     annotationProcessor 'org.projectlombok:lombok'
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingInvalidException.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingInvalidException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingInvalidException.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingInvalidException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingNotFoundException.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingNotFoundException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingNotFoundException.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/exception/ProductToGLAccountMappingNotFoundException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/serialization/ProductToGLAccountMappingFromApiJsonDeserializer.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/LoanProductToGLAccountMappingHelper.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/LoanProductToGLAccountMappingHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/LoanProductToGLAccountMappingHelper.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/LoanProductToGLAccountMappingHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/SavingsProductToGLAccountMappingHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java b/fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java
rename to fineract-loan/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ShareProductToGLAccountMappingHelper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/exceptions/LoanAccountLockCannotBeOverruledException.java b/fineract-loan/src/main/java/org/apache/fineract/cob/exceptions/LoanAccountLockCannotBeOverruledException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/cob/exceptions/LoanAccountLockCannotBeOverruledException.java
rename to fineract-loan/src/main/java/org/apache/fineract/cob/exceptions/LoanAccountLockCannotBeOverruledException.java
diff --git a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandlerRegister.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandlerRegister.java
new file mode 100644
index 000000000..e0d91e64c
--- /dev/null
+++ b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandlerRegister.java
@@ -0,0 +1,41 @@
+/**
+ * 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.core.exception;
+
+import jakarta.annotation.PostConstruct;
+import org.apache.fineract.batch.exception.ErrorHandler;
+import org.apache.fineract.batch.exception.ErrorInfo;
+import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformDomainRuleExceptionMapper;
+import org.apache.fineract.infrastructure.jobs.exception.LoanIdsHardLockedException;
+import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException;
+import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException;
+import org.apache.http.HttpStatus;
+
+public class ErrorHandlerRegister {
+
+    @PostConstruct
+    public void init() {
+        ErrorHandler.registerNewErrorHandler(LoanIdsHardLockedException.class, runtimeException -> new ErrorInfo(HttpStatus.SC_CONFLICT,
+                4090,
+                ApiGlobalErrorResponse.loanIsLocked(((LoanIdsHardLockedException) runtimeException).getLoanIdFromRequest()).toJson()));
+        ErrorHandler.registerNewErrorHandler(LinkedAccountRequiredException.class, new PlatformDomainRuleExceptionMapper(), 3002);
+        ErrorHandler.registerNewErrorHandler(MultiDisbursementDataRequiredException.class, new PlatformDomainRuleExceptionMapper(), 3003);
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
rename to fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/journalentry/LoanJournalEntryCreatedBusinessEvent.java
similarity index 59%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java
rename to fineract-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/journalentry/LoanJournalEntryCreatedBusinessEvent.java
index 741a92664..f21a70979 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/AbstractBusinessEvent.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/journalentry/LoanJournalEntryCreatedBusinessEvent.java
@@ -16,17 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.infrastructure.event.business.domain;
+package org.apache.fineract.infrastructure.event.business.domain.journalentry;
 
-import lombok.RequiredArgsConstructor;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
+import org.apache.fineract.infrastructure.event.business.domain.NoExternalEvent;
 
-@RequiredArgsConstructor
-public abstract class AbstractBusinessEvent<T> implements BusinessEvent<T> {
+public class LoanJournalEntryCreatedBusinessEvent extends JournalEntryBusinessEvent implements NoExternalEvent {
 
-    private final T value;
+    private static final String TYPE = "JournalEntryCreatedBusinessEvent";
+
+    public LoanJournalEntryCreatedBusinessEvent(JournalEntry value) {
+        super(value);
+    }
+
+    @Override
+    public String getType() {
+        return TYPE;
+    }
 
     @Override
-    public T get() {
-        return value;
+    public Long getAggregateRootId() {
+        return get().getLoanTransactionId();
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/LoanIdsHardLockedException.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/jobs/exception/LoanIdsHardLockedException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/LoanIdsHardLockedException.java
rename to fineract-loan/src/main/java/org/apache/fineract/infrastructure/jobs/exception/LoanIdsHardLockedException.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanScheduleDelinquencyData.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanScheduleDelinquencyData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanScheduleDelinquencyData.java
rename to fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanScheduleDelinquencyData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/UnpaidChargeData.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/UnpaidChargeData.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/UnpaidChargeData.java
rename to fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/UnpaidChargeData.java
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionRepository.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionRepository.java
similarity index 87%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionRepository.java
rename to fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionRepository.java
index 5b77f107d..9a48625b3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionRepository.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionRepository.java
@@ -33,6 +33,7 @@ import org.springframework.data.repository.query.Param;
 public interface LoanTransactionRepository extends JpaRepository<LoanTransaction, Long>, JpaSpecificationExecutor<LoanTransaction> {
 
     String FIND_ID_BY_EXTERNAL_ID = "SELECT lt.id FROM LoanTransaction lt WHERE lt.externalId = :externalId";
+    String FIND_LOAN_ID_BY_ID = "SELECT lt.loan.id FROM LoanTransaction lt WHERE lt.id = :id";
 
     Optional<LoanTransaction> findByIdAndLoanId(Long transactionId, Long loanId);
 
@@ -48,7 +49,8 @@ public interface LoanTransactionRepository extends JpaRepository<LoanTransaction
             lt.loan.loanProduct.delinquencyBucket is not null
             GROUP BY lt.loan
             """)
-    Collection<LoanScheduleDelinquencyData> fetchLoanTransactionsByTypeAndLessOrEqualDate(Integer transactionType, LocalDate businessDate);
+    Collection<LoanScheduleDelinquencyData> fetchLoanTransactionsByTypeAndLessOrEqualDate(@Param("transactionType") Integer transactionType,
+            @Param("businessDate") LocalDate businessDate);
 
     @Query(FIND_ID_BY_EXTERNAL_ID)
     Long findIdByExternalId(@Param("externalId") ExternalId externalId);
@@ -64,5 +66,8 @@ public interface LoanTransactionRepository extends JpaRepository<LoanTransaction
                     AND lc.amountOutstanding > 0
                     GROUP BY lc.charge.id, lc.charge.name
             """)
-    List<UnpaidChargeData> fetchTotalUnpaidChargesForLoan(Loan loan);
+    List<UnpaidChargeData> fetchTotalUnpaidChargesForLoan(@Param("loan") Loan loan);
+
+    @Query(FIND_LOAN_ID_BY_ID)
+    Optional<Long> findLoanIdById(@Param("id") Long id);
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/exception/LinkedAccountRequiredException.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/exception/LinkedAccountRequiredException.java
similarity index 100%
rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/exception/LinkedAccountRequiredException.java
rename to fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/exception/LinkedAccountRequiredException.java
diff --git a/fineract-loan/src/main/resources/jpa/loan/persistence.xml b/fineract-loan/src/main/resources/jpa/loan/persistence.xml
index b3d099766..49d7498ea 100644
--- a/fineract-loan/src/main/resources/jpa/loan/persistence.xml
+++ b/fineract-loan/src/main/resources/jpa/loan/persistence.xml
@@ -31,6 +31,7 @@
         <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
         <!-- Fineract core module -->
         <class>org.apache.fineract.accounting.glaccount.domain.GLAccount</class>
+        <class>org.apache.fineract.accounting.journalentry.domain.JournalEntry</class>
         <class>org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom</class>
         <class>org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom</class>
         <class>org.apache.fineract.infrastructure.codes.domain.Code</class>
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepositoryCustom.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepositoryCustom.java
deleted file mode 100755
index dccad7b90..000000000
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepositoryCustom.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * 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.accounting.journalentry.domain;
-
-import java.util.List;
-
-public interface JournalEntryRepositoryCustom {
-
-    List<JournalEntry> findFirstJournalEntryForAccount(long glAccountId);
-}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepositoryImpl.java
deleted file mode 100755
index bff5f993d..000000000
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepositoryImpl.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * 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.accounting.journalentry.domain;
-
-import jakarta.persistence.EntityManager;
-import jakarta.persistence.PersistenceContext;
-import java.util.List;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public class JournalEntryRepositoryImpl implements JournalEntryRepositoryCustom {
-
-    @PersistenceContext
-    private EntityManager entityManager;
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public List<JournalEntry> findFirstJournalEntryForAccount(final long glAccountId) {
-        return (List<JournalEntry>) this.entityManager
-                .createQuery("SELECT journalEntry FROM JournalEntry journalEntry where journalEntry.glAccount.id= :glAccountId")
-                .setParameter("glAccountId", glAccountId).setFirstResult(0).setMaxResults(1).getResultList();
-    }
-}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
index fec88b4f4..2aa882c6f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
@@ -59,6 +59,8 @@ import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGL
 import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.event.business.domain.journalentry.LoanJournalEntryCreatedBusinessEvent;
+import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
 import org.apache.fineract.organisation.office.domain.Office;
 import org.apache.fineract.organisation.office.domain.OfficeRepository;
 import org.apache.fineract.portfolio.account.PortfolioAccountType;
@@ -70,7 +72,6 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
-import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionEnumData;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository;
@@ -99,6 +100,7 @@ public class AccountingProcessorHelper {
     private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
     private final AccountTransfersReadPlatformService accountTransfersReadPlatformService;
     private final ChargeRepositoryWrapper chargeRepositoryWrapper;
+    private final BusinessEventNotifierService businessEventNotifierService;
 
     public LoanDTO populateLoanDtoFromMap(final Map<String, Object> accountingBridgeData, final boolean cashBasedAccountingEnabled,
             final boolean upfrontAccrualBasedAccountingEnabled, final boolean periodicAccrualBasedAccountingEnabled) {
@@ -807,148 +809,105 @@ public class AccountingProcessorHelper {
     private void createCreditJournalEntryForClientPayments(final Office office, final String currencyCode, final GLAccount account,
             final Long clientId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        final PaymentDetail paymentDetail = null;
-        final Long shareTransactionId = null;
-
-        ClientTransaction clientTransaction = getClientTransactionById(transactionId);
 
         String modifiedTransactionId = CLIENT_TRANSACTION_IDENTIFIER + transactionId;
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.CLIENT.getValue(), clientId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.CLIENT.getValue(), clientId, null, null, null,
+                transactionId, null);
+        persistJournalEntry(journalEntry);
     }
 
     private void createCreditJournalEntryForSavings(final Office office, final String currencyCode, final GLAccount account,
             final Long savingsId, final String transactionId, final LocalDate transactionDate, final BigDecimal amount)
             throws DataAccessException {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
-        final Long shareTransactionId = null;
-        final PaymentDetail paymentDetail = null;
+        Long savingsAccountTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
-            long id = Long.parseLong(transactionId);
-            savingsAccountTransaction = getSavingsTransactionById(id);
+            savingsAccountTransactionId = Long.parseLong(transactionId);
             modifiedTransactionId = SAVINGS_TRANSACTION_IDENTIFIER + transactionId;
         }
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId,
-                null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId, null, null,
+                savingsAccountTransactionId, null, null);
 
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        persistJournalEntry(journalEntry);
     }
 
     private void createCreditJournalEntryForLoan(final Office office, final String currencyCode, final GLAccount account, final Long loanId,
             final String transactionId, final LocalDate transactionDate, final BigDecimal amount) {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
-        final PaymentDetail paymentDetail = null;
-        final Long shareTransactionId = null;
+        Long loanTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
-            long id = Long.parseLong(transactionId);
-            loanTransaction = getLoanTransactionById(id);
+            loanTransactionId = Long.parseLong(transactionId);
             modifiedTransactionId = LOAN_TRANSACTION_IDENTIFIER + transactionId;
         }
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null,
+                loanTransactionId, null, null, null);
+        persistJournalEntry(journalEntry);
     }
 
     public void createProvisioningDebitJournalEntry(LocalDate transactionDate, Long provisioningEntryId, Office office, String currencyCode,
             GLAccount account, BigDecimal amount) {
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
-        PaymentDetail paymentDetail = null;
-        final Long shareTransactionId = null;
         final boolean manualEntry = false;
         String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + provisioningEntryId;
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.PROVISIONING.getValue(),
-                provisioningEntryId, null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.PROVISIONING.getValue(), provisioningEntryId,
+                null, null, null, null, null);
+        persistJournalEntry(journalEntry);
     }
 
     public void createProvisioningCreditJournalEntry(LocalDate transactionDate, Long provisioningEntryId, Office office,
             String currencyCode, GLAccount account, BigDecimal amount) {
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
-        PaymentDetail paymentDetail = null;
-        final Long shareTransactionId = null;
         final boolean manualEntry = false;
         String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + provisioningEntryId;
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.PROVISIONING.getValue(),
-                provisioningEntryId, null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.PROVISIONING.getValue(), provisioningEntryId,
+                null, null, null, null, null);
+        persistJournalEntry(journalEntry);
     }
 
     private void createDebitJournalEntryForLoan(final Office office, final String currencyCode, final GLAccount account, final Long loanId,
             final String transactionId, final LocalDate transactionDate, final BigDecimal amount) {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
-        final PaymentDetail paymentDetail = null;
-        final Long shareTransactionId = null;
+        Long loanTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
-            long id = Long.parseLong(transactionId);
-            loanTransaction = getLoanTransactionById(id);
+            loanTransactionId = Long.parseLong(transactionId);
             modifiedTransactionId = LOAN_TRANSACTION_IDENTIFIER + transactionId;
         }
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null,
+                loanTransactionId, null, null, null);
+        persistJournalEntry(journalEntry);
     }
 
     private void createDebitJournalEntryForSavings(final Office office, final String currencyCode, final GLAccount account,
             final Long savingsId, final String transactionId, final LocalDate transactionDate, final BigDecimal amount) {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
-        final PaymentDetail paymentDetail = null;
-        final Long shareTransactionId = null;
+        Long savingsAccountTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
-            long id = Long.parseLong(transactionId);
-            savingsAccountTransaction = getSavingsTransactionById(id);
+            savingsAccountTransactionId = Long.parseLong(transactionId);
             modifiedTransactionId = SAVINGS_TRANSACTION_IDENTIFIER + transactionId;
         }
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId, null, null,
+                savingsAccountTransactionId, null, null);
 
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        persistJournalEntry(journalEntry);
     }
 
     private void createDebitJournalEntryForClientPayments(final Office office, final String currencyCode, final GLAccount account,
             final Long clientId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        final PaymentDetail paymentDetail = null;
-        final Long shareTransactionId = null;
-
-        ClientTransaction clientTransaction = getClientTransactionById(transactionId);
         String modifiedTransactionId = CLIENT_TRANSACTION_IDENTIFIER + transactionId;
-
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.CLIENT.getValue(), clientId, null,
-                loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.CLIENT.getValue(), clientId, null, null, null,
+                transactionId, null);
+        persistJournalEntry(journalEntry);
     }
 
     public void createJournalEntriesForShares(final Office office, final String currencyCode, final int accountTypeToDebitId,
@@ -1052,39 +1011,31 @@ public class AccountingProcessorHelper {
     private void createDebitJournalEntryForShares(final Office office, final String currencyCode, final GLAccount account,
             final Long shareAccountId, final String transactionId, final LocalDate transactionDate, final BigDecimal amount) {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
-        final PaymentDetail paymentDetail = null;
         Long shareTransactionId = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
             shareTransactionId = Long.parseLong(transactionId);
             modifiedTransactionId = SHARE_TRANSACTION_IDENTIFIER + transactionId;
         }
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.SHARES.getValue(), shareAccountId,
-                null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.SHARES.getValue(), shareAccountId, null, null,
+                null, null, shareTransactionId);
+        persistJournalEntry(journalEntry);
     }
 
     private void createCreditJournalEntryForShares(final Office office, final String currencyCode, final GLAccount account,
             final Long shareAccountId, final String transactionId, final LocalDate transactionDate, final BigDecimal amount) {
         final boolean manualEntry = false;
-        LoanTransaction loanTransaction = null;
-        SavingsAccountTransaction savingsAccountTransaction = null;
-        ClientTransaction clientTransaction = null;
         Long shareTransactionId = null;
-        final PaymentDetail paymentDetail = null;
         String modifiedTransactionId = transactionId;
         if (StringUtils.isNumeric(transactionId)) {
             shareTransactionId = Long.parseLong(transactionId);
             modifiedTransactionId = SHARE_TRANSACTION_IDENTIFIER + transactionId;
         }
-        final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
-                manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.SHARES.getValue(), shareAccountId,
-                null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
-        this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
+                transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.SHARES.getValue(), shareAccountId, null, null,
+                null, null, shareTransactionId);
+        persistJournalEntry(journalEntry);
     }
 
     public GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId, final Long paymentTypeId) {
@@ -1316,4 +1267,13 @@ public class AccountingProcessorHelper {
         return incomeAccount;
     }
 
+    public JournalEntry persistJournalEntry(JournalEntry journalEntry) {
+        boolean isNew = journalEntry.isNew();
+        JournalEntry savedJournalEntry = this.glJournalEntryRepository.saveAndFlush(journalEntry);
+        if (isNew && journalEntry.getLoanTransactionId() != null) {
+            businessEventNotifierService.notifyPostBusinessEvent(new LoanJournalEntryCreatedBusinessEvent(savedJournalEntry));
+        }
+        return savedJournalEntry;
+    }
+
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
index 81427dde3..97d09dcbf 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
@@ -75,7 +75,6 @@ import org.apache.fineract.infrastructure.security.service.PlatformSecurityConte
 import org.apache.fineract.organisation.office.domain.Office;
 import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
 import org.apache.fineract.organisation.office.domain.OrganisationCurrencyRepositoryWrapper;
-import org.apache.fineract.portfolio.client.domain.ClientTransaction;
 import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
 import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
 import org.apache.fineract.useradministration.domain.AppUser;
@@ -332,24 +331,24 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
                         + journalEntry.getTransactionId();
             }
             if (journalEntry.isDebitEntry()) {
-                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetails(),
+                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetail(),
                         journalEntry.getGlAccount(), journalEntry.getCurrencyCode(), reversalTransactionId, manualEntry,
                         journalEntry.getTransactionDate(), JournalEntryType.CREDIT, journalEntry.getAmount(), reversalComment, null, null,
-                        journalEntry.getReferenceNumber(), journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(),
-                        journalEntry.getClientTransaction(), journalEntry.getShareTransactionId());
+                        journalEntry.getReferenceNumber(), journalEntry.getLoanTransactionId(), journalEntry.getSavingsTransactionId(),
+                        journalEntry.getClientTransactionId(), journalEntry.getShareTransactionId());
             } else {
-                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetails(),
+                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetail(),
                         journalEntry.getGlAccount(), journalEntry.getCurrencyCode(), reversalTransactionId, manualEntry,
                         journalEntry.getTransactionDate(), JournalEntryType.DEBIT, journalEntry.getAmount(), reversalComment, null, null,
-                        journalEntry.getReferenceNumber(), journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(),
-                        journalEntry.getClientTransaction(), journalEntry.getShareTransactionId());
+                        journalEntry.getReferenceNumber(), journalEntry.getLoanTransactionId(), journalEntry.getSavingsTransactionId(),
+                        journalEntry.getClientTransactionId(), journalEntry.getShareTransactionId());
             }
             // save the reversal entry
-            this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry);
+            helper.persistJournalEntry(reversalJournalEntry);
             journalEntry.setReversed(true);
             journalEntry.setReversalJournalEntry(reversalJournalEntry);
             // save the updated journal entry
-            this.glJournalEntryRepository.saveAndFlush(journalEntry);
+            helper.persistJournalEntry(journalEntry);
         }
         return reversalTransactionId;
     }
@@ -363,26 +362,26 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
             String reversalComment = "Reversal entry for Journal Entry with Entry Id  :" + journalEntry.getId() + " and transaction Id "
                     + journalEntry.getTransactionId();
             if (journalEntry.isDebitEntry()) {
-                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetails(),
+                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetail(),
                         journalEntry.getGlAccount(), journalEntry.getCurrencyCode(), journalEntry.getTransactionId(), Boolean.FALSE,
                         reversalTransactionDate, JournalEntryType.CREDIT, journalEntry.getAmount(), reversalComment,
                         journalEntry.getEntityType(), journalEntry.getEntityId(), journalEntry.getReferenceNumber(),
-                        journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction(),
+                        journalEntry.getLoanTransactionId(), journalEntry.getSavingsTransactionId(), journalEntry.getClientTransactionId(),
                         journalEntry.getShareTransactionId());
             } else {
-                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetails(),
+                reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetail(),
                         journalEntry.getGlAccount(), journalEntry.getCurrencyCode(), journalEntry.getTransactionId(), Boolean.FALSE,
                         reversalTransactionDate, JournalEntryType.DEBIT, journalEntry.getAmount(), reversalComment,
                         journalEntry.getEntityType(), journalEntry.getEntityId(), journalEntry.getReferenceNumber(),
-                        journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction(),
+                        journalEntry.getLoanTransactionId(), journalEntry.getSavingsTransactionId(), journalEntry.getClientTransactionId(),
                         journalEntry.getShareTransactionId());
             }
             // save the reversal entry
-            this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry);
+            helper.persistJournalEntry(reversalJournalEntry);
             journalEntry.setReversalJournalEntry(reversalJournalEntry);
             journalEntry.setReversed(true);
             // save the updated journal entry
-            this.glJournalEntryRepository.saveAndFlush(journalEntry);
+            helper.persistJournalEntry(journalEntry);
         }
         return reversalTransactionId;
 
@@ -531,26 +530,26 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
                 String reversalComment = "Reversal entry for Journal Entry with id  :" + journalEntry.getId() + " and transaction Id "
                         + journalEntry.getTransactionId();
                 if (journalEntry.isDebitEntry()) {
-                    reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetails(),
+                    reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetail(),
                             journalEntry.getGlAccount(), journalEntry.getCurrencyCode(), reversalTransactionId, Boolean.FALSE,
                             transactionDate, JournalEntryType.CREDIT, journalEntry.getAmount(), reversalComment,
                             journalEntry.getEntityType(), journalEntry.getEntityId(), journalEntry.getReferenceNumber(),
-                            journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction(),
-                            journalEntry.getShareTransactionId());
+                            journalEntry.getLoanTransactionId(), journalEntry.getSavingsTransactionId(),
+                            journalEntry.getClientTransactionId(), journalEntry.getShareTransactionId());
                 } else {
-                    reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetails(),
+                    reversalJournalEntry = JournalEntry.createNew(journalEntry.getOffice(), journalEntry.getPaymentDetail(),
                             journalEntry.getGlAccount(), journalEntry.getCurrencyCode(), reversalTransactionId, Boolean.FALSE,
                             transactionDate, JournalEntryType.DEBIT, journalEntry.getAmount(), reversalComment,
                             journalEntry.getEntityType(), journalEntry.getEntityId(), journalEntry.getReferenceNumber(),
-                            journalEntry.getLoanTransaction(), journalEntry.getSavingsTransaction(), journalEntry.getClientTransaction(),
-                            journalEntry.getShareTransactionId());
+                            journalEntry.getLoanTransactionId(), journalEntry.getSavingsTransactionId(),
+                            journalEntry.getClientTransactionId(), journalEntry.getShareTransactionId());
                 }
                 // save the reversal entry
-                this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry);
+                helper.persistJournalEntry(reversalJournalEntry);
                 journalEntry.setReversalJournalEntry(reversalJournalEntry);
                 journalEntry.setReversed(true);
                 // save the updated journal entry
-                this.glJournalEntryRepository.saveAndFlush(journalEntry);
+                helper.persistJournalEntry(journalEntry);
             }
         }
     }
@@ -604,12 +603,10 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
             /** Validate current code is appropriate **/
             this.organisationCurrencyRepository.findOneWithNotFoundDetection(currencyCode);
 
-            final ClientTransaction clientTransaction = null;
-            final Long shareTransactionId = null;
             final JournalEntry glJournalEntry = JournalEntry.createNew(office, paymentDetail, glAccount, currencyCode, transactionId,
                     manualEntry, transactionDate, type, singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, referenceNumber,
-                    null, null, clientTransaction, shareTransactionId);
-            this.glJournalEntryRepository.saveAndFlush(glJournalEntry);
+                    null, null, null, null);
+            helper.persistJournalEntry(glJournalEntry);
         }
     }
 
@@ -716,17 +713,14 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
                 comments = singleDebitOrCreditEntryCommand.getComments();
             }
 
-            final ClientTransaction clientTransaction = null;
-            final Long shareTransactionId = null;
             final JournalEntry glJournalEntry = JournalEntry.createNew(office, null, glAccount, currencyCode, transactionId, manualEntry,
-                    transactionDate, type, singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, null, null, null,
-                    clientTransaction, shareTransactionId);
-            this.glJournalEntryRepository.saveAndFlush(glJournalEntry);
+                    transactionDate, type, singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, null, null, null, null, null);
+            helper.persistJournalEntry(glJournalEntry);
 
             final JournalEntry contraEntry = JournalEntry.createNew(office, null, contraAccount, currencyCode, transactionId, manualEntry,
-                    transactionDate, contraType, singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, null, null, null,
-                    clientTransaction, shareTransactionId);
-            this.glJournalEntryRepository.saveAndFlush(contraEntry);
+                    transactionDate, contraType, singleDebitOrCreditEntryCommand.getAmount(), comments, null, null, null, null, null, null,
+                    null);
+            helper.persistJournalEntry(contraEntry);
         }
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java b/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java
deleted file mode 100644
index d5e5d7ba4..000000000
--- a/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * 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.batch.exception;
-
-import com.google.gson.Gson;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.ExceptionMapper;
-import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
-import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
-import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
-import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
-import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
-import org.apache.fineract.infrastructure.core.exception.PlatformInternalServerException;
-import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
-import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformApiDataValidationExceptionMapper;
-import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformDataIntegrityExceptionMapper;
-import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformDomainRuleExceptionMapper;
-import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformInternalServerExceptionMapper;
-import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformResourceNotFoundExceptionMapper;
-import org.apache.fineract.infrastructure.core.exceptionmapper.UnsupportedParameterExceptionMapper;
-import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
-import org.apache.fineract.infrastructure.jobs.exception.LoanIdsHardLockedException;
-import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException;
-import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException;
-import org.apache.http.HttpStatus;
-import org.springframework.dao.NonTransientDataAccessException;
-import org.springframework.transaction.TransactionException;
-
-/**
- * Provides an Error Handler method that returns an object of type {@link ErrorInfo} to the CommandStrategy which raised
- * the exception. This class uses various subclasses of RuntimeException to check the kind of exception raised and
- * provide appropriate status and error codes for each one of the raised exception.
- *
- * @author Rishabh Shukla
- *
- * @see org.apache.fineract.batch.command.CommandStrategy
- * @see org.apache.fineract.batch.command.internal.CreateClientCommandStrategy
- */
-public class ErrorHandler extends RuntimeException {
-
-    private static Gson jsonHelper = GoogleGsonSerializerHelper.createGsonBuilder(true).create();
-
-    /**
-     * Sole Constructor
-     */
-    ErrorHandler() {
-
-    }
-
-    private static <E extends Exception, M extends ExceptionMapper<E>> ErrorInfo handleException(final E exception, final M mapper,
-            final int errorCode) {
-        final Response response = mapper.toResponse(exception);
-        final String errorBody = jsonHelper.toJson(response.getEntity());
-        return new ErrorInfo(response.getStatus(), errorCode, errorBody);
-    }
-
-    /**
-     * Returns an object of ErrorInfo type containing the information regarding the raised error.
-     *
-     * @param exception
-     * @return ErrorInfo
-     */
-    public static ErrorInfo handler(final RuntimeException exception) {
-        if (exception instanceof AbstractPlatformResourceNotFoundException e) {
-            return handleException(e, new PlatformResourceNotFoundExceptionMapper(), 1001);
-        }
-        if (exception instanceof UnsupportedParameterException e) {
-            return handleException(e, new UnsupportedParameterExceptionMapper(), 2001);
-        }
-        if (exception instanceof PlatformApiDataValidationException e) {
-            return handleException(e, new PlatformApiDataValidationExceptionMapper(), 2002);
-        }
-        if (exception instanceof PlatformDataIntegrityException e) {
-            return handleException(e, new PlatformDataIntegrityExceptionMapper(), 3001);
-        }
-        if (exception instanceof LinkedAccountRequiredException e) {
-            return handleException(e, new PlatformDomainRuleExceptionMapper(), 3002);
-        }
-        if (exception instanceof MultiDisbursementDataRequiredException e) {
-            return handleException(e, new PlatformDomainRuleExceptionMapper(), 3003);
-        }
-        if (exception instanceof AbstractPlatformDomainRuleException e) {
-            return handleException(e, new PlatformDomainRuleExceptionMapper(), 9999);
-        }
-        if (exception instanceof TransactionException) {
-            return new ErrorInfo(HttpStatus.SC_BAD_REQUEST, 4001, "{\"Exception\": %s}".formatted(exception.getMessage()));
-        }
-        if (exception instanceof PlatformInternalServerException e) {
-            return handleException(e, new PlatformInternalServerExceptionMapper(), 5001);
-        }
-        if (exception instanceof NonTransientDataAccessException) {
-            return new ErrorInfo(HttpStatus.SC_BAD_REQUEST, 4002, "{\"Exception\": %s}".formatted(exception.getMessage()));
-        }
-        if (exception instanceof LoanIdsHardLockedException e) {
-            String message = ApiGlobalErrorResponse.loanIsLocked(e.getLoanIdFromRequest()).toJson();
-            return new ErrorInfo(HttpStatus.SC_CONFLICT, 4090, message);
-        }
-
-        return new ErrorInfo(500, 9999, "{\"Exception\": %s}".formatted(exception.getMessage()));
-    }
-}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
index dc2631687..4a3068019 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
@@ -52,7 +52,6 @@ import org.apache.fineract.organisation.teller.domain.TellerRepositoryWrapper;
 import org.apache.fineract.organisation.teller.exception.CashierExistForTellerException;
 import org.apache.fineract.organisation.teller.exception.CashierNotFoundException;
 import org.apache.fineract.organisation.teller.serialization.TellerCommandFromApiJsonDeserializer;
-import org.apache.fineract.portfolio.client.domain.ClientTransaction;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -410,8 +409,6 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
             final Long time = System.currentTimeMillis();
             final String uniqueVal = String.valueOf(time) + currentUser.getId() + cashierOffice.getId();
             final String transactionId = Long.toHexString(Long.parseLong(uniqueVal));
-            ClientTransaction clientTransaction = null;
-            final Long shareTransactionId = null;
 
             final JournalEntry debitJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
                                                                                                // detail
@@ -420,10 +417,10 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
                     transactionId, false, // manual entry
                     cashierTxn.getTxnDate(), JournalEntryType.DEBIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
                     null, null, null, // entity Type, entityId, reference number
-                    null, null, clientTransaction, shareTransactionId); // Loan
-                                                                        // and
-                                                                        // Savings
-                                                                        // Txn
+                    null, null, null, null); // Loan
+                                             // and
+                                             // Savings
+                                             // Txn
 
             final JournalEntry creditJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
                                                                                                 // detail
@@ -432,10 +429,10 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
                     transactionId, false, // manual entry
                     cashierTxn.getTxnDate(), JournalEntryType.CREDIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
                     null, null, null, // entity Type, entityId, reference number
-                    null, null, clientTransaction, shareTransactionId); // Loan
-                                                                        // and
-                                                                        // Savings
-                                                                        // Txn
+                    null, null, null, null); // Loan
+                                             // and
+                                             // Savings
+                                             // Txn
 
             this.glJournalEntryRepository.saveAndFlush(debitJournalEntry);
             this.glJournalEntryRepository.saveAndFlush(creditJournalEntry);
diff --git a/fineract-provider/src/main/resources/application.properties b/fineract-provider/src/main/resources/application.properties
index d69d2f7f3..fd3832da3 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -124,7 +124,7 @@ fineract.sampling.samplingRate=${FINERACT_SAMPLING_RATE:1000}
 fineract.sampling.sampledClasses=${FINERACT_SAMPLED_CLASSES:}
 fineract.sampling.resetPeriodSec=${FINERACT_SAMPLING_RESET_PERIOD_IN_SEC:60}
 
-fineract.module.external-asset-owner.enabled=${FINERACT_MODULE_EXTERNAL_ASSET_OWNER_ENABLED:true}
+fineract.module.investor.enabled=${FINERACT_MODULE_INVESTOR_ENABLED:true}
 
 # Logging pattern for the console
 logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
diff --git a/fineract-provider/src/main/resources/jpa/persistence.xml b/fineract-provider/src/main/resources/jpa/persistence.xml
index c4119fd3a..f901e617d 100644
--- a/fineract-provider/src/main/resources/jpa/persistence.xml
+++ b/fineract-provider/src/main/resources/jpa/persistence.xml
@@ -31,6 +31,7 @@
         <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
         <!-- Fineract core module -->
         <class>org.apache.fineract.accounting.glaccount.domain.GLAccount</class>
+        <class>org.apache.fineract.accounting.journalentry.domain.JournalEntry</class>
         <class>org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom</class>
         <class>org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom</class>
         <class>org.apache.fineract.infrastructure.codes.domain.Code</class>
@@ -72,6 +73,8 @@
         <class>org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer</class>
         <class>org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMapping</class>
         <class>org.apache.fineract.investor.domain.ExternalAssetOwnerTransferDetails</class>
+        <class>org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping</class>
+        <class>org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping</class>
         <!-- Fineract loan module -->
         <class>org.apache.fineract.portfolio.collateral.domain.LoanCollateral</class>
         <class>org.apache.fineract.portfolio.collateralmanagement.domain.ClientCollateralManagement</class>
diff --git a/fineract-provider/src/test/resources/application-test.properties b/fineract-provider/src/test/resources/application-test.properties
index 3b6db8af2..f81768f7b 100644
--- a/fineract-provider/src/test/resources/application-test.properties
+++ b/fineract-provider/src/test/resources/application-test.properties
@@ -84,6 +84,8 @@ fineract.jpa.statementLoggingEnabled=${FINERACT_STATEMENT_LOGGING_ENABLED:false}
 fineract.sampling.enabled=false
 fineract.sampling.sampledClasses=
 
+fineract.module.investor.enabled=true
+
 management.health.jms.enabled=false
 
 # FINERACT 1296
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalAssetOwnerHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalAssetOwnerHelper.java
index d114e124f..0ce5a378b 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalAssetOwnerHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalAssetOwnerHelper.java
@@ -18,6 +18,9 @@
  */
 package org.apache.fineract.integrationtests.common;
 
+import org.apache.fineract.client.models.ExternalOwnerJournalEntryData;
+import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
+import org.apache.fineract.client.models.ExternalTransferData;
 import org.apache.fineract.client.models.PageExternalTransferData;
 import org.apache.fineract.client.models.PostInitiateTransferRequest;
 import org.apache.fineract.client.models.PostInitiateTransferResponse;
@@ -32,18 +35,39 @@ public class ExternalAssetOwnerHelper extends IntegrationTest {
     }
 
     public PageExternalTransferData retrieveTransferByTransferExternalId(String transferExternalId) {
-        return ok(fineract().externalAssetOwners.getTransfer1(transferExternalId, null, null, 0, 100));
+        return ok(fineract().externalAssetOwners.getTransfers(transferExternalId, null, null, 0, 100));
     }
 
     public PageExternalTransferData retrieveTransferByLoanExternalId(String loanExternalId) {
-        return ok(fineract().externalAssetOwners.getTransfer1(null, null, loanExternalId, 0, 100));
+        return ok(fineract().externalAssetOwners.getTransfers(null, null, loanExternalId, 0, 100));
     }
 
-    public PageExternalTransferData retrieveTransferByLoanId(Long loanId) {
-        return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, 0, 100));
+    public PageExternalTransferData retrieveTransfersByLoanId(Long loanId) {
+        return ok(fineract().externalAssetOwners.getTransfers(null, loanId, null, 0, 100));
     }
 
-    public PageExternalTransferData retrieveTransferByLoanId(Long loanId, int offset, int limit) {
-        return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, offset, limit));
+    public PageExternalTransferData retrieveTransfersByLoanId(Long loanId, int offset, int limit) {
+        return ok(fineract().externalAssetOwners.getTransfers(null, loanId, null, offset, limit));
     }
+
+    public ExternalTransferData retrieveActiveTransferByLoanExternalId(String loanExternalId) {
+        return ok(fineract().externalAssetOwners.getActiveTransfer(null, null, loanExternalId));
+    }
+
+    public ExternalTransferData retrieveActiveTransferByTransferExternalId(String transferExternalId) {
+        return ok(fineract().externalAssetOwners.getActiveTransfer(transferExternalId, null, null));
+    }
+
+    public ExternalTransferData retrieveActiveTransferByLoanId(Long loanId) {
+        return ok(fineract().externalAssetOwners.getActiveTransfer(null, loanId, null));
+    }
+
+    public ExternalOwnerTransferJournalEntryData retrieveJournalEntriesOfTransfer(Long transferId) {
+        return ok(fineract().externalAssetOwners.getJournalEntriesOfTransfer(transferId, 0, 100));
+    }
+
+    public ExternalOwnerJournalEntryData retrieveJournalEntriesOfOwner(String ownerExternalId) {
+        return ok(fineract().externalAssetOwners.getJournalEntriesOfOwner(ownerExternalId, 0, 100));
+    }
+
 }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/FinancialActivityAccountHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/FinancialActivityAccountHelper.java
index 36a18dd79..d47d93a30 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/FinancialActivityAccountHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/FinancialActivityAccountHelper.java
@@ -22,10 +22,15 @@ import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import java.util.HashMap;
 import java.util.List;
+import org.apache.fineract.client.models.DeleteFinancialActivityAccountsResponse;
+import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse;
+import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest;
+import org.apache.fineract.client.models.PostFinancialActivityAccountsResponse;
+import org.apache.fineract.integrationtests.client.IntegrationTest;
 import org.apache.fineract.integrationtests.common.Utils;
 
 @SuppressWarnings("rawtypes")
-public class FinancialActivityAccountHelper {
+public class FinancialActivityAccountHelper extends IntegrationTest {
 
     private static final String FINANCIAL_ACTIVITY_ACCOUNT_MAPPING_URL = "/fineract-provider/api/v1/financialactivityaccounts";
     private final RequestSpecification requestSpec;
@@ -65,4 +70,15 @@ public class FinancialActivityAccountHelper {
         return Utils.performServerDelete(this.requestSpec, responseSpecification, url, jsonBack);
     }
 
+    public PostFinancialActivityAccountsResponse createFinancialActivityAccount(PostFinancialActivityAccountsRequest request) {
+        return ok(fineract().financialActivyAccountMappings.createGLAccount(request));
+    }
+
+    public List<GetFinancialActivityAccountsResponse> getAllFinancialActivityAccounts() {
+        return ok(fineract().financialActivyAccountMappings.retrieveAll());
+    }
+
+    public DeleteFinancialActivityAccountsResponse deleteFinancialActivityAccount(Long financialMappingId) {
+        return ok(fineract().financialActivyAccountMappings.deleteGLAccount(financialMappingId));
+    }
 }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java
index 883c18f7b..1b4b8e8c2 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/investor/externalassetowner/InitiateExternalAssetOwnerTransferTest.java
@@ -23,7 +23,6 @@ import static org.apache.fineract.client.models.ExternalTransferData.StatusEnum.
 import static org.apache.fineract.client.models.ExternalTransferData.StatusEnum.CANCELLED;
 import static org.apache.fineract.client.models.ExternalTransferData.StatusEnum.PENDING;
 import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
-import static org.apache.fineract.integrationtests.investor.externalassetowner.InitiateExternalAssetOwnerTransferTest.ExpectedExternalTransferData.expected;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
@@ -38,6 +37,8 @@ import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -45,10 +46,17 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.UUID;
 import lombok.RequiredArgsConstructor;
+import org.apache.fineract.accounting.common.AccountingConstants;
+import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
+import org.apache.fineract.client.models.ExternalOwnerJournalEntryData;
+import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
 import org.apache.fineract.client.models.ExternalTransferData;
+import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse;
 import org.apache.fineract.client.models.PageExternalTransferData;
+import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest;
 import org.apache.fineract.client.models.PostInitiateTransferRequest;
 import org.apache.fineract.client.models.PostInitiateTransferResponse;
+import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
 import org.apache.fineract.client.util.CallFailedRuntimeException;
 import org.apache.fineract.integrationtests.common.BusinessDateHelper;
 import org.apache.fineract.integrationtests.common.BusinessStepHelper;
@@ -58,6 +66,9 @@ import org.apache.fineract.integrationtests.common.ExternalAssetOwnerHelper;
 import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
 import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
 import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.accounting.Account;
+import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
+import org.apache.fineract.integrationtests.common.accounting.FinancialActivityAccountHelper;
 import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
 import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
 import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
@@ -67,7 +78,6 @@ import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import org.jetbrains.annotations.NotNull;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 
@@ -75,30 +85,55 @@ import org.junit.jupiter.api.extension.ExtendWith;
 @ExtendWith(LoanTestLifecycleExtension.class)
 public class InitiateExternalAssetOwnerTransferTest {
 
-    private ResponseSpecification responseSpec;
-    private RequestSpecification requestSpec;
-    private ExternalAssetOwnerHelper externalAssetOwnerHelper;
-    private LoanTransactionHelper loanTransactionHelper;
-    private SchedulerJobHelper schedulerJobHelper;
-    private LocalDate todaysDate;
+    public String ownerExternalId;
+    private static ResponseSpecification RESPONSE_SPEC;
+    private static RequestSpecification REQUEST_SPEC;
+    private static Account ASSET_ACCOUNT;
+    private static Account FEE_PENALTY_ACCOUNT;
+    private static Account TRANSFER_ACCOUNT;
+    private static Account EXPENSE_ACCOUNT;
+    private static Account INCOME_ACCOUNT;
+    private static Account OVERPAYMENT_ACCOUNT;
+    private static FinancialActivityAccountHelper FINANCIAL_ACTIVITY_ACCOUNT_HELPER;
+    private static ExternalAssetOwnerHelper EXTERNAL_ASSET_OWNER_HELPER;
+    private static LoanTransactionHelper LOAN_TRANSACTION_HELPER;
+    private static SchedulerJobHelper SCHEDULER_JOB_HELPER;
+    private static LocalDate TODAYS_DATE;
+    private DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder().appendPattern("dd MMMM yyyy").toFormatter();
 
     @BeforeAll
     public static void setupInvestorBusinessStep() {
+        Utils.initializeRESTAssured();
+        REQUEST_SPEC = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+        REQUEST_SPEC.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+        RESPONSE_SPEC = new ResponseSpecBuilder().expectStatusCode(200).build();
+        AccountHelper accountHelper = new AccountHelper(REQUEST_SPEC, RESPONSE_SPEC);
+        EXTERNAL_ASSET_OWNER_HELPER = new ExternalAssetOwnerHelper();
+        SCHEDULER_JOB_HELPER = new SchedulerJobHelper(REQUEST_SPEC);
+        FINANCIAL_ACTIVITY_ACCOUNT_HELPER = new FinancialActivityAccountHelper(REQUEST_SPEC);
+        LOAN_TRANSACTION_HELPER = new LoanTransactionHelper(REQUEST_SPEC, RESPONSE_SPEC);
+
+        TODAYS_DATE = Utils.getLocalDateOfTenant();
         new BusinessStepHelper().updateSteps("LOAN_CLOSE_OF_BUSINESS", "APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION",
                 "CHECK_LOAN_REPAYMENT_DUE", "CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
                 "EXTERNAL_ASSET_OWNER_TRANSFER");
+
+        ASSET_ACCOUNT = accountHelper.createAssetAccount();
+        FEE_PENALTY_ACCOUNT = accountHelper.createAssetAccount();
+        TRANSFER_ACCOUNT = accountHelper.createAssetAccount();
+        EXPENSE_ACCOUNT = accountHelper.createExpenseAccount();
+        INCOME_ACCOUNT = accountHelper.createIncomeAccount();
+        OVERPAYMENT_ACCOUNT = accountHelper.createLiabilityAccount();
+
+        setProperFinancialActivity(TRANSFER_ACCOUNT);
     }
 
-    @BeforeEach
-    public void setup() {
-        Utils.initializeRESTAssured();
-        requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
-        requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
-        responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
-        externalAssetOwnerHelper = new ExternalAssetOwnerHelper();
-        loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
-        schedulerJobHelper = new SchedulerJobHelper(requestSpec);
-        todaysDate = Utils.getLocalDateOfTenant();
+    private static void setProperFinancialActivity(Account transferAccount) {
+        List<GetFinancialActivityAccountsResponse> financialMappings = FINANCIAL_ACTIVITY_ACCOUNT_HELPER.getAllFinancialActivityAccounts();
+        financialMappings.forEach(mapping -> FINANCIAL_ACTIVITY_ACCOUNT_HELPER.deleteFinancialActivityAccount(mapping.getId()));
+        FINANCIAL_ACTIVITY_ACCOUNT_HELPER.createFinancialActivityAccount(new PostFinancialActivityAccountsRequest()
+                .financialActivityId((long) AccountingConstants.FinancialActivity.ASSET_TRANSFER.getValue())
+                .glAccountId((long) transferAccount.getAccountID()));
     }
 
     @Test
@@ -111,29 +146,154 @@ public class InitiateExternalAssetOwnerTransferTest {
 
             String transferExternalId = createExternalAssetOwnerTransfer(loanID, "sale", "2020-03-02");
             getAndValidateExternalAssetOwnerTransferByLoan(loanID,
-                    expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "9999-12-31", false));
+                    ExpectedExternalTransferData.expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "9999-12-31", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")));
+            getAndValidateThereIsNoActiveMapping(transferExternalId);
+            PageExternalTransferData retrieveResponse = EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+            retrieveResponse.getContent().forEach(transfer -> getAndValidateThereIsNoJournalEntriesForTransfer(transfer.getTransferId()));
 
             updateBusinessDateAndExecuteCOBJob("2020-03-03");
             getAndValidateExternalAssetOwnerTransferByLoan(loanID,
-                    expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false),
-                    expected(ACTIVE, transferExternalId, "2020-03-02", "2020-03-03", "9999-12-31", true));
+                    ExpectedExternalTransferData.expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(ACTIVE, transferExternalId, "2020-03-02", "2020-03-03", "9999-12-31", true,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")));
+            getAndValidateThereIsActiveMapping(loanID);
+            retrieveResponse = EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+            LocalDate expectedDate = LocalDate.of(2020, 3, 2);
+            getAndValidateThereIsJournalEntriesForTransfer(retrieveResponse.getContent().get(1).getTransferId(),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(15757.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(10.000000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(15767.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(15757.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(10.000000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(15767.420000), expectedDate, expectedDate));
 
             String buybackTransferExternalId = createExternalAssetOwnerTransfer(loanID, "buyback", "2020-03-03");
             getAndValidateExternalAssetOwnerTransferByLoan(loanID,
-                    expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false),
-                    expected(ACTIVE, transferExternalId, "2020-03-02", "2020-03-03", "9999-12-31", true),
-                    expected(BUYBACK, buybackTransferExternalId, "2020-03-03", "2020-03-03", "9999-12-31", false));
+                    ExpectedExternalTransferData.expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(ACTIVE, transferExternalId, "2020-03-02", "2020-03-03", "9999-12-31", true,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(BUYBACK, buybackTransferExternalId, "2020-03-03", "2020-03-03", "9999-12-31",
+                            false, new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")));
+            getAndValidateThereIsActiveMapping(loanID);
+            retrieveResponse = EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+            getAndValidateThereIsNoJournalEntriesForTransfer(retrieveResponse.getContent().get(2).getTransferId());
+
+            LOAN_TRANSACTION_HELPER.makeLoanRepayment((long) loanID, new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy")
+                    .transactionDate(dateFormatter.format(expectedDate)).locale("en").transactionAmount(5.0));
+            LocalDate repaymentSubmittedOnDate = expectedDate.plusDays(1);
+            getAndValidateOwnerJournalEntries(ownerExternalId,
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(15757.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(10.000000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(5.000000), expectedDate, repaymentSubmittedOnDate),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(5.000000), expectedDate, repaymentSubmittedOnDate));
 
             updateBusinessDateAndExecuteCOBJob("2020-03-04");
             getAndValidateExternalAssetOwnerTransferByLoan(loanID,
-                    expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false),
-                    expected(ACTIVE, transferExternalId, "2020-03-02", "2020-03-03", "2020-03-03", true),
-                    expected(BUYBACK, buybackTransferExternalId, "2020-03-03", "2020-03-03", "2020-03-03", true));
+                    ExpectedExternalTransferData.expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(ACTIVE, transferExternalId, "2020-03-02", "2020-03-03", "2020-03-03", true,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(BUYBACK, buybackTransferExternalId, "2020-03-03", "2020-03-03", "2020-03-03",
+                            true, new BigDecimal("15762.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("5.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")));
+            getAndValidateThereIsNoActiveMapping(transferExternalId);
+            retrieveResponse = EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
+            expectedDate = LocalDate.of(2020, 3, 3);
+            getAndValidateThereIsJournalEntriesForTransfer(retrieveResponse.getContent().get(2).getTransferId(),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(15757.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(5.000000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(15762.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(15757.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(5.000000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) TRANSFER_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(15762.420000), expectedDate, expectedDate));
+            LocalDate previousDayDate = LocalDate.of(2020, 3, 2);
+            getAndValidateOwnerJournalEntries(ownerExternalId,
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(15757.420000), previousDayDate, previousDayDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(10.000000), previousDayDate, previousDayDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(5.000000), previousDayDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(5.000000), previousDayDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.DEBIT.getValue(),
+                            BigDecimal.valueOf(9.680000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) INCOME_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(9.680000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) ASSET_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(15757.420000), expectedDate, expectedDate),
+                    ExpectedJournalEntryData.expected((long) FEE_PENALTY_ACCOUNT.getAccountID(), (long) JournalEntryType.CREDIT.getValue(),
+                            BigDecimal.valueOf(5.000000), expectedDate, expectedDate));
         } finally {
             cleanUpAndRestoreBusinessDate();
         }
     }
 
+    private void getAndValidateOwnerJournalEntries(String ownerExternalId, ExpectedJournalEntryData... expectedItems) {
+        ExternalOwnerJournalEntryData result = EXTERNAL_ASSET_OWNER_HELPER.retrieveJournalEntriesOfOwner(ownerExternalId);
+        assertNotNull(result);
+        assertEquals(expectedItems.length, result.getJournalEntryData().getTotalElements());
+        int i = 0;
+        assertEquals(ownerExternalId, result.getOwnerData().getExternalId());
+        for (ExpectedJournalEntryData expectedJournalEntryData : expectedItems) {
+            assertTrue(expectedJournalEntryData.amount.compareTo(result.getJournalEntryData().getContent().get(i).getAmount()) == 0);
+            assertEquals(expectedJournalEntryData.entryTypeId, result.getJournalEntryData().getContent().get(i).getEntryType().getId());
+            assertEquals(expectedJournalEntryData.glAccountId, result.getJournalEntryData().getContent().get(i).getGlAccountId());
+            assertEquals(expectedJournalEntryData.transactionDate, result.getJournalEntryData().getContent().get(i).getTransactionDate());
+            assertEquals(expectedJournalEntryData.submittedOnDate, result.getJournalEntryData().getContent().get(i).getSubmittedOnDate());
+            i++;
+        }
+    }
+
+    private void getAndValidateThereIsJournalEntriesForTransfer(Long transferId, ExpectedJournalEntryData... expectedItems) {
+        ExternalOwnerTransferJournalEntryData result = EXTERNAL_ASSET_OWNER_HELPER.retrieveJournalEntriesOfTransfer(transferId);
+        assertNotNull(result);
+        long totalElements = result.getJournalEntryData().getTotalElements();
+        assertEquals(expectedItems.length, totalElements);
+        int i = 0;
+        assertEquals(transferId, result.getTransferData().getTransferId());
+        for (ExpectedJournalEntryData expectedJournalEntryData : expectedItems) {
+            assertTrue(expectedJournalEntryData.amount.compareTo(result.getJournalEntryData().getContent().get(i).getAmount()) == 0);
+            assertEquals(expectedJournalEntryData.entryTypeId, result.getJournalEntryData().getContent().get(i).getEntryType().getId());
+            assertEquals(expectedJournalEntryData.glAccountId, result.getJournalEntryData().getContent().get(i).getGlAccountId());
+            assertEquals(expectedJournalEntryData.transactionDate, result.getJournalEntryData().getContent().get(i).getTransactionDate());
+            assertEquals(expectedJournalEntryData.submittedOnDate, result.getJournalEntryData().getContent().get(i).getSubmittedOnDate());
+            i++;
+        }
+    }
+
+    private void getAndValidateThereIsNoJournalEntriesForTransfer(Long transferId) {
+        ExternalOwnerTransferJournalEntryData result = EXTERNAL_ASSET_OWNER_HELPER.retrieveJournalEntriesOfTransfer(transferId);
+        assertNull(result.getJournalEntryData());
+    }
+
     @Test
     public void saleIsNotAllowedWhenTransferIsAlreadyPending() {
         try {
@@ -160,7 +320,7 @@ public class InitiateExternalAssetOwnerTransferTest {
 
             updateBusinessDateAndExecuteCOBJob("2020-03-04");
 
-            loanTransactionHelper.makeRepayment("04 March 2020", 16000.0f, loanID);
+            LOAN_TRANSACTION_HELPER.makeRepayment("04 March 2020", 16000.0f, loanID);
 
             CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
                     () -> createExternalAssetOwnerTransfer(loanID, "sale", "2020-03-02"));
@@ -181,16 +341,31 @@ public class InitiateExternalAssetOwnerTransferTest {
             String buyBackTransferExternalId = createExternalAssetOwnerTransfer(loanID, "buyback", "2020-03-02");
 
             getAndValidateExternalAssetOwnerTransferByLoan(loanID,
-                    expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "9999-12-31", false),
-                    expected(BUYBACK, buyBackTransferExternalId, "2020-03-02", "2020-03-02", "9999-12-31", false));
+                    ExpectedExternalTransferData.expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "9999-12-31", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(BUYBACK, buyBackTransferExternalId, "2020-03-02", "2020-03-02", "9999-12-31",
+                            false, new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")));
+            getAndValidateThereIsNoActiveMapping(transferExternalId);
+            getAndValidateThereIsNoActiveMapping(buyBackTransferExternalId);
 
             updateBusinessDateAndExecuteCOBJob("2020-03-03");
 
             getAndValidateExternalAssetOwnerTransferByLoan(loanID,
-                    expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false),
-                    expected(BUYBACK, buyBackTransferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false),
-                    expected(CANCELLED, buyBackTransferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false),
-                    expected(CANCELLED, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false));
+                    ExpectedExternalTransferData.expected(PENDING, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(BUYBACK, buyBackTransferExternalId, "2020-03-02", "2020-03-02", "2020-03-02",
+                            false, new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(CANCELLED, buyBackTransferExternalId, "2020-03-02", "2020-03-02", "2020-03-02",
+                            false, new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(CANCELLED, transferExternalId, "2020-03-02", "2020-03-02", "2020-03-02", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")));
+            getAndValidateThereIsNoActiveMapping((long) loanID);
         } finally {
             cleanUpAndRestoreBusinessDate();
         }
@@ -207,8 +382,12 @@ public class InitiateExternalAssetOwnerTransferTest {
             String buybackTransferExternalId = createExternalAssetOwnerTransfer(loanID, "buyback", "2020-03-04");
 
             getAndValidateExternalAssetOwnerTransferByLoan(loanID,
-                    expected(PENDING, transferExternalId, "2020-03-04", "2020-03-02", "9999-12-31", false),
-                    expected(BUYBACK, buybackTransferExternalId, "2020-03-04", "2020-03-02", "9999-12-31", false));
+                    ExpectedExternalTransferData.expected(PENDING, transferExternalId, "2020-03-04", "2020-03-02", "9999-12-31", false,
+                            new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")),
+                    ExpectedExternalTransferData.expected(BUYBACK, buybackTransferExternalId, "2020-03-04", "2020-03-02", "9999-12-31",
+                            false, new BigDecimal("15767.420000"), new BigDecimal("15000.000000"), new BigDecimal("757.420000"),
+                            new BigDecimal("10.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000")));
 
             CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
                     () -> createExternalAssetOwnerTransfer(loanID, "sale", "2020-03-04"));
@@ -224,53 +403,56 @@ public class InitiateExternalAssetOwnerTransferTest {
     }
 
     private void updateBusinessDateAndExecuteCOBJob(String date) {
-        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BUSINESS_DATE, LocalDate.parse(date));
-        schedulerJobHelper.executeAndAwaitJob("Loan COB");
+        BusinessDateHelper.updateBusinessDate(REQUEST_SPEC, RESPONSE_SPEC, BUSINESS_DATE, LocalDate.parse(date));
+        SCHEDULER_JOB_HELPER.executeAndAwaitJob("Loan COB");
     }
 
     private String createExternalAssetOwnerTransfer(Integer loanID, String command, String settlementDate) {
         String transferExternalId = UUID.randomUUID().toString();
-        PostInitiateTransferResponse saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), command,
+        if (command.equals("sale")) {
+            ownerExternalId = UUID.randomUUID().toString();
+        }
+        PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), command,
                 new PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
-                        .transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0"));
+                        .transferExternalId(transferExternalId).ownerExternalId(ownerExternalId).purchasePriceRatio("1.0"));
         assertEquals(transferExternalId, saleResponse.getResourceExternalId());
         return transferExternalId;
     }
 
     private void addPenaltyForLoan(Integer loanID, String amount) {
         // Add Charge Penalty
-        Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
+        Integer penalty = ChargesHelper.createCharges(REQUEST_SPEC, RESPONSE_SPEC,
                 ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, amount, true));
-        Integer penalty1LoanChargeId = this.loanTransactionHelper.addChargesForLoan(loanID,
+        Integer penalty1LoanChargeId = this.LOAN_TRANSACTION_HELPER.addChargesForLoan(loanID,
                 LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), "02 March 2020", amount));
         assertNotNull(penalty1LoanChargeId);
     }
 
     private void setInitialBusinessDate(String date) {
-        GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
-        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BUSINESS_DATE, LocalDate.parse(date));
-        GlobalConfigurationHelper.updateValueForGlobalConfiguration(requestSpec, responseSpec, "10", "0");
+        GlobalConfigurationHelper.updateIsBusinessDateEnabled(REQUEST_SPEC, RESPONSE_SPEC, Boolean.TRUE);
+        BusinessDateHelper.updateBusinessDate(REQUEST_SPEC, RESPONSE_SPEC, BUSINESS_DATE, LocalDate.parse(date));
+        GlobalConfigurationHelper.updateValueForGlobalConfiguration(REQUEST_SPEC, RESPONSE_SPEC, "10", "0");
     }
 
     private void cleanUpAndRestoreBusinessDate() {
-        requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
-        requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
-        requestSpec.header("Fineract-Platform-TenantId", "default");
-        responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
-        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BUSINESS_DATE, todaysDate);
-        GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
+        REQUEST_SPEC = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+        REQUEST_SPEC.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+        REQUEST_SPEC.header("Fineract-Platform-TenantId", "default");
+        RESPONSE_SPEC = new ResponseSpecBuilder().expectStatusCode(200).build();
+        BusinessDateHelper.updateBusinessDate(REQUEST_SPEC, RESPONSE_SPEC, BUSINESS_DATE, TODAYS_DATE);
+        GlobalConfigurationHelper.updateIsBusinessDateEnabled(REQUEST_SPEC, RESPONSE_SPEC, Boolean.FALSE);
     }
 
     @NotNull
     private Integer createClient() {
-        final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec);
+        final Integer clientID = ClientHelper.createClient(REQUEST_SPEC, RESPONSE_SPEC);
         Assertions.assertNotNull(clientID);
         return clientID;
     }
 
     @NotNull
     private Integer createLoanForClient(Integer clientID) {
-        Integer overdueFeeChargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
+        Integer overdueFeeChargeId = ChargesHelper.createCharges(REQUEST_SPEC, RESPONSE_SPEC,
                 ChargesHelper.getLoanOverdueFeeJSONWithCalculationTypePercentage("1"));
         Assertions.assertNotNull(overdueFeeChargeId);
 
@@ -282,32 +464,34 @@ public class InitiateExternalAssetOwnerTransferTest {
 
         Assertions.assertNotNull(loanID);
 
-        loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
+        loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(REQUEST_SPEC, RESPONSE_SPEC, loanID);
         LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
 
-        loanStatusHashMap = loanTransactionHelper.approveLoan("01 March 2020", loanID);
+        loanStatusHashMap = LOAN_TRANSACTION_HELPER.approveLoan("01 March 2020", loanID);
         LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
 
-        String loanDetails = loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
-        loanStatusHashMap = loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
+        String loanDetails = LOAN_TRANSACTION_HELPER.getLoanDetails(REQUEST_SPEC, RESPONSE_SPEC, loanID);
+        loanStatusHashMap = LOAN_TRANSACTION_HELPER.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
                 JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
         LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
         return loanID;
     }
 
     private Integer createLoanProduct(final String chargeId) {
+
         final String loanProductJSON = new LoanProductTestBuilder().withPrincipal("15,000.00").withNumberOfRepayments("4")
                 .withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("1")
+                .withAccountingRulePeriodicAccrual(new Account[] { ASSET_ACCOUNT, EXPENSE_ACCOUNT, INCOME_ACCOUNT, OVERPAYMENT_ACCOUNT })
                 .withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
-                .build(chargeId);
-        return loanTransactionHelper.getLoanProductId(loanProductJSON);
+                .withFeeAndPenaltyAssetAccount(FEE_PENALTY_ACCOUNT).build(chargeId);
+        return LOAN_TRANSACTION_HELPER.getLoanProductId(loanProductJSON);
     }
 
     private Integer applyForLoanApplication(final String clientID, final String loanProductID, final String date) {
         List<HashMap> collaterals = new ArrayList<>();
-        Integer collateralId = CollateralManagementHelper.createCollateralProduct(requestSpec, responseSpec);
+        Integer collateralId = CollateralManagementHelper.createCollateralProduct(REQUEST_SPEC, RESPONSE_SPEC);
         Assertions.assertNotNull(collateralId);
-        Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(requestSpec, responseSpec, clientID, collateralId);
+        Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(REQUEST_SPEC, RESPONSE_SPEC, clientID, collateralId);
         Assertions.assertNotNull(clientCollateralId);
         addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
 
@@ -317,7 +501,7 @@ public class InitiateExternalAssetOwnerTransferTest {
                 .withInterestTypeAsDecliningBalance().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
                 .withExpectedDisbursementDate(date).withSubmittedOnDate(date).withCollaterals(collaterals)
                 .build(clientID, loanProductID, null);
-        return loanTransactionHelper.getLoanId(loanApplicationJSON);
+        return LOAN_TRANSACTION_HELPER.getLoanId(loanApplicationJSON);
     }
 
     private void addCollaterals(List<HashMap> collaterals, Integer collateralId, BigDecimal quantity) {
@@ -331,26 +515,8 @@ public class InitiateExternalAssetOwnerTransferTest {
         return collateral;
     }
 
-    @RequiredArgsConstructor()
-    public static class ExpectedExternalTransferData {
-
-        private final ExternalTransferData.StatusEnum status;
-        private final String transferExternalId;
-        private final String settlementDate;
-        private final String effectiveFrom;
-        private final String effectiveTo;
-        private final boolean detailsExpected;
-
-        static ExpectedExternalTransferData expected(ExternalTransferData.StatusEnum status, String transferExternalId,
-                String settlementDate, String effectiveFrom, String effectiveTo, boolean detailsExpected) {
-            return new ExpectedExternalTransferData(status, transferExternalId, settlementDate, effectiveFrom, effectiveTo,
-                    detailsExpected);
-        }
-
-    }
-
     private void getAndValidateExternalAssetOwnerTransferByLoan(Integer loanID, ExpectedExternalTransferData... expectedItems) {
-        PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
+        PageExternalTransferData retrieveResponse = EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue());
         assertEquals(expectedItems.length, retrieveResponse.getNumberOfElements());
 
         for (ExpectedExternalTransferData expected : expectedItems) {
@@ -370,14 +536,75 @@ public class InitiateExternalAssetOwnerTransferTest {
                 assertNull(etd.getDetails());
             } else {
                 assertNotNull(etd.getDetails());
-                assertEquals(new BigDecimal("15767.420000"), etd.getDetails().getTotalOutstanding());
-                assertEquals(new BigDecimal("15000.000000"), etd.getDetails().getTotalPrincipalOutstanding());
-                assertEquals(new BigDecimal("757.420000"), etd.getDetails().getTotalInterestOutstanding());
-                assertEquals(new BigDecimal("10.000000"), etd.getDetails().getTotalPenaltyChargesOutstanding());
-                assertEquals(new BigDecimal("0.000000"), etd.getDetails().getTotalFeeChargesOutstanding());
-                assertEquals(new BigDecimal("0.000000"), etd.getDetails().getTotalOverpaid());
+                assertEquals(expected.totalOutstanding, etd.getDetails().getTotalOutstanding());
+                assertEquals(expected.totalPrincipalOutstanding, etd.getDetails().getTotalPrincipalOutstanding());
+                assertEquals(expected.totalInterestOutstanding, etd.getDetails().getTotalInterestOutstanding());
+                assertEquals(expected.totalPenaltyOutstanding, etd.getDetails().getTotalPenaltyChargesOutstanding());
+                assertEquals(expected.totalFeeOutstanding, etd.getDetails().getTotalFeeChargesOutstanding());
+                assertEquals(expected.totalOverpaid, etd.getDetails().getTotalOverpaid());
             }
         }
     }
 
+    private void getAndValidateThereIsActiveMapping(Integer loanID) {
+        ExternalTransferData activeTransfer = EXTERNAL_ASSET_OWNER_HELPER.retrieveActiveTransferByLoanId((long) loanID);
+        assertNotNull(activeTransfer);
+        ExternalTransferData retrieveResponse = EXTERNAL_ASSET_OWNER_HELPER.retrieveTransfersByLoanId(loanID.longValue()).getContent()
+                .stream().filter(transfer -> ExternalTransferData.StatusEnum.ACTIVE.equals(transfer.getStatus())).findFirst().get();
+        assertEquals(retrieveResponse.getTransferId(), activeTransfer.getTransferId());
+    }
+
+    private void getAndValidateThereIsNoActiveMapping(Long loanId) {
+        ExternalTransferData activeTransfer = EXTERNAL_ASSET_OWNER_HELPER.retrieveActiveTransferByLoanId(loanId);
+        assertNull(activeTransfer);
+    }
+
+    private void getAndValidateThereIsNoActiveMapping(String transferExternalId) {
+        ExternalTransferData activeTransfer = EXTERNAL_ASSET_OWNER_HELPER.retrieveActiveTransferByTransferExternalId(transferExternalId);
+        assertNull(activeTransfer);
+    }
+
+    @RequiredArgsConstructor()
+    public static class ExpectedExternalTransferData {
+
+        private final ExternalTransferData.StatusEnum status;
+
+        private final String transferExternalId;
+        private final String settlementDate;
+        private final String effectiveFrom;
+        private final String effectiveTo;
+        private final boolean detailsExpected;
+        private final BigDecimal totalOutstanding;
+        private final BigDecimal totalPrincipalOutstanding;
+        private final BigDecimal totalInterestOutstanding;
+        private final BigDecimal totalPenaltyOutstanding;
+        private final BigDecimal totalFeeOutstanding;
+        private final BigDecimal totalOverpaid;
+
+        static ExpectedExternalTransferData expected(ExternalTransferData.StatusEnum status, String transferExternalId,
+                String settlementDate, String effectiveFrom, String effectiveTo, boolean detailsExpected, BigDecimal totalOutstanding,
+                BigDecimal totalPrincipalOutstanding, BigDecimal totalInterestOutstanding, BigDecimal totalPenaltyOutstanding,
+                BigDecimal totalFeeOutstanding, BigDecimal totalOverpaid) {
+            return new ExpectedExternalTransferData(status, transferExternalId, settlementDate, effectiveFrom, effectiveTo, detailsExpected,
+                    totalOutstanding, totalPrincipalOutstanding, totalInterestOutstanding, totalPenaltyOutstanding, totalFeeOutstanding,
+                    totalOverpaid);
+        }
+
+    }
+
+    @RequiredArgsConstructor()
+    public static class ExpectedJournalEntryData {
+
+        private final Long glAccountId;
+        private final Long entryTypeId;
+        private final BigDecimal amount;
+        private final LocalDate transactionDate;
+        private final LocalDate submittedOnDate;
+
+        static ExpectedJournalEntryData expected(Long glAccountId, Long entryTypeId, BigDecimal amount, LocalDate transactionDate,
+                LocalDate submittedOnDate) {
+            return new ExpectedJournalEntryData(glAccountId, entryTypeId, amount, transactionDate, submittedOnDate);
+        }
+
+    }
 }