FINERACT-1932: Fineract modularization - fineract-charge

This commit is contained in:
Jose Alberto Hernandez
2024-05-21 22:53:36 +02:00
committed by Adam Saghy
parent e13a9cba01
commit a3fb836b73
53 changed files with 306 additions and 8 deletions
@@ -1,187 +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.portfolio.charge.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
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.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
import org.springframework.stereotype.Component;
@Path("/v1/charges")
@Component
@Tag(name = "Charges", description = "Its typical for MFIs to add extra costs for their financial products. These are typically Fees or Penalties.\n"
+ "\n" + "A Charge on fineract platform is what we use to model both Fees and Penalties.\n" + "\n"
+ "At present we support defining charges for use with Client accounts and both loan and saving products.")
@RequiredArgsConstructor
public class ChargesApiResource {
private static final Set<String> CHARGES_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "amount", "currency", "penalty",
"active", "chargeAppliesTo", "chargeTimeType", "chargeCalculationType", "chargeCalculationTypeOptions",
"chargeAppliesToOptions", "chargeTimeTypeOptions", "currencyOptions", "loanChargeCalculationTypeOptions",
"loanChargeTimeTypeOptions", "savingsChargeCalculationTypeOptions", "savingsChargeTimeTypeOptions", "incomeAccount",
"clientChargeCalculationTypeOptions", "clientChargeTimeTypeOptions"));
private static final String RESOURCE_NAME_FOR_PERMISSIONS = "CHARGE";
private final PlatformSecurityContext context;
private final ChargeReadPlatformService readPlatformService;
private final DefaultToApiJsonSerializer<ChargeData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Retrieve Charges", description = "Returns the list of defined charges.\n" + "\n" + "Example Requests:\n" + "\n"
+ "charges")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ChargesApiResourceSwagger.GetChargesResponse.class)))) })
public String retrieveAllCharges(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final Collection<ChargeData> charges = this.readPlatformService.retrieveAllCharges();
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, charges, CHARGES_DATA_PARAMETERS);
}
@GET
@Path("{chargeId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Retrieve a Charge", description = "Returns the details of a defined Charge.\n" + "\n" + "Example Requests:\n"
+ "\n" + "charges/1")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ChargesApiResourceSwagger.GetChargesResponse.class))) })
public String retrieveCharge(@PathParam("chargeId") @Parameter(description = "chargeId") final Long chargeId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
ChargeData charge = this.readPlatformService.retrieveCharge(chargeId);
if (settings.isTemplate()) {
final ChargeData templateData = this.readPlatformService.retrieveNewChargeDetails();
charge = ChargeData.withTemplate(charge, templateData);
}
return this.toApiJsonSerializer.serialize(settings, charge, CHARGES_DATA_PARAMETERS);
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Retrieve Charge Template", description = "This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of:\n"
+ "\n" + "Field Defaults\n" + "Allowed description Lists\n" + "Example Request:\n" + "\n" + "charges/template\n")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ChargesApiResourceSwagger.GetChargesTemplateResponse.class))) })
public String retrieveNewChargeDetails(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final ChargeData charge = this.readPlatformService.retrieveNewChargeDetails();
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, charge, CHARGES_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Create/Define a Charge", description = "Define a new charge that can later be associated with loans and savings through their respective product definitions or directly on each account instance.")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = ChargesApiResourceSwagger.PostChargesRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ChargesApiResourceSwagger.PostChargesResponse.class))) })
public String createCharge(@Parameter(hidden = true) final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createCharge().withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@PUT
@Path("{chargeId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Update a Charge", description = "Updates the details of a Charge.")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = ChargesApiResourceSwagger.PutChargesChargeIdRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ChargesApiResourceSwagger.PutChargesChargeIdResponse.class))) })
public String updateCharge(@PathParam("chargeId") @Parameter(description = "chargeId") final Long chargeId,
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateCharge(chargeId).withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@DELETE
@Path("{chargeId}")
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Delete a Charge", description = "Deletes a Charge.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ChargesApiResourceSwagger.DeleteChargesChargeIdResponse.class))) })
public String deleteCharge(@PathParam("chargeId") @Parameter(description = "chargeId") final Long chargeId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteCharge(chargeId).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -1,237 +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.portfolio.charge.api;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Set;
/**
* Created by Chirag Gupta on 12/01/17.
*/
final class ChargesApiResourceSwagger {
@Schema(description = "GetChargesResponse")
public static final class GetChargesResponse {
private GetChargesResponse() {}
static final class GetChargesCurrencyResponse {
@Schema(example = "USD")
public String code;
@Schema(example = "US Dollar")
public String name;
@Schema(example = "2")
public Integer decimalPlaces;
@Schema(example = "$")
public String displaySymbol;
@Schema(example = "currency.USD")
public String nameCode;
@Schema(example = "US Dollar ($)")
public String displayLabel;
}
static final class GetChargesTimeTypeResponse {
private GetChargesTimeTypeResponse() {}
@Schema(example = "1")
public Long id;
@Schema(example = "chargeTimeType.disbursement")
public String code;
@Schema(example = "Disbursement")
public String description;
}
static final class GetChargesAppliesToResponse {
private GetChargesAppliesToResponse() {}
@Schema(example = "1")
public Long id;
@Schema(example = "chargeAppliesTo.loan")
public String code;
@Schema(example = "Loan")
public String description;
}
static final class GetChargesCalculationTypeResponse {
private GetChargesCalculationTypeResponse() {}
@Schema(example = "1")
public Long id;
@Schema(example = "chargeCalculationType.flat")
public String code;
@Schema(example = "Flat")
public String description;
}
static final class GetChargesPaymentModeResponse {
private GetChargesPaymentModeResponse() {}
@Schema(example = "1")
public Long id;
@Schema(example = "chargepaymentmode.accounttransfer")
public String code;
@Schema(example = "Account Transfer")
public String description;
}
@Schema(example = "1")
public Long id;
@Schema(example = "Loan Service fee")
public String name;
@Schema(example = "true")
public boolean active;
@Schema(example = "false")
public boolean penalty;
public GetChargesCurrencyResponse currency;
@Schema(example = "230.56")
public Double amount;
public GetChargesTimeTypeResponse chargeTimeType;
public GetChargesAppliesToResponse chargeAppliesTo;
public GetChargesCalculationTypeResponse chargeCalculationType;
public GetChargesPaymentModeResponse chargePaymentMode;
}
@Schema(description = "PostChargesRequest")
public static final class PostChargesRequest {
private PostChargesRequest() {}
@Schema(example = "Loan Service fee")
public String name;
@Schema(example = "1")
public Integer chargeAppliesTo;
@Schema(example = "USD")
public String currencyCode;
@Schema(example = "en")
public String locale;
@Schema(example = "230.56")
public Double amount;
@Schema(example = "1")
public Integer chargeTimeType;
@Schema(example = "1")
public Integer chargeCalculationType;
@Schema(example = "1")
public Integer chargePaymentMode;
@Schema(example = "true")
public boolean active;
@Schema(example = "dd MMMM")
public String monthDayFormat;
@Schema(example = "false")
public boolean penalty;
}
@Schema(description = "PostChargesResponse")
public static final class PostChargesResponse {
private PostChargesResponse() {}
@Schema(example = "1")
public Long resourceId;
}
@Schema(description = "PutChargesChargeIdRequest")
public static final class PutChargesChargeIdRequest {
private PutChargesChargeIdRequest() {}
@Schema(example = "Loan service fee(changed)")
public String name;
}
@Schema(description = "PutChargesChargeIdResponse")
public static final class PutChargesChargeIdResponse {
private PutChargesChargeIdResponse() {}
@Schema(example = "1")
public Long resourceId;
public PutChargesChargeIdRequest changes;
}
@Schema(description = "DeleteChargesChargeIdResponse")
public static final class DeleteChargesChargeIdResponse {
private DeleteChargesChargeIdResponse() {}
@Schema(example = "1")
public Long resourceId;
}
@Schema(description = "GetChargesTemplateResponse")
public static final class GetChargesTemplateResponse {
private GetChargesTemplateResponse() {}
static final class GetChargesTemplateLoanChargeCalculationTypeOptions {
private GetChargesTemplateLoanChargeCalculationTypeOptions() {}
@Schema(example = "1")
public Long id;
@Schema(example = "chargeCalculationType.flat")
public String code;
@Schema(example = "Flat")
public String description;
}
static final class GetChargesTemplateLoanChargeTimeTypeOptions {
private GetChargesTemplateLoanChargeTimeTypeOptions() {}
@Schema(example = "2")
public Long id;
@Schema(example = "chargeTimeType.specifiedDueDate")
public String code;
@Schema(example = "Specified due date")
public String description;
}
static final class GetChargesTemplateFeeFrequencyOptions {
private GetChargesTemplateFeeFrequencyOptions() {}
@Schema(example = "0")
public Long id;
@Schema(example = "loanTermFrequency.periodFrequencyType.days")
public String code;
@Schema(example = "Days")
public String description;
}
@Schema(example = "false")
public boolean active;
@Schema(example = "false")
public boolean penalty;
public Set<GetChargesResponse.GetChargesCurrencyResponse> currencyOptions;
public Set<GetChargesResponse.GetChargesCalculationTypeResponse> chargeCalculationTypeOptions;
public Set<GetChargesResponse.GetChargesAppliesToResponse> chargeAppliesToOptions;
public Set<GetChargesResponse.GetChargesTimeTypeResponse> chargeTimeTypeOptions;
public Set<GetChargesResponse.GetChargesPaymentModeResponse> chargePaymentModeOptions;
public Set<GetChargesTemplateLoanChargeCalculationTypeOptions> loanChargeCalculationTypeOptions;
public Set<GetChargesTemplateLoanChargeTimeTypeOptions> loanChargeTimeTypeOptions;
public Set<GetChargesTemplateLoanChargeCalculationTypeOptions> savingsChargeCalculationTypeOptions;
public Set<GetChargesTemplateLoanChargeTimeTypeOptions> savingsChargeTimeTypeOptions;
public Set<GetChargesTemplateFeeFrequencyOptions> feeFrequencyOptions;
}
}
@@ -1,31 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class ChargeCannotBeDeletedException extends AbstractPlatformDomainRuleException {
public ChargeCannotBeDeletedException(final String globalisationMessageCode, final String defaultUserMessage,
final Object... defaultUserMessageArgs) {
super(globalisationMessageCode, defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -1,31 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class ChargeCannotBeUpdatedException extends AbstractPlatformDomainRuleException {
public ChargeCannotBeUpdatedException(final String globalisationMessageCode, final String defaultUserMessage,
final Object... defaultUserMessageArgs) {
super(globalisationMessageCode, defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -1,56 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanChargeCannotBeDeletedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Loan Charge cannot be waived **/
public enum LoanChargeCannotBeDeletedReason {
ALREADY_PAID, ALREADY_WAIVED, LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "This loan charge has been partially/completely paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This loan charge has already been waived";
} else if (name().toString().equalsIgnoreCase("LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE")) {
return "This charge cannot be deleted as the loan it is associated with is not in submitted and pending approval stage";
}
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.loan.charge.already.paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.loan.charge.already.waived";
} else if (name().toString().equalsIgnoreCase("LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE")) {
return "error.msg.loan.charge.associated.loan.not.in.submitted.and.pending.approval.stage";
}
return name().toString();
}
}
public LoanChargeCannotBeDeletedException(final LoanChargeCannotBeDeletedReason reason, final Long loanChargeId) {
super(reason.errorCode(), reason.errorMessage(), loanChargeId);
}
}
@@ -1,65 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanChargeCannotBePayedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Loan Charge cannot be waived **/
public enum LoanChargeCannotBePayedReason {
ALREADY_PAID, ALREADY_WAIVED, LOAN_INACTIVE, CHARGE_NOT_ACCOUNT_TRANSFER, CHARGE_NOT_PAYABLE;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "This loan charge has been completely paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This loan charge has already been waived";
} else if (name().toString().equalsIgnoreCase("LOAN_INACTIVE")) {
return "This loan charge can be payed as the loan associated with it is currently inactive";
} else if (name().toString().equalsIgnoreCase("CHARGE_NOT_ACCOUNT_TRANSFER")) {
return "This loan charge can be payed as the charge payment mode is not account transfer";
} else if (name().toString().equalsIgnoreCase("CHARGE_NOT_PAYABLE")) {
return "This loan charge is not Payable through account transfer";
}
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.loan.charge.already.paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.loan.charge.already.waived";
} else if (name().toString().equalsIgnoreCase("LOAN_INACTIVE")) {
return "error.msg.loan.charge.associated.loan.inactive";
} else if (name().toString().equalsIgnoreCase("CHARGE_NOT_ACCOUNT_TRANSFER")) {
return "error.msg.loan.charge.payment.mode.not.account.transfer";
} else if (name().toString().equalsIgnoreCase("CHARGE_NOT_PAYABLE")) {
return "error.msg.loan.charge.payment.not.allowed.account.transfer";
}
return name().toString();
}
}
public LoanChargeCannotBePayedException(final LoanChargeCannotBePayedReason reason, final Long loanChargeId) {
super(reason.errorCode(), reason.errorMessage(), loanChargeId);
}
}
@@ -1,56 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanChargeCannotBeUpdatedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Loan Charge cannot be waived **/
public enum LoanChargeCannotBeUpdatedReason {
ALREADY_PAID, ALREADY_WAIVED, LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "This loan charge has been partially/completely paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This loan charge has already been waived";
} else if (name().toString().equalsIgnoreCase("LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE")) {
return "This charge cannot be updated as the loan it is associated with is not in submitted and pending approval stage";
}
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.loan.charge.already.paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.loan.charge.already.waived";
} else if (name().toString().equalsIgnoreCase("LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE")) {
return "error.msg.loan.charge.associated.loan.not.in.submitted.and.pending.approval.stage";
}
return name().toString();
}
}
public LoanChargeCannotBeUpdatedException(final LoanChargeCannotBeUpdatedReason reason, final Long loanChargeId) {
super(reason.errorCode(), reason.errorMessage(), loanChargeId);
}
}
@@ -1,61 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanChargeCannotBeWaivedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Loan Charge cannot be waived **/
public enum LoanChargeCannotBeWaivedReason {
ALREADY_PAID, ALREADY_WAIVED, LOAN_INACTIVE, WAIVE_NOT_ALLOWED_FOR_CHARGE;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "This loan charge has been completely paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This loan charge has already been waived";
} else if (name().toString().equalsIgnoreCase("LOAN_INACTIVE")) {
return "This loan charge can be waived as the loan associated with it is currently inactive";
} else if (name().toString().equalsIgnoreCase("WAIVE_NOT_ALLOWED_FOR_CHARGE")) {
return "This loan charge can be waived";
}
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.loan.charge.already.paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.loan.charge.already.waived";
} else if (name().toString().equalsIgnoreCase("LOAN_INACTIVE")) {
return "error.msg.loan.charge.associated.loan.inactive";
} else if (name().toString().equalsIgnoreCase("WAIVE_NOT_ALLOWED_FOR_CHARGE")) {
return "error.msg.loan.charge.waive.not.allowed";
}
return name().toString();
}
}
public LoanChargeCannotBeWaivedException(final LoanChargeCannotBeWaivedReason reason, final Long loanChargeId) {
super(reason.errorCode(), reason.errorMessage(), loanChargeId);
}
}
@@ -1,54 +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.portfolio.charge.exception;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when loan charge does not exist.
*/
public class LoanChargeNotFoundException extends AbstractPlatformResourceNotFoundException {
public LoanChargeNotFoundException() {
super("error.msg.loanCharge.invalid", "Loan charge cannot be found");
}
public LoanChargeNotFoundException(final Long id) {
super("error.msg.loanCharge.id.invalid", "Loan charge with identifier " + id + " does not exist", id);
}
public LoanChargeNotFoundException(final Long id, final Long loanId) {
super("error.msg.loanCharge.id.invalid.for.given.loan", "Loan charge with identifier " + id + " does not exist for loan " + loanId,
id, loanId);
}
public LoanChargeNotFoundException(final Long id, final Long loanId, final EmptyResultDataAccessException e) {
super("error.msg.loanCharge.id.invalid.for.given.loan", "Loan charge with identifier " + id + " does not exist for loan " + loanId,
id, loanId, e);
}
public LoanChargeNotFoundException(ExternalId externalId) {
super("error.msg.loanCharge.external.id.invalid", "Loan Charge with external identifier "
+ ObjectUtils.defaultIfNull(externalId, ExternalId.empty()).getValue() + " does not exist", externalId);
}
}
@@ -1,71 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanChargeWaiveCannotBeReversedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Loan Charge waive cannot undo **/
public enum LoanChargeWaiveCannotUndoReason {
ALREADY_PAID, ALREADY_WAIVED, LOAN_INACTIVE, WAIVE_NOT_ALLOWED_FOR_CHARGE, NOT_WAIVED, ALREADY_REVERSED;
public String errorMessage() {
if (name().equalsIgnoreCase("ALREADY_PAID")) {
return "This loan charge has been completely paid";
} else if (name().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This loan charge has already been waived";
} else if (name().equalsIgnoreCase("LOAN_INACTIVE")) {
return "This loan charge can be waived as the loan associated with it is currently inactive";
} else if (name().equalsIgnoreCase("WAIVE_NOT_ALLOWED_FOR_CHARGE")) {
return "This loan charge can be waived";
} else if (name().equalsIgnoreCase("NOT_WAIVED")) {
return "This loan charge waive cannot be reversed as this charge is not waived";
} else if (name().equalsIgnoreCase("ALREADY_REVERSED")) {
return "This loan charge waive cannot be reversed as this transaction is already reversed";
}
return name();
}
public String errorCode() {
if (name().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.loan.charge.already.paid";
} else if (name().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.loan.charge.already.waived";
} else if (name().equalsIgnoreCase("LOAN_INACTIVE")) {
return "error.msg.loan.charge.associated.loan.inactive";
} else if (name().equalsIgnoreCase("WAIVE_NOT_ALLOWED_FOR_CHARGE")) {
return "error.msg.loan.charge.waive.not.allowed";
} else if (name().equalsIgnoreCase("NOT_WAIVED")) {
return "error.msg.loan.charge.waive.cannot.undo";
} else if (name().equalsIgnoreCase("ALREADY_REVERSED")) {
return "error.msg.transaction.cannot.reverse";
}
return name();
}
}
public LoanChargeWaiveCannotBeReversedException(final LoanChargeWaiveCannotUndoReason reason, final Long id) {
super(reason.errorCode(), reason.errorMessage(), id);
}
}
@@ -1,33 +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.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when currency mismatch occurs
*/
public class ShareAccountChargeWithoutMandatoryFieldException extends AbstractPlatformDomainRuleException {
public ShareAccountChargeWithoutMandatoryFieldException(final String entity, final String postFix, final String defaultUserMessage,
final Object... defaultUserMessageArgs) {
super("error.msg." + entity + "." + postFix + ".cannot.be.blank", defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -1,47 +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.portfolio.charge.handler;
import org.apache.fineract.commands.annotation.CommandType;
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.portfolio.charge.service.ChargeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "CHARGE", action = "CREATE")
public class CreateChargeDefinitionCommandHandler implements NewCommandSourceHandler {
private final ChargeWritePlatformService clientWritePlatformService;
@Autowired
public CreateChargeDefinitionCommandHandler(final ChargeWritePlatformService clientWritePlatformService) {
this.clientWritePlatformService = clientWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.clientWritePlatformService.createCharge(command);
}
}
@@ -1,47 +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.portfolio.charge.handler;
import org.apache.fineract.commands.annotation.CommandType;
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.portfolio.charge.service.ChargeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "CHARGE", action = "DELETE")
public class DeleteChargeDefinitionCommandHandler implements NewCommandSourceHandler {
private final ChargeWritePlatformService clientWritePlatformService;
@Autowired
public DeleteChargeDefinitionCommandHandler(final ChargeWritePlatformService clientWritePlatformService) {
this.clientWritePlatformService = clientWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.clientWritePlatformService.deleteCharge(command.entityId());
}
}
@@ -1,47 +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.portfolio.charge.handler;
import org.apache.fineract.commands.annotation.CommandType;
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.portfolio.charge.service.ChargeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "CHARGE", action = "UPDATE")
public class UpdateChargeDefinitionCommandHandler implements NewCommandSourceHandler {
private final ChargeWritePlatformService clientWritePlatformService;
@Autowired
public UpdateChargeDefinitionCommandHandler(final ChargeWritePlatformService clientWritePlatformService) {
this.clientWritePlatformService = clientWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.clientWritePlatformService.updateCharge(command.entityId(), command);
}
}
@@ -1,487 +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.portfolio.charge.serialization;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.MonthDay;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.charge.api.ChargesApiConstants;
import org.apache.fineract.portfolio.charge.domain.ChargeAppliesTo;
import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType;
import org.apache.fineract.portfolio.charge.domain.ChargePaymentMode;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public final class ChargeDefinitionCommandFromApiJsonDeserializer {
public static final String NAME = "name";
public static final String AMOUNT = "amount";
public static final String LOCALE = "locale";
public static final String CURRENCY_CODE = "currencyCode";
public static final String PENALTY = "penalty";
public static final String CHARGE_CALCULATION_TYPE_OPTIONS = "chargeCalculationTypeOptions";
public static final String CHARGE_CALCULATION_TYPE = "chargeCalculationType";
public static final String CHARGE_TIME_TYPE = "chargeTimeType";
public static final String CHARGE_APPLIES_TO = "chargeAppliesTo";
public static final String CURRENCY_OPTIONS = "currencyOptions";
public static final String ACTIVE = "active";
public static final String CHARGE_PAYMENT_MODE = "chargePaymentMode";
public static final String FEE_ON_MONTH_DAY = "feeOnMonthDay";
public static final String FEE_INTERVAL = "feeInterval";
public static final String MONTH_DAY_FORMAT = "monthDayFormat";
public static final String MIN_CAP = "minCap";
public static final String MAX_CAP = "maxCap";
public static final String FEE_FREQUENCY = "feeFrequency";
public static final String ENABLE_FREE_WITHDRAWAL_CHARGE = "enableFreeWithdrawalCharge";
public static final String FREE_WITHDRAWAL_FREQUENCY = "freeWithdrawalFrequency";
public static final String RESTART_COUNT_FREQUENCY = "restartCountFrequency";
public static final String COUNT_FREQUENCY_TYPE = "countFrequencyType";
public static final String ENABLE_PAYMENT_TYPE = "enablePaymentType";
public static final String PAYMENT_TYPE_ID = "paymentTypeId";
public static final String CHARGE = "charge";
/**
* The parameters supported for this command.
*/
private static final Set<String> SUPPORTED_PARAMETERS = new HashSet<>(Arrays.asList(NAME, AMOUNT, LOCALE, CURRENCY_CODE,
CURRENCY_OPTIONS, CHARGE_APPLIES_TO, CHARGE_TIME_TYPE, CHARGE_CALCULATION_TYPE, CHARGE_CALCULATION_TYPE_OPTIONS, PENALTY,
ACTIVE, CHARGE_PAYMENT_MODE, FEE_ON_MONTH_DAY, FEE_INTERVAL, MONTH_DAY_FORMAT, MIN_CAP, MAX_CAP, FEE_FREQUENCY,
ENABLE_FREE_WITHDRAWAL_CHARGE, FREE_WITHDRAWAL_FREQUENCY, RESTART_COUNT_FREQUENCY, COUNT_FREQUENCY_TYPE, PAYMENT_TYPE_ID,
ENABLE_PAYMENT_TYPE, ChargesApiConstants.glAccountIdParamName, ChargesApiConstants.taxGroupIdParamName));
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public ChargeDefinitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(CHARGE);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Integer chargeAppliesTo = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_APPLIES_TO, element);
baseDataValidator.reset().parameter(CHARGE_APPLIES_TO).value(chargeAppliesTo).notNull();
if (chargeAppliesTo != null) {
baseDataValidator.reset().parameter(CHARGE_APPLIES_TO).value(chargeAppliesTo).isOneOfTheseValues(ChargeAppliesTo.validValues());
}
final Integer chargeCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_CALCULATION_TYPE, element);
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType).notNull();
final Integer feeInterval = this.fromApiJsonHelper.extractIntegerNamed(FEE_INTERVAL, element, Locale.getDefault());
baseDataValidator.reset().parameter(FEE_INTERVAL).value(feeInterval).integerGreaterThanZero();
final Integer feeFrequency = this.fromApiJsonHelper.extractIntegerNamed(FEE_FREQUENCY, element, Locale.getDefault());
baseDataValidator.reset().parameter(FEE_FREQUENCY).value(feeFrequency).inMinMaxRange(0, 3);
if (this.fromApiJsonHelper.parameterExists(ENABLE_FREE_WITHDRAWAL_CHARGE, element)) {
final Boolean enableFreeWithdrawalCharge = this.fromApiJsonHelper.extractBooleanNamed(ENABLE_FREE_WITHDRAWAL_CHARGE, element);
baseDataValidator.reset().parameter(ENABLE_FREE_WITHDRAWAL_CHARGE).value(enableFreeWithdrawalCharge).notNull();
if (enableFreeWithdrawalCharge) {
final Integer freeWithdrawalFrequency = this.fromApiJsonHelper.extractIntegerNamed(FREE_WITHDRAWAL_FREQUENCY, element,
Locale.getDefault());
baseDataValidator.reset().parameter(FREE_WITHDRAWAL_FREQUENCY).value(freeWithdrawalFrequency).integerGreaterThanZero();
final Integer restartCountFrequency = this.fromApiJsonHelper.extractIntegerNamed(RESTART_COUNT_FREQUENCY, element,
Locale.getDefault());
baseDataValidator.reset().parameter(RESTART_COUNT_FREQUENCY).value(restartCountFrequency).integerGreaterThanZero();
final Integer countFrequencyType = this.fromApiJsonHelper.extractIntegerNamed(COUNT_FREQUENCY_TYPE, element,
Locale.getDefault());
baseDataValidator.reset().parameter(COUNT_FREQUENCY_TYPE).value(countFrequencyType);
}
}
if (this.fromApiJsonHelper.parameterExists(ENABLE_PAYMENT_TYPE, element)) {
final boolean enablePaymentType = this.fromApiJsonHelper.extractBooleanNamed(ENABLE_PAYMENT_TYPE, element);
baseDataValidator.reset().parameter(ENABLE_PAYMENT_TYPE).value(enablePaymentType).notNull();
if (enablePaymentType) {
final Integer paymentTypeId = this.fromApiJsonHelper.extractIntegerNamed(PAYMENT_TYPE_ID, element, Locale.getDefault());
baseDataValidator.reset().parameter(PAYMENT_TYPE_ID).value(paymentTypeId).integerGreaterThanZero();
}
}
if (feeFrequency != null) {
baseDataValidator.reset().parameter(FEE_INTERVAL).value(feeInterval).notNull();
}
final ChargeAppliesTo appliesTo = ChargeAppliesTo.fromInt(chargeAppliesTo);
if (appliesTo.isLoanCharge()) {
// loan applicable validation
final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_TIME_TYPE, element);
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType).notNull();
if (chargeTimeType != null) {
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType)
.isOneOfTheseValues(ChargeTimeType.validLoanValues());
}
final Integer chargePaymentMode = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_PAYMENT_MODE, element);
baseDataValidator.reset().parameter(CHARGE_PAYMENT_MODE).value(chargePaymentMode).notNull()
.isOneOfTheseValues(ChargePaymentMode.validValues());
if (chargePaymentMode != null) {
baseDataValidator.reset().parameter(CHARGE_PAYMENT_MODE).value(chargePaymentMode)
.isOneOfTheseValues(ChargePaymentMode.validValues());
}
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForLoan());
}
if (chargeTimeType != null && chargeCalculationType != null) {
performChargeTimeNCalculationTypeValidation(baseDataValidator, chargeTimeType, chargeCalculationType);
}
} else if (appliesTo.isSavingsCharge()) {
// savings applicable validation
final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_TIME_TYPE, element);
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType).notNull();
if (chargeTimeType != null) {
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType)
.isOneOfTheseValues(ChargeTimeType.validSavingsValues());
}
final ChargeTimeType ctt = ChargeTimeType.fromInt(chargeTimeType);
if (ctt.isWeeklyFee()) {
final String monthDay = this.fromApiJsonHelper.extractStringNamed(FEE_ON_MONTH_DAY, element);
baseDataValidator.reset().parameter(FEE_ON_MONTH_DAY).value(monthDay).mustBeBlankWhenParameterProvidedIs(CHARGE_TIME_TYPE,
chargeTimeType);
}
if (ctt.isMonthlyFee()) {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed(FEE_ON_MONTH_DAY, element);
baseDataValidator.reset().parameter(FEE_ON_MONTH_DAY).value(monthDay).notNull();
baseDataValidator.reset().parameter(FEE_INTERVAL).value(feeInterval).notNull().inMinMaxRange(1, 12);
}
if (ctt.isAnnualFee()) {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed(FEE_ON_MONTH_DAY, element);
baseDataValidator.reset().parameter(FEE_ON_MONTH_DAY).value(monthDay).notNull();
}
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForSavings());
}
} else if (appliesTo.isClientCharge()) {
// client applicable validation
final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_TIME_TYPE, element);
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType).notNull();
if (chargeTimeType != null) {
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType)
.isOneOfTheseValues(ChargeTimeType.validClientValues());
}
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForClients());
}
// GL Account can be linked to clients
if (this.fromApiJsonHelper.parameterExists(ChargesApiConstants.glAccountIdParamName, element)) {
final Long glAccountId = this.fromApiJsonHelper.extractLongNamed(ChargesApiConstants.glAccountIdParamName, element);
baseDataValidator.reset().parameter(ChargesApiConstants.glAccountIdParamName).value(glAccountId).notNull()
.longGreaterThanZero();
}
} else if (appliesTo.isSharesCharge()) {
final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_TIME_TYPE, element);
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType).notNull();
if (chargeTimeType != null) {
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType)
.isOneOfTheseValues(ChargeTimeType.validShareValues());
}
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForShares());
}
if (chargeTimeType != null && chargeTimeType.equals(ChargeTimeType.SHAREACCOUNT_ACTIVATION.getValue())
&& chargeCalculationType != null) {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForShareAccountActivation());
}
}
final String name = this.fromApiJsonHelper.extractStringNamed(NAME, element);
baseDataValidator.reset().parameter(NAME).value(name).notBlank().notExceedingLengthOf(100);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(CURRENCY_CODE, element);
baseDataValidator.reset().parameter(CURRENCY_CODE).value(currencyCode).notBlank().notExceedingLengthOf(3);
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(AMOUNT, element.getAsJsonObject());
baseDataValidator.reset().parameter(AMOUNT).value(amount).notNull().positiveAmount();
if (this.fromApiJsonHelper.parameterExists(PENALTY, element)) {
final Boolean penalty = this.fromApiJsonHelper.extractBooleanNamed(PENALTY, element);
baseDataValidator.reset().parameter(PENALTY).value(penalty).notNull();
}
if (this.fromApiJsonHelper.parameterExists(ACTIVE, element)) {
final Boolean active = this.fromApiJsonHelper.extractBooleanNamed(ACTIVE, element);
baseDataValidator.reset().parameter(ACTIVE).value(active).notNull();
}
if (this.fromApiJsonHelper.parameterExists(MIN_CAP, element)) {
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(MIN_CAP, element.getAsJsonObject());
baseDataValidator.reset().parameter(MIN_CAP).value(minCap).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(MAX_CAP, element)) {
final BigDecimal maxCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(MAX_CAP, element.getAsJsonObject());
baseDataValidator.reset().parameter(MAX_CAP).value(maxCap).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(ChargesApiConstants.taxGroupIdParamName, element)) {
final Long taxGroupId = this.fromApiJsonHelper.extractLongNamed(ChargesApiConstants.taxGroupIdParamName, element);
baseDataValidator.reset().parameter(ChargesApiConstants.taxGroupIdParamName).value(taxGroupId).notNull().longGreaterThanZero();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(CHARGE);
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists(NAME, element)) {
final String name = this.fromApiJsonHelper.extractStringNamed(NAME, element);
baseDataValidator.reset().parameter(NAME).value(name).notBlank().notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(CURRENCY_CODE, element)) {
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(CURRENCY_CODE, element);
baseDataValidator.reset().parameter(CURRENCY_CODE).value(currencyCode).notBlank().notExceedingLengthOf(3);
}
if (this.fromApiJsonHelper.parameterExists(AMOUNT, element)) {
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(AMOUNT, element.getAsJsonObject());
baseDataValidator.reset().parameter(AMOUNT).value(amount).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(MIN_CAP, element)) {
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(MIN_CAP, element.getAsJsonObject());
baseDataValidator.reset().parameter(MIN_CAP).value(minCap).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(MAX_CAP, element)) {
final BigDecimal maxCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(MAX_CAP, element.getAsJsonObject());
baseDataValidator.reset().parameter(MAX_CAP).value(maxCap).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(CHARGE_APPLIES_TO, element)) {
final Integer chargeAppliesTo = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_APPLIES_TO, element);
baseDataValidator.reset().parameter(CHARGE_APPLIES_TO).value(chargeAppliesTo).notNull()
.isOneOfTheseValues(ChargeAppliesTo.validValues());
}
Boolean enableFreeWithdrawalCharge = false;
if (this.fromApiJsonHelper.parameterExists(ENABLE_FREE_WITHDRAWAL_CHARGE, element)) {
enableFreeWithdrawalCharge = this.fromApiJsonHelper.extractBooleanNamed(ENABLE_FREE_WITHDRAWAL_CHARGE, element);
baseDataValidator.reset().parameter(ENABLE_FREE_WITHDRAWAL_CHARGE).value(enableFreeWithdrawalCharge).notNull();
if (enableFreeWithdrawalCharge) {
final Integer freeWithdrawalFrequency = this.fromApiJsonHelper.extractIntegerNamed(FREE_WITHDRAWAL_FREQUENCY, element,
Locale.getDefault());
baseDataValidator.reset().parameter(FREE_WITHDRAWAL_FREQUENCY).value(freeWithdrawalFrequency).integerGreaterThanZero();
final Integer restartCountFrequency = this.fromApiJsonHelper.extractIntegerNamed(RESTART_COUNT_FREQUENCY, element,
Locale.getDefault());
baseDataValidator.reset().parameter(RESTART_COUNT_FREQUENCY).value(restartCountFrequency).integerGreaterThanZero();
final Integer countFrequencyType = this.fromApiJsonHelper.extractIntegerNamed(COUNT_FREQUENCY_TYPE, element,
Locale.getDefault());
baseDataValidator.reset().parameter(COUNT_FREQUENCY_TYPE).value(countFrequencyType);
}
Boolean enablePaymentType = false;
if (this.fromApiJsonHelper.parameterExists(ENABLE_PAYMENT_TYPE, element)) {
enablePaymentType = this.fromApiJsonHelper.extractBooleanNamed(ENABLE_PAYMENT_TYPE, element);
baseDataValidator.reset().parameter(ENABLE_PAYMENT_TYPE).value(enablePaymentType).notNull();
if (enablePaymentType) {
final Integer paymentTypeId = this.fromApiJsonHelper.extractIntegerNamed(PAYMENT_TYPE_ID, element, Locale.getDefault());
baseDataValidator.reset().parameter(PAYMENT_TYPE_ID).value(paymentTypeId).integerGreaterThanZero();
}
}
}
if (this.fromApiJsonHelper.parameterExists(CHARGE_APPLIES_TO, element)) {
final Integer chargeAppliesTo = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_APPLIES_TO, element);
baseDataValidator.reset().parameter(CHARGE_APPLIES_TO).value(chargeAppliesTo).notNull()
.isOneOfTheseValues(ChargeAppliesTo.validValues());
}
if (this.fromApiJsonHelper.parameterExists(CHARGE_APPLIES_TO, element)) {
final Integer chargeAppliesTo = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_APPLIES_TO, element);
baseDataValidator.reset().parameter(CHARGE_APPLIES_TO).value(chargeAppliesTo).notNull()
.isOneOfTheseValues(ChargeAppliesTo.validValues());
}
if (this.fromApiJsonHelper.parameterExists(CHARGE_TIME_TYPE, element)) {
final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CHARGE_TIME_TYPE, element);
final Collection<Object> validLoanValues = Arrays.asList(ChargeTimeType.validLoanValues());
final Collection<Object> validSavingsValues = Arrays.asList(ChargeTimeType.validSavingsValues());
final Collection<Object> validClientValues = Arrays.asList(ChargeTimeType.validClientValues());
final Collection<Object> validShareValues = Arrays.asList(ChargeTimeType.validShareValues());
final Collection<Object> allValidValues = new ArrayList<>(validLoanValues);
allValidValues.addAll(validSavingsValues);
allValidValues.addAll(validClientValues);
allValidValues.addAll(validShareValues);
baseDataValidator.reset().parameter(CHARGE_TIME_TYPE).value(chargeTimeType).notNull()
.isOneOfTheseValues(allValidValues.toArray(new Object[allValidValues.size()]));
}
if (this.fromApiJsonHelper.parameterExists(FEE_ON_MONTH_DAY, element)) {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed(FEE_ON_MONTH_DAY, element);
baseDataValidator.reset().parameter(FEE_ON_MONTH_DAY).value(monthDay).notNull();
}
if (this.fromApiJsonHelper.parameterExists(FEE_INTERVAL, element)) {
final Integer feeInterval = this.fromApiJsonHelper.extractIntegerNamed(FEE_INTERVAL, element, Locale.getDefault());
baseDataValidator.reset().parameter(FEE_INTERVAL).value(feeInterval).integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(CHARGE_CALCULATION_TYPE, element)) {
final Integer chargeCalculationType = this.fromApiJsonHelper.extractIntegerNamed(CHARGE_CALCULATION_TYPE, element,
Locale.getDefault());
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType).notNull().inMinMaxRange(1, 5);
}
if (this.fromApiJsonHelper.parameterExists(CHARGE_PAYMENT_MODE, element)) {
final Integer chargePaymentMode = this.fromApiJsonHelper.extractIntegerNamed(CHARGE_PAYMENT_MODE, element, Locale.getDefault());
baseDataValidator.reset().parameter(CHARGE_PAYMENT_MODE).value(chargePaymentMode).notNull().inMinMaxRange(0, 1);
}
if (this.fromApiJsonHelper.parameterExists(PENALTY, element)) {
final Boolean penalty = this.fromApiJsonHelper.extractBooleanNamed(PENALTY, element);
baseDataValidator.reset().parameter(PENALTY).value(penalty).notNull();
}
if (this.fromApiJsonHelper.parameterExists(ACTIVE, element)) {
final Boolean active = this.fromApiJsonHelper.extractBooleanNamed(ACTIVE, element);
baseDataValidator.reset().parameter(ACTIVE).value(active).notNull();
}
if (this.fromApiJsonHelper.parameterExists(MIN_CAP, element)) {
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(MIN_CAP, element.getAsJsonObject());
baseDataValidator.reset().parameter(MIN_CAP).value(minCap).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(MAX_CAP, element)) {
final BigDecimal maxCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(MAX_CAP, element.getAsJsonObject());
baseDataValidator.reset().parameter(MAX_CAP).value(maxCap).notNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(FEE_FREQUENCY, element)) {
final Integer feeFrequency = this.fromApiJsonHelper.extractIntegerNamed(FEE_FREQUENCY, element, Locale.getDefault());
baseDataValidator.reset().parameter(FEE_FREQUENCY).value(feeFrequency).inMinMaxRange(0, 3);
}
if (this.fromApiJsonHelper.parameterExists(ChargesApiConstants.glAccountIdParamName, element)) {
final Long glAccountId = this.fromApiJsonHelper.extractLongNamed(ChargesApiConstants.glAccountIdParamName, element);
baseDataValidator.reset().parameter(ChargesApiConstants.glAccountIdParamName).value(glAccountId).notNull()
.longGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(ChargesApiConstants.taxGroupIdParamName, element)) {
final Long taxGroupId = this.fromApiJsonHelper.extractLongNamed(ChargesApiConstants.taxGroupIdParamName, element);
baseDataValidator.reset().parameter(ChargesApiConstants.taxGroupIdParamName).value(taxGroupId).notNull().longGreaterThanZero();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateChargeTimeNCalculationType(Integer chargeTimeType, Integer chargeCalculationType) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(CHARGE);
performChargeTimeNCalculationTypeValidation(baseDataValidator, chargeTimeType, chargeCalculationType);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void performChargeTimeNCalculationTypeValidation(DataValidatorBuilder baseDataValidator, final Integer chargeTimeType,
final Integer chargeCalculationType) {
if (chargeTimeType.equals(ChargeTimeType.SHAREACCOUNT_ACTIVATION.getValue())) {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForShareAccountActivation());
}
if (chargeTimeType.equals(ChargeTimeType.TRANCHE_DISBURSEMENT.getValue())) {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isOneOfTheseValues(ChargeCalculationType.validValuesForTrancheDisbursement());
} else {
baseDataValidator.reset().parameter(CHARGE_CALCULATION_TYPE).value(chargeCalculationType)
.isNotOneOfTheseValues(ChargeCalculationType.PERCENT_OF_DISBURSEMENT_AMOUNT.getValue());
}
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
}
@@ -1,50 +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.portfolio.charge.service;
import java.util.List;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
public interface ChargeDropdownReadPlatformService {
List<EnumOptionData> retrieveCalculationTypes();
List<EnumOptionData> retrieveApplicableToTypes();
List<EnumOptionData> retrieveCollectionTimeTypes();
List<EnumOptionData> retrivePaymentModes();
List<EnumOptionData> retrieveLoanCalculationTypes();
List<EnumOptionData> retrieveLoanCollectionTimeTypes();
List<EnumOptionData> retrieveSavingsCalculationTypes();
List<EnumOptionData> retrieveSavingsCollectionTimeTypes();
List<EnumOptionData> retrieveClientCalculationTypes();
List<EnumOptionData> retrieveClientCollectionTimeTypes();
List<EnumOptionData> retrieveSharesCalculationTypes();
List<EnumOptionData> retrieveSharesCollectionTimeTypes();
}
@@ -1,127 +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.portfolio.charge.service;
import static org.apache.fineract.portfolio.charge.service.ChargeEnumerations.chargeCalculationType;
import static org.apache.fineract.portfolio.charge.service.ChargeEnumerations.chargePaymentMode;
import static org.apache.fineract.portfolio.charge.service.ChargeEnumerations.chargeTimeType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.portfolio.charge.domain.ChargeAppliesTo;
import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType;
import org.apache.fineract.portfolio.charge.domain.ChargePaymentMode;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
public class ChargeDropdownReadPlatformServiceImpl implements ChargeDropdownReadPlatformService {
@Override
public List<EnumOptionData> retrieveCalculationTypes() {
return Arrays.asList(chargeCalculationType(ChargeCalculationType.FLAT),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_AMOUNT),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_AMOUNT_AND_INTEREST),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_INTEREST),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_DISBURSEMENT_AMOUNT));
}
@Override
public List<EnumOptionData> retrieveApplicableToTypes() {
final List<EnumOptionData> chargeAppliesToTypes = new ArrayList<>();
for (final ChargeAppliesTo chargeAppliesTo : ChargeAppliesTo.values()) {
if (ChargeAppliesTo.INVALID.equals(chargeAppliesTo)) {
continue;
}
chargeAppliesToTypes.add(ChargeEnumerations.chargeAppliesTo(chargeAppliesTo));
}
return chargeAppliesToTypes;
}
@Override
public List<EnumOptionData> retrieveCollectionTimeTypes() {
final List<EnumOptionData> chargeTimeTypes = new ArrayList<>();
for (final ChargeTimeType chargeTimeType : ChargeTimeType.values()) {
if (ChargeTimeType.INVALID.equals(chargeTimeType) || ChargeTimeType.SAVINGS_CLOSURE.equals(chargeTimeType)) {
continue;
}
chargeTimeTypes.add(ChargeEnumerations.chargeTimeType(chargeTimeType));
}
return chargeTimeTypes;
}
@Override
public List<EnumOptionData> retrivePaymentModes() {
return Arrays.asList(chargePaymentMode(ChargePaymentMode.REGULAR), chargePaymentMode(ChargePaymentMode.ACCOUNT_TRANSFER));
}
@Override
public List<EnumOptionData> retrieveLoanCalculationTypes() {
return Arrays.asList(chargeCalculationType(ChargeCalculationType.FLAT),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_AMOUNT),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_AMOUNT_AND_INTEREST),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_INTEREST),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_DISBURSEMENT_AMOUNT));
}
@Override
public List<EnumOptionData> retrieveLoanCollectionTimeTypes() {
return Arrays.asList(chargeTimeType(ChargeTimeType.DISBURSEMENT), chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE),
chargeTimeType(ChargeTimeType.INSTALMENT_FEE), chargeTimeType(ChargeTimeType.OVERDUE_INSTALLMENT),
chargeTimeType(ChargeTimeType.TRANCHE_DISBURSEMENT));
}
@Override
public List<EnumOptionData> retrieveSavingsCalculationTypes() {
return Arrays.asList(chargeCalculationType(ChargeCalculationType.FLAT),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_AMOUNT));
}
@Override
public List<EnumOptionData> retrieveSavingsCollectionTimeTypes() {
return Arrays.asList(chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE), chargeTimeType(ChargeTimeType.SAVINGS_ACTIVATION),
// chargeTimeType(ChargeTimeType.SAVINGS_CLOSURE),
chargeTimeType(ChargeTimeType.WITHDRAWAL_FEE), chargeTimeType(ChargeTimeType.ANNUAL_FEE),
chargeTimeType(ChargeTimeType.MONTHLY_FEE), chargeTimeType(ChargeTimeType.WEEKLY_FEE),
chargeTimeType(ChargeTimeType.OVERDRAFT_FEE), chargeTimeType(ChargeTimeType.SAVINGS_NOACTIVITY_FEE));
}
@Override
public List<EnumOptionData> retrieveClientCalculationTypes() {
return Arrays.asList(chargeCalculationType(ChargeCalculationType.FLAT));
}
@Override
public List<EnumOptionData> retrieveClientCollectionTimeTypes() {
return Arrays.asList(chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE));
}
@Override
public List<EnumOptionData> retrieveSharesCalculationTypes() {
return Arrays.asList(chargeCalculationType(ChargeCalculationType.FLAT),
chargeCalculationType(ChargeCalculationType.PERCENT_OF_AMOUNT));
}
@Override
public List<EnumOptionData> retrieveSharesCollectionTimeTypes() {
return Arrays.asList(chargeTimeType(ChargeTimeType.SHAREACCOUNT_ACTIVATION), chargeTimeType(ChargeTimeType.SHARE_PURCHASE),
chargeTimeType(ChargeTimeType.SHARE_REDEEM));
}
}
@@ -1,124 +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.portfolio.charge.service;
import java.util.Collection;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
public interface ChargeReadPlatformService {
Collection<ChargeData> retrieveAllCharges();
Collection<ChargeData> retrieveAllChargesForCurrency(String currencyCode);
ChargeData retrieveCharge(Long chargeId);
ChargeData retrieveNewChargeDetails();
/**
* Returns all charges that can be applied to Cients
*
* @return
*/
Collection<ChargeData> retrieveAllChargesApplicableToClients();
/**
* Returns all Fees (excluding penalties) applicable for loans
*
* @return
*/
Collection<ChargeData> retrieveLoanApplicableFees();
/**
* Returns all charges applicable for a given loan account
*
* @param excludeChargeTimes
* Excludes Given List of Charge Types from the response
* @return
*/
Collection<ChargeData> retrieveLoanAccountApplicableCharges(Long loanId, ChargeTimeType[] excludeChargeTimes);
/**
* Returns all charges applicable for a given loan product (filter based on Currency of Selected Loan Product)
*
* @param excludeChargeTimes
* Excludes Given List of Charge Types from the response
* @return
*/
Collection<ChargeData> retrieveLoanProductApplicableCharges(Long loanProductId, ChargeTimeType[] excludeChargeTimes);
/**
* Returns all Penalties applicable for loans
*
* @return
*/
Collection<ChargeData> retrieveLoanApplicablePenalties();
/**
* Returns all Charges associated with a given Loan Product
*
* @param loanProductId
* @return
*/
Collection<ChargeData> retrieveLoanProductCharges(Long loanProductId);
/**
* Returns all charges applicable for a given loan product
*
* @param loanProductId
* @param chargeTime
* Filters based on the type of the charge to be returned
* @return
*/
Collection<ChargeData> retrieveLoanProductCharges(Long loanProductId, ChargeTimeType chargeTime);
/**
* Returns all charges applicable for savings
*
* @param feeChargesOnly
* @return
*/
Collection<ChargeData> retrieveSavingsProductApplicableCharges(boolean feeChargesOnly);
/**
* Returns all penalties applicable for savings
*
* @return
*/
Collection<ChargeData> retrieveSavingsApplicablePenalties();
/**
* Returns all charges applicable for a given savings product
*
* @param savingsProductId
* @return
*/
Collection<ChargeData> retrieveSavingsProductCharges(Long savingsProductId);
/** Retrieve savings account charges **/
Collection<ChargeData> retrieveSavingsAccountApplicableCharges(Long savingsId);
/**
* Returns charge definitions which are applicable for shares
*/
Collection<ChargeData> retrieveSharesApplicableCharges();
Collection<ChargeData> retrieveShareProductCharges(Long shareProductId);
}
@@ -1,31 +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.portfolio.charge.service;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
public interface ChargeWritePlatformService {
CommandProcessingResult createCharge(JsonCommand command);
CommandProcessingResult updateCharge(Long chargeId, JsonCommand command);
CommandProcessingResult deleteCharge(Long chargeId);
}
@@ -53,7 +53,6 @@
<class>org.apache.fineract.portfolio.fund.domain.Fund</class>
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket</class>
<class>org.apache.fineract.portfolio.delinquency.domain.DelinquencyRange</class>
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
<class>org.apache.fineract.portfolio.paymenttype.domain.PaymentType</class>
<class>org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail</class>
<class>org.apache.fineract.portfolio.tax.domain.TaxGroup</class>
@@ -143,6 +142,8 @@
<class>org.apache.fineract.accounting.rule.domain.AccountingTagRule</class>
<!-- Fineract Document module -->
<class>org.apache.fineract.infrastructure.documentmanagement.domain.Document</class>
<!-- Fineract Charge module -->
<class>org.apache.fineract.portfolio.charge.domain.Charge</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.weaving" value="static" />