From b7fef480d5b9533bc88c2a827e4df3f5fd37a676 Mon Sep 17 00:00:00 2001 From: Nayan Ambali Date: Thu, 7 Feb 2013 15:24:40 +0530 Subject: [PATCH] Adding unique constraint on Loan Product name --- ...atch_add_remove_loanofficer_permission.sql | 1 + .../commands/domain/CommandWrapper.java | 4 ++ .../service/CommandWrapperBuilder.java | 9 +++ .../SynchronousCommandProcessingService.java | 2 + .../loanaccount/api/LoansApiResource.java | 14 +++++ .../command/LoanUpdateCommand.java | 33 +++++++++++ .../command/UpdateLoanOfficerCommand.java | 18 +++--- .../portfolio/loanaccount/domain/Loan.java | 17 ++++++ .../UnassignLoanOfficerException.java | 11 ++++ .../RemoveLoanOfficerCommandHandler.java | 27 +++++++++ ...nUpdateCommandFromApiJsonDeserializer.java | 55 +++++++++++++++++++ .../service/LoanWritePlatformService.java | 2 + ...WritePlatformServiceJpaRepositoryImpl.java | 43 ++++++++++++++- 13 files changed, 226 insertions(+), 10 deletions(-) create mode 100644 mifosng-db/patches/03-patch_add_remove_loanofficer_permission.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanUpdateCommand.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/UnassignLoanOfficerException.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/RemoveLoanOfficerCommandHandler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanUpdateCommandFromApiJsonDeserializer.java diff --git a/mifosng-db/patches/03-patch_add_remove_loanofficer_permission.sql b/mifosng-db/patches/03-patch_add_remove_loanofficer_permission.sql new file mode 100644 index 000000000..8a206967d --- /dev/null +++ b/mifosng-db/patches/03-patch_add_remove_loanofficer_permission.sql @@ -0,0 +1 @@ +INSERT INTO `m_permission` (`id`, `grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES (358, 'transaction_loan', 'REMOVELOANOFFICER_LOAN', 'LOAN', 'REMOVELOANOFFICER', 1); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java index e56aa192a..3979b0fbd 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java @@ -297,6 +297,10 @@ public class CommandWrapper { return this.actionName.equalsIgnoreCase("UPDATELOANOFFICER") && this.entityName.equalsIgnoreCase("LOAN"); } + public boolean isRemoveLoanOfficer() { + return this.actionName.equalsIgnoreCase("REMOVELOANOFFICER") && this.entityName.equalsIgnoreCase("LOAN"); + } + public boolean isBulkUpdateLoanOfficer() { return this.actionName.equalsIgnoreCase("BULKREASSIGN") && this.entityName.equalsIgnoreCase("LOAN"); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index ef994e66e..4a3d8feae 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -549,6 +549,15 @@ public class CommandWrapperBuilder { this.href = "/loans/" + loanId; return this; } + + public CommandWrapperBuilder unassignLoanOfficer(final Long loanId) { + this.actionName = "REMOVELOANOFFICER"; + this.entityName = "LOAN"; + this.entityId = null; + this.loanId = loanId; + this.href = "/loans/" + loanId; + return this; + } public CommandWrapperBuilder assignLoanOfficersInBulk() { this.actionName = "BULKREASSIGN"; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java index 39619d779..084e3b454 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java @@ -281,6 +281,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer handler = applicationContext.getBean("closeLoanAsRescheduledCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isUpdateLoanOfficer()) { handler = applicationContext.getBean("updateLoanOfficerCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isRemoveLoanOfficer()) { + handler = applicationContext.getBean("removeLoanOfficerCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isBulkUpdateLoanOfficer()) { handler = applicationContext.getBean("bulkUpdateLoanOfficerCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isCreate()) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java index 0c0ecd3d9..28f8e2910 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoansApiResource.java @@ -457,4 +457,18 @@ public class LoansApiResource { return this.toApiJsonSerializer.serialize(result); } + + @POST + @Path("{loanId}/unassign") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String unassignLoanOfficer(@PathParam("loanId") final Long loanId, final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().unassignLoanOfficer(loanId).withJson(apiRequestBodyAsJson) + .build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanUpdateCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanUpdateCommand.java new file mode 100644 index 000000000..059b2354d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/LoanUpdateCommand.java @@ -0,0 +1,33 @@ +package org.mifosplatform.portfolio.loanaccount.command; + +import java.util.ArrayList; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; + +/** + * Immutable command for loan transactions. + */ +public class LoanUpdateCommand { + + private final LocalDate unassignedDate; + + public LoanUpdateCommand(final LocalDate unassignDate) { + this.unassignedDate = unassignDate; + } + + public void validate() { + + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction"); + + baseDataValidator.reset().parameter("unassignedDate").value(this.unassignedDate).notNull(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/UpdateLoanOfficerCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/UpdateLoanOfficerCommand.java index da0500e4e..3f3988349 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/UpdateLoanOfficerCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/UpdateLoanOfficerCommand.java @@ -9,7 +9,8 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; /** - * Immutable data object for updating relationship between loan officer and a loan. + * Immutable data object for updating relationship between loan officer and a + * loan. */ public class UpdateLoanOfficerCommand { @@ -26,17 +27,18 @@ public class UpdateLoanOfficerCommand { this.loans = null; } - public UpdateLoanOfficerCommand(final Long fromLoanOfficerId, final Long toLoanOfficerId, final LocalDate assignmentDate, final String[] loans) { + public UpdateLoanOfficerCommand(final Long fromLoanOfficerId, final Long toLoanOfficerId, final LocalDate assignmentDate, + final String[] loans) { this.fromLoanOfficerId = fromLoanOfficerId; this.toLoanOfficerId = toLoanOfficerId; this.assignmentDate = assignmentDate; this.loans = loans; } - - public void validateForBulkLoanReassignment() { - List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loans.reassignment"); + public void validateForBulkLoanReassignment() { + final List dataValidationErrors = new ArrayList(); + + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loans.reassignment"); baseDataValidator.reset().parameter("fromLoanOfficerId").value(this.fromLoanOfficerId).notNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("toLoanOfficerId").value(this.toLoanOfficerId).notNull().integerGreaterThanZero() @@ -51,9 +53,9 @@ public class UpdateLoanOfficerCommand { } public void validateForLoanReassignment() { - List dataValidationErrors = new ArrayList(); + final List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loans.reassignment"); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loans.reassignment"); baseDataValidator.reset().parameter("toLoanOfficerId").value(this.toLoanOfficerId).notNull().integerGreaterThanZero() .notSameAsParameter("fromLoanOfficerId", this.fromLoanOfficerId); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 4705504ed..9687d3630 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -1941,6 +1941,18 @@ public class Loan extends AbstractAuditableCustom { } } + + public void removeLoanOfficer(final LocalDate updatedDate) { + + final LoanOfficerAssignmentHistory latestHistoryRecord = findLatestIncompleteHistoryRecord(); + + if (latestHistoryRecord != null) { + latestHistoryRecord.updateEndDate(updatedDate); + } + + this.loanofficer = null; + } + private LoanOfficerAssignmentHistory findLatestIncompleteHistoryRecord() { LoanOfficerAssignmentHistory latestRecordWithNoEndDate = null; @@ -2006,4 +2018,9 @@ public class Loan extends AbstractAuditableCustom { public Long productId() { return this.loanProduct.getId(); } + + public Staff getLoanOfficer() { + return this.loanofficer; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/UnassignLoanOfficerException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/UnassignLoanOfficerException.java new file mode 100644 index 000000000..0923bf9e4 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/exception/UnassignLoanOfficerException.java @@ -0,0 +1,11 @@ +package org.mifosplatform.portfolio.loanaccount.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class UnassignLoanOfficerException extends AbstractPlatformDomainRuleException { + + public UnassignLoanOfficerException(final Long loanId) { + super("error.msg.loan.not.assigned.to.loan.officer", "Loan with identifier " + loanId + + " is not assigned to any loan officer.", loanId); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/RemoveLoanOfficerCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/RemoveLoanOfficerCommandHandler.java new file mode 100644 index 000000000..861e739b9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/RemoveLoanOfficerCommandHandler.java @@ -0,0 +1,27 @@ +package org.mifosplatform.portfolio.loanaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class RemoveLoanOfficerCommandHandler implements NewCommandSourceHandler { + + private final LoanWritePlatformService writePlatformService; + + @Autowired + public RemoveLoanOfficerCommandHandler(final LoanWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.writePlatformService.removeLoanOfficer(command.getLoanId(), command); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanUpdateCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanUpdateCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..b1e8a21b2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanUpdateCommandFromApiJsonDeserializer.java @@ -0,0 +1,55 @@ +package org.mifosplatform.portfolio.loanaccount.serialization; + +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.portfolio.loanaccount.command.LoanStateTransitionCommand; +import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +/** + * Implementation of {@link FromApiJsonDeserializer} for + * {@link LoanStateTransitionCommand}'s. + */ +@Component +public final class LoanUpdateCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + final Set supportedParameters = new HashSet(Arrays.asList("unassignedDate", "locale", "dateFormat")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public LoanUpdateCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + @Override + public LoanUpdateCommand commandFromApiJson(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + final LocalDate unassignedDate = this.fromApiJsonHelper.extractLocalDateNamed("unassignedDate", element); + + return new LoanUpdateCommand(unassignedDate); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformService.java index 9f5ba66b5..c567b72ab 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformService.java @@ -32,4 +32,6 @@ public interface LoanWritePlatformService { CommandProcessingResult loanReassignment(Long loanId, JsonCommand command); CommandProcessingResult bulkLoanReassignment(JsonCommand command); + + CommandProcessingResult removeLoanOfficer(Long loanId, JsonCommand command); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index c30660dfd..b5bf18ed8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -32,6 +32,7 @@ import org.mifosplatform.portfolio.client.domain.NoteRepository; import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand; import org.mifosplatform.portfolio.loanaccount.command.LoanStateTransitionCommand; import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand; +import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge; @@ -44,9 +45,11 @@ import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository; import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException; import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException; import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException; +import org.mifosplatform.portfolio.loanaccount.exception.UnassignLoanOfficerException; import org.mifosplatform.portfolio.loanaccount.serialization.LoanChargeCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.loanaccount.serialization.LoanStateTransitionCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.loanaccount.serialization.LoanTransactionCommandFromApiJsonDeserializer; +import org.mifosplatform.portfolio.loanaccount.serialization.LoanUpdateCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException; import org.mifosplatform.useradministration.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; @@ -60,6 +63,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private final LoanStateTransitionCommandFromApiJsonDeserializer loanStateTransitionCommandFromApiJsonDeserializer; private final LoanTransactionCommandFromApiJsonDeserializer loanTransactionCommandFromApiJsonDeserializer; private final LoanChargeCommandFromApiJsonDeserializer loanChargeCommandFromApiJsonDeserializer; + private final LoanUpdateCommandFromApiJsonDeserializer loanUpdateCommandFromApiJsonDeserializer; private final LoanRepository loanRepository; private final NoteRepository noteRepository; private final LoanTransactionRepository loanTransactionRepository; @@ -73,7 +77,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final LoanStateTransitionCommandFromApiJsonDeserializer loanStateTransitionCommandFromApiJsonDeserializer, final LoanTransactionCommandFromApiJsonDeserializer loanTransactionCommandFromApiJsonDeserializer, - final LoanChargeCommandFromApiJsonDeserializer loanChargeCommandFromApiJsonDeserializer, final LoanAssembler loanAssembler, + final LoanChargeCommandFromApiJsonDeserializer loanChargeCommandFromApiJsonDeserializer, + final LoanUpdateCommandFromApiJsonDeserializer loanUpdateCommandFromApiJsonDeserializer, + final LoanAssembler loanAssembler, final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository, final NoteRepository noteRepository, final ChargeRepository chargeRepository, final LoanChargeRepository loanChargeRepository, final ApplicationCurrencyRepository applicationCurrencyRepository, @@ -90,6 +96,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanChargeRepository = loanChargeRepository; this.applicationCurrencyRepository = applicationCurrencyRepository; this.journalEntryWritePlatformService = journalEntryWritePlatformService; + this.loanUpdateCommandFromApiJsonDeserializer = loanUpdateCommandFromApiJsonDeserializer; } private boolean isBeforeToday(final LocalDate date) { @@ -695,7 +702,39 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf .withCommandId(command.commandId()) // .build(); } - + + @Transactional + @Override + public CommandProcessingResult removeLoanOfficer(final Long loanId, final JsonCommand command) { + + this.context.authenticatedUser(); + + final LoanUpdateCommand loanUpdateCommand = this.loanUpdateCommandFromApiJsonDeserializer.commandFromApiJson(command + .json()); + + loanUpdateCommand.validate(); + + + final LocalDate dateOfLoanOfficerunAssigned = command.localDateValueOfParameterNamed("unassignedDate"); + + final Loan loan = retrieveLoanBy(loanId); + + if (loan.getLoanOfficer() == null) { throw new UnassignLoanOfficerException(loanId); } + + loan.removeLoanOfficer(dateOfLoanOfficerunAssigned); + + this.loanRepository.saveAndFlush(loan); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(loanId) // + .withOfficeId(loan.getOfficeId()) // + .withClientId(loan.getClientId()) // + .withGroupId(loan.getGroupId()) // + .withLoanId(loanId) // + .build(); + } + private LoanDTO populateLoanDTO(Loan loan, List loanTransactions) { List loanTransactionDTOs = new ArrayList(); for (LoanTransaction loanTransaction : loanTransactions) {