FINERACT-2169: Refactor collection sheet api;

This commit is contained in:
viktorpavlenko
2025-04-23 12:17:35 +02:00
committed by Adam Saghy
parent a72a919562
commit a9fe523eae
8 changed files with 216 additions and 42 deletions
@@ -22,6 +22,8 @@ import org.apache.commons.lang3.StringUtils;
public final class CommandParameterUtil {
public static final String GENERATE_COLLECTION_SHEET_COMMAND_VALUE = "generateCollectionSheet";
public static final String SAVE_COLLECTION_SHEET_COMMAND_VALUE = "saveCollectionSheet";
public static final String INTERMEDIARY_SALE_COMMAND_VALUE = "intermediarySale";
public static final String SALE_COMMAND_VALUE = "sale";
public static final String BUY_BACK_COMMAND_VALUE = "buyback";
@@ -18,6 +18,9 @@
*/
package org.apache.fineract.portfolio.collectionsheet.api;
import static org.apache.fineract.infrastructure.core.service.CommandParameterUtil.GENERATE_COLLECTION_SHEET_COMMAND_VALUE;
import static org.apache.fineract.infrastructure.core.service.CommandParameterUtil.SAVE_COLLECTION_SHEET_COMMAND_VALUE;
import com.google.gson.JsonElement;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -32,23 +35,19 @@ import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
import jakarta.ws.rs.core.Response;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
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.api.JsonQuery;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.collectionsheet.CollectionSheetConstants;
import org.apache.fineract.portfolio.collectionsheet.data.IndividualCollectionSheetData;
import org.apache.fineract.portfolio.collectionsheet.data.CollectionSheetRequest;
import org.apache.fineract.portfolio.collectionsheet.service.CollectionSheetReadPlatformService;
import org.springframework.stereotype.Component;
@@ -61,7 +60,6 @@ public class CollectionSheetApiResource {
private final CollectionSheetReadPlatformService collectionSheetReadPlatformService;
private final ToApiJsonSerializer<Object> toApiJsonSerializer;
private final FromJsonHelper fromJsonHelper;
private final ApiRequestParameterHelper apiRequestPrameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final PlatformSecurityContext context;
@@ -72,31 +70,23 @@ public class CollectionSheetApiResource {
+ "This Api retrieves repayment details of all individual loans under a office as on a specified meeting date.\n\n"
+ "Save Collection Sheet:\n\n"
+ "This Api allows the loan officer to perform bulk repayments of individual loans and deposit of mandatory savings on a given meeting date.")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = CollectionSheetApiResourceSwagger.PostCollectionSheetRequest.class)))
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = CollectionSheetRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CollectionSheetApiResourceSwagger.PostCollectionSheetResponse.class))) })
public String generateCollectionSheet(@QueryParam("command") @Parameter(description = "command") final String commandParam,
@Parameter(hidden = true) final String apiRequestBodyAsJson, @Context final UriInfo uriInfo) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandProcessingResult result = null;
public Response generateCollectionSheet(@QueryParam("command") @Parameter(description = "command") final String commandParam,
@Parameter(hidden = true) CollectionSheetRequest collectionSheetRequest) {
final String payload = toApiJsonSerializer.serialize(collectionSheetRequest);
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(payload);
if (is(commandParam, "generateCollectionSheet")) {
if (CommandParameterUtil.is(commandParam, GENERATE_COLLECTION_SHEET_COMMAND_VALUE)) {
this.context.authenticatedUser().validateHasReadPermission(CollectionSheetConstants.COLLECTIONSHEET_RESOURCE_NAME);
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
final IndividualCollectionSheetData collectionSheet = this.collectionSheetReadPlatformService
.generateIndividualCollectionSheet(query);
final ApiRequestJsonSerializationSettings settings = this.apiRequestPrameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, collectionSheet);
} else if (is(commandParam, "saveCollectionSheet")) {
final JsonElement parsedQuery = this.fromJsonHelper.parse(payload);
final JsonQuery query = JsonQuery.from(payload, parsedQuery, this.fromJsonHelper);
return Response.ok(this.collectionSheetReadPlatformService.generateIndividualCollectionSheet(query)).build();
} else if (CommandParameterUtil.is(commandParam, SAVE_COLLECTION_SHEET_COMMAND_VALUE)) {
final CommandWrapper commandRequest = builder.saveIndividualCollectionSheet().build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
return Response.ok(this.commandsSourceWritePlatformService.logCommandSource(commandRequest)).build();
}
return null;
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
return Response.ok().build();
}
}
@@ -0,0 +1,46 @@
/**
* 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.portfolio.collectionsheet.data;
import java.io.Serial;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
@Data
@NoArgsConstructor
@Builder
@AllArgsConstructor
@FieldNameConstants
public class CollectionSheetRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Long officeId;
private String dateFormat;
private String locale;
private String actualDisbursementDate;
private String transactionDate;
private DisbursementTransactionsRequest bulkDisbursementTransactions;
}
@@ -0,0 +1,42 @@
/**
* 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.portfolio.collectionsheet.data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
@Data
@NoArgsConstructor
@FieldNameConstants
@AllArgsConstructor
@Builder
public class DisbursementTransactionsRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private List<RepaymentTransactionRequest> bulkRepaymentTransactions;
private List<SavingDueTransactionRequest> bulkSavingsDueTransactions;
}
@@ -18,14 +18,23 @@
*/
package org.apache.fineract.portfolio.collectionsheet.data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Collection;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
/**
* Immutable data object for collection sheet.
*/
public final class IndividualCollectionSheetData {
@Getter
@RequiredArgsConstructor
public final class IndividualCollectionSheetData implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@SuppressWarnings("unused")
private final LocalDate dueDate;
@@ -35,16 +44,4 @@ public final class IndividualCollectionSheetData {
@SuppressWarnings("unused")
private final Collection<PaymentTypeData> paymentTypeOptions;
public static IndividualCollectionSheetData instance(final LocalDate date, final Collection<IndividualClientData> clients,
final Collection<PaymentTypeData> paymentTypeOptions) {
return new IndividualCollectionSheetData(date, clients, paymentTypeOptions);
}
private IndividualCollectionSheetData(final LocalDate dueDate, final Collection<IndividualClientData> clients,
final Collection<PaymentTypeData> paymentTypeOptions) {
this.dueDate = dueDate;
this.clients = clients;
this.paymentTypeOptions = paymentTypeOptions;
}
}
@@ -0,0 +1,48 @@
/**
* 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.portfolio.collectionsheet.data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
@Data
@NoArgsConstructor
@FieldNameConstants
@AllArgsConstructor
@Builder
public class RepaymentTransactionRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Long loanId;
private BigDecimal transactionAmount;
private Long paymentTypeId;
private String accountNumber;
private String checkNumber;
private String routingCode;
private String receiptNumber;
private String bankNumber;
}
@@ -0,0 +1,49 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.collectionsheet.data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
@Data
@NoArgsConstructor
@FieldNameConstants
@AllArgsConstructor
@Builder
public class SavingDueTransactionRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Long savingsId;
private BigDecimal transactionAmount;
private Long depositAccountType;
private Long paymentTypeId;
private String accountNumber;
private String checkNumber;
private String routingCode;
private String receiptNumber;
private String bankNumber;
}
@@ -713,7 +713,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
final Collection<PaymentTypeData> paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
return IndividualCollectionSheetData.instance(transactionDate, clientData, paymentOptions);
return new IndividualCollectionSheetData(transactionDate, clientData, paymentOptions);
}