diff --git a/mifosng-db/patches/patch-01-add-update-loan-officer-permission.sql b/mifosng-db/patches/patch-01-add-update-loan-officer-permission.sql new file mode 100644 index 000000000..2f6e72121 --- /dev/null +++ b/mifosng-db/patches/patch-01-add-update-loan-officer-permission.sql @@ -0,0 +1,9 @@ +INSERT INTO `m_permission` +(`grouping`, +`code`, +`entity_name`, +`action_name`, +`can_maker_checker`) +VALUES +('transaction_loan', 'UPDATELOANOFFICER_LOAN', 'LOAN', 'UPDATELOANOFFICER', 1), +('transaction_loan', 'UPDATELOANOFFICER_LOAN_CHECKER', 'LOAN', 'UPDATELOANOFFICER', 0); \ No newline at end of file diff --git a/mifosng-db/patches/patch-01-just-a-place-holder-use-me.sql b/mifosng-db/patches/patch-01-just-a-place-holder-use-me.sql deleted file mode 100644 index e69de29bb..000000000 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 5fb95a517..f72c575ef 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 @@ -231,4 +231,12 @@ public class CommandWrapper { public boolean isWaiveLoanCharge() { return this.actionName.equalsIgnoreCase("WAIVE") && this.entityName.equalsIgnoreCase("LOANCHARGE"); } + + public boolean isUpdateLoanOfficer() { + return this.actionName.equalsIgnoreCase("UPDATELOANOFFICER") && this.entityName.equalsIgnoreCase("LOAN"); + } + + public boolean isBulkUpdateLoanOfficer() { + return this.actionName.equalsIgnoreCase("BULKREASSIGN") && this.entityName.equalsIgnoreCase("LOAN"); + } } \ No newline at end of file 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 b39f6dc49..07052ad18 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 @@ -244,6 +244,10 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer handler = applicationContext.getBean("updateLoanChargeCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isWaiveLoanCharge()) { handler = applicationContext.getBean("waiveLoanChargeCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isUpdateLoanOfficer()) { + handler = applicationContext.getBean("updateLoanOfficerCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isBulkUpdateLoanOfficer()) { + handler = applicationContext.getBean("bulkUpdateLoanOfficerCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isCreate()) { handler = applicationContext.getBean("createLoanApplicationCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isUpdate()) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java index 38b420323..6c12cb2bb 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java @@ -10,8 +10,6 @@ import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData; import org.mifosplatform.infrastructure.security.data.AuthenticatedUserData; -import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData; -import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData; import org.mifosplatform.portfolio.group.data.GroupData; @@ -33,9 +31,6 @@ import com.google.gson.Gson; @Service public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApiJsonSerializerService { - private static final Set STAFF_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "firstname", "lastname", - "displayName", "officeId", "officeName", "loanOfficerFlag", "allowedOffices")); - private static final Set SAVINGS_PRODUCT_DATA_PARAMETERS = new HashSet(Arrays.asList("currencyOptions", "id", "createdOn", "lastModifedOn", "locale", "name", "description", "currencyCode", "digitsAfterDecimal", "interstRate", "minInterestRate", "maxInterestRate", "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency", @@ -76,9 +71,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi private static final Set GROUP_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "officeId", "name", "externalId", "clientMembers", "allowedClients", "allowedOffices")); - private static final Set LOAN_REASSIGNMENT_DATA_PARAMETERS = new HashSet(Arrays.asList("officeId", "fromLoanOfficerId", - "assignmentDate", "officeOptions", "loanOfficerOptions", "accountSummaryCollection")); - private static final Set SAVINGS_ACCOUNTS_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "status", "externalId", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", "savingsFrequencyType", "totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType", @@ -199,28 +191,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi return helper.serializedJsonFrom(gsonDeserializer, group); } - @Override - public String serializeLoanReassignmentDataToJson(boolean prettyPrint, Set responseParameters, - BulkTransferLoanOfficerData loanReassignmentData) { - final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy( - LOAN_REASSIGNMENT_DATA_PARAMETERS, prettyPrint, responseParameters); - return helper.serializedJsonFrom(gsonDeserializer, loanReassignmentData); - } - - @Override - public String serializeStaffDataToJson(boolean prettyPrint, Set responseParameters, StaffData staff) { - final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(STAFF_DATA_PARAMETERS, - prettyPrint, responseParameters); - return helper.serializedJsonFrom(gsonDeserializer, staff); - } - - @Override - public String serializeStaffDataToJson(boolean prettyPrint, Set responseParameters, Collection staff) { - final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(STAFF_DATA_PARAMETERS, - prettyPrint, responseParameters); - return helper.serializedJsonFrom(gsonDeserializer, staff.toArray(new StaffData[staff.size()])); - } - @Override public String serializeDocumentDataToJson(boolean prettyPrint, Set responseParameters, Collection documentDatas) { final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(DOCUMENT_DATA_PARAMETERS, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java index bc936c6c3..c3006ba42 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java @@ -1,6 +1,5 @@ package org.mifosplatform.infrastructure.core.api; -import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand; import org.mifosplatform.portfolio.client.command.NoteCommand; import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.group.command.GroupCommand; @@ -32,10 +31,6 @@ public interface PortfolioApiDataConversionService { DepositStateTransitionApprovalCommand convertJsonToDepositStateTransitionApprovalCommand(Long resourceIdentifier, String json); - BulkTransferLoanOfficerCommand convertJsonToLoanReassignmentCommand(Long resourceIdentifier, String json); - - BulkTransferLoanOfficerCommand convertJsonToBulkLoanReassignmentCommand(String json); - DepositAccountWithdrawalCommand convertJsonToDepositWithdrawalCommand(Long resourceIdentifier, String json); DepositAccountWithdrawInterestCommand convertJsonToDepositAccountWithdrawInterestCommand(Long resourceIdentifier, String json); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java index 4b5c338a8..254973236 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java @@ -21,7 +21,6 @@ import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.UnsupportedParameterException; -import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand; import org.mifosplatform.portfolio.client.command.ClientCommand; import org.mifosplatform.portfolio.client.command.NoteCommand; import org.mifosplatform.portfolio.client.data.ClientData; @@ -63,68 +62,6 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo this.gsonConverter = new Gson(); } - @Override - public BulkTransferLoanOfficerCommand convertJsonToLoanReassignmentCommand(Long resourceIdentifier, String json) { - - if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - - Type typeOfMap = new TypeToken>() {}.getType(); - Map requestMap = gsonConverter.fromJson(json, typeOfMap); - - Set supportedParams = new HashSet(Arrays.asList("fromLoanOfficerId", "toLoanOfficerId", "assignmentDate", "locale", - "dateFormat")); - - checkForUnsupportedParameters(requestMap, supportedParams); - - Set modifiedParameters = new HashSet(); - - Long fromLoanOfficerId = extractLongParameter("fromLoanOfficerId", requestMap, modifiedParameters); - Long toLoanOfficerId = extractLongParameter("toLoanOfficerId", requestMap, modifiedParameters); - LocalDate assignmentDate = extractLocalDateParameter("assignmentDate", requestMap, modifiedParameters); - - return new BulkTransferLoanOfficerCommand(resourceIdentifier, fromLoanOfficerId, toLoanOfficerId, assignmentDate); - } - - @Override - public BulkTransferLoanOfficerCommand convertJsonToBulkLoanReassignmentCommand(final String json) { - - if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - - Type typeOfMap = new TypeToken>() {}.getType(); - Map requestMap = gsonConverter.fromJson(json, typeOfMap); - - Set supportedParams = new HashSet(Arrays.asList("fromLoanOfficerId", "toLoanOfficerId", "assignmentDate", "locale", - "dateFormat", "loans")); - - checkForUnsupportedParameters(requestMap, supportedParams); - - Set modifiedParameters = new HashSet(); - - Long fromLoanOfficerId = extractLongParameter("fromLoanOfficerId", requestMap, modifiedParameters); - Long toLoanOfficerId = extractLongParameter("toLoanOfficerId", requestMap, modifiedParameters); - LocalDate assignmentDate = extractLocalDateParameter("assignmentDate", requestMap, modifiedParameters); - - // check array - JsonParser parser = new JsonParser(); - - String[] loans = null; - JsonElement element = parser.parse(json); - if (element.isJsonObject()) { - JsonObject object = element.getAsJsonObject(); - if (object.has("loans")) { - modifiedParameters.add("loans"); - JsonArray array = object.get("loans").getAsJsonArray(); - loans = new String[array.size()]; - for (int i = 0; i < array.size(); i++) { - loans[i] = array.get(i).getAsString(); - } - } - } - // - - return new BulkTransferLoanOfficerCommand(fromLoanOfficerId, toLoanOfficerId, assignmentDate, loans); - } - @Override public ClientData convertInternalJsonFormatToClientDataChange(final Long resourceIdentifier, final String json) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java index c7a688841..48d122a0c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java @@ -7,8 +7,6 @@ import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData; import org.mifosplatform.infrastructure.security.data.AuthenticatedUserData; -import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData; -import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData; import org.mifosplatform.portfolio.group.data.GroupData; @@ -49,13 +47,6 @@ public interface PortfolioApiJsonSerializerService { String serializeGroupDataToJson(boolean prettyPrint, Set responseParameters, GroupData group); - String serializeLoanReassignmentDataToJson(boolean prettyPrint, Set responseParameters, - BulkTransferLoanOfficerData loanReassignmentData); - - String serializeStaffDataToJson(boolean prettyPrint, Set responseParameters, StaffData staff); - - String serializeStaffDataToJson(boolean prettyPrint, Set responseParameters, Collection staff); - String serializeDocumentDataToJson(boolean prettyPrint, Set responseParameters, Collection documentDatas); String serializeDocumentDataToJson(boolean prettyPrint, Set responseParameters, DocumentData documentData); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/command/BulkTransferLoanOfficerCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/command/BulkTransferLoanOfficerCommand.java deleted file mode 100644 index 77b1ac068..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/command/BulkTransferLoanOfficerCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.mifosplatform.organisation.staff.command; - -import org.joda.time.LocalDate; - -/** - * Immutable data object for bulk transferring same loan officers out and in on loans. - */ -public class BulkTransferLoanOfficerCommand { - - private final Long loanId; - - private final Long fromLoanOfficerId; - private final Long toLoanOfficerId; - private final LocalDate assignmentDate; - - private final String[] loans; - - public BulkTransferLoanOfficerCommand(final Long loanId, final Long fromLoanOfficerId, final Long toLoanOfficerId, final LocalDate assignmentDate) { - this.loanId = loanId; - this.fromLoanOfficerId = fromLoanOfficerId; - this.toLoanOfficerId = toLoanOfficerId; - this.assignmentDate = assignmentDate; - this.loans = null; - } - - public BulkTransferLoanOfficerCommand(final Long fromLoanOfficerId, final Long toLoanOfficerId, final LocalDate assignmentDate, final String[] loans) { - this.fromLoanOfficerId = fromLoanOfficerId; - this.toLoanOfficerId = toLoanOfficerId; - this.assignmentDate = assignmentDate; - this.loans = loans; - this.loanId = null; - } - - public Long getLoanId() { - return loanId; - } - - public Long getFromLoanOfficerId() { - return fromLoanOfficerId; - } - - public Long getToLoanOfficerId() { - return toLoanOfficerId; - } - - public LocalDate getAssignmentDate() { - return assignmentDate; - } - - public String[] getLoans() { - return loans; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/BulkLoansApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/BulkLoansApiResource.java new file mode 100644 index 000000000..d49660683 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/BulkLoansApiResource.java @@ -0,0 +1,105 @@ +package org.mifosplatform.portfolio.loanaccount.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.joda.time.LocalDate; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.organisation.office.data.OfficeLookup; +import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; +import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData; +import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData; +import org.mifosplatform.organisation.staff.data.StaffData; +import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/loans/loanreassignment") +@Component +@Scope("singleton") +public class BulkLoansApiResource { + + private final Set RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList("officeId", "fromLoanOfficerId", + "assignmentDate", "officeOptions", "loanOfficerOptions", "accountSummaryCollection")); + + private final String resourceNameForPermissions = "LOAN"; + + private final PlatformSecurityContext context; + private final StaffReadPlatformService staffReadPlatformService; + private final OfficeReadPlatformService officeReadPlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final ApiRequestParameterHelper apiRequestParameterHelper; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public BulkLoansApiResource(final PlatformSecurityContext context, final StaffReadPlatformService staffReadPlatformService, + final OfficeReadPlatformService officeReadPlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer, + final ApiRequestParameterHelper apiRequestParameterHelper, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.staffReadPlatformService = staffReadPlatformService; + this.officeReadPlatformService = officeReadPlatformService; + this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String loanReassignmentTemplate(@QueryParam("officeId") final Long officeId, + @QueryParam("fromLoanOfficerId") final Long loanOfficerId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Collection offices = this.officeReadPlatformService.retrieveAllOfficesForLookup(); + + Collection loanOfficers = null; + StaffAccountSummaryCollectionData staffAccountSummaryCollectionData = null; + + if (officeId != null) { + loanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId); + } + + if (loanOfficerId != null) { + staffAccountSummaryCollectionData = this.staffReadPlatformService.retrieveLoanOfficerAccountSummary(loanOfficerId); + } + + final BulkTransferLoanOfficerData loanReassignmentData = BulkTransferLoanOfficerData.templateForBulk(officeId, loanOfficerId, + new LocalDate(), offices, loanOfficers, staffAccountSummaryCollectionData); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, loanReassignmentData, RESPONSE_DATA_PARAMETERS); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String loanReassignment(final String apiRequestBodyAsJson) { + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("BULKREASSIGN", "LOAN", "N/A", "loans", + null, apiRequestBodyAsJson); + + return this.toApiJsonSerializer.serialize(result); + } +} \ No newline at end of file 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 5587c6aae..474e61e40 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 @@ -16,7 +16,6 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; @@ -25,8 +24,6 @@ import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformSer import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.api.JsonQuery; -import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService; -import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService; import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; @@ -36,11 +33,7 @@ import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.Money; -import org.mifosplatform.organisation.office.data.OfficeLookup; -import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; -import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand; import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData; -import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData; import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; import org.mifosplatform.portfolio.charge.data.ChargeData; @@ -58,7 +51,6 @@ import org.mifosplatform.portfolio.loanaccount.gaurantor.service.GuarantorReadPl import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData; import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService; import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService; -import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService; import org.mifosplatform.portfolio.loanproduct.data.LoanProductData; import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData; import org.mifosplatform.portfolio.loanproduct.service.LoanDropdownReadPlatformService; @@ -90,52 +82,45 @@ public class LoansApiResource { private final PlatformSecurityContext context; private final LoanReadPlatformService loanReadPlatformService; - private final LoanWritePlatformService loanWritePlatformService; private final LoanProductReadPlatformService loanProductReadPlatformService; private final LoanDropdownReadPlatformService dropdownReadPlatformService; private final FundReadPlatformService fundReadPlatformService; private final ChargeReadPlatformService chargeReadPlatformService; private final LoanScheduleCalculationPlatformService calculationPlatformService; private final StaffReadPlatformService staffReadPlatformService; - private final OfficeReadPlatformService officeReadPlatformService; private final GuarantorReadPlatformService guarantorReadPlatformService; - private final PortfolioApiJsonSerializerService apiJsonSerializerService; - private final PortfolioApiDataConversionService apiDataConversionService; private final DefaultToApiJsonSerializer toApiJsonSerializer; private final DefaultToApiJsonSerializer loanScheduleToApiJsonSerializer; + private final DefaultToApiJsonSerializer loanOfficeTransferToApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; private final FromJsonHelper fromJsonHelper; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; @Autowired public LoansApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService, - final LoanWritePlatformService loanWritePlatformService, final LoanProductReadPlatformService loanProductReadPlatformService, + final LoanProductReadPlatformService loanProductReadPlatformService, final LoanDropdownReadPlatformService dropdownReadPlatformService, final FundReadPlatformService fundReadPlatformService, final ChargeReadPlatformService chargeReadPlatformService, final LoanScheduleCalculationPlatformService calculationPlatformService, - final StaffReadPlatformService staffReadPlatformService, final OfficeReadPlatformService officeReadPlatformService, - final GuarantorReadPlatformService guarantorReadPlatformService, + final StaffReadPlatformService staffReadPlatformService, final GuarantorReadPlatformService guarantorReadPlatformService, final DefaultToApiJsonSerializer toApiJsonSerializer, final DefaultToApiJsonSerializer loanScheduleToApiJsonSerializer, - final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioApiJsonSerializerService apiJsonSerializerService, - final PortfolioApiDataConversionService apiDataConversionService, final FromJsonHelper fromJsonHelper, + final DefaultToApiJsonSerializer loanOfficeTransferToApiJsonSerializer, + final ApiRequestParameterHelper apiRequestParameterHelper, final FromJsonHelper fromJsonHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { this.context = context; this.loanReadPlatformService = loanReadPlatformService; - this.loanWritePlatformService = loanWritePlatformService; this.loanProductReadPlatformService = loanProductReadPlatformService; this.dropdownReadPlatformService = dropdownReadPlatformService; this.fundReadPlatformService = fundReadPlatformService; this.chargeReadPlatformService = chargeReadPlatformService; this.calculationPlatformService = calculationPlatformService; this.staffReadPlatformService = staffReadPlatformService; - this.officeReadPlatformService = officeReadPlatformService; this.guarantorReadPlatformService = guarantorReadPlatformService; this.toApiJsonSerializer = toApiJsonSerializer; this.loanScheduleToApiJsonSerializer = loanScheduleToApiJsonSerializer; + this.loanOfficeTransferToApiJsonSerializer = loanOfficeTransferToApiJsonSerializer; this.apiRequestParameterHelper = apiRequestParameterHelper; - this.apiJsonSerializerService = apiJsonSerializerService; - this.apiDataConversionService = apiDataConversionService; this.fromJsonHelper = fromJsonHelper; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; } @@ -409,30 +394,12 @@ public class LoansApiResource { return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); } - @POST - @Path("{loanId}/assign") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response assignLoanOfficer(@PathParam("loanId") final Long loanId, final String jsonRequestBody) { - - final BulkTransferLoanOfficerCommand command = this.apiDataConversionService.convertJsonToLoanReassignmentCommand(loanId, - jsonRequestBody); - - EntityIdentifier identifier = this.loanWritePlatformService.loanReassignment(command); - - return Response.ok().entity(identifier).build(); - } - @GET @Path("{loanId}/assign/template") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String assignLoanOfficerTemplate(@PathParam("loanId") final Long loanId, @Context final UriInfo uriInfo) { - final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - - final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - final LoanBasicDetailsData loanBasicDetails = this.loanReadPlatformService.retrieveLoanAccountDetails(loanId); final Collection allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails @@ -442,65 +409,22 @@ public class LoansApiResource { final BulkTransferLoanOfficerData loanReassignmentData = BulkTransferLoanOfficerData.template(fromLoanOfficerId, allowedLoanOfficers, new LocalDate()); - return this.apiJsonSerializerService.serializeLoanReassignmentDataToJson(prettyPrint, responseParameters, loanReassignmentData); + final Set RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList("officeId", "fromLoanOfficerId", "assignmentDate", + "officeOptions", "loanOfficerOptions", "accountSummaryCollection")); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.loanOfficeTransferToApiJsonSerializer.serialize(settings, loanReassignmentData, RESPONSE_DATA_PARAMETERS); } @POST - @Path("loanreassignment") + @Path("{loanId}/assign") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response loanReassignment(final String apiRequestBodyAsJson) { + public String assignLoanOfficer(@PathParam("loanId") final Long loanId, final String apiRequestBodyAsJson) { - // final List allowedPermissions = - // Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", - // "BULKREASSIGN_LOAN"); - // context.authenticatedUser().validateHasPermissionTo("BULKREASSIGN_LOAN", - // allowedPermissions); - // - // final EntityIdentifier result = - // this.commandsSourceWritePlatformService.logCommandSource("BULKREASSIGN_LOAN", - // "staff", null, - // apiRequestBodyAsJson); - // - // return - // this.apiJsonSerializerService.serializeEntityIdentifier(result); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATELOANOFFICER", "LOAN", "N/A", + "loans", loanId, apiRequestBodyAsJson); - final BulkTransferLoanOfficerCommand command = this.apiDataConversionService - .convertJsonToBulkLoanReassignmentCommand(apiRequestBodyAsJson); - - final EntityIdentifier loanOfficerIdentifier = this.loanWritePlatformService.bulkLoanReassignment(command); - - return Response.ok().entity(loanOfficerIdentifier).build(); - } - - @GET - @Path("loanreassignment/template") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String loanReassignmentTemplate(@QueryParam("officeId") final Long officeId, - @QueryParam("fromLoanOfficerId") final Long loanOfficerId, @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission("LOAN"); - - final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - final Collection offices = this.officeReadPlatformService.retrieveAllOfficesForLookup(); - - Collection loanOfficers = null; - StaffAccountSummaryCollectionData staffAccountSummaryCollectionData = null; - - if (officeId != null) { - loanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId); - } - - if (loanOfficerId != null) { - staffAccountSummaryCollectionData = this.staffReadPlatformService.retrieveLoanOfficerAccountSummary(loanOfficerId); - } - - final BulkTransferLoanOfficerData loanReassignmentData = BulkTransferLoanOfficerData.templateForBulk(officeId, loanOfficerId, - new LocalDate(), offices, loanOfficers, staffAccountSummaryCollectionData); - - return this.apiJsonSerializerService.serializeLoanReassignmentDataToJson(prettyPrint, responseParameters, loanReassignmentData); + return this.toApiJsonSerializer.serialize(result); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/command/BulkTransferLoanOfficerCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/UpdateLoanOfficerCommand.java similarity index 50% rename from mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/command/BulkTransferLoanOfficerCommandValidator.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/UpdateLoanOfficerCommand.java index 4eae14c83..da0500e4e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/command/BulkTransferLoanOfficerCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/command/UpdateLoanOfficerCommand.java @@ -1,32 +1,50 @@ -package org.mifosplatform.organisation.staff.command; - -import org.mifosplatform.infrastructure.core.data.ApiParameterError; -import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; -import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +package org.mifosplatform.portfolio.loanaccount.command; import java.util.ArrayList; import java.util.List; -public class BulkTransferLoanOfficerCommandValidator { +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; - private final BulkTransferLoanOfficerCommand command; +/** + * Immutable data object for updating relationship between loan officer and a loan. + */ +public class UpdateLoanOfficerCommand { - public BulkTransferLoanOfficerCommandValidator(BulkTransferLoanOfficerCommand command) { - this.command = command; + private final Long fromLoanOfficerId; + private final Long toLoanOfficerId; + private final LocalDate assignmentDate; + + private final String[] loans; + + public UpdateLoanOfficerCommand(final Long fromLoanOfficerId, final Long toLoanOfficerId, final LocalDate assignmentDate) { + this.fromLoanOfficerId = fromLoanOfficerId; + this.toLoanOfficerId = toLoanOfficerId; + this.assignmentDate = assignmentDate; + this.loans = null; } + 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"); - baseDataValidator.reset().parameter("fromLoanOfficerId").value(command.getFromLoanOfficerId()).notNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("toLoanOfficerId").value(command.getToLoanOfficerId()).notNull().integerGreaterThanZero() - .notSameAsParameter("fromLoanOfficerId", command.getFromLoanOfficerId()); + baseDataValidator.reset().parameter("fromLoanOfficerId").value(this.fromLoanOfficerId).notNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("toLoanOfficerId").value(this.toLoanOfficerId).notNull().integerGreaterThanZero() + .notSameAsParameter("fromLoanOfficerId", this.fromLoanOfficerId); - baseDataValidator.reset().parameter("assignmentDate").value(command.getAssignmentDate()).notNull(); + baseDataValidator.reset().parameter("assignmentDate").value(this.assignmentDate).notNull(); - baseDataValidator.reset().parameter("loans").value(command.getLoans()).arrayNotEmpty(); + baseDataValidator.reset().parameter("loans").value(this.loans).arrayNotEmpty(); if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } @@ -37,14 +55,12 @@ public class BulkTransferLoanOfficerCommandValidator { DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loans.reassignment"); - baseDataValidator.reset().parameter("toLoanOfficerId").value(command.getToLoanOfficerId()).notNull().integerGreaterThanZero() - .notSameAsParameter("fromLoanOfficerId", command.getFromLoanOfficerId()); + baseDataValidator.reset().parameter("toLoanOfficerId").value(this.toLoanOfficerId).notNull().integerGreaterThanZero() + .notSameAsParameter("fromLoanOfficerId", this.fromLoanOfficerId); - baseDataValidator.reset().parameter("assignmentDate").value(command.getAssignmentDate()).notNull(); - - baseDataValidator.reset().parameter("loanId").value(command.getLoanId()).notNull(); + baseDataValidator.reset().parameter("assignmentDate").value(this.assignmentDate).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/handler/BulkUpdateLoanOfficerCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/BulkUpdateLoanOfficerCommandHandler.java new file mode 100644 index 000000000..c16a94f5e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/BulkUpdateLoanOfficerCommandHandler.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.EntityIdentifier; +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 BulkUpdateLoanOfficerCommandHandler implements NewCommandSourceHandler { + + private final LoanWritePlatformService writePlatformService; + + @Autowired + public BulkUpdateLoanOfficerCommandHandler(final LoanWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public EntityIdentifier processCommand(final JsonCommand command) { + + return this.writePlatformService.bulkLoanReassignment(command); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/UpdateLoanOfficerCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/UpdateLoanOfficerCommandHandler.java new file mode 100644 index 000000000..2ee67ff3b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/handler/UpdateLoanOfficerCommandHandler.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.EntityIdentifier; +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 UpdateLoanOfficerCommandHandler implements NewCommandSourceHandler { + + private final LoanWritePlatformService writePlatformService; + + @Autowired + public UpdateLoanOfficerCommandHandler(final LoanWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public EntityIdentifier processCommand(final JsonCommand command) { + + return this.writePlatformService.loanReassignment(command.resourceId(), command); + } +} \ 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 6532ce4fe..2d772ed45 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 @@ -2,8 +2,6 @@ package org.mifosplatform.portfolio.loanaccount.service; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand; -import org.springframework.security.access.prepost.PreAuthorize; public interface LoanWritePlatformService { @@ -45,9 +43,7 @@ public interface LoanWritePlatformService { EntityIdentifier waiveLoanCharge(Long loanId, Long loanChargeId, JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'BULKREASSIGN_LOAN')") - EntityIdentifier bulkLoanReassignment(final BulkTransferLoanOfficerCommand command); + EntityIdentifier loanReassignment(Long loanId, JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - EntityIdentifier loanReassignment(final BulkTransferLoanOfficerCommand command); + EntityIdentifier bulkLoanReassignment(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 919d7b098..575bfa49f 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 @@ -17,8 +17,6 @@ import org.mifosplatform.infrastructure.security.exception.NoAuthorizationExcept import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository; -import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand; -import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommandValidator; import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.portfolio.charge.domain.Charge; import org.mifosplatform.portfolio.charge.domain.ChargeRepository; @@ -657,7 +655,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } this.loanChargeRepository.save(loanCharge); - + loan.addLoanCharge(loanCharge); this.loanRepository.save(loan); @@ -694,7 +692,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Loan loan = retrieveLoanBy(loanId); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); - + final Map changes = new LinkedHashMap(3); final LoanTransaction waiveTransaction = loan.waiveLoanCharge(loanCharge, defaultLoanLifecycleStateMachine(), changes); @@ -742,52 +740,55 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf @Transactional @Override - public EntityIdentifier loanReassignment(BulkTransferLoanOfficerCommand command) { + public EntityIdentifier loanReassignment(final Long loanId, final JsonCommand command) { this.context.authenticatedUser(); - BulkTransferLoanOfficerCommandValidator validator = new BulkTransferLoanOfficerCommandValidator(command); - validator.validateForLoanReassignment(); + final Long fromLoanOfficerId = command.longValueOfParameterNamed("fromLoanOfficerId"); + final Long toLoanOfficerId = command.longValueOfParameterNamed("toLoanOfficerId"); - final Staff fromLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(command.getFromLoanOfficerId()); - final Staff toLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(command.getToLoanOfficerId()); + final Staff fromLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(fromLoanOfficerId); + final Staff toLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(toLoanOfficerId); + final LocalDate dateOfLoanOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate"); - final Loan loan = retrieveLoanBy(command.getLoanId()); + final Loan loan = retrieveLoanBy(loanId); - if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loan.getId(), fromLoanOfficer.getId()); } + if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); } - loan.reassignLoanOfficer(toLoanOfficer, command.getAssignmentDate()); + loan.reassignLoanOfficer(toLoanOfficer, dateOfLoanOfficerAssignment); this.loanRepository.saveAndFlush(loan); - return new EntityIdentifier(loan.getId()); + return EntityIdentifier.resourceResult(loanId, command.commandId()); } @Transactional @Override - public EntityIdentifier bulkLoanReassignment(final BulkTransferLoanOfficerCommand command) { + public EntityIdentifier bulkLoanReassignment(final JsonCommand command) { this.context.authenticatedUser(); - BulkTransferLoanOfficerCommandValidator validator = new BulkTransferLoanOfficerCommandValidator(command); - validator.validateForBulkLoanReassignment(); + final Long fromLoanOfficerId = command.longValueOfParameterNamed("fromLoanOfficerId"); + final Long toLoanOfficerId = command.longValueOfParameterNamed("toLoanOfficerId"); + final String[] loanIds = command.arrayValueOfParameterNamed("loans"); - Staff fromLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(command.getFromLoanOfficerId()); - Staff toLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(command.getToLoanOfficerId()); + final LocalDate dateOfLoanOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate"); - for (String loanIdString : command.getLoans()) { + final Staff fromLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(fromLoanOfficerId); + final Staff toLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(toLoanOfficerId); + + for (final String loanIdString : loanIds) { final Long loanId = Long.valueOf(loanIdString); - final Loan loan = retrieveLoanBy(loanId); - if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loan.getId(), fromLoanOfficer.getId()); } + if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); } - loan.reassignLoanOfficer(toLoanOfficer, command.getAssignmentDate()); + loan.reassignLoanOfficer(toLoanOfficer, dateOfLoanOfficerAssignment); this.loanRepository.save(loan); } this.loanRepository.flush(); - return new EntityIdentifier(toLoanOfficer.getId()); + return EntityIdentifier.resourceResult(null, command.commandId()); } } \ No newline at end of file