Business date part 1 (#2362)

Business date implementation - part 1
This commit is contained in:
Adam Saghy
2022-06-14 19:05:52 +02:00
committed by GitHub
parent a38fc32315
commit 4465e632f1
42 changed files with 1998 additions and 125 deletions
@@ -3478,4 +3478,11 @@ public class CommandWrapperBuilder {
return this;
}
public CommandWrapperBuilder updateBusinessDate() {
this.actionName = "UPDATE";
this.entityName = "BUSINESS_DATE";
this.href = "/businessdate";
return this;
}
}
@@ -0,0 +1,107 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.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 java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
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.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
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.springframework.stereotype.Component;
@RequiredArgsConstructor
@Path("businessdate")
@Component
@Tag(name = "Business Date Management", description = "Business date management enables you to set up, fetch and adjust organisation business dates")
public class BusinessDateApiResource {
private final ApiRequestParameterHelper parameterHelper;
private final PlatformSecurityContext securityContext;
private final DefaultToApiJsonSerializer<BusinessDateData> jsonSerializer;
private final BusinessDateReadPlatformService readPlatformService;
private final PortfolioCommandSourceWritePlatformService commandWritePlatformService;
@GET
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "List all business dates", description = "")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = BusinessDateApiResourceSwagger.BusinessDateResponse.class)))) })
public String getBusinessDates(@Context final UriInfo uriInfo) {
securityContext.authenticatedUser().validateHasReadPermission("BUSINESS_DATE");
final List<BusinessDateData> foundBusinessDates = this.readPlatformService.findAll();
ApiRequestJsonSerializationSettings settings = parameterHelper.process(uriInfo.getQueryParameters());
return this.jsonSerializer.serialize(settings, foundBusinessDates);
}
@GET
@Path("{type}")
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "Retrieve a specific Business date", description = "")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = BusinessDateApiResourceSwagger.BusinessDateResponse.class))) })
public String getBusinessDate(@PathParam("type") @Parameter(description = "type") final String type, @Context final UriInfo uriInfo) {
securityContext.authenticatedUser().validateHasReadPermission("BUSINESS_DATE");
final BusinessDateData businessDate = this.readPlatformService.findByType(type);
ApiRequestJsonSerializationSettings settings = parameterHelper.process(uriInfo.getQueryParameters());
return this.jsonSerializer.serialize(settings, businessDate);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Update Business Date", description = "")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = BusinessDateApiResourceSwagger.BusinessDateRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "", content = @Content(schema = @Schema(implementation = BusinessDateApiResourceSwagger.BusinessDateRequest.class))) })
public String updateBusinessDate(final String jsonRequestBody, @Context UriInfo uriInfo) {
securityContext.authenticatedUser().validateHasUpdatePermission("BUSINESS_DATE");
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateBusinessDate().withJson(jsonRequestBody).build();
CommandProcessingResult result = commandWritePlatformService.logCommandSource(commandRequest);
return jsonSerializer.serialize(result);
}
}
@@ -0,0 +1,63 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.api;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
final class BusinessDateApiResourceSwagger {
private BusinessDateApiResourceSwagger() {
}
@Schema(description = "BusinessDateResponse")
public static final class BusinessDateResponse {
@Schema(example = "yyyy-MM-dd")
public String dateFormat;
@Schema(example = "COB date")
private String description;
@Schema(example = "COB_DATE")
private String type;
@Schema(example = "2015-02-15")
private LocalDate date;
private BusinessDateResponse() {
}
}
@Schema(description = "BusinessDateRequest")
public static final class BusinessDateRequest {
@Schema(example = "yyyy-MM-dd")
public String dateFormat;
@Schema(example = "COB_DATE")
private String type;
@Schema(example = "2015-02-15")
private LocalDate date;
@Schema(example = "en")
private String locale;
private BusinessDateRequest() {}
}
}
@@ -0,0 +1,45 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.data;
import java.io.Serializable;
import java.time.LocalDate;
import lombok.Getter;
import lombok.ToString;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
@ToString
@Getter
public class BusinessDateData implements Serializable {
private String description;
private String type;
private LocalDate date;
public BusinessDateData(BusinessDateType businessDateType, LocalDate date) {
this.type = businessDateType.getName();
this.description = businessDateType.getDescription();
this.date = date;
}
public static BusinessDateData instance(BusinessDateType businessDateType, LocalDate value) {
return new BusinessDateData(businessDateType, value);
}
}
@@ -0,0 +1,64 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.domain;
import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;
import lombok.Getter;
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
@Getter
@Entity
@Table(name = "m_business_date", uniqueConstraints = { @UniqueConstraint(name = "uq_business_date_type", columnNames = { "type" }) })
public class BusinessDate extends AbstractAuditableCustom {
@Enumerated(EnumType.STRING)
@Column(name = "type")
private BusinessDateType type;
@Column(name = "date", columnDefinition = "DATE")
private LocalDate date;
@Version
private Long version;
protected BusinessDate() {
// TODO Auto-generated constructor stub
}
protected BusinessDate(@NotNull BusinessDateType type, @NotNull LocalDate date) {
this.type = type;
this.date = date;
}
public static BusinessDate instance(@NotNull BusinessDateType businessDateType, @NotNull LocalDate date) {
return new BusinessDate(businessDateType, date);
}
public void updateDate(LocalDate date) {
this.date = date;
}
}
@@ -0,0 +1,28 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.domain;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface BusinessDateRepository extends JpaRepository<BusinessDate, Long>, JpaSpecificationExecutor<BusinessDate> {
Optional<BusinessDate> findByType(BusinessDateType type);
}
@@ -0,0 +1,37 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum BusinessDateType {
BUSINESS_DATE(1, "Business Date"), COB_DATE(2, "Close of Business Date");
private final Integer id;
private final String description;
public String getName() {
return name();
}
}
@@ -0,0 +1,31 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when business date is violating any domain rule.
*/
public class BusinessDateActionException extends AbstractPlatformDomainRuleException {
public BusinessDateActionException(final String violationCode, String message) {
super(violationCode, message, violationCode);
}
}
@@ -0,0 +1,41 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
/**
* A {@link RuntimeException} thrown when business date is not found.
*/
public class BusinessDateNotFoundException extends AbstractPlatformResourceNotFoundException {
public BusinessDateNotFoundException(String globalisationMessageCode, String defaultUserMessage, Object... defaultUserMessageArgs) {
super(globalisationMessageCode, defaultUserMessage, defaultUserMessageArgs);
}
public static BusinessDateNotFoundException notExist(final String type, Throwable... e) {
return new BusinessDateNotFoundException("error.msg.businessdate.type.not.exist",
"Business date with type `" + type + "` does not exist.", type, e);
}
public static BusinessDateNotFoundException notFound(final String type, Throwable... e) {
return new BusinessDateNotFoundException("error.msg.businessdate.not.found",
"Business date with type `" + type + "` does not found.", type, e);
}
}
@@ -0,0 +1,43 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.handler;
import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.commands.annotation.CommandType;
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
@Service
@CommandType(entity = "BUSINESS_DATE", action = "UPDATE")
public class BusinessDateUpdateHandler implements NewCommandSourceHandler {
private final BusinessDateWritePlatformService businessDateWritePlatformService;
@Transactional
@Override
public CommandProcessingResult processCommand(@NotNull final JsonCommand command) {
return businessDateWritePlatformService.updateBusinessDate(command);
}
}
@@ -0,0 +1,35 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.mapper;
import java.util.List;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
@Mapper(componentModel = "spring")
public interface BusinessDateMapper {
@Mappings({ @Mapping(target = "businessDateType", source = "source.type"), @Mapping(target = "date", source = "source.date") })
BusinessDateData map(BusinessDate source);
List<BusinessDateData> map(List<BusinessDate> sources);
}
@@ -0,0 +1,29 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.service;
import java.util.List;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
public interface BusinessDateReadPlatformService {
List<BusinessDateData> findAll();
BusinessDateData findByType(String type);
}
@@ -0,0 +1,63 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.service;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateNotFoundException;
import org.apache.fineract.infrastructure.businessdate.mapper.BusinessDateMapper;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlatformService {
private final BusinessDateRepository repository;
private final BusinessDateMapper mapper;
@Override
public List<BusinessDateData> findAll() {
List<BusinessDate> businessDateList = repository.findAll();
return mapper.map(businessDateList);
}
@Override
public BusinessDateData findByType(String type) {
BusinessDateType businessDateType;
try {
businessDateType = BusinessDateType.valueOf(type);
} catch (IllegalArgumentException e) {
log.error("Provided business date type cannot be found: {}", type);
throw BusinessDateNotFoundException.notExist(type, e);
}
Optional<BusinessDate> businessDate = repository.findByType(businessDateType);
if (businessDate.isEmpty()) {
log.error("Business date with the provided type cannot be found {}", type);
throw BusinessDateNotFoundException.notFound(type);
}
return mapper.map(businessDate.get());
}
}
@@ -0,0 +1,32 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.service;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
public interface BusinessDateWritePlatformService {
CommandProcessingResult updateBusinessDate(JsonCommand command);
void increaseCOBDateByOneDay() throws JobExecutionException;
void increaseBusinessDateByOneDay() throws JobExecutionException;
}
@@ -0,0 +1,149 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.service;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateActionException;
import org.apache.fineract.infrastructure.businessdate.validator.BusinessDateDataParserAndValidator;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class BusinessDateWritePlatformServiceImpl implements BusinessDateWritePlatformService {
private final BusinessDateDataParserAndValidator dataValidator;
private final BusinessDateRepository repository;
private final ConfigurationDomainService configurationDomainService;
@Override
public CommandProcessingResult updateBusinessDate(@NotNull final JsonCommand command) {
BusinessDateData data = dataValidator.validateAndParseUpdate(command);
Map<String, Object> changes = new HashMap<>();
adjustDate(data, changes);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).with(changes).build();
}
private void adjustDate(BusinessDateData data, Map<String, Object> changes) {
boolean isCOBDateAdjustmentEnabled = configurationDomainService.isCOBDateAdjustmentEnabled();
boolean isBusinessDateEnabled = configurationDomainService.isBusinessDateEnabled();
if (!isBusinessDateEnabled) {
log.error("Business date functionality is not enabled!");
throw new BusinessDateActionException("business.date.is.not.enabled", "Business date functionality is not enabled");
}
updateOrCreateBusinessDate(data.getType(), data.getDate(), changes);
if (isCOBDateAdjustmentEnabled && BusinessDateType.BUSINESS_DATE.name().equals(data.getType())) {
updateOrCreateBusinessDate(BusinessDateType.COB_DATE.getName(), data.getDate().minus(1, ChronoUnit.DAYS), changes);
}
}
@Override
@CronTarget(jobName = JobName.INCREASE_COB_DATE_BY_1_DAY)
public void increaseCOBDateByOneDay() throws JobExecutionException {
increaseDateByTypeByOneDay(BusinessDateType.COB_DATE);
}
@Override
@CronTarget(jobName = JobName.INCREASE_BUSINESS_DATE_BY_1_DAY)
public void increaseBusinessDateByOneDay() throws JobExecutionException {
increaseDateByTypeByOneDay(BusinessDateType.BUSINESS_DATE);
}
private void increaseDateByTypeByOneDay(BusinessDateType businessDateType) throws JobExecutionException {
List<Throwable> exceptions = new ArrayList<>();
Map<String, Object> changes = new HashMap<>();
Optional<BusinessDate> businessDateEntity = repository.findByType(businessDateType);
LocalDate businessDate = businessDateEntity.map(BusinessDate::getDate).orElse(DateUtils.getLocalDateOfTenant());
businessDate = businessDate.plusDays(1);
try {
BusinessDateData businessDateData = BusinessDateData.instance(businessDateType, businessDate);
adjustDate(businessDateData, changes);
} catch (final PlatformApiDataValidationException e) {
final List<ApiParameterError> errors = e.getErrors();
for (final ApiParameterError error : errors) {
log.error("Increasing {} by 1 day failed due to: {}", businessDateType.getDescription(), error.getDeveloperMessage());
}
exceptions.add(e);
} catch (final AbstractPlatformDomainRuleException e) {
log.error("Increasing {} by 1 day failed due to: {}", businessDateType.getDescription(), e.getDefaultUserMessage());
exceptions.add(e);
} catch (Exception e) {
log.error("Increasing {} by 1 day failed due to: {}", businessDateType.getDescription(), e.getMessage());
exceptions.add(e);
}
if (!exceptions.isEmpty()) {
throw new JobExecutionException(exceptions);
}
}
private void updateOrCreateBusinessDate(String type, LocalDate newDate, Map<String, Object> changes) {
BusinessDateType businessDateType = BusinessDateType.valueOf(type);
Optional<BusinessDate> businessDate = repository.findByType(businessDateType);
if (businessDate.isEmpty()) {
BusinessDate newBusinessDate = BusinessDate.instance(businessDateType, newDate);
repository.save(newBusinessDate);
changes.put(type, newBusinessDate.getDate());
} else {
updateBusinessDate(businessDate.get(), newDate, changes);
}
}
private void updateBusinessDate(BusinessDate businessDate, LocalDate newDate, Map<String, Object> changes) {
LocalDate oldDate = businessDate.getDate();
if (!hasChange(oldDate, newDate)) {
return;
}
businessDate.updateDate(newDate);
repository.save(businessDate);
changes.put(businessDate.getType().name(), newDate);
}
private boolean hasChange(@NotNull LocalDate oldDate, @NotNull LocalDate date) {
return (date.isBefore(oldDate) || date.isAfter(oldDate));
}
}
@@ -0,0 +1,107 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.businessdate.validator;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
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.springframework.stereotype.Component;
@Slf4j
@RequiredArgsConstructor
@Component
public class BusinessDateDataParserAndValidator {
private final FromJsonHelper jsonHelper;
public BusinessDateData validateAndParseUpdate(@NotNull final JsonCommand command) {
final DataValidatorBuilder dataValidator = new DataValidatorBuilder(new ArrayList<>()).resource("businessdate.update");
JsonObject element = extractJsonObject(command);
BusinessDateData result = validateAndParseUpdate(dataValidator, element, jsonHelper);
throwExceptionIfValidationWarningsExist(dataValidator);
return result;
}
private JsonObject extractJsonObject(JsonCommand command) {
String json = command.json();
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final JsonElement element = jsonHelper.parse(json);
return element.getAsJsonObject();
}
private void throwExceptionIfValidationWarningsExist(DataValidatorBuilder dataValidator) {
if (dataValidator.hasError()) {
log.error("Business date - Validation errors: {}", dataValidator.getDataValidationErrors());
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidator.getDataValidationErrors());
}
}
private BusinessDateData validateAndParseUpdate(final DataValidatorBuilder dataValidator, JsonObject element,
FromJsonHelper jsonHelper) {
if (element == null) {
return null;
}
jsonHelper.checkForUnsupportedParameters(element, List.of("type", "date", "dateFormat", "locale"));
String businessDateTypeName = jsonHelper.extractStringNamed("type", element);
final String localeValue = jsonHelper.extractStringNamed("locale", element);
final String dateFormat = jsonHelper.extractDateFormatParameter(element);
final String dateValue = jsonHelper.extractStringNamed("date", element);
dataValidator.reset().parameter("type").value(businessDateTypeName).notBlank();
dataValidator.reset().parameter("locale").value(localeValue).notBlank();
dataValidator.reset().parameter("dateFormat").value(dateFormat).notBlank();
dataValidator.reset().parameter("date").value(dateValue).notBlank();
if (dataValidator.hasError()) {
return null;
}
Locale locale = jsonHelper.extractLocaleParameter(element);
BusinessDateType type;
try {
type = BusinessDateType.valueOf(businessDateTypeName);
} catch (IllegalArgumentException e) {
dataValidator.reset().parameter("type").failWithCode("Invalid Business Type value: `" + businessDateTypeName + "`");
return null;
}
LocalDate date = jsonHelper.extractLocalDateNamed("date", element, dateFormat, locale);
dataValidator.reset().parameter("date").value(date).notNull();
return dataValidator.hasError() ? null : BusinessDateData.instance(type, date);
}
}
@@ -112,4 +112,8 @@ public interface ConfigurationDomainService {
boolean isRelaxingDaysConfigForPivotDateEnabled();
Long retrieveRelaxingDaysConfigForPivotDate();
boolean isBusinessDateEnabled();
boolean isCOBDateAdjustmentEnabled();
}
@@ -38,6 +38,8 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class ConfigurationDomainServiceJpa implements ConfigurationDomainService {
public static final String ENABLE_BUSINESS_DATE = "enable_business_date";
public static final String ENABLE_AUTOMATIC_COB_DATE_ADJUSTMENT = "enable_automatic_cob_date_adjustment";
private final PermissionRepository permissionRepository;
private final GlobalConfigurationRepositoryWrapper globalConfigurationRepository;
private final PlatformCacheRepository cacheTypeRepository;
@@ -432,4 +434,13 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
return property.isEnabled();
}
@Override
public boolean isBusinessDateEnabled() {
return getGlobalConfigurationPropertyData(ENABLE_BUSINESS_DATE).isEnabled();
}
@Override
public boolean isCOBDateAdjustmentEnabled() {
return getGlobalConfigurationPropertyData(ENABLE_AUTOMATIC_COB_DATE_ADJUSTMENT).isEnabled();
}
}
@@ -175,6 +175,11 @@ public final class JsonCommand {
this.organisationCreditBureauId = null;
}
public static JsonCommand from(final String jsonCommand) {
return new JsonCommand(null, jsonCommand, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
}
public Long getOrganisationCreditBureauId() {
return this.organisationCreditBureauId;
}
@@ -133,6 +133,6 @@ public final class ApiParameterError {
@Override
public String toString() {
return "ApiParameterError{developerMessage=" + developerMessage + "; ... }";
return developerMessage;
}
}
@@ -21,10 +21,12 @@ package org.apache.fineract.infrastructure.core.data;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import lombok.ToString;
/**
* Represents the successful result of an REST API call that results in processing a command.
*/
@ToString
public class CommandProcessingResult implements Serializable {
private Long commandId;
@@ -115,8 +115,8 @@ public class DataValidatorBuilder {
if (StringUtils.isBlank(linkedValue)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(linkedParameterName).append(".cannot.be.empty.when.").append(this.parameter).append(".is.populated");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(linkedParameterName)
.append(" cannot be empty when ").append(this.parameter).append(" is populated.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(linkedParameterName)
.append("` cannot be empty when ").append(this.parameter).append(" is populated.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), linkedParameterName, linkedValue, this.value);
this.dataValidationErrors.add(error);
@@ -149,8 +149,8 @@ public class DataValidatorBuilder {
if (this.value != null && !this.value.equals(linkedValue)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(linkedParameterName).append(".not.equal.to.").append(this.parameter);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(linkedParameterName)
.append(" is not equal to ").append(this.parameter).append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(linkedParameterName)
.append("` is not equal to ").append(this.parameter).append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), linkedParameterName, linkedValue, this.value);
this.dataValidationErrors.add(error);
@@ -166,8 +166,8 @@ public class DataValidatorBuilder {
if (this.value != null && this.value.equals(linkedValue)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(linkedParameterName).append(".same.as.").append(this.parameter);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(linkedParameterName)
.append(" is same as ").append(this.parameter).append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(linkedParameterName)
.append("` is same as ").append(this.parameter).append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), linkedParameterName, linkedValue, this.value);
this.dataValidationErrors.add(error);
@@ -184,8 +184,8 @@ public class DataValidatorBuilder {
if (!trueOfFalseFieldProvided && !this.ignoreNullValue) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".must.be.true.or.false");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be set as true or false.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be set as true or false.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter);
this.dataValidationErrors.add(error);
@@ -199,8 +199,8 @@ public class DataValidatorBuilder {
if (!trueOfFalseField.toString().equalsIgnoreCase("true") && !trueOfFalseField.toString().equalsIgnoreCase("false")) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".must.be.true.or.false");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be set as true or false.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be set as true or false.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter);
this.dataValidationErrors.add(error);
@@ -223,8 +223,8 @@ public class DataValidatorBuilder {
}
validationErrorCode.append(".cannot.be.blank");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(realParameterName)
.append(" is mandatory.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(realParameterName)
.append("` is mandatory.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), realParameterName, this.arrayIndex);
this.dataValidationErrors.add(error);
@@ -248,8 +248,8 @@ public class DataValidatorBuilder {
}
validationErrorCode.append(".cannot.be.blank");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(realParameterName)
.append(" is mandatory.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(realParameterName)
.append("` is mandatory.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), realParameterName, this.arrayIndex);
this.dataValidationErrors.add(error);
@@ -265,8 +265,8 @@ public class DataValidatorBuilder {
if (this.value != null && this.value.toString().trim().length() > maxLength) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".exceeds.max.length");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" exceeds max length of ").append(maxLength).append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` exceeds max length of ").append(maxLength).append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, maxLength, this.value.toString());
this.dataValidationErrors.add(error);
@@ -284,8 +284,8 @@ public class DataValidatorBuilder {
if (number < min || number > max) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.not.within.expected.range");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be between ").append(min).append(" and ").append(max).append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be between ").append(min).append(" and ").append(max).append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, min, max);
this.dataValidationErrors.add(error);
@@ -305,8 +305,8 @@ public class DataValidatorBuilder {
if (this.value == null || !valuesList.contains(this.value)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.not.one.of.expected.enumerations");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be one of [ ").append(valuesListStr).append(" ] ").append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be one of [ ").append(valuesListStr).append(" ] ").append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value, values);
@@ -333,8 +333,8 @@ public class DataValidatorBuilder {
if (this.value == null || !valuesList.contains(this.value.toString().toLowerCase())) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.not.one.of.expected.enumerations");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be one of [ ").append(valuesListStr).append(" ] ").append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be one of [ ").append(valuesListStr).append(" ] ").append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value, values);
@@ -357,8 +357,8 @@ public class DataValidatorBuilder {
if (this.value == null || !valuesListLowercase.contains(this.value.toString().toLowerCase())) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.not.one.of.expected.enumerations");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be one of [ ").append(valuesListStr).append(" ] ").append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be one of [ ").append(valuesListStr).append(" ] ").append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value, valuesList);
@@ -381,8 +381,8 @@ public class DataValidatorBuilder {
if (valuesList.contains(this.value)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.one.of.unwanted.enumerations");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must not be any of [ ").append(valuesListStr).append(" ] ").append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must not be any of [ ").append(valuesListStr).append(" ] ").append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value, values);
@@ -403,8 +403,8 @@ public class DataValidatorBuilder {
if (number.compareTo(BigDecimal.ZERO) <= 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.greater.than.zero");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than 0.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than 0.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, 0);
this.dataValidationErrors.add(error);
@@ -426,8 +426,8 @@ public class DataValidatorBuilder {
if (number.compareTo(BigDecimal.ZERO) < 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.zero.or.greater");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than or equal to 0.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than or equal to 0.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, 0);
this.dataValidationErrors.add(error);
@@ -449,8 +449,8 @@ public class DataValidatorBuilder {
if (number < 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.zero.or.greater");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be zero or greater.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be zero or greater.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, 0);
this.dataValidationErrors.add(error);
@@ -472,8 +472,8 @@ public class DataValidatorBuilder {
if (number < 1) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.greater.than.zero");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than 0.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than 0.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, 0);
this.dataValidationErrors.add(error);
@@ -492,8 +492,8 @@ public class DataValidatorBuilder {
if (intValue < number + 1) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.greater.than.specified.number");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than ").append(number);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than ").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, intValue, number);
this.dataValidationErrors.add(error);
@@ -512,8 +512,8 @@ public class DataValidatorBuilder {
if (intValue < number) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.equal.to.or.greater.than.specified.number");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be equal to or greater than").append(number);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be equal to or greater than").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, intValue, number);
this.dataValidationErrors.add(error);
@@ -532,8 +532,8 @@ public class DataValidatorBuilder {
if (!intValue.equals(number)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.equal.to.specified.number");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be same as").append(number);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be same as").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, intValue, number);
this.dataValidationErrors.add(error);
@@ -552,8 +552,8 @@ public class DataValidatorBuilder {
if (intValue < number || intValue % number != 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.in.multiples.of.specified.number");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be multiples of ").append(number);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be multiples of ").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, intValue, number);
this.dataValidationErrors.add(error);
@@ -575,8 +575,8 @@ public class DataValidatorBuilder {
if (number < 1) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.greater.than.zero");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than 0.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than 0.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, 0);
this.dataValidationErrors.add(error);
@@ -598,8 +598,8 @@ public class DataValidatorBuilder {
if (number < 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.equal.or.greater.than.zero");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be equal or greater than 0.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be equal or greater than 0.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, 0);
this.dataValidationErrors.add(error);
@@ -618,8 +618,8 @@ public class DataValidatorBuilder {
if (longValue < number + 1) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.greater.than.specified.number");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than ").append(number);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than ").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, longValue, number);
this.dataValidationErrors.add(error);
@@ -638,8 +638,8 @@ public class DataValidatorBuilder {
if (longValue < number + 1) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".not.greater.than.specified.").append(paramName).append(".at Index.").append(index);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be greater than ").append(number);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than ").append(number);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, longValue, number);
this.dataValidationErrors.add(error);
@@ -657,8 +657,8 @@ public class DataValidatorBuilder {
if (ObjectUtils.isEmpty(array)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".cannot.be.empty");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" cannot be empty. You must select at least one.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` cannot be empty. You must select at least one.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter);
this.dataValidationErrors.add(error);
@@ -675,8 +675,8 @@ public class DataValidatorBuilder {
if (this.value != null && !array.iterator().hasNext()) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".cannot.be.empty");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" cannot be empty. You must select at least one.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` cannot be empty. You must select at least one.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter);
this.dataValidationErrors.add(error);
@@ -687,7 +687,8 @@ public class DataValidatorBuilder {
public void expectedArrayButIsNot() {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.not.an.array");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter).append(" is not an array.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` is not an array.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
this.parameter);
this.dataValidationErrors.add(error);
@@ -716,8 +717,8 @@ public class DataValidatorBuilder {
public DataValidatorBuilder inValidValue(final String parameterValueCode, final Object invalidValue) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".invalid.").append(parameterValueCode);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" has an invalid value.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` has an invalid value.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
this.parameter, invalidValue);
this.dataValidationErrors.add(error);
@@ -740,8 +741,8 @@ public class DataValidatorBuilder {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".cannot.also.be.provided.when.").append(parameterName).append(".is.populated");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" cannot also be provided when ").append(parameterName).append(" is populated.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` cannot also be provided when `").append(parameterName).append("` is populated.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
this.parameter, this.value, parameterName, parameterValue);
this.dataValidationErrors.add(error);
@@ -765,8 +766,8 @@ public class DataValidatorBuilder {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".cannot.also.be.provided.when.").append(parameterName).append(".is.")
.append(parameterValue);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" cannot also be provided when ").append(parameterName).append(" is ").append(parameterValue);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` cannot also be provided when `").append(parameterName).append("` is ").append(parameterValue);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
this.parameter, this.value, parameterName, parameterValue);
this.dataValidationErrors.add(error);
@@ -780,21 +781,22 @@ public class DataValidatorBuilder {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".must.be.provided.when.").append(parameterName).append(".is.").append(parameterValue);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must be provided when ").append(parameterName).append(" is ").append(parameterValue);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be provided when `").append(parameterName).append("` is ").append(parameterValue);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
this.parameter, this.value, parameterName, parameterValue);
this.dataValidationErrors.add(error);
return this;
}
public DataValidatorBuilder comapareMinimumAndMaximumAmounts(final BigDecimal minimumBalance, final BigDecimal maximumBalance) {
public DataValidatorBuilder compareMinimumAndMaximumAmounts(final BigDecimal minimumBalance, final BigDecimal maximumBalance) {
if (minimumBalance != null && maximumBalance != null) {
if (maximumBalance.compareTo(minimumBalance) < 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.not.within.expected.range");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(" minimum amount ")
.append(minimumBalance).append(" should less than maximum amount ").append(maximumBalance).append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` minimum amount ").append(minimumBalance).append(" should less than the maximum amount ")
.append(maximumBalance).append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, minimumBalance, maximumBalance);
this.dataValidationErrors.add(error);
@@ -810,7 +812,7 @@ public class DataValidatorBuilder {
if (amount.compareTo(minimumAmount) < 0 || amount.compareTo(maximumAmount) > 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".amount.is.not.within.min.max.range");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter).append(" amount ")
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter).append("` amount ")
.append(amount).append(" must be between ").append(minimumAmount).append(" and ").append(maximumAmount)
.append(" .");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
@@ -828,8 +830,8 @@ public class DataValidatorBuilder {
if (amount.compareTo(min) < 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.less.than.min");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter).append(" value ")
.append(amount).append(" must not be less than minimum value ").append(min);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter).append("` value ")
.append(amount).append(" must not be less than the minimum value ").append(min);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, amount, min);
this.dataValidationErrors.add(error);
@@ -845,7 +847,7 @@ public class DataValidatorBuilder {
if (amount.compareTo(max) > 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.greater.than.max");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter).append(" value ")
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter).append("` value ")
.append(amount).append(" must not be more than maximum value ").append(max);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, amount, max);
@@ -856,7 +858,7 @@ public class DataValidatorBuilder {
return this;
}
public DataValidatorBuilder comapareMinAndMaxOfTwoBigDecmimalNos(final BigDecimal min, final BigDecimal max) {
public DataValidatorBuilder compareMinAndMaxOfTwoBigDecmimalNos(final BigDecimal min, final BigDecimal max) {
if (min != null && max != null) {
if (max.compareTo(min) < 0) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
@@ -884,7 +886,7 @@ public class DataValidatorBuilder {
return this;
} catch (final ParseException e) {
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.recurring.rule.parsing.error",
"Error in pasring the Recurring Rule value: " + recurringRule + ".", this.parameter, recurringRule);
"Error in parsing the Recurring Rule value: " + recurringRule + ".", this.parameter, recurringRule);
this.dataValidationErrors.add(error);
return this;
}
@@ -902,8 +904,8 @@ public class DataValidatorBuilder {
if (number < min) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.less.than.min");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter)
.append(" must be greater than minimum value ").append(min);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than the minimum value ").append(min);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, min);
this.dataValidationErrors.add(error);
@@ -922,8 +924,8 @@ public class DataValidatorBuilder {
if (number > max) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.greater.than.max");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter)
.append(" must be less than maximum value ").append(max);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be less than the maximum value ").append(max);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, number, max);
this.dataValidationErrors.add(error);
@@ -940,8 +942,8 @@ public class DataValidatorBuilder {
if (this.value != null && !this.value.toString().matches(expression)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".does.not.match.regexp");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" must match the provided regular expression [ ").append(expression).append(" ] ").append(".");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must match the provided regular expression [ ").append(expression).append(" ] ").append(".");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value, expression);
@@ -986,8 +988,8 @@ public class DataValidatorBuilder {
if (validationErr) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".value.should.true.or.false");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" value should true or false ");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` value should true or false ");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value);
this.dataValidationErrors.add(error);
@@ -1017,8 +1019,8 @@ public class DataValidatorBuilder {
if (validationErr) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".format.is.invalid");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.resource).append(this.parameter)
.append(" is in invalid format, should contain '-','+','()' and numbers only.");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` is in invalid format, should contain '-','+','()' and numbers only.");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value);
this.dataValidationErrors.add(error);
@@ -1030,8 +1032,8 @@ public class DataValidatorBuilder {
if (this.value != null && !CronExpression.isValidExpression(this.value.toString().trim())) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".invalid");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(this.parameter)
.append(" value is not a valid cron expression");
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` value is not a valid cron expression");
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, this.value);
this.dataValidationErrors.add(error);
@@ -1049,8 +1051,8 @@ public class DataValidatorBuilder {
if (date.isAfter(dateVal)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.less.than.date");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter)
.append(" must be greter than provided date").append(date);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be greater than the provided date").append(date);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, dateVal, date);
this.dataValidationErrors.add(error);
@@ -1069,8 +1071,8 @@ public class DataValidatorBuilder {
if (date.isBefore(dateVal)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.greater.than.date");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter)
.append(" must be less than provided date").append(date);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be less than the provided date").append(date);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, dateVal, date);
this.dataValidationErrors.add(error);
@@ -1089,8 +1091,8 @@ public class DataValidatorBuilder {
if (dateVal.isAfter(date)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.greater.than.date");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter)
.append(" must be less than or equal to provided date").append(date);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be less than or equal to the provided date").append(date);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, dateVal, date);
this.dataValidationErrors.add(error);
@@ -1109,8 +1111,8 @@ public class DataValidatorBuilder {
if (!dateVal.isEqual(date)) {
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
.append(this.parameter).append(".is.not.equal.to.date");
final StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(this.parameter)
.append(" must be equal to provided date").append(date);
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
.append("` must be equal to the provided date").append(date);
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(), this.parameter, dateVal, date);
this.dataValidationErrors.add(error);
@@ -59,4 +59,9 @@ public class PlatformApiDataValidationException extends AbstractPlatformExceptio
public List<ApiParameterError> getErrors() {
return this.errors;
}
@Override
public String toString() {
return "PlatformApiDataValidationException{" + "errors=" + errors + '}';
}
}
@@ -30,7 +30,7 @@ import org.springframework.stereotype.Component;
* into JSON.
*/
@Component
public final class DefaultToApiJsonSerializer<T> implements ToApiJsonSerializer<T> {
public class DefaultToApiJsonSerializer<T> implements ToApiJsonSerializer<T> {
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOff;
private final ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOn;
@@ -36,6 +36,7 @@ import java.time.LocalDateTime;
import java.time.MonthDay;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.ArrayList;
import java.util.Arrays;
@@ -349,8 +350,8 @@ public class JsonParserHelper {
} catch (final IllegalArgumentException e) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.month.day",
"The parameter " + parameterName + " is invalid based on the monthDayFormat: '" + dateFormat
+ "' and locale: '" + clientApplicationLocale + "' provided:",
"The parameter `" + parameterName + "` is invalid based on the monthDayFormat: `" + dateFormat
+ "` and locale: `" + clientApplicationLocale + "` provided:",
parameterName, valueAsString, dateFormat);
dataValidationErrors.add(error);
@@ -422,7 +423,7 @@ public class JsonParserHelper {
}
} catch (IllegalArgumentException e) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final String defaultMessage = new StringBuilder("The parameter '" + timeValueAsString + "' is not in correct format.")
final String defaultMessage = new StringBuilder("The parameter `" + timeValueAsString + "` is not in correct format.")
.toString();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.TimeFormat", defaultMessage,
parameterName);
@@ -475,12 +476,12 @@ public class JsonParserHelper {
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0).parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0).toFormatter(clientApplicationLocale);
eventLocalDateTime = LocalDateTime.parse(dateTimeAsString, formatter);
} catch (final IllegalArgumentException e) {
} catch (final IllegalArgumentException | DateTimeParseException e) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final ApiParameterError error = ApiParameterError
.parameterError("validation.msg.invalid.dateFormat.format",
"The parameter " + parameterName + " is invalid based on the dateFormat: '" + dateTimeFormat
+ "' and locale: '" + clientApplicationLocale + "' provided:",
"The parameter `" + parameterName + "` is invalid based on the dateFormat: `" + dateTimeFormat
+ "` and locale: `" + clientApplicationLocale + "` provided:",
parameterName, eventLocalDateTime, dateTimeFormat);
dataValidationErrors.add(error);
@@ -499,14 +500,14 @@ public class JsonParserHelper {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
if (StringUtils.isBlank(dateFormat)) {
final String defaultMessage = new StringBuilder(
"The parameter '" + parameterName + "' requires a 'dateFormat' parameter to be passed with it.").toString();
"The parameter `" + parameterName + "` requires a `dateFormat` parameter to be passed with it.").toString();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.missing.dateFormat.parameter",
defaultMessage, parameterName);
dataValidationErrors.add(error);
}
if (clientApplicationLocale == null) {
final String defaultMessage = new StringBuilder(
"The parameter '" + parameterName + "' requires a 'locale' parameter to be passed with it.").toString();
"The parameter `" + parameterName + "` requires a `locale` parameter to be passed with it.").toString();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.missing.locale.parameter", defaultMessage,
parameterName);
dataValidationErrors.add(error);
@@ -524,7 +525,7 @@ public class JsonParserHelper {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final String defaultMessage = new StringBuilder(
"The parameter '" + parameterName + "' requires a 'locale' parameter to be passed with it.").toString();
"The parameter `" + parameterName + "` requires a `locale` parameter to be passed with it.").toString();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.missing.locale.parameter", defaultMessage,
parameterName);
dataValidationErrors.add(error);
@@ -572,7 +573,7 @@ public class JsonParserHelper {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final ApiParameterError error = ApiParameterError.parameterErrorWithValue("validation.msg.invalid.integer.format",
"The parameter " + parameterName + " has value: " + numericalValueFormatted
"The parameter `" + parameterName + "` has value: " + numericalValueFormatted
+ " which is invalid integer value for provided locale of [" + clientApplicationLocale.toString() + "].",
parameterName, numericalValueFormatted, numericalValueFormatted, clientApplicationLocale);
dataValidationErrors.add(error);
@@ -596,7 +597,7 @@ public class JsonParserHelper {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final ApiParameterError error = ApiParameterError.parameterErrorWithValue("validation.msg.invalid.integer",
"The parameter " + parameterName + " has value: " + numericalValueFormatted + " which is invalid integer.",
"The parameter `" + parameterName + "` has value: " + numericalValueFormatted + " which is invalid integer.",
parameterName, numericalValueFormatted, numericalValueFormatted);
dataValidationErrors.add(error);
@@ -611,7 +612,7 @@ public class JsonParserHelper {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final String defaultMessage = new StringBuilder(
"The parameter '" + parameterName + "' requires a 'locale' parameter to be passed with it.").toString();
"The parameter `" + parameterName + "` requires a `locale` parameter to be passed with it.").toString();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.missing.locale.parameter", defaultMessage,
parameterName);
dataValidationErrors.add(error);
@@ -650,8 +651,8 @@ public class JsonParserHelper {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final ApiParameterError error = ApiParameterError.parameterErrorWithValue("validation.msg.invalid.decimal.format",
"The parameter " + parameterName + " has value: " + numericalValueFormatted
+ " which is invalid decimal value for provided locale of [" + clientApplicationLocale.toString() + "].",
"The parameter `" + parameterName + "` has value: " + numericalValueFormatted
+ " which is invalid decimal value for provided locale of [" + clientApplicationLocale + "].",
parameterName, numericalValueFormatted, numericalValueFormatted, clientApplicationLocale);
dataValidationErrors.add(error);
@@ -668,7 +669,7 @@ public class JsonParserHelper {
if (StringUtils.isBlank(localeAsString)) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.locale.format",
"The parameter locale is invalid. It cannot be blank.", "locale");
"The parameter `locale` is invalid. It cannot be blank.", "locale");
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
@@ -706,7 +707,7 @@ public class JsonParserHelper {
final List<String> allowedLanguages = Arrays.asList(Locale.getISOLanguages());
if (!allowedLanguages.contains(languageCode.toLowerCase())) {
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.locale.format",
"The parameter locale has an invalid language value " + languageCode + " .", "locale", languageCode);
"The parameter `locale` has an invalid language value " + languageCode + " .", "locale", languageCode);
dataValidationErrors.add(error);
}
@@ -714,7 +715,7 @@ public class JsonParserHelper {
final List<String> allowedCountries = Arrays.asList(Locale.getISOCountries());
if (!allowedCountries.contains(courntryCode)) {
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.locale.format",
"The parameter locale has an invalid country value " + courntryCode + " .", "locale", courntryCode);
"The parameter `locale` has an invalid country value " + courntryCode + " .", "locale", courntryCode);
dataValidationErrors.add(error);
}
}
@@ -45,9 +45,11 @@ public enum JobName {
"Get Delivery Reports from SMS Gateway"), GENERATE_ADHOCCLIENT_SCEHDULE(
"Generate AdhocClient Schedule"), UPDATE_EMAIL_OUTBOUND_WITH_CAMPAIGN_MESSAGE(
"Update Email Outbound with campaign message"), EXECUTE_EMAIL(
"Execute Email"), UPDATE_TRAIL_BALANCE_DETAILS(
"Execute Email"), UPDATE_TRIAL_BALANCE_DETAILS(
"Update Trial Balance Details"), EXECUTE_DIRTY_JOBS(
"Execute All Dirty Jobs");
"Execute All Dirty Jobs"), INCREASE_BUSINESS_DATE_BY_1_DAY(
"Increase Business Date by 1 day"), INCREASE_COB_DATE_BY_1_DAY(
"Increase COB Date by 1 day");
private final String name;
@@ -151,7 +151,7 @@ public class AdHocQueryDataValidator {
.extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.maxOutStandingAmountPercentageParamName, element);
baseDataValidator.reset().parameter(AdHocQuerySearchConstants.maxOutStandingAmountPercentageParamName)
.value(maxOutStandingAmountPercentage).notNull().notLessThanMin(BigDecimal.ZERO);
baseDataValidator.reset().comapareMinAndMaxOfTwoBigDecmimalNos(minOutStandingAmountPercentage,
baseDataValidator.reset().compareMinAndMaxOfTwoBigDecmimalNos(minOutStandingAmountPercentage,
maxOutStandingAmountPercentage);
} else {
if (this.fromApiJsonHelper.parameterExists(AdHocQuerySearchConstants.outStandingAmountPercentageParamName, element)) {
@@ -184,7 +184,7 @@ public class AdHocQueryDataValidator {
.extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.maxOutstandingAmountParamName, element);
baseDataValidator.reset().parameter(AdHocQuerySearchConstants.maxOutstandingAmountParamName).value(maxOutstandingAmount)
.notNull().notLessThanMin(BigDecimal.ZERO);
baseDataValidator.reset().comapareMinAndMaxOfTwoBigDecmimalNos(minOutstandingAmount, maxOutstandingAmount);
baseDataValidator.reset().compareMinAndMaxOfTwoBigDecmimalNos(minOutstandingAmount, maxOutstandingAmount);
} else {
final BigDecimal outstandingAmount = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(AdHocQuerySearchConstants.outstandingAmountParamName, element);
@@ -20,7 +20,6 @@ package org.apache.fineract.scheduledjobs.service;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@@ -329,7 +328,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
}
@Override
@CronTarget(jobName = JobName.UPDATE_TRAIL_BALANCE_DETAILS)
@CronTarget(jobName = JobName.UPDATE_TRIAL_BALANCE_DETAILS)
public void updateTrialBalanceDetails() throws JobExecutionException {
final JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
final StringBuilder tbGapSqlBuilder = new StringBuilder(500);
@@ -344,15 +343,14 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
if (days < 1) {
continue;
}
final String formattedDate = new SimpleDateFormat("yyyy-MM-dd").format(tbGap);
final StringBuilder sqlBuilder = new StringBuilder(600);
sqlBuilder.append("Insert Into m_trial_balance(office_id, account_id, Amount, entry_date, created_date,closing_balance) ")
.append("Select je.office_id, je.account_id, SUM(CASE WHEN je.type_enum=1 THEN (-1) * je.amount ELSE je.amount END) ")
.append("as Amount, Date(je.entry_date) as 'Entry_Date', je.transaction_date as 'Created_Date',sum(je.amount) as closing_balance ")
.append("as Amount, Date(je.entry_date) as Entry_Date, je.transaction_date as Created_Date,sum(je.amount) as closing_balance ")
.append("from acc_gl_journal_entry je WHERE je.transaction_date = ? ")
.append("group by je.account_id, je.office_id, je.transaction_date, Date(je.entry_date)");
final int result = jdbcTemplate.update(sqlBuilder.toString(), formattedDate);
final int result = jdbcTemplate.update(sqlBuilder.toString(), tbGap);
LOG.info("{}: Records affected by updateTrialBalanceDetails: {}", ThreadLocalContextUtil.getTenant().getName(), result);
}
@@ -552,9 +552,20 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser {
}
public void validateHasReadPermission(final String resourceType) {
validateHasPermission("READ", resourceType);
}
final String authorizationMessage = "User has no authority to view " + resourceType.toLowerCase() + "s";
final String matchPermission = "READ_" + resourceType.toUpperCase();
public void validateHasCreatePermission(final String resourceType) {
validateHasPermission("CREATE", resourceType);
}
public void validateHasUpdatePermission(final String resourceType) {
validateHasPermission("UPDATE", resourceType);
}
private void validateHasPermission(final String prefix, final String resourceType) {
final String authorizationMessage = "User has no authority to " + prefix + " " + resourceType.toLowerCase() + "s";
final String matchPermission = prefix + "_" + resourceType.toUpperCase();
if (!hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", matchPermission)) {
return;