bulk auto reformat ca. 2900 files using ./gradlew :spotlessApply [FINERACT-1006]

This commit is contained in:
Michael Vorburger
2020-06-14 18:31:47 +02:00
committed by Michael Vorburger ⛑️
parent 89e321acaf
commit 9da5932307
2899 changed files with 44572 additions and 46101 deletions
@@ -29,11 +29,12 @@ import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
/**
* Fineract main() application which launches Fineract in an embedded Tomcat HTTP
* (using Spring Boot).
* Fineract main() application which launches Fineract in an embedded Tomcat
* HTTP (using Spring Boot).
*
* The DataSource used is a to a "normal" external database (not use MariaDB4j).
* This DataSource can be configured with parameters, see {@link DataSourceProperties}.
* This DataSource can be configured with parameters, see
* {@link DataSourceProperties}.
*
* You can easily launch this via Debug as Java Application in your IDE -
* without needing command line Gradle stuff, no need to build and deploy a WAR,
@@ -48,7 +49,7 @@ public class ServerApplication extends SpringBootServletInitializer {
@Import({ EmbeddedTomcatWithSSLConfiguration.class })
@ImportResource({ "classpath*:META-INF/spring/hikariDataSource.xml" })
private static class Configuration extends AbstractApplicationConfiguration { }
private static class Configuration extends AbstractApplicationConfiguration {}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
@@ -61,6 +62,6 @@ public class ServerApplication extends SpringBootServletInitializer {
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext ctx = configureApplication(new SpringApplicationBuilder(ServerApplication.class)).run(args);
//ApplicationExitUtil.waitForKeyPressToCleanlyExit(ctx);
// ApplicationExitUtil.waitForKeyPressToCleanlyExit(ctx);
}
}
}
@@ -32,7 +32,6 @@ import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
// import org.apache.fineract.accounting.accrual.swagger.runaccuralPost;
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
@@ -45,10 +44,9 @@ import org.springframework.stereotype.Component;
@Path("/runaccruals")
@Component
@Scope("singleton")
@Api(tags = {"Periodic Accrual Accounting"})
@Api(tags = { "Periodic Accrual Accounting" })
@SwaggerDefinition(tags = {
@Tag(name = "Periodic Accrual Accounting", description = "Periodic Accrual is to accrue the loan income till the specific date or till batch job scheduled time.\n")
})
@Tag(name = "Periodic Accrual Accounting", description = "Periodic Accrual is to accrue the loan income till the specific date or till batch job scheduled time.\n") })
public class AccrualAccountingApiResource {
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@@ -66,9 +64,12 @@ public class AccrualAccountingApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Executes Periodic Accrual Accounting", httpMethod = "POST", notes = "Mandatory Fields\n" + "\n" + "tillDate\n")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", required = true, type = "body", dataTypeClass = AccrualAccountingApiResourceSwagger.PostRunaccrualsRequest.class, value = "Request Body\n" + "\n" + "Field Descriptions: \n" + "tillDate: \n" + "which specifies periodic accruals should happen till the given Date" )})
@ApiResponses({@ApiResponse(code = 200, message = "OK")})
public String executePeriodicAccrualAccounting( @ApiParam(hidden = true) final String jsonRequestBody) {
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", required = true, type = "body", dataTypeClass = AccrualAccountingApiResourceSwagger.PostRunaccrualsRequest.class, value = "Request Body\n"
+ "\n" + "Field Descriptions: \n" + "tillDate: \n"
+ "which specifies periodic accruals should happen till the given Date") })
@ApiResponses({ @ApiResponse(code = 200, message = "OK") })
public String executePeriodicAccrualAccounting(@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().excuteAccrualAccounting().withJson(jsonRequestBody).build();
@@ -77,4 +78,4 @@ public class AccrualAccountingApiResource {
return this.apiJsonSerializerService.serialize(result);
}
}
}
@@ -25,12 +25,14 @@ import io.swagger.annotations.ApiModelProperty;
* Created by sanyam on 24/7/17.
*/
final class AccrualAccountingApiResourceSwagger {
private AccrualAccountingApiResourceSwagger() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModel(value = "runaccrualsRequest")
public static final class PostRunaccrualsRequest {
private PostRunaccrualsRequest() {
// don't allow to instantiate; use only for live API documentation
}
@@ -43,4 +43,4 @@ public class ExecutePeriodicAccrualCommandHandler implements NewCommandSourceHan
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.executeLoansPeriodicAccrual(command);
}
}
}
@@ -53,8 +53,7 @@ public final class AccrualAccountingDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private static final Set<String> LOAN_PERIODIC_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(accrueTillParamName, AccrualAccountingConstants.localeParamName,
AccrualAccountingConstants.dateFormatParamName));
Arrays.asList(accrueTillParamName, AccrualAccountingConstants.localeParamName, AccrualAccountingConstants.dateFormatParamName));
@Autowired
public AccrualAccountingDataValidator(final FromJsonHelper fromApiJsonfromApiJsonHelper) {
@@ -81,4 +80,4 @@ public final class AccrualAccountingDataValidator {
public void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
}
}
@@ -59,7 +59,8 @@ public class AccrualAccountingWritePlatformServiceImpl implements AccrualAccount
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE, e.getMessage());
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(PERIODIC_ACCRUAL_ACCOUNTING_EXECUTION_ERROR_CODE,
e.getMessage());
throw new PlatformApiDataValidationException(dataValidationErrors);
}
return CommandProcessingResult.empty();
@@ -25,6 +25,7 @@ import java.util.Set;
* Enum of all parameters passed in while creating/updating a loan product
***/
public enum GLClosureJsonInputParams {
ID("id"), OFFICE_ID("officeId"), CLOSING_DATE("closingDate"), COMMENTS("comments"), LOCALE("locale"), DATE_FORMAT("dateFormat");
private final String value;
@@ -52,4 +53,4 @@ public enum GLClosureJsonInputParams {
public String getValue() {
return this.value;
}
}
}
@@ -61,15 +61,17 @@ import org.springframework.stereotype.Component;
@Path("/glclosures")
@Component
@Scope("singleton")
@Api(tags = {"Accounting Closure"})
@Api(tags = { "Accounting Closure" })
@SwaggerDefinition(tags = {
@Tag(name = "Accounting Closure", description = "An accounting closure indicates that no more journal entries may be logged (or reversed) in the system, either manually or via the portfolio with an entry date prior to the defined closure date\n" + "\n" + "Field Descriptions\n" + "closingDate\n" + "The date for which the accounting closure is defined\n" + "officeId\n" + "The identifer of the branch for which accounting has been closed\n" + "comments\n" + "Description associated with an Accounting closure")
})
@Tag(name = "Accounting Closure", description = "An accounting closure indicates that no more journal entries may be logged (or reversed) in the system, either manually or via the portfolio with an entry date prior to the defined closure date\n"
+ "\n" + "Field Descriptions\n" + "closingDate\n" + "The date for which the accounting closure is defined\n" + "officeId\n"
+ "The identifer of the branch for which accounting has been closed\n" + "comments\n"
+ "Description associated with an Accounting closure") })
public class GLClosuresApiResource {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "officeId", "officeName",
"closingDate", "deleted", "createdDate", "lastUpdatedDate", "createdByUserId", "createdByUsername", "lastUpdatedByUserId",
"lastUpdatedByUsername"));
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList("id", "officeId", "officeName", "closingDate", "deleted", "createdDate", "lastUpdatedDate", "createdByUserId",
"createdByUsername", "lastUpdatedByUserId", "lastUpdatedByUsername"));
private final String resourceNameForPermission = "GLCLOSURE";
@@ -97,8 +99,10 @@ public class GLClosuresApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "List Accounting closures", notes = "Example Requests:\n" + "\n" + "glclosures")
@ApiResponses({@ApiResponse(code = 200, response = GLClosuresApiResourceSwagger.GetGlClosureResponse.class, message = "", responseContainer = "list")})
public String retrieveAllClosures(@Context final UriInfo uriInfo, @QueryParam("officeId") @ApiParam(value = "officeId") final Long officeId) {
@ApiResponses({
@ApiResponse(code = 200, response = GLClosuresApiResourceSwagger.GetGlClosureResponse.class, message = "", responseContainer = "list") })
public String retrieveAllClosures(@Context final UriInfo uriInfo,
@QueryParam("officeId") @ApiParam(value = "officeId") final Long officeId) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
final List<GLClosureData> glClosureDatas = this.glClosureReadPlatformService.retrieveAllGLClosures(officeId);
@@ -111,9 +115,11 @@ public class GLClosuresApiResource {
@Path("{glClosureId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve an Accounting Closure", notes = "Example Requests:\n" + "\n" + "glclosures/1\n" + "\n" + "\n" + "/glclosures/1?fields=officeName,closingDate")
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.GetGlClosureResponse.class)})
public String retreiveClosure(@PathParam("glClosureId") @ApiParam(value = "glClosureId") final Long glClosureId, @Context final UriInfo uriInfo) {
@ApiOperation(value = "Retrieve an Accounting Closure", notes = "Example Requests:\n" + "\n" + "glclosures/1\n" + "\n" + "\n"
+ "/glclosures/1?fields=officeName,closingDate")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.GetGlClosureResponse.class) })
public String retreiveClosure(@PathParam("glClosureId") @ApiParam(value = "glClosureId") final Long glClosureId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -132,8 +138,9 @@ public class GLClosuresApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Create an Accounting Closure", notes = "Mandatory Fields\n" + "officeId,closingDate")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", required = true, type = "body", dataTypeClass = GLClosuresApiResourceSwagger.PostGlClosuresRequest.class, value = "Request Body")})
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.PostGlClosuresResponse.class)})
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", required = true, type = "body", dataTypeClass = GLClosuresApiResourceSwagger.PostGlClosuresRequest.class, value = "Request Body") })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.PostGlClosuresResponse.class) })
public String createGLClosure(@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLClosure().withJson(jsonRequestBody).build();
@@ -148,9 +155,11 @@ public class GLClosuresApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Update an Accounting closure", notes = "Once an accounting closure is created, only the comments associated with it may be edited")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", value = "Request body", dataType = "body", dataTypeClass = GLClosuresApiResourceSwagger.PutGlClosuresRequest.class, required = true)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.PutGlClosuresResponse.class)})
public String updateGLClosure(@PathParam("glClosureId") @ApiParam(value = "glClosureId") final Long glClosureId, @ApiParam(hidden = true) final String jsonRequestBody) {
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "Request body", dataType = "body", dataTypeClass = GLClosuresApiResourceSwagger.PutGlClosuresRequest.class, required = true) })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.PutGlClosuresResponse.class) })
public String updateGLClosure(@PathParam("glClosureId") @ApiParam(value = "glClosureId") final Long glClosureId,
@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLClosure(glClosureId).withJson(jsonRequestBody).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
@@ -163,7 +172,7 @@ public class GLClosuresApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Delete an accounting closure", notes = "Note: Only the latest accounting closure associated with a branch may be deleted.")
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.DeleteGlClosuresResponse.class)})
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLClosuresApiResourceSwagger.DeleteGlClosuresResponse.class) })
public String deleteGLClosure(@PathParam("glClosureId") @ApiParam(value = "glclosureId") final Long glClosureId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLClosure(glClosureId).build();
@@ -172,4 +181,4 @@ public class GLClosuresApiResource {
return this.apiJsonSerializerService.serialize(result);
}
}
}
@@ -23,6 +23,7 @@ import io.swagger.annotations.ApiModelProperty;
import org.joda.time.LocalDate;
final class GLClosuresApiResourceSwagger {
private GLClosuresApiResourceSwagger() {
// don't allow to instantiate; use only for live API documentation
}
@@ -35,6 +36,7 @@ final class GLClosuresApiResourceSwagger {
@ApiModel(value = "GetGLClosureResponse")
public static final class GetGlClosureResponse {
private GetGlClosureResponse() {
// dont allow to initiatiate
}
@@ -68,9 +70,11 @@ final class GLClosuresApiResourceSwagger {
@ApiModel(value = "PostGLCLosuresRequest")
public static final class PostGlClosuresRequest {
private PostGlClosuresRequest() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "06 December 2012")
@@ -85,9 +89,11 @@ final class GLClosuresApiResourceSwagger {
@ApiModel(value = "PostGlClosuresResponse")
public static final class PostGlClosuresResponse {
private PostGlClosuresResponse() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
@@ -96,18 +102,22 @@ final class GLClosuresApiResourceSwagger {
@ApiModel(value = "PutGlClosuresRequest")
public static final class PutGlClosuresRequest {
private PutGlClosuresRequest() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "All transactions verified by Johnny Cash")
public String comments;
}
@ApiModel(value = "PutGlClosuresResponse")
public static final class PutGlClosuresResponse{
public static final class PutGlClosuresResponse {
private PutGlClosuresResponse() {
// don't allow to instantiate; use only for live API documentation
}
@ApiModelProperty(example = "1")
public Long officeId;
@ApiModelProperty(example = "9")
@@ -117,8 +127,9 @@ final class GLClosuresApiResourceSwagger {
}
@ApiModel(value = "DeleteGlClosuresResponse")
public static final class DeleteGlClosuresResponse{
private DeleteGlClosuresResponse(){
public static final class DeleteGlClosuresResponse {
private DeleteGlClosuresResponse() {
}
@@ -127,4 +138,4 @@ final class GLClosuresApiResourceSwagger {
@ApiModelProperty(example = "9")
public Long resourceId;
}
}
}
@@ -56,8 +56,10 @@ public class GLClosureCommand {
baseDataValidator.reset().parameter(GLClosureJsonInputParams.COMMENTS.getValue()).value(this.comments).ignoreIfNull()
.notExceedingLengthOf(500);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
public void validateForUpdate() {
@@ -69,8 +71,10 @@ public class GLClosureCommand {
.notExceedingLengthOf(500);
baseDataValidator.reset().anyOfNotNull(this.comments);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
}
@@ -84,4 +84,4 @@ public class GLClosureData {
this.allowedOffices = allowedOffices;
}
}
}
@@ -36,7 +36,8 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
import org.apache.fineract.organisation.office.domain.Office;
@Entity
@Table(name = "acc_gl_closure", uniqueConstraints = { @UniqueConstraint(columnNames = { "office_id", "closing_date" }, name = "office_id_closing_date") })
@Table(name = "acc_gl_closure", uniqueConstraints = {
@UniqueConstraint(columnNames = { "office_id", "closing_date" }, name = "office_id_closing_date") })
public class GLClosure extends AbstractAuditableCustom {
@ManyToOne
@@ -99,4 +100,4 @@ public class GLClosure extends AbstractAuditableCustom {
return this.office;
}
}
}
@@ -28,8 +28,9 @@ import org.joda.time.LocalDate;
public class GLClosureDuplicateException extends AbstractPlatformDomainRuleException {
public GLClosureDuplicateException(final Long officeId, final LocalDate closureDate) {
super("error.msg.glclosure.glcode.duplicate", "An accounting closure for branch with Id " + officeId
+ " already exists for the date " + closureDate, officeId, closureDate);
super("error.msg.glclosure.glcode.duplicate",
"An accounting closure for branch with Id " + officeId + " already exists for the date " + closureDate, officeId,
closureDate);
}
}
}
@@ -30,4 +30,4 @@ public class GLClosureInvalidDeleteException extends AbstractPlatformDomainRuleE
super("error.msg.glclosure.invalid.delete", "The latest closure for office with Id " + officeId + " and name " + officeName
+ " is on " + latestclosureDate.toString() + ", please delete this closure first", latestclosureDate);
}
}
}
@@ -28,12 +28,15 @@ public class GLClosureInvalidException extends AbstractPlatformDomainRuleExcepti
/*** enum of reasons for invalid Accounting Closure **/
public static enum GlClosureInvalidReason {
FUTURE_DATE, ACCOUNTING_CLOSED;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
return "Accounting closures cannot be made for a future date";
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) { return "Accounting Closure for this branch has already been defined for a greater date"; }
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
return "Accounting Closure for this branch has already been defined for a greater date";
}
return name().toString();
}
@@ -48,4 +51,4 @@ public class GLClosureInvalidException extends AbstractPlatformDomainRuleExcepti
public GLClosureInvalidException(final GlClosureInvalidReason reason, final Date date) {
super(reason.errorCode(), reason.errorMessage(), date);
}
}
}
@@ -29,4 +29,4 @@ public class GLClosureNotFoundException extends AbstractPlatformResourceNotFound
public GLClosureNotFoundException(final Long id) {
super("error.msg.glclosure.id.invalid", "Accounting Closure with identifier " + id + " does not exist", id);
}
}
}
@@ -44,4 +44,4 @@ public class CreateGLClosureCommandHandler implements NewCommandSourceHandler {
return this.writePlatformService.createGLClosure(command);
}
}
}
@@ -43,4 +43,4 @@ public class DeleteGLClosureCommandHandler implements NewCommandSourceHandler {
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.closureWritePlatformService.deleteGLClosure(command.entityId());
}
}
}
@@ -43,4 +43,4 @@ public class UpdateGLClosureCommandHandler implements NewCommandSourceHandler {
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.updateGLClosure(command.entityId(), command);
}
}
}
@@ -67,4 +67,4 @@ public final class GLClosureCommandFromApiJsonDeserializer extends AbstractFromA
return new GLClosureCommand(id, officeId, closingDate, comments);
}
}
}
@@ -79,8 +79,9 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
// shouldn't be before an existing accounting closure
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(officeId);
if (latestGLClosure != null) {
if (latestGLClosure.getClosingDate().after(closureDate)) { throw new GLClosureInvalidException(
GlClosureInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate()); }
if (latestGLClosure.getClosingDate().after(closureDate)) {
throw new GLClosureInvalidException(GlClosureInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate());
}
}
final GLClosure glClosure = GLClosure.fromJson(office, command);
@@ -101,7 +102,8 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
closureCommand.validateForUpdate();
// is the glClosure valid
final GLClosure glClosure = this.glClosureRepository.findById(glClosureId).orElseThrow(() -> new GLClosureNotFoundException(glClosureId));
final GLClosure glClosure = this.glClosureRepository.findById(glClosureId)
.orElseThrow(() -> new GLClosureNotFoundException(glClosureId));
final Map<String, Object> changesOnly = glClosure.update(command);
@@ -119,15 +121,16 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
final GLClosure glClosure = this.glClosureRepository.findById(glClosureId)
.orElseThrow(() -> new GLClosureNotFoundException(glClosureId));
/**
* check if any closures are present for this branch at a later date
* than this closure date
**/
final Date closureDate = glClosure.getClosingDate();
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(glClosure.getOffice().getId());
if (latestGLClosure.getClosingDate().after(closureDate)) { throw new GLClosureInvalidDeleteException(latestGLClosure.getOffice()
.getId(), latestGLClosure.getOffice().getName(), latestGLClosure.getClosingDate()); }
if (latestGLClosure.getClosingDate().after(closureDate)) {
throw new GLClosureInvalidDeleteException(latestGLClosure.getOffice().getId(), latestGLClosure.getOffice().getName(),
latestGLClosure.getClosingDate());
}
this.glClosureRepository.delete(glClosure);
@@ -140,9 +143,10 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
*/
private void handleGLClosureIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
final Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("office_id_closing_date")) { throw new GLClosureDuplicateException(
command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue()), new LocalDate(
command.dateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue()))); }
if (realCause.getMessage().contains("office_id_closing_date")) {
throw new GLClosureDuplicateException(command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue()),
new LocalDate(command.dateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue())));
}
LOG.error("Error occured.", dve);
throw new PlatformDataIntegrityException("error.msg.glClosure.unknown.data.integrity.issue",
@@ -27,10 +27,13 @@ import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
public class AccountingConstants {
/*** Accounting placeholders for cash based accounting for loan products ***/
/***
* Accounting placeholders for cash based accounting for loan products
***/
public static enum CashAccountsForLoan {
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6), TRANSFERS_SUSPENSE(
10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(
6), TRANSFERS_SUSPENSE(10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
private final Integer value;
@@ -60,10 +63,14 @@ public class AccountingConstants {
}
}
/*** Accounting placeholders for accrual based accounting for loan products ***/
/***
* Accounting placeholders for accrual based accounting for loan products
***/
public static enum AccrualAccountsForLoan {
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(6), INTEREST_RECEIVABLE(
7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9), TRANSFERS_SUSPENSE(10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
FUND_SOURCE(1), LOAN_PORTFOLIO(2), INTEREST_ON_LOANS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), LOSSES_WRITTEN_OFF(
6), INTEREST_RECEIVABLE(
7), FEES_RECEIVABLE(8), PENALTIES_RECEIVABLE(9), TRANSFERS_SUSPENSE(10), OVERPAYMENT(11), INCOME_FROM_RECOVERY(12);
private final Integer value;
@@ -99,14 +106,20 @@ public class AccountingConstants {
* creating/updating a loan product
***/
public static enum LoanProductAccountingParams {
FUND_SOURCE("fundSourceAccountId"), LOAN_PORTFOLIO("loanPortfolioAccountId"), INTEREST_ON_LOANS("interestOnLoanAccountId"), INCOME_FROM_FEES(
"incomeFromFeeAccountId"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccountId"), LOSSES_WRITTEN_OFF("writeOffAccountId"), OVERPAYMENT(
"overpaymentLiabilityAccountId"), INTEREST_RECEIVABLE("receivableInterestAccountId"), FEES_RECEIVABLE(
"receivableFeeAccountId"), PENALTIES_RECEIVABLE("receivablePenaltyAccountId"), TRANSFERS_SUSPENSE(
"transfersInSuspenseAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING("paymentChannelToFundSourceMappings"), PAYMENT_TYPE(
"paymentTypeId"), FEE_INCOME_ACCOUNT_MAPPING("feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING(
"penaltyToIncomeAccountMappings"), CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID("incomeAccountId"), INCOME_FROM_RECOVERY(
"incomeFromRecoveryAccountId");
FUND_SOURCE("fundSourceAccountId"), LOAN_PORTFOLIO("loanPortfolioAccountId"), INTEREST_ON_LOANS(
"interestOnLoanAccountId"), INCOME_FROM_FEES("incomeFromFeeAccountId"), INCOME_FROM_PENALTIES(
"incomeFromPenaltyAccountId"), LOSSES_WRITTEN_OFF("writeOffAccountId"), OVERPAYMENT(
"overpaymentLiabilityAccountId"), INTEREST_RECEIVABLE("receivableInterestAccountId"), FEES_RECEIVABLE(
"receivableFeeAccountId"), PENALTIES_RECEIVABLE("receivablePenaltyAccountId"), TRANSFERS_SUSPENSE(
"transfersInSuspenseAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING(
"paymentChannelToFundSourceMappings"), PAYMENT_TYPE(
"paymentTypeId"), FEE_INCOME_ACCOUNT_MAPPING(
"feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING(
"penaltyToIncomeAccountMappings"), CHARGE_ID(
"chargeId"), INCOME_ACCOUNT_ID(
"incomeAccountId"), INCOME_FROM_RECOVERY(
"incomeFromRecoveryAccountId");
private final String value;
@@ -125,11 +138,15 @@ public class AccountingConstants {
}
public static enum LoanProductAccountingDataParams {
FUND_SOURCE("fundSourceAccount"), LOAN_PORTFOLIO("loanPortfolioAccount"), INTEREST_ON_LOANS("interestOnLoanAccount"), INCOME_FROM_FEES(
"incomeFromFeeAccount"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccount"), LOSSES_WRITTEN_OFF("writeOffAccount"), OVERPAYMENT(
"overpaymentLiabilityAccount"), INTEREST_RECEIVABLE("receivableInterestAccount"), FEES_RECEIVABLE("receivableFeeAccount"), PENALTIES_RECEIVABLE(
"receivablePenaltyAccount"), TRANSFERS_SUSPENSE("transfersInSuspenseAccount"), INCOME_ACCOUNT_ID("incomeAccount"), INCOME_FROM_RECOVERY(
"incomeFromRecoveryAccount"), LIABILITY_TRANSFER_SUSPENSE("liabilityTransferInSuspenseAccount");
FUND_SOURCE("fundSourceAccount"), LOAN_PORTFOLIO("loanPortfolioAccount"), INTEREST_ON_LOANS(
"interestOnLoanAccount"), INCOME_FROM_FEES("incomeFromFeeAccount"), INCOME_FROM_PENALTIES(
"incomeFromPenaltyAccount"), LOSSES_WRITTEN_OFF("writeOffAccount"), OVERPAYMENT(
"overpaymentLiabilityAccount"), INTEREST_RECEIVABLE("receivableInterestAccount"), FEES_RECEIVABLE(
"receivableFeeAccount"), PENALTIES_RECEIVABLE("receivablePenaltyAccount"), TRANSFERS_SUSPENSE(
"transfersInSuspenseAccount"), INCOME_ACCOUNT_ID("incomeAccount"), INCOME_FROM_RECOVERY(
"incomeFromRecoveryAccount"), LIABILITY_TRANSFER_SUSPENSE(
"liabilityTransferInSuspenseAccount");
private final String value;
@@ -147,8 +164,11 @@ public class AccountingConstants {
}
}
/*** Accounting placeholders for cash based accounting for savings products ***/
/***
* Accounting placeholders for cash based accounting for savings products
***/
public static enum CashAccountsForSavings {
SAVINGS_REFERENCE(1), SAVINGS_CONTROL(2), INTEREST_ON_SAVINGS(3), INCOME_FROM_FEES(4), INCOME_FROM_PENALTIES(5), TRANSFERS_SUSPENSE(
10), OVERDRAFT_PORTFOLIO_CONTROL(11), INCOME_FROM_INTEREST(12), LOSSES_WRITTEN_OFF(13), ESCHEAT_LIABILITY(14);
@@ -185,13 +205,20 @@ public class AccountingConstants {
* creating/updating a savings product
***/
public static enum SavingProductAccountingParams {
SAVINGS_REFERENCE("savingsReferenceAccountId"), SAVINGS_CONTROL("savingsControlAccountId"), INCOME_FROM_FEES(
"incomeFromFeeAccountId"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccountId"), INTEREST_ON_SAVINGS(
"interestOnSavingsAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING("paymentChannelToFundSourceMappings"), PAYMENT_TYPE(
"paymentTypeId"), FUND_SOURCE("fundSourceAccountId"), TRANSFERS_SUSPENSE("transfersInSuspenseAccountId"), FEE_INCOME_ACCOUNT_MAPPING(
"feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING("penaltyToIncomeAccountMappings"), CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID(
"incomeAccountId"), OVERDRAFT_PORTFOLIO_CONTROL("overdraftPortfolioControlId"), INCOME_FROM_INTEREST("incomeFromInterestId"), LOSSES_WRITTEN_OFF(
"writeOffAccountId"), ESCHEAT_LIABILITY("escheatLiabilityId");
"interestOnSavingsAccountId"), PAYMENT_CHANNEL_FUND_SOURCE_MAPPING(
"paymentChannelToFundSourceMappings"), PAYMENT_TYPE("paymentTypeId"), FUND_SOURCE(
"fundSourceAccountId"), TRANSFERS_SUSPENSE(
"transfersInSuspenseAccountId"), FEE_INCOME_ACCOUNT_MAPPING(
"feeToIncomeAccountMappings"), PENALTY_INCOME_ACCOUNT_MAPPING(
"penaltyToIncomeAccountMappings"), CHARGE_ID("chargeId"), INCOME_ACCOUNT_ID(
"incomeAccountId"), OVERDRAFT_PORTFOLIO_CONTROL(
"overdraftPortfolioControlId"), INCOME_FROM_INTEREST(
"incomeFromInterestId"), LOSSES_WRITTEN_OFF(
"writeOffAccountId"), ESCHEAT_LIABILITY(
"escheatLiabilityId");
private final String value;
@@ -210,12 +237,15 @@ public class AccountingConstants {
}
public static enum SavingProductAccountingDataParams {
SAVINGS_REFERENCE("savingsReferenceAccount"), SAVINGS_CONTROL("savingsControlAccount"), INCOME_FROM_FEES("incomeFromFeeAccount"), INCOME_FROM_PENALTIES(
"incomeFromPenaltyAccount"), INTEREST_ON_SAVINGS("interestOnSavingsAccount"), PAYMENT_TYPE("paymentType"), FUND_SOURCE(
"fundSourceAccount"), TRANSFERS_SUSPENSE("transfersInSuspenseAccount"), PENALTY_INCOME_ACCOUNT_MAPPING(
"penaltyToIncomeAccountMappings"), CHARGE_ID("charge"), INCOME_ACCOUNT_ID("incomeAccount"), OVERDRAFT_PORTFOLIO_CONTROL(
"overdraftPortfolioControl"), INCOME_FROM_INTEREST("incomeFromInterest"), LOSSES_WRITTEN_OFF("writeOffAccount"),
ESCHEAT_LIABILITY("escheatLiabilityAccount");
SAVINGS_REFERENCE("savingsReferenceAccount"), SAVINGS_CONTROL("savingsControlAccount"), INCOME_FROM_FEES(
"incomeFromFeeAccount"), INCOME_FROM_PENALTIES("incomeFromPenaltyAccount"), INTEREST_ON_SAVINGS(
"interestOnSavingsAccount"), PAYMENT_TYPE("paymentType"), FUND_SOURCE("fundSourceAccount"), TRANSFERS_SUSPENSE(
"transfersInSuspenseAccount"), PENALTY_INCOME_ACCOUNT_MAPPING("penaltyToIncomeAccountMappings"), CHARGE_ID(
"charge"), INCOME_ACCOUNT_ID("incomeAccount"), OVERDRAFT_PORTFOLIO_CONTROL(
"overdraftPortfolioControl"), INCOME_FROM_INTEREST(
"incomeFromInterest"), LOSSES_WRITTEN_OFF(
"writeOffAccount"), ESCHEAT_LIABILITY("escheatLiabilityAccount");
private final String value;
@@ -234,10 +264,12 @@ public class AccountingConstants {
}
public static enum FinancialActivity {
ASSET_TRANSFER(100, "assetTransfer", GLAccountType.ASSET), LIABILITY_TRANSFER(200, "liabilityTransfer", GLAccountType.LIABILITY), CASH_AT_MAINVAULT(
101, "cashAtMainVault", GLAccountType.ASSET), CASH_AT_TELLER(102, "cashAtTeller", GLAccountType.ASSET), OPENING_BALANCES_TRANSFER_CONTRA(
300, "openingBalancesTransferContra", GLAccountType.EQUITY), ASSET_FUND_SOURCE(103, "fundSource", GLAccountType.ASSET), PAYABLE_DIVIDENDS(
201, "payableDividends", GLAccountType.LIABILITY);
ASSET_TRANSFER(100, "assetTransfer", GLAccountType.ASSET), LIABILITY_TRANSFER(200, "liabilityTransfer",
GLAccountType.LIABILITY), CASH_AT_MAINVAULT(101, "cashAtMainVault", GLAccountType.ASSET), CASH_AT_TELLER(102,
"cashAtTeller", GLAccountType.ASSET), OPENING_BALANCES_TRANSFER_CONTRA(300, "openingBalancesTransferContra",
GLAccountType.EQUITY), ASSET_FUND_SOURCE(103, "fundSource",
GLAccountType.ASSET), PAYABLE_DIVIDENDS(201, "payableDividends", GLAccountType.LIABILITY);
private final Integer value;
private final String code;
@@ -245,7 +277,7 @@ public class AccountingConstants {
private static List<FinancialActivityData> financialActivities;
static {
financialActivities = new ArrayList<>();
financialActivities = new ArrayList<>();
for (final FinancialActivity type : FinancialActivity.values()) {
FinancialActivityData financialActivityData = convertToFinancialActivityData(type);
financialActivities.add(financialActivityData);
@@ -306,8 +338,11 @@ public class AccountingConstants {
}
}
/*** Accounting placeholders for cash based accounting for Share products ***/
/***
* Accounting placeholders for cash based accounting for Share products
***/
public static enum CashAccountsForShares {
SHARES_REFERENCE(1), SHARES_SUSPENSE(2), INCOME_FROM_FEES(3), SHARES_EQUITY(4);
private final Integer value;
@@ -343,6 +378,7 @@ public class AccountingConstants {
* creating/updating a savings product
***/
public static enum SharesProductAccountingParams {
SHARES_REFERENCE("shareReferenceId"), SHARES_SUSPENSE("shareSuspenseId"), INCOME_FROM_FEES("incomeFromFeeAccountId"), SHARES_EQUITY(
"shareEquityId");
@@ -43,4 +43,4 @@ public interface AccountingDropdownReadPlatformService {
public Map<String, List<GLAccountData>> retrieveAccountMappingOptionsForShareProducts();
}
}
@@ -157,4 +157,4 @@ public class AccountingDropdownReadPlatformServiceImpl implements AccountingDrop
includeEquityAccounts);
}
}
}
@@ -60,4 +60,4 @@ public enum AccountingRuleType {
public String getCode() {
return this.code;
}
}
}
@@ -56,10 +56,11 @@ import org.springframework.stereotype.Component;
@Path("/financialactivityaccounts")
@Component
@Scope("singleton")
@Api(tags = {"Mapping Financial Activities to Accounts"})
@Api(tags = { "Mapping Financial Activities to Accounts" })
@SwaggerDefinition(tags = {
@Tag(name = "Mapping Financial Activities to Accounts", description = "Organization Level Financial Activities like Asset and Liability Transfer can be mapped to GL Account. Integrated accounting takes these accounts into consideration when an Account transfer is made between a savings to loan/savings account and vice-versa\n" + "\n" + "Field Descriptions\n" + "financialActivityId\n" + "The identifier of the Financial Activity\n" + "glAccountId\n" + "The identifier of a GL Account ( Ledger Account) which shall be used as the default account for the selected Financial Activity")
})
@Tag(name = "Mapping Financial Activities to Accounts", description = "Organization Level Financial Activities like Asset and Liability Transfer can be mapped to GL Account. Integrated accounting takes these accounts into consideration when an Account transfer is made between a savings to loan/savings account and vice-versa\n"
+ "\n" + "Field Descriptions\n" + "financialActivityId\n" + "The identifier of the Financial Activity\n" + "glAccountId\n"
+ "The identifier of a GL Account ( Ledger Account) which shall be used as the default account for the selected Financial Activity") })
public class FinancialActivityAccountsApiResource {
private final FinancialActivityAccountReadPlatformService financialActivityAccountReadPlatformService;
@@ -100,8 +101,10 @@ public class FinancialActivityAccountsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "List Financial Activities to Accounts Mappings", notes = "Example Requests:\n" + "\n" + "financialactivityaccounts")
@ApiResponses({@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class, responseContainer = "list" )})
@ApiOperation(value = "List Financial Activities to Accounts Mappings", notes = "Example Requests:\n" + "\n"
+ "financialactivityaccounts")
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class, responseContainer = "list") })
public String retrieveAll(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
@@ -116,8 +119,10 @@ public class FinancialActivityAccountsApiResource {
@Path("{mappingId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve a Financial Activity to Account Mapping\n", notes = "Example Requests:\n" + "\n" + "financialactivityaccounts/1")
@ApiResponses({@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class)})
@ApiOperation(value = "Retrieve a Financial Activity to Account Mapping\n", notes = "Example Requests:\n" + "\n"
+ "financialactivityaccounts/1")
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.GetFinancialActivityAccountsResponse.class) })
public String retreive(@PathParam("mappingId") @ApiParam(value = "mappingId") final Long mappingId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(FinancialActivityAccountsConstants.resourceNameForPermission);
@@ -136,9 +141,12 @@ public class FinancialActivityAccountsApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Create a new Financial Activity to Accounts Mapping", notes = "Mandatory Fields\n" + "financialActivityId, glAccountId")
@ApiImplicitParams({@ApiImplicitParam(value = "Request body", paramType = "body", dataType = "body", dataTypeClass = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsResponse.class)})
@ApiOperation(value = "Create a new Financial Activity to Accounts Mapping", notes = "Mandatory Fields\n"
+ "financialActivityId, glAccountId")
@ApiImplicitParams({
@ApiImplicitParam(value = "Request body", paramType = "body", dataType = "body", dataTypeClass = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class) })
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsResponse.class) })
public String createGLAccount(@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createOfficeToGLAccountMapping().withJson(jsonRequestBody)
@@ -154,9 +162,12 @@ public class FinancialActivityAccountsApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Update a Financial Activity to Account Mapping", notes = "the API updates the Ledger account linked to a Financial Activity \n")
@ApiImplicitParams({@ApiImplicitParam(value = "Request body", dataType = "body", paramType = "body", dataTypeClass = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.PutFinancialActivityAccountsResponse.class)})
public String updateGLAccount(@PathParam("mappingId") @ApiParam(value = "mappingId") final Long mappingId, @ApiParam(hidden = true) final String jsonRequestBody) {
@ApiImplicitParams({
@ApiImplicitParam(value = "Request body", dataType = "body", paramType = "body", dataTypeClass = FinancialActivityAccountsApiResourceSwagger.PostFinancialActivityAccountsRequest.class) })
@ApiResponses({
@ApiResponse(code = 200, message = "", response = FinancialActivityAccountsApiResourceSwagger.PutFinancialActivityAccountsResponse.class) })
public String updateGLAccount(@PathParam("mappingId") @ApiParam(value = "mappingId") final Long mappingId,
@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateOfficeToGLAccountMapping(mappingId)
.withJson(jsonRequestBody).build();
@@ -171,7 +182,8 @@ public class FinancialActivityAccountsApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Delete a Financial Activity to Account Mapping")
@ApiResponses({@ApiResponse(code = 200, message = "OK", response = FinancialActivityAccountsApiResourceSwagger.DeleteFinancialActivityAccountsResponse.class)})
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = FinancialActivityAccountsApiResourceSwagger.DeleteFinancialActivityAccountsResponse.class) })
public String deleteGLAccount(@PathParam("mappingId") @ApiParam(value = "mappingId") final Long mappingId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteOfficeToGLAccountMapping(mappingId).build();
@@ -27,14 +27,16 @@ import org.apache.fineract.accounting.glaccount.data.GLAccountData;
* Created by sanyam on 24/7/17.
*/
final class FinancialActivityAccountsApiResourceSwagger {
private FinancialActivityAccountsApiResourceSwagger() {
}
private FinancialActivityAccountsApiResourceSwagger() {}
@ApiModel(value = "GetFinancialActivityAccountsResponse")
public static final class GetFinancialActivityAccountsResponse{
public static final class GetFinancialActivityAccountsResponse {
private GetFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
public Long id;
public FinancialActivityData financialActivityData;
@@ -43,10 +45,12 @@ final class FinancialActivityAccountsApiResourceSwagger {
}
@ApiModel(value = "PostFinancialActivityAccountsRequest")
public static final class PostFinancialActivityAccountsRequest{
public static final class PostFinancialActivityAccountsRequest {
private PostFinancialActivityAccountsRequest() {
}
@ApiModelProperty(example = "200")
public Long financialActivityId;
@ApiModelProperty(example = "2")
@@ -54,19 +58,23 @@ final class FinancialActivityAccountsApiResourceSwagger {
}
@ApiModel(value = "PostFinancialActivityAccountsResponse")
public static final class PostFinancialActivityAccountsResponse{
public static final class PostFinancialActivityAccountsResponse {
private PostFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
public Long resourceId;
}
@ApiModel(value = "PutFinancialActivityAccountsRequest")
public static final class PutFinancialActivityAccountsRequest{
public static final class PutFinancialActivityAccountsRequest {
private PutFinancialActivityAccountsRequest() {
}
@ApiModelProperty(example = "200")
public Long financialActivityId;
@ApiModelProperty(example = "3")
@@ -74,25 +82,32 @@ final class FinancialActivityAccountsApiResourceSwagger {
}
@ApiModel(value = "PutFinancialActivityAccountsResponse")
public static final class PutFinancialActivityAccountsResponse{
public static final class PutFinancialActivityAccountsResponse {
private PutFinancialActivityAccountsResponse() {
}
public final class PutFinancialActivityAccountscommentsSwagger{
private PutFinancialActivityAccountscommentsSwagger(){}
public final class PutFinancialActivityAccountscommentsSwagger {
private PutFinancialActivityAccountscommentsSwagger() {}
@ApiModelProperty(example = "1")
public Long glAccountId;
}
@ApiModelProperty(example = "1")
public Long resourceId;
public PutFinancialActivityAccountscommentsSwagger comments;
}
@ApiModel(value = "DeleteFinancialActivityAccountsResponse")
public static final class DeleteFinancialActivityAccountsResponse{
public static final class DeleteFinancialActivityAccountsResponse {
private DeleteFinancialActivityAccountsResponse() {
}
@ApiModelProperty(example = "1")
public Long resourceId;
}
@@ -23,13 +23,13 @@ import java.util.HashSet;
import java.util.Set;
public class FinancialActivityAccountsConstants {
private static final String idParamName = "id";
private static final String factivityDataParamName = "financialActivityData";
private static final String glAccountDataParamName = "glAccountData";
private static final String glAccountOptionsParamName = "glAccountOptions";
private static final String financialActivityOptionsParamName = "financialActivityOptions";
public static final String resourceNameForPermission = "FINANCIALACTIVITYACCOUNT";
protected static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, factivityDataParamName, glAccountDataParamName, glAccountOptionsParamName,
financialActivityOptionsParamName));
protected static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(idParamName, factivityDataParamName,
glAccountDataParamName, glAccountOptionsParamName, financialActivityOptionsParamName));
}
@@ -25,6 +25,7 @@ import java.util.Set;
* Enum of all parameters passed in while creating/updating a GL Account
***/
public enum FinancialActivityAccountsJsonInputParams {
FINANCIAL_ACTIVITY_ID("financialActivityId"), GL_ACCOUNT_ID("glAccountId");
private final String value;
@@ -52,4 +53,4 @@ public enum FinancialActivityAccountsJsonInputParams {
public String getValue() {
return this.value;
}
}
}
@@ -38,7 +38,8 @@ public class FinancialActivityAccountData {
this.financialActivityOptions = null;
}
public FinancialActivityAccountData(final Long id, final FinancialActivityData financialActivityData, final GLAccountData glAccountData) {
public FinancialActivityAccountData(final Long id, final FinancialActivityData financialActivityData,
final GLAccountData glAccountData) {
this.id = id;
this.glAccountData = glAccountData;
this.financialActivityData = financialActivityData;
@@ -66,4 +66,4 @@ public class FinancialActivityAccount extends AbstractPersistableCustom {
public void updateFinancialActivityType(final Integer financialActivityType) {
this.financialActivityType = financialActivityType;
}
}
}
@@ -23,8 +23,8 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface FinancialActivityAccountRepository extends JpaRepository<FinancialActivityAccount, Long>,
JpaSpecificationExecutor<FinancialActivityAccount> {
public interface FinancialActivityAccountRepository
extends JpaRepository<FinancialActivityAccount, Long>, JpaSpecificationExecutor<FinancialActivityAccount> {
@Query("select faa from FinancialActivityAccount faa where faa.financialActivityType = :financialActivityType")
FinancialActivityAccount findByFinancialActivityType(@Param("financialActivityType") int financialAccountType);
@@ -40,8 +40,7 @@ public class FinancialActivityAccountRepositoryWrapper {
}
public FinancialActivityAccount findOneWithNotFoundDetection(final Long id) {
return this.repository.findById(id)
.orElseThrow(() -> new FinancialActivityAccountNotFoundException(id));
return this.repository.findById(id).orElseThrow(() -> new FinancialActivityAccountNotFoundException(id));
}
public FinancialActivityAccount findByFinancialActivityTypeWithNotFoundDetection(final int financialActivityType) {
@@ -36,4 +36,4 @@ public class DuplicateFinancialActivityAccountFoundException extends AbstractPla
return errorCode;
}
}
}
@@ -31,14 +31,16 @@ public class FinancialActivityAccountInvalidException extends AbstractPlatformDo
private final static String errorCode = "error.msg.financialActivityAccount.invalid";
public FinancialActivityAccountInvalidException(final FinancialActivity financialActivity, final GLAccount glAccount) {
super(errorCode, "Financial Activity '" + financialActivity.getCode() + "' with Id :" + financialActivity.getValue()
+ "' can only be associated with a Ledger Account of Type " + financialActivity.getMappedGLAccountType().getCode()
+ " the provided Ledger Account '" + glAccount.getName() + "(" + glAccount.getGlCode()
+ ")' does not of the required type", financialActivity.getCode(), financialActivity.getValue(), financialActivity
.getMappedGLAccountType().getCode(), glAccount.getName(), glAccount.getGlCode());
super(errorCode,
"Financial Activity '" + financialActivity.getCode() + "' with Id :" + financialActivity.getValue()
+ "' can only be associated with a Ledger Account of Type " + financialActivity.getMappedGLAccountType().getCode()
+ " the provided Ledger Account '" + glAccount.getName() + "(" + glAccount.getGlCode()
+ ")' does not of the required type",
financialActivity.getCode(), financialActivity.getValue(), financialActivity.getMappedGLAccountType().getCode(),
glAccount.getName(), glAccount.getGlCode());
}
public static String getErrorcode() {
return errorCode;
}
}
}
@@ -31,8 +31,9 @@ public class FinancialActivityAccountNotFoundException extends AbstractPlatformR
}
public FinancialActivityAccountNotFoundException(final Integer financialActivityType) {
super("error.msg.financialActivityAccount.not.found", "Financial Activity account with for the financial Activity with Id "
+ financialActivityType + " does not exist", financialActivityType);
super("error.msg.financialActivityAccount.not.found",
"Financial Activity account with for the financial Activity with Id " + financialActivityType + " does not exist",
financialActivityType);
}
}
}
@@ -44,4 +44,4 @@ public class CreateFinancialActivityAccountHandler implements NewCommandSourceHa
return this.writePlatformService.createFinancialActivityAccountMapping(command);
}
}
}
@@ -43,4 +43,4 @@ public class DeleteFinancialActivityAccountCommandHandler implements NewCommandS
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.deleteGLAccountActivityMapping(command.entityId(), command);
}
}
}
@@ -43,4 +43,4 @@ public class UpdateFinancialActivityAccountCommandHandler implements NewCommandS
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.updateGLAccountActivityMapping(command.entityId(), command);
}
}
}
@@ -113,8 +113,10 @@ public final class FinancialActivityAccountDataValidator {
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
}
@@ -31,4 +31,4 @@ public interface FinancialActivityAccountReadPlatformService {
FinancialActivityAccountData getFinancialActivityAccountTemplate();
}
}
@@ -91,7 +91,8 @@ public class FinancialActivityAccountReadPlatformServiceImpl implements Financia
public FinancialActivityAccountMapper() {
StringBuilder sb = new StringBuilder(300);
sb.append(" faa.id as id, faa.financial_activity_type as financialActivityId, glaccount.id as glAccountId,glaccount.name as glAccountName,glaccount.gl_code as glCode ");
sb.append(
" faa.id as id, faa.financial_activity_type as financialActivityId, glaccount.id as glAccountId,glaccount.name as glAccountName,glaccount.gl_code as glCode ");
sb.append(" from acc_gl_financial_activity_account faa ");
sb.append(" join acc_gl_account glaccount on glaccount.id = faa.gl_account_id");
sql = sb.toString();
@@ -29,4 +29,4 @@ public interface FinancialActivityAccountWritePlatformService {
CommandProcessingResult deleteGLAccountActivityMapping(Long mappingId, JsonCommand command);
}
}
@@ -52,7 +52,8 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
@Autowired
public FinancialActivityAccountWritePlatformServiceImpl(
final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository,
final FinancialActivityAccountDataValidator fromApiJsonDeserializer, final GLAccountRepositoryWrapper glAccountRepositoryWrapper) {
final FinancialActivityAccountDataValidator fromApiJsonDeserializer,
final GLAccountRepositoryWrapper glAccountRepositoryWrapper) {
this.financialActivityAccountRepository = financialActivityAccountRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.glAccountRepositoryWrapper = glAccountRepositoryWrapper;
@@ -77,10 +78,11 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
.withEntityId(financialActivityAccount.getId()) //
.build();
} catch (DataIntegrityViolationException dataIntegrityViolationException) {
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(), dataIntegrityViolationException);
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(),
dataIntegrityViolationException);
return CommandProcessingResult.empty();
}catch(final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ;
} catch (final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
handleFinancialActivityAccountDataIntegrityIssues(command, throwable, ee);
return CommandProcessingResult.empty();
}
@@ -93,8 +95,9 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
private void validateFinancialActivityAndAccountMapping(FinancialActivityAccount financialActivityAccount) {
FinancialActivity financialActivity = FinancialActivity.fromInt(financialActivityAccount.getFinancialActivityType());
GLAccount glAccount = financialActivityAccount.getGlAccount();
if (!financialActivity.getMappedGLAccountType().getValue().equals(glAccount.getType())) { throw new FinancialActivityAccountInvalidException(
financialActivity, glAccount); }
if (!financialActivity.getMappedGLAccountType().getValue().equals(glAccount.getType())) {
throw new FinancialActivityAccountInvalidException(financialActivity, glAccount);
}
}
@Override
@@ -127,10 +130,11 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
.with(changes) //
.build();
} catch (DataIntegrityViolationException dataIntegrityViolationException) {
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(), dataIntegrityViolationException);
handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(),
dataIntegrityViolationException);
return CommandProcessingResult.empty();
}catch(final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ;
} catch (final PersistenceException ee) {
Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
handleFinancialActivityAccountDataIntegrityIssues(command, throwable, ee);
return CommandProcessingResult.empty();
}
@@ -147,7 +151,8 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
.build();
}
private void handleFinancialActivityAccountDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) {
private void handleFinancialActivityAccountDataIntegrityIssues(final JsonCommand command, final Throwable realCause,
final Exception dve) {
if (realCause.getMessage().contains("financial_activity_type")) {
final Integer financialActivityId = command
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
@@ -25,8 +25,9 @@ import java.util.Set;
* Enum of all parameters passed in while creating/updating a GL Account
***/
public enum GLAccountJsonInputParams {
ID("id"), NAME("name"), PARENT_ID("parentId"), GL_CODE("glCode"), DISABLED("disabled"), MANUAL_ENTRIES_ALLOWED("manualEntriesAllowed"), TYPE(
"type"), USAGE("usage"), DESCRIPTION("description"), TAGID("tagId");
ID("id"), NAME("name"), PARENT_ID("parentId"), GL_CODE("glCode"), DISABLED("disabled"), MANUAL_ENTRIES_ALLOWED(
"manualEntriesAllowed"), TYPE("type"), USAGE("usage"), DESCRIPTION("description"), TAGID("tagId");
private final String value;
@@ -53,4 +54,4 @@ public enum GLAccountJsonInputParams {
public String getValue() {
return this.value;
}
}
}
@@ -75,17 +75,17 @@ import org.springframework.stereotype.Component;
@Path("/glaccounts")
@Component
@Scope("singleton")
@Api(tags = {"General Ledger Account"})
@Api(tags = { "General Ledger Account" })
@SwaggerDefinition(tags = {
@Tag(name = "General Ledger Account", description = "Ledger accounts represent an Individual account within an Organizations Chart Of Accounts(COA) and are assigned a name and unique number by which they can be identified. \n" + "All transactions relating to a company's assets, liabilities, owners' equity, revenue and expenses are recorded against these accounts")
})
@Tag(name = "General Ledger Account", description = "Ledger accounts represent an Individual account within an Organizations Chart Of Accounts(COA) and are assigned a name and unique number by which they can be identified. \n"
+ "All transactions relating to a company's assets, liabilities, owners' equity, revenue and expenses are recorded against these accounts") })
public class GLAccountsApiResource {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "parentId", "glCode",
"disabled", "manualEntriesAllowed", "type", "usage", "description", "assetHeaderAccountOptions",
"liabilityHeaderAccountOptions", "equityHeaderAccountOptions", "incomeHeaderAccountOptions", "expenseHeaderAccountOptions",
"nameDecorated", "tagId", "allowedAssetsTagOptions", "allowedLiabilitiesTagOptions", "allowedEquityTagOptions",
"allowedIncomeTagOptions", "allowedExpensesTagOptions", "creditAccounts", "debitAccounts"));
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "name", "parentId", "glCode", "disabled",
"manualEntriesAllowed", "type", "usage", "description", "assetHeaderAccountOptions", "liabilityHeaderAccountOptions",
"equityHeaderAccountOptions", "incomeHeaderAccountOptions", "expenseHeaderAccountOptions", "nameDecorated", "tagId",
"allowedAssetsTagOptions", "allowedLiabilitiesTagOptions", "allowedEquityTagOptions", "allowedIncomeTagOptions",
"allowedExpensesTagOptions", "creditAccounts", "debitAccounts"));
private final String resourceNameForPermission = "GLACCOUNT";
@@ -99,15 +99,12 @@ public class GLAccountsApiResource {
private final BulkImportWorkbookService bulkImportWorkbookService;
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
@Autowired
public GLAccountsApiResource(final PlatformSecurityContext context, final GLAccountReadPlatformService glAccountReadPlatformService,
final DefaultToApiJsonSerializer<GLAccountData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final AccountingDropdownReadPlatformService dropdownReadPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService,
final BulkImportWorkbookService bulkImportWorkbookService,
final CodeValueReadPlatformService codeValueReadPlatformService, final BulkImportWorkbookService bulkImportWorkbookService,
final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService) {
this.context = context;
this.apiRequestParameterHelper = apiRequestParameterHelper;
@@ -116,17 +113,21 @@ public class GLAccountsApiResource {
this.glAccountReadPlatformService = glAccountReadPlatformService;
this.dropdownReadPlatformService = dropdownReadPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
this.bulkImportWorkbookService=bulkImportWorkbookService;
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
this.bulkImportWorkbookService = bulkImportWorkbookService;
this.bulkImportWorkbookPopulatorService = bulkImportWorkbookPopulatorService;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve GL Accounts Template", notes = "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 Value Lists\n" + "Example Request:\n" + "\n" + "glaccounts/template\n" + "glaccounts/template?type=1\n" + "\n" + "type is optional and integer value from 1 to 5.\n" + "\n" + "1.Assets \n" + "2.Liabilities \n" + "3.Equity \n" + "4.Income \n" + "5.Expenses")
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsTemplateResponse.class)})
public String retrieveNewAccountDetails(@Context final UriInfo uriInfo, @QueryParam("type") @ApiParam(value = "type") final Integer type) {
@ApiOperation(value = "Retrieve GL Accounts Template", notes = "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 Value Lists\n" + "Example Request:\n" + "\n" + "glaccounts/template\n"
+ "glaccounts/template?type=1\n" + "\n" + "type is optional and integer value from 1 to 5.\n" + "\n" + "1.Assets \n"
+ "2.Liabilities \n" + "3.Equity \n" + "4.Income \n" + "5.Expenses")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsTemplateResponse.class) })
public String retrieveNewAccountDetails(@Context final UriInfo uriInfo,
@QueryParam("type") @ApiParam(value = "type") final Integer type) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -140,11 +141,17 @@ public class GLAccountsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "List General Ledger Accounts", notes = "ARGUMENTS\n" + "type Integer optional manualEntriesAllowed boolean optional usage Integer optional disabled boolean optional parentId Long optional tagId Long optional\n" + "Example Requests:\n" + "\n" + "glaccounts\n" + "\n" + "\n" + "glaccounts?type=1&manualEntriesAllowed=true&usage=1&disabled=false\n" + "\n" + "glaccounts?fetchRunningBalance=true")
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class, responseContainer = "list")})
@ApiOperation(value = "List General Ledger Accounts", notes = "ARGUMENTS\n"
+ "type Integer optional manualEntriesAllowed boolean optional usage Integer optional disabled boolean optional parentId Long optional tagId Long optional\n"
+ "Example Requests:\n" + "\n" + "glaccounts\n" + "\n" + "\n"
+ "glaccounts?type=1&manualEntriesAllowed=true&usage=1&disabled=false\n" + "\n" + "glaccounts?fetchRunningBalance=true")
@ApiResponses({
@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class, responseContainer = "list") })
public String retrieveAllAccounts(@Context final UriInfo uriInfo, @QueryParam("type") @ApiParam(value = "type") final Integer type,
@QueryParam("searchParam") @ApiParam(value = "searchParam") final String searchParam, @QueryParam("usage") @ApiParam(value = "usage") final Integer usage,
@QueryParam("manualEntriesAllowed") @ApiParam(value = "manualEntriesAllowed") final Boolean manualEntriesAllowed, @QueryParam("disabled") @ApiParam(value = "disabled") final Boolean disabled,
@QueryParam("searchParam") @ApiParam(value = "searchParam") final String searchParam,
@QueryParam("usage") @ApiParam(value = "usage") final Integer usage,
@QueryParam("manualEntriesAllowed") @ApiParam(value = "manualEntriesAllowed") final Boolean manualEntriesAllowed,
@QueryParam("disabled") @ApiParam(value = "disabled") final Boolean disabled,
@QueryParam("fetchRunningBalance") @ApiParam(value = "fetchRunningBalance") final boolean runningBalance) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -160,9 +167,12 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve a General Ledger Account", notes = "Example Requests:\n" + "\n" + "glaccounts/1\n" + "\n" + "\n" + "glaccounts/1?template=true\n" + "\n" + "\n" + "glaccounts/1?fields=name,glCode\n" + "\n" + "\n" + "glaccounts/1?fetchRunningBalance=true")
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class)})
public String retreiveAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId, @Context final UriInfo uriInfo,
@ApiOperation(value = "Retrieve a General Ledger Account", notes = "Example Requests:\n" + "\n" + "glaccounts/1\n" + "\n" + "\n"
+ "glaccounts/1?template=true\n" + "\n" + "\n" + "glaccounts/1?fields=name,glCode\n" + "\n" + "\n"
+ "glaccounts/1?fetchRunningBalance=true")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.GetGLAccountsResponse.class) })
public String retreiveAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId,
@Context final UriInfo uriInfo,
@QueryParam("fetchRunningBalance") @ApiParam(value = "fetchRunningBalance") final boolean runningBalance) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -180,9 +190,11 @@ public class GLAccountsApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Create a General Ledger Account", notes = "Note: You may optionally create Hierarchical Chart of Accounts by using the \"parentId\" property of an Account\n" + "Mandatory Fields: \n" + "name, glCode, type, usage and manualEntriesAllowed")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = GLAccountsApiResourceSwagger.PostGLAccountsRequest.class )})
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.PostGLAccountsResponse.class)})
@ApiOperation(value = "Create a General Ledger Account", notes = "Note: You may optionally create Hierarchical Chart of Accounts by using the \"parentId\" property of an Account\n"
+ "Mandatory Fields: \n" + "name, glCode, type, usage and manualEntriesAllowed")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = GLAccountsApiResourceSwagger.PostGLAccountsRequest.class) })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.PostGLAccountsResponse.class) })
public String createGLAccount(@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createGLAccount().withJson(jsonRequestBody).build();
@@ -196,10 +208,13 @@ public class GLAccountsApiResource {
@Path("{glAccountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Update an Accounting closure", notes = "Once an accounting closure is created, only the comments associated with it may be edited\n" + "\n")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = GLAccountsApiResourceSwagger.PutGLAccountsRequest.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.PutGLAccountsResponse.class)})
public String updateGLAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId, @ApiParam(hidden = true) final String jsonRequestBody) {
@ApiOperation(value = "Update an Accounting closure", notes = "Once an accounting closure is created, only the comments associated with it may be edited\n"
+ "\n")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = GLAccountsApiResourceSwagger.PutGLAccountsRequest.class) })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.PutGLAccountsResponse.class) })
public String updateGLAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId,
@ApiParam(hidden = true) final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateGLAccount(glAccountId).withJson(jsonRequestBody).build();
@@ -213,7 +228,7 @@ public class GLAccountsApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Delete an accounting closure", notes = "Note: Only the latest accounting closure associated with a branch may be deleted.")
@ApiResponses({@ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.DeleteGLAccountsRequest.class)})
@ApiResponses({ @ApiResponse(code = 200, message = "", response = GLAccountsApiResourceSwagger.DeleteGLAccountsRequest.class) })
public String deleteGLAccount(@PathParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
@@ -226,16 +241,16 @@ public class GLAccountsApiResource {
private GLAccountData handleTemplate(final GLAccountData glAccountData) {
final List<EnumOptionData> accountTypeOptions = this.dropdownReadPlatformService.retrieveGLAccountTypeOptions();
final List<EnumOptionData> usageOptions = this.dropdownReadPlatformService.retrieveGLAccountUsageOptions();
final List<GLAccountData> assetHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.ASSET));
final List<GLAccountData> liabilityHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.LIABILITY));
final List<GLAccountData> equityHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EQUITY));
final List<GLAccountData> incomeHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.INCOME));
final List<GLAccountData> expenseHeaderAccountOptions = defaultIfEmpty(this.glAccountReadPlatformService
.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EXPENSE));
final List<GLAccountData> assetHeaderAccountOptions = defaultIfEmpty(
this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.ASSET));
final List<GLAccountData> liabilityHeaderAccountOptions = defaultIfEmpty(
this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.LIABILITY));
final List<GLAccountData> equityHeaderAccountOptions = defaultIfEmpty(
this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EQUITY));
final List<GLAccountData> incomeHeaderAccountOptions = defaultIfEmpty(
this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.INCOME));
final List<GLAccountData> expenseHeaderAccountOptions = defaultIfEmpty(
this.glAccountReadPlatformService.retrieveAllEnabledHeaderGLAccounts(GLAccountType.EXPENSE));
final Collection<CodeValueData> allowedAssetsTagOptions = this.codeValueReadPlatformService
.retrieveCodeValuesByCode(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME);
final Collection<CodeValueData> allowedLiabilitiesTagOptions = this.codeValueReadPlatformService
@@ -264,17 +279,17 @@ public class GLAccountsApiResource {
@Path("downloadtemplate")
@Produces("application/vnd.ms-excel")
public Response getGlAccountsTemplate(@QueryParam("dateFormat") final String dateFormat) {
return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.CHART_OF_ACCOUNTS.toString(),null,null,dateFormat);
return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.CHART_OF_ACCOUNTS.toString(), null, null, dateFormat);
}
@POST
@Path("uploadtemplate")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String postGlAccountsTemplate(@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail,
@FormDataParam("locale") final String locale, @FormDataParam("dateFormat") final String dateFormat){
Long importDocumentId= bulkImportWorkbookService.importWorkbook(GlobalEntityType.CHART_OF_ACCOUNTS.toString(), uploadedInputStream,fileDetail,
locale,dateFormat);
@FormDataParam("file") FormDataContentDisposition fileDetail, @FormDataParam("locale") final String locale,
@FormDataParam("dateFormat") final String dateFormat) {
Long importDocumentId = bulkImportWorkbookService.importWorkbook(GlobalEntityType.CHART_OF_ACCOUNTS.toString(), uploadedInputStream,
fileDetail, locale, dateFormat);
return this.apiJsonSerializerService.serialize(importDocumentId);
}
}
@@ -30,13 +30,15 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData;
* Created by sanyam on 24/7/17.
*/
final class GLAccountsApiResourceSwagger {
private GLAccountsApiResourceSwagger() {
}
@ApiModel(value = "GetGLAccountsResponse")
public static final class GetGLAccountsResponse{
private GetGLAccountsResponse(){
public static final class GetGLAccountsResponse {
private GetGLAccountsResponse() {
}
@@ -74,8 +76,9 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModel(value = "GetGLAccountsTemplateResponse")
public static final class GetGLAccountsTemplateResponse{
private GetGLAccountsTemplateResponse(){
public static final class GetGLAccountsTemplateResponse {
private GetGLAccountsTemplateResponse() {
}
@@ -102,8 +105,9 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModel(value = "PostGLAccountsRequest")
public static final class PostGLAccountsRequest{
private PostGLAccountsRequest(){
public static final class PostGLAccountsRequest {
private PostGLAccountsRequest() {
}
@@ -134,7 +138,8 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModel(value = "PostGLAccountsResponse")
public static final class PostGLAccountsResponse{
public static final class PostGLAccountsResponse {
private PostGLAccountsResponse() {
}
@@ -144,7 +149,8 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModel(value = "PutGLAccountsRequest")
public static final class PutGLAccountsRequest{
public static final class PutGLAccountsRequest {
private PutGLAccountsRequest() {
}
@@ -154,29 +160,36 @@ final class GLAccountsApiResourceSwagger {
}
@ApiModel(value = "PutGLAccountsResponse")
public static final class PutGLAccountsResponse{
public static final class PutGLAccountsResponse {
private PutGLAccountsResponse() {
}
@ApiModel
public static final class PutGLAccountsResponsechangesSwagger{
private PutGLAccountsResponsechangesSwagger(){}
public static final class PutGLAccountsResponsechangesSwagger {
private PutGLAccountsResponsechangesSwagger() {}
@ApiModelProperty(example = "Cash at Bangalore")
public String name;
}
@ApiModelProperty(example = "1")
public int resourceId;
public PutGLAccountsResponsechangesSwagger changes;
}
@ApiModel(value = "DeleteGLAccountsRequest")
public static final class DeleteGLAccountsRequest{
public static final class DeleteGLAccountsRequest {
private DeleteGLAccountsRequest() {
}
private static final class DeleteGLAccountsRequestchangesSwagger{
private DeleteGLAccountsRequestchangesSwagger(){}
private static final class DeleteGLAccountsRequestchangesSwagger {
private DeleteGLAccountsRequestchangesSwagger() {}
}
@@ -87,8 +87,10 @@ public class GLAccountCommand {
baseDataValidator.reset().parameter(GLAccountJsonInputParams.TAGID.getValue()).value(this.tagId).ignoreIfNull()
.longGreaterThanZero();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
public void validateForUpdate() {
@@ -117,8 +119,10 @@ public class GLAccountCommand {
baseDataValidator.reset().anyOfNotNull(this.name, this.glCode, this.parentId, this.type, this.description, this.disabled);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
baseDataValidator.reset().parameter(GLAccountJsonInputParams.TAGID.getValue()).value(this.tagId).ignoreIfNull()
.longGreaterThanZero();
}
@@ -127,4 +131,4 @@ public class GLAccountCommand {
return GLAccountUsage.HEADER.getValue().equals(this.usage);
}
}
}
@@ -62,19 +62,16 @@ public class GLAccountData implements Serializable {
final Collection<CodeValueData> allowedIncomeTagOptions;
final Collection<CodeValueData> allowedExpensesTagOptions;
//import fields
// import fields
private transient Integer rowIndex;
public static GLAccountData importInstance(String name, Long parentId, String glCode, Boolean manualEntriesAllowed,
EnumOptionData type, EnumOptionData usage, String description, CodeValueData tagId,
Integer rowIndex){
return new GLAccountData(name,parentId,glCode,manualEntriesAllowed,type,
usage,description,tagId,rowIndex);
public static GLAccountData importInstance(String name, Long parentId, String glCode, Boolean manualEntriesAllowed, EnumOptionData type,
EnumOptionData usage, String description, CodeValueData tagId, Integer rowIndex) {
return new GLAccountData(name, parentId, glCode, manualEntriesAllowed, type, usage, description, tagId, rowIndex);
}
private GLAccountData(String name, Long parentId, String glCode, Boolean manualEntriesAllowed,
EnumOptionData type, EnumOptionData usage, String description, CodeValueData tagId,
Integer rowIndex) {
private GLAccountData(String name, Long parentId, String glCode, Boolean manualEntriesAllowed, EnumOptionData type,
EnumOptionData usage, String description, CodeValueData tagId, Integer rowIndex) {
this.name = name;
this.parentId = parentId;
@@ -192,8 +189,8 @@ public class GLAccountData implements Serializable {
final CodeValueData tagId = null;
final Long organizationRunningBalance = null;
return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description, nameDecorated,
tagId, organizationRunningBalance);
return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description, nameDecorated, tagId,
organizationRunningBalance);
}
public GLAccountData(final Long id, final String name, final String glCode) {
@@ -244,5 +241,4 @@ public class GLAccountData implements Serializable {
return null;
}
}
}
@@ -98,8 +98,8 @@ public class GLAccount extends AbstractPersistableCustom {
final String name = command.stringValueOfParameterNamed(GLAccountJsonInputParams.NAME.getValue());
final String glCode = command.stringValueOfParameterNamed(GLAccountJsonInputParams.GL_CODE.getValue());
final boolean disabled = command.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.DISABLED.getValue());
final boolean manualEntriesAllowed = command.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED
.getValue());
final boolean manualEntriesAllowed = command
.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue());
final Integer usage = command.integerValueSansLocaleOfParameterNamed(GLAccountJsonInputParams.USAGE.getValue());
final Integer type = command.integerValueSansLocaleOfParameterNamed(GLAccountJsonInputParams.TYPE.getValue());
final String description = command.stringValueOfParameterNamed(GLAccountJsonInputParams.DESCRIPTION.getValue());
@@ -38,7 +38,7 @@ public class GLAccountRepositoryWrapper {
}
public GLAccount findOneWithNotFoundDetection(final Long id) {
return this.repository.findById(id).orElseThrow(() -> new GLAccountNotFoundException(id));
return this.repository.findById(id).orElseThrow(() -> new GLAccountNotFoundException(id));
}
}
@@ -23,8 +23,9 @@ import java.util.Map;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
public enum GLAccountType {
ASSET(1, "accountType.asset"), LIABILITY(2, "accountType.liability"), EQUITY(3, "accountType.equity"), INCOME(4, "accountType.income"), EXPENSE(
5, "accountType.expense");
ASSET(1, "accountType.asset"), LIABILITY(2, "accountType.liability"), EQUITY(3, "accountType.equity"), INCOME(4,
"accountType.income"), EXPENSE(5, "accountType.expense");
private final Integer value;
private final String code;
@@ -61,24 +62,25 @@ public enum GLAccountType {
i = i + 1;
}
}
public static EnumOptionData fromString(String accountType){
Long accountTypeId=null;
if (accountType!=null && accountType.equalsIgnoreCase(ASSET.toString())){
accountTypeId=1L;
return new EnumOptionData(accountTypeId,null,null);
}else if(accountType!=null && accountType.equalsIgnoreCase(LIABILITY.toString())) {
public static EnumOptionData fromString(String accountType) {
Long accountTypeId = null;
if (accountType != null && accountType.equalsIgnoreCase(ASSET.toString())) {
accountTypeId = 1L;
return new EnumOptionData(accountTypeId, null, null);
} else if (accountType != null && accountType.equalsIgnoreCase(LIABILITY.toString())) {
accountTypeId = 2L;
return new EnumOptionData(accountTypeId, null, null);
}else if(accountType!=null && accountType.equalsIgnoreCase(EQUITY.toString())){
accountTypeId=3L;
return new EnumOptionData(accountTypeId,null,null);
}else if(accountType!=null && accountType.equalsIgnoreCase(INCOME.toString())) {
} else if (accountType != null && accountType.equalsIgnoreCase(EQUITY.toString())) {
accountTypeId = 3L;
return new EnumOptionData(accountTypeId, null, null);
} else if (accountType != null && accountType.equalsIgnoreCase(INCOME.toString())) {
accountTypeId = 4L;
return new EnumOptionData(accountTypeId, null, null);
}else if(accountType!=null && accountType.equalsIgnoreCase(EXPENSE.toString())){
accountTypeId=5L;
return new EnumOptionData(accountTypeId,null,null);
}else {
} else if (accountType != null && accountType.equalsIgnoreCase(EXPENSE.toString())) {
accountTypeId = 5L;
return new EnumOptionData(accountTypeId, null, null);
} else {
return null;
}
}
@@ -19,7 +19,6 @@
package org.apache.fineract.accounting.glaccount.domain;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
@@ -54,13 +53,13 @@ public class TrialBalance extends AbstractPersistableCustom {
@Column(name = "closing_balance", nullable = false)
private BigDecimal closingBalance;
public static TrialBalance getInstance(final Long officeId, final Long glAccountId,
final BigDecimal amount, final Date entryDate, final Date transactionDate) {
public static TrialBalance getInstance(final Long officeId, final Long glAccountId, final BigDecimal amount, final Date entryDate,
final Date transactionDate) {
return new TrialBalance(officeId, glAccountId, amount, entryDate, transactionDate);
}
private TrialBalance(final Long officeId, final Long glAccountId,
final BigDecimal amount, final Date entryDate, final Date transactionDate) {
private TrialBalance(final Long officeId, final Long glAccountId, final BigDecimal amount, final Date entryDate,
final Date transactionDate) {
this.officeId = officeId;
this.glAccountId = glAccountId;
this.amount = amount;
@@ -68,8 +67,7 @@ public class TrialBalance extends AbstractPersistableCustom {
this.transactionDate = transactionDate;
}
protected TrialBalance() {
}
protected TrialBalance() {}
public Long getOfficeId() {
return officeId;
@@ -97,16 +95,11 @@ public class TrialBalance extends AbstractPersistableCustom {
@Override
public boolean equals(Object obj) {
if (!(obj instanceof TrialBalance)) {
return false;
}
if (!(obj instanceof TrialBalance)) { return false; }
TrialBalance other = (TrialBalance) obj;
return Objects.equals(other.officeId, officeId)
&& Objects.equals(other.glAccountId, glAccountId)
&& Objects.equals(other.amount, amount)
&& Objects.equals(other.entryDate, entryDate)
&& Objects.equals(other.transactionDate, transactionDate)
&& Objects.equals(other.closingBalance, closingBalance);
return Objects.equals(other.officeId, officeId) && Objects.equals(other.glAccountId, glAccountId)
&& Objects.equals(other.amount, amount) && Objects.equals(other.entryDate, entryDate)
&& Objects.equals(other.transactionDate, transactionDate) && Objects.equals(other.closingBalance, closingBalance);
}
@Override
@@ -27,6 +27,5 @@ import org.springframework.data.repository.query.Param;
public interface TrialBalanceRepository extends JpaRepository<TrialBalance, Long>, JpaSpecificationExecutor<TrialBalance> {
@Query(value = "select * from m_trial_balance where office_id=:officeId and account_id=:accountId and closing_balance is null order by created_date, entry_date", nativeQuery = true)
List<TrialBalance> findNewByOfficeAndAccount(@Param("officeId") final Long officeId,
@Param("accountId") final Long accountId);
}
List<TrialBalance> findNewByOfficeAndAccount(@Param("officeId") final Long officeId, @Param("accountId") final Long accountId);
}
@@ -25,23 +25,22 @@ import org.springframework.stereotype.Service;
@Service
public class TrialBalanceRepositoryWrapper {
private final TrialBalanceRepository repository;
private final TrialBalanceRepository repository;
@Autowired
public TrialBalanceRepositoryWrapper(final TrialBalanceRepository repository){
this.repository=repository;
public TrialBalanceRepositoryWrapper(final TrialBalanceRepository repository) {
this.repository = repository;
}
public List<TrialBalance> findNewByOfficeAndAccount(final Long officeId, final Long accountId){
final List<TrialBalance> trialBalanceList=this.repository.findNewByOfficeAndAccount(officeId,accountId);
if (trialBalanceList==null) {
throw new TrialBalanceNotFoundException(officeId, accountId);
}
public List<TrialBalance> findNewByOfficeAndAccount(final Long officeId, final Long accountId) {
final List<TrialBalance> trialBalanceList = this.repository.findNewByOfficeAndAccount(officeId, accountId);
if (trialBalanceList == null) { throw new TrialBalanceNotFoundException(officeId, accountId); }
return trialBalanceList;
}
public void save(final List<TrialBalance> tbRows){
public void save(final List<TrialBalance> tbRows) {
this.repository.saveAll(tbRows);
}
}
@@ -25,11 +25,9 @@ import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainR
* when gl account is attached with any product(loan/saving) then we can not
* disable the gl account
*/
public class GLAccountDisableException extends
AbstractPlatformDomainRuleException {
public class GLAccountDisableException extends AbstractPlatformDomainRuleException {
public GLAccountDisableException() {
super("error.msg.glaccount.attached.to.product",
"General Ledger Account is already attached to product.");
super("error.msg.glaccount.attached.to.product", "General Ledger Account is already attached to product.");
}
}
@@ -30,4 +30,4 @@ public class GLAccountDuplicateException extends AbstractPlatformDomainRuleExcep
super("error.msg.glaccount.glcode.duplicate", "General Ledger Account with GL code " + glCode + " is already present", glCode);
}
}
}
@@ -29,4 +29,4 @@ public class GLAccountInvalidClassificationException extends AbstractPlatformDom
public GLAccountInvalidClassificationException(final Integer usage) {
super("error.msg.glaccount.usage.invalid", "The following COA usage is invalid: " + usage);
}
}
}
@@ -28,19 +28,24 @@ public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleE
/*** Enum of reasons for invalid delete **/
public static enum GlAccountInvalidDeleteReason {
TRANSANCTIONS_LOGGED, HAS_CHILDREN;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
return "This GL Account cannot be deleted as it has transactions logged against it";
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) { return "Cannot delete this Header GL Account without first deleting or reassinging its children"; }
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) {
return "Cannot delete this Header GL Account without first deleting or reassinging its children";
}
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
return "error.msg.glaccount.glcode.invalid.delete.transactions.logged";
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) { return "error.msg.glaccount.glcode.invalid.delete.has.children"; }
} else if (name().toString().equalsIgnoreCase("HAS_CHILDREN")) {
return "error.msg.glaccount.glcode.invalid.delete.has.children";
}
return name().toString();
}
}
@@ -48,4 +53,4 @@ public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleE
public GLAccountInvalidDeleteException(final GlAccountInvalidDeleteReason reason, final Long glAccountId) {
super(reason.errorCode(), reason.errorMessage(), glAccountId);
}
}
}
@@ -27,7 +27,7 @@ import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainR
public class GLAccountInvalidParentException extends AbstractPlatformDomainRuleException {
public GLAccountInvalidParentException(final long glAccountId) {
super("error.msg.glaccount.parent.invalid", "The account with id " + glAccountId
+ " is a 'Detail' account and cannot be used as a parent", glAccountId);
super("error.msg.glaccount.parent.invalid",
"The account with id " + glAccountId + " is a 'Detail' account and cannot be used as a parent", glAccountId);
}
}
}
@@ -28,15 +28,20 @@ public class GLAccountInvalidUpdateException extends AbstractPlatformDomainRuleE
/*** Enum of reasons for invalid delete **/
public static enum GlAccountInvalidUpdateReason {
TRANSANCTIONS_LOGGED;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) { return "This Usage of this (detail) GL Account as it already has transactions logged against it"; }
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
return "This Usage of this (detail) GL Account as it already has transactions logged against it";
}
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) { return "error.msg.glaccount.glcode.invalid.update.transactions.logged"; }
if (name().toString().equalsIgnoreCase("TRANSANCTIONS_LOGGED")) {
return "error.msg.glaccount.glcode.invalid.update.transactions.logged";
}
return name().toString();
}
}
@@ -44,4 +49,4 @@ public class GLAccountInvalidUpdateException extends AbstractPlatformDomainRuleE
public GLAccountInvalidUpdateException(final GlAccountInvalidUpdateReason reason, final Long glAccountId) {
super(reason.errorCode(), reason.errorMessage(), glAccountId);
}
}
}
@@ -29,4 +29,4 @@ public class GLAccountInvalidUsageException extends AbstractPlatformDomainRuleEx
public GLAccountInvalidUsageException(final Integer type) {
super("error.msg.glaccount.classification.invalid", "The following COA type is invalid: " + type);
}
}
}
@@ -28,4 +28,4 @@ public class GLAccountNotFoundException extends AbstractPlatformResourceNotFound
public GLAccountNotFoundException(final Long id) {
super("error.msg.glaccount.id.invalid", "General Ledger account with identifier " + id + " does not exist ", id);
}
}
}
@@ -44,4 +44,4 @@ public class CreateGLAccountCommandHandler implements NewCommandSourceHandler {
return this.writePlatformService.createGLAccount(command);
}
}
}
@@ -43,4 +43,4 @@ public class DeleteGLAccountCommandHandler implements NewCommandSourceHandler {
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.deleteGLAccount(command.entityId());
}
}
}
@@ -43,4 +43,4 @@ public class UpdateGLAccountCommandHandler implements NewCommandSourceHandler {
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.updateGLAccount(command.entityId(), command);
}
}
}
@@ -63,8 +63,8 @@ public final class GLAccountCommandFromApiJsonDeserializer extends AbstractFromA
final Long parentId = this.fromApiJsonHelper.extractLongNamed(GLAccountJsonInputParams.PARENT_ID.getValue(), element);
final String glCode = this.fromApiJsonHelper.extractStringNamed(GLAccountJsonInputParams.GL_CODE.getValue(), element);
final Boolean disabled = this.fromApiJsonHelper.extractBooleanNamed(GLAccountJsonInputParams.DISABLED.getValue(), element);
final Boolean manualEntriesAllowed = this.fromApiJsonHelper.extractBooleanNamed(
GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue(), element);
final Boolean manualEntriesAllowed = this.fromApiJsonHelper
.extractBooleanNamed(GLAccountJsonInputParams.MANUAL_ENTRIES_ALLOWED.getValue(), element);
final Integer type = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(GLAccountJsonInputParams.TYPE.getValue(), element);
final Integer usage = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(GLAccountJsonInputParams.USAGE.getValue(), element);
final String description = this.fromApiJsonHelper.extractStringNamed(GLAccountJsonInputParams.DESCRIPTION.getValue(), element);
@@ -72,4 +72,4 @@ public final class GLAccountCommandFromApiJsonDeserializer extends AbstractFromA
return new GLAccountCommand(id, name, parentId, glCode, disabled, manualEntriesAllowed, type, usage, description, tagId);
}
}
}
@@ -40,4 +40,4 @@ public interface GLAccountReadPlatformService {
GLAccountData retrieveNewGLAccountDetails(final Integer type);
List<GLAccountDataForLookup> retrieveAccountsByTagId(final Long ruleId, final Integer transactionType);
}
}
@@ -110,9 +110,12 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
@Override
public List<GLAccountData> retrieveAllGLAccounts(final Integer accountClassification, final String searchParam, final Integer usage,
final Boolean manualTransactionsAllowed, final Boolean disabled, JournalEntryAssociationParametersData associationParametersData) {
final Boolean manualTransactionsAllowed, final Boolean disabled,
JournalEntryAssociationParametersData associationParametersData) {
if (accountClassification != null) {
if (!checkValidGLAccountType(accountClassification)) { throw new GLAccountInvalidClassificationException(accountClassification); }
if (!checkValidGLAccountType(accountClassification)) {
throw new GLAccountInvalidClassificationException(accountClassification);
}
}
if (usage != null) {
@@ -122,7 +125,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
final GLAccountMapper rm = new GLAccountMapper(associationParametersData);
String sql = "select " + rm.schema();
// append SQL statement for fetching account totals
if (associationParametersData!=null) {
if (associationParametersData != null) {
if (associationParametersData.isRunningBalanceRequired()) {
sql = sql + " and gl_j.id in (select t1.id from (select t2.account_id, max(t2.id) as id from "
+ "(select id, max(entry_date) as entry_date, account_id from acc_gl_journal_entry where is_running_balance_calculated = 1 "
@@ -133,8 +136,8 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
final Object[] paramaterArray = new Object[3];
int arrayPos = 0;
boolean filtersPresent = false;
if ((accountClassification != null) || StringUtils.isNotBlank(searchParam) || (usage != null)
|| (manualTransactionsAllowed != null) || (disabled != null)) {
if ((accountClassification != null) || StringUtils.isNotBlank(searchParam) || (usage != null) || (manualTransactionsAllowed != null)
|| (disabled != null)) {
filtersPresent = true;
sql += " where";
}
@@ -195,7 +198,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
}
}
sql+=" ORDER BY gl_code ASC";
sql += " ORDER BY gl_code ASC";
final Object[] finalObjectArray = Arrays.copyOf(paramaterArray, arrayPos);
return this.jdbcTemplate.query(sql, rm, finalObjectArray);
@@ -231,7 +234,8 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
@Override
public List<GLAccountData> retrieveAllEnabledDetailGLAccounts() {
return retrieveAllGLAccounts(null, null, GLAccountUsage.DETAIL.getValue(), null, false, new JournalEntryAssociationParametersData());
return retrieveAllGLAccounts(null, null, GLAccountUsage.DETAIL.getValue(), null, false,
new JournalEntryAssociationParametersData());
}
private static boolean checkValidGLAccountType(final int type) {
@@ -281,4 +285,4 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
}
}
}
}
@@ -120,11 +120,8 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
try {
final GLAccountCommand accountCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
accountCommand.validateForUpdate();
if (command.hasParameter(GLAccountJsonInputParams.DISABLED
.getValue())
&& command
.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.DISABLED
.getValue())) {
if (command.hasParameter(GLAccountJsonInputParams.DISABLED.getValue())
&& command.booleanPrimitiveValueOfParameterNamed(GLAccountJsonInputParams.DISABLED.getValue())) {
validateForAttachedProduct(glAccountId);
}
final Long parentId = command.longValueOfParameterNamed(GLAccountJsonInputParams.PARENT_ID.getValue());
@@ -159,8 +156,9 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
if (glAccount.isHeaderAccount()) {
final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository
.findFirstJournalEntryForAccount(glAccountId);
if (journalEntriesForAccount.size() > 0) { throw new GLAccountInvalidUpdateException(
GlAccountInvalidUpdateReason.TRANSANCTIONS_LOGGED, glAccountId); }
if (journalEntriesForAccount.size() > 0) {
throw new GLAccountInvalidUpdateException(GlAccountInvalidUpdateReason.TRANSANCTIONS_LOGGED, glAccountId);
}
}
}
@@ -168,8 +166,8 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
this.glAccountRepository.saveAndFlush(glAccount);
}
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(glAccount.getId())
.with(changesOnly).build();
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(glAccount.getId()).with(changesOnly)
.build();
} catch (final DataIntegrityViolationException dve) {
handleGLAccountDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
@@ -180,11 +178,9 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
String sql = "select count(*) from acc_product_mapping acc where acc.gl_account_id = ?";
try {
int count = this.jdbcTemplate.queryForObject(sql, Integer.class, glAccountId);
if (count > 0) {
throw new GLAccountDisableException();
}
if (count > 0) { throw new GLAccountDisableException(); }
} catch (EmptyResultDataAccessException e) {
LOG.error("Problem encountered in validateForAttachedProduct()",e);
LOG.error("Problem encountered in validateForAttachedProduct()", e);
}
}
@@ -195,13 +191,15 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
.orElseThrow(() -> new GLAccountNotFoundException(glAccountId));
// validate this isn't a header account that has children
if (glAccount.isHeaderAccount() && glAccount.getChildren().size() > 0) { throw new GLAccountInvalidDeleteException(
GlAccountInvalidDeleteReason.HAS_CHILDREN, glAccountId); }
if (glAccount.isHeaderAccount() && glAccount.getChildren().size() > 0) {
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.HAS_CHILDREN, glAccountId);
}
// does this account have transactions logged against it
final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository.findFirstJournalEntryForAccount(glAccountId);
if (journalEntriesForAccount.size() > 0) { throw new GLAccountInvalidDeleteException(
GlAccountInvalidDeleteReason.TRANSANCTIONS_LOGGED, glAccountId); }
if (journalEntriesForAccount.size() > 0) {
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.TRANSANCTIONS_LOGGED, glAccountId);
}
this.glAccountRepository.delete(glAccount);
return new CommandProcessingResultBuilder().withEntityId(glAccountId).build();
@@ -241,20 +239,20 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
private CodeValue retrieveTagId(final Long tagId, final GLAccountType accountType) {
CodeValue glAccountTagType = null;
if (accountType.isAssetType()) {
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME, tagId);
glAccountTagType = this.codeValueRepositoryWrapper
.findOneByCodeNameAndIdWithNotFoundDetection(AccountingConstants.ASSESTS_TAG_OPTION_CODE_NAME, tagId);
} else if (accountType.isLiabilityType()) {
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME, tagId);
glAccountTagType = this.codeValueRepositoryWrapper
.findOneByCodeNameAndIdWithNotFoundDetection(AccountingConstants.LIABILITIES_TAG_OPTION_CODE_NAME, tagId);
} else if (accountType.isEquityType()) {
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME, tagId);
glAccountTagType = this.codeValueRepositoryWrapper
.findOneByCodeNameAndIdWithNotFoundDetection(AccountingConstants.EQUITY_TAG_OPTION_CODE_NAME, tagId);
} else if (accountType.isIncomeType()) {
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
AccountingConstants.INCOME_TAG_OPTION_CODE_NAME, tagId);
glAccountTagType = this.codeValueRepositoryWrapper
.findOneByCodeNameAndIdWithNotFoundDetection(AccountingConstants.INCOME_TAG_OPTION_CODE_NAME, tagId);
} else if (accountType.isExpenseType()) {
glAccountTagType = this.codeValueRepositoryWrapper.findOneByCodeNameAndIdWithNotFoundDetection(
AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME, tagId);
glAccountTagType = this.codeValueRepositoryWrapper
.findOneByCodeNameAndIdWithNotFoundDetection(AccountingConstants.EXPENSES_TAG_OPTION_CODE_NAME, tagId);
}
return glAccountTagType;
}
@@ -73,16 +73,16 @@ import org.springframework.stereotype.Component;
@Path("/journalentries")
@Component
@Scope("singleton")
@Api(tags = {"Journal Entries"})
@Api(tags = { "Journal Entries" })
@SwaggerDefinition(tags = {
@Tag(name = "Journal Entries", description = "A journal entry refers to the logging of transactions against general ledger accounts. A journal entry may consist of several line items, each of which is either a \"debit\" or a \"credit\". The total amount of the debits must equal the total amount of the credits or the journal entry is said to be \"unbalanced\" \n" + "\n" + "A journal entry directly changes the account balances on the general ledger")
})
@Tag(name = "Journal Entries", description = "A journal entry refers to the logging of transactions against general ledger accounts. A journal entry may consist of several line items, each of which is either a \"debit\" or a \"credit\". The total amount of the debits must equal the total amount of the credits or the journal entry is said to be \"unbalanced\" \n"
+ "\n" + "A journal entry directly changes the account balances on the general ledger") })
public class JournalEntriesApiResource {
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "officeId", "officeName",
"glAccountName", "glAccountId", "glAccountCode", "glAccountType", "transactionDate", "entryType", "amount", "transactionId",
"manualEntry", "entityType", "entityId", "createdByUserId", "createdDate", "createdByUserName", "comments", "reversed",
"referenceNumber", "currency", "transactionDetails"));
private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList("id", "officeId", "officeName", "glAccountName", "glAccountId", "glAccountCode", "glAccountType",
"transactionDate", "entryType", "amount", "transactionId", "manualEntry", "entityType", "entityId", "createdByUserId",
"createdDate", "createdByUserName", "comments", "reversed", "referenceNumber", "currency", "transactionDetails"));
private final String resourceNameForPermission = "JOURNALENTRY";
@@ -94,7 +94,6 @@ public class JournalEntriesApiResource {
private final BulkImportWorkbookService bulkImportWorkbookService;
private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
@Autowired
public JournalEntriesApiResource(final PlatformSecurityContext context,
final JournalEntryReadPlatformService journalEntryReadPlatformService,
@@ -107,24 +106,37 @@ public class JournalEntriesApiResource {
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
this.apiJsonSerializerService = toApiJsonSerializer;
this.journalEntryReadPlatformService = journalEntryReadPlatformService;
this.bulkImportWorkbookService=bulkImportWorkbookService;
this.bulkImportWorkbookPopulatorService=bulkImportWorkbookPopulatorService;
this.bulkImportWorkbookService = bulkImportWorkbookService;
this.bulkImportWorkbookPopulatorService = bulkImportWorkbookPopulatorService;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "List Journal Entries", notes = "The list capability of journal entries can support pagination and sorting.\n\n" + "Example Requests:\n" + "\n" + "journalentries\n" + "\n" + "journalentries?transactionId=PB37X8Y21EQUY4S\n" + "\n" + "journalentries?officeId=1&manualEntriesOnly=true&fromDate=1 July 2013&toDate=15 July 2013&dateFormat=dd MMMM yyyy&locale=en\n" + "\n" + "journalentries?fields=officeName,glAccountName,transactionDate\n" + "\n" + "journalentries?offset=10&limit=50\n" + "\n" + "journalentries?orderBy=transactionId&sortOrder=DESC\n" + "\n" + "journalentries?runningBalance=true\n" + "\n" + "journalentries?transactionDetails=true\n" + "\n" + "journalentries?loanId=12\n" + "\n" + "journalentries?savingsId=24")
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntryData.class, responseContainer = "list")})
@ApiOperation(value = "List Journal Entries", notes = "The list capability of journal entries can support pagination and sorting.\n\n"
+ "Example Requests:\n" + "\n" + "journalentries\n" + "\n" + "journalentries?transactionId=PB37X8Y21EQUY4S\n" + "\n"
+ "journalentries?officeId=1&manualEntriesOnly=true&fromDate=1 July 2013&toDate=15 July 2013&dateFormat=dd MMMM yyyy&locale=en\n"
+ "\n" + "journalentries?fields=officeName,glAccountName,transactionDate\n" + "\n" + "journalentries?offset=10&limit=50\n"
+ "\n" + "journalentries?orderBy=transactionId&sortOrder=DESC\n" + "\n" + "journalentries?runningBalance=true\n" + "\n"
+ "journalentries?transactionDetails=true\n" + "\n" + "journalentries?loanId=12\n" + "\n" + "journalentries?savingsId=24")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = JournalEntryData.class, responseContainer = "list") })
public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("officeId") @ApiParam(value = "officeId") final Long officeId,
@QueryParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId, @QueryParam("manualEntriesOnly") @ApiParam(value = "manualEntriesOnly") final Boolean onlyManualEntries,
@QueryParam("fromDate") @ApiParam(value = "fromDate") final DateParam fromDateParam, @QueryParam("toDate") @ApiParam(value = "toDate") final DateParam toDateParam,
@QueryParam("transactionId") @ApiParam(value = "transactionId") final String transactionId, @QueryParam("entityType") @ApiParam(value = "entityType") final Integer entityType,
@QueryParam("offset") @ApiParam(value = "offset") final Integer offset, @QueryParam("limit") @ApiParam(value = "limit") final Integer limit,
@QueryParam("orderBy") @ApiParam(value = "orderBy") final String orderBy, @QueryParam("sortOrder") @ApiParam(value = "sortOrder") final String sortOrder,
@QueryParam("locale") @ApiParam(value = "locale") final String locale, @QueryParam("dateFormat") @ApiParam(value = "dateFormat") final String dateFormat,
@QueryParam("loanId") @ApiParam(value = "loanId") final Long loanId, @QueryParam("savingsId") @ApiParam(value = "savingsId") final Long savingsId,
@QueryParam("runningBalance") @ApiParam(value = "runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") @ApiParam(value = "transactionDetails") final boolean transactionDetails) {
@QueryParam("glAccountId") @ApiParam(value = "glAccountId") final Long glAccountId,
@QueryParam("manualEntriesOnly") @ApiParam(value = "manualEntriesOnly") final Boolean onlyManualEntries,
@QueryParam("fromDate") @ApiParam(value = "fromDate") final DateParam fromDateParam,
@QueryParam("toDate") @ApiParam(value = "toDate") final DateParam toDateParam,
@QueryParam("transactionId") @ApiParam(value = "transactionId") final String transactionId,
@QueryParam("entityType") @ApiParam(value = "entityType") final Integer entityType,
@QueryParam("offset") @ApiParam(value = "offset") final Integer offset,
@QueryParam("limit") @ApiParam(value = "limit") final Integer limit,
@QueryParam("orderBy") @ApiParam(value = "orderBy") final String orderBy,
@QueryParam("sortOrder") @ApiParam(value = "sortOrder") final String sortOrder,
@QueryParam("locale") @ApiParam(value = "locale") final String locale,
@QueryParam("dateFormat") @ApiParam(value = "dateFormat") final String dateFormat,
@QueryParam("loanId") @ApiParam(value = "loanId") final Long loanId,
@QueryParam("savingsId") @ApiParam(value = "savingsId") final Long savingsId,
@QueryParam("runningBalance") @ApiParam(value = "runningBalance") final boolean runningBalance,
@QueryParam("transactionDetails") @ApiParam(value = "transactionDetails") final boolean transactionDetails) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
@@ -152,10 +164,13 @@ public class JournalEntriesApiResource {
@Path("{journalEntryId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Retrieve a single Entry", notes = "Example Requests:\n" + "\n" + "journalentries/1\n" + "\n" + "\n" + "\n" + "journalentries/1?fields=officeName,glAccountId,entryType,amount\n" + "\n" + "journalentries/1?runningBalance=true\n" + "\n" + "journalentries/1?transactionDetails=true")
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntryData.class)})
public String retreiveJournalEntryById(@PathParam("journalEntryId") @ApiParam(value = "journalEntryId") final Long journalEntryId, @Context final UriInfo uriInfo,
@QueryParam("runningBalance") @ApiParam(value = "runningBalance") final boolean runningBalance, @QueryParam("transactionDetails") @ApiParam(value = "transactionDetails") final boolean transactionDetails) {
@ApiOperation(value = "Retrieve a single Entry", notes = "Example Requests:\n" + "\n" + "journalentries/1\n" + "\n" + "\n" + "\n"
+ "journalentries/1?fields=officeName,glAccountId,entryType,amount\n" + "\n" + "journalentries/1?runningBalance=true\n" + "\n"
+ "journalentries/1?transactionDetails=true")
@ApiResponses({ @ApiResponse(code = 200, message = "", response = JournalEntryData.class) })
public String retreiveJournalEntryById(@PathParam("journalEntryId") @ApiParam(value = "journalEntryId") final Long journalEntryId,
@Context final UriInfo uriInfo, @QueryParam("runningBalance") @ApiParam(value = "runningBalance") final boolean runningBalance,
@QueryParam("transactionDetails") @ApiParam(value = "transactionDetails") final boolean transactionDetails) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(transactionDetails,
@@ -170,10 +185,16 @@ public class JournalEntriesApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Create \"Balanced\" Journal Entries", notes = "Note: A Balanced (simple) Journal entry would have atleast one \"Debit\" and one \"Credit\" entry whose amounts are equal \n" + "Compound Journal entries may have \"n\" debits and \"m\" credits where both \"m\" and \"n\" are greater than 0 and the net sum or all debits and credits are equal \n\n" + "\n" + "Mandatory Fields\n" + "officeId, transactionDate\n\n" + "\ncredits- glAccountId, amount, comments\n\n " + "\ndebits- glAccountId, amount, comments\n\n " + "\n" + "Optional Fields\n" + "paymentTypeId, accountNumber, checkNumber, routingCode, receiptNumber, bankNumber")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = JournalEntryCommand.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntriesApiResourceSwagger.PostJournalEntriesResponse.class)})
public String createGLJournalEntry(@ApiParam(hidden = true) final String jsonRequestBody, @QueryParam("command") @ApiParam(value = "command") final String commandParam) {
@ApiOperation(value = "Create \"Balanced\" Journal Entries", notes = "Note: A Balanced (simple) Journal entry would have atleast one \"Debit\" and one \"Credit\" entry whose amounts are equal \n"
+ "Compound Journal entries may have \"n\" debits and \"m\" credits where both \"m\" and \"n\" are greater than 0 and the net sum or all debits and credits are equal \n\n"
+ "\n" + "Mandatory Fields\n" + "officeId, transactionDate\n\n" + "\ncredits- glAccountId, amount, comments\n\n "
+ "\ndebits- glAccountId, amount, comments\n\n " + "\n" + "Optional Fields\n"
+ "paymentTypeId, accountNumber, checkNumber, routingCode, receiptNumber, bankNumber")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = JournalEntryCommand.class) })
@ApiResponses({ @ApiResponse(code = 200, message = "", response = JournalEntriesApiResourceSwagger.PostJournalEntriesResponse.class) })
public String createGLJournalEntry(@ApiParam(hidden = true) final String jsonRequestBody,
@QueryParam("command") @ApiParam(value = "command") final String commandParam) {
CommandProcessingResult result = null;
if (is(commandParam, "updateRunningBalance")) {
@@ -195,10 +216,14 @@ public class JournalEntriesApiResource {
@Path("{transactionId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Update Running balances for Journal Entries", notes = "This API calculates the running balances for office. If office ID not provided this API calculates running balances for all offices. \n" + "Mandatory Fields\n" + "officeId")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = JournalEntriesApiResourceSwagger.PostJournalEntriesTransactionIdRequest.class)})
@ApiResponses({@ApiResponse(code = 200, message = "", response = JournalEntriesApiResourceSwagger.PostJournalEntriesTransactionIdResponse.class)})
public String createReversalJournalEntry(@ApiParam(hidden = true) final String jsonRequestBody, @PathParam("transactionId") @ApiParam(value = "transactionId") final String transactionId,
@ApiOperation(value = "Update Running balances for Journal Entries", notes = "This API calculates the running balances for office. If office ID not provided this API calculates running balances for all offices. \n"
+ "Mandatory Fields\n" + "officeId")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "body", value = "body", dataType = "body", dataTypeClass = JournalEntriesApiResourceSwagger.PostJournalEntriesTransactionIdRequest.class) })
@ApiResponses({
@ApiResponse(code = 200, message = "", response = JournalEntriesApiResourceSwagger.PostJournalEntriesTransactionIdResponse.class) })
public String createReversalJournalEntry(@ApiParam(hidden = true) final String jsonRequestBody,
@PathParam("transactionId") @ApiParam(value = "transactionId") final String transactionId,
@QueryParam("command") @ApiParam(value = "command") final String commandParam) {
CommandProcessingResult result = null;
if (is(commandParam, "reverse")) {
@@ -219,14 +244,14 @@ public class JournalEntriesApiResource {
public String retrieveJournalEntries(@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
@QueryParam("entryId") final Long entryId, @Context final UriInfo uriInfo) {
this.context.authenticatedUser();
String transactionId = "P"+entryId ;
SearchParameters params = SearchParameters.forPagination(offset, limit) ;
Page<JournalEntryData> entries = this.journalEntryReadPlatformService.retrieveAll(params, null, null, null, null, transactionId, PortfolioProductType.PROVISIONING.getValue(), null) ;
String transactionId = "P" + entryId;
SearchParameters params = SearchParameters.forPagination(offset, limit);
Page<JournalEntryData> entries = this.journalEntryReadPlatformService.retrieveAll(params, null, null, null, null, transactionId,
PortfolioProductType.PROVISIONING.getValue(), null);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.apiJsonSerializerService.serialize(settings, entries, RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("openingbalance")
@Consumes({ MediaType.APPLICATION_JSON })
@@ -235,8 +260,8 @@ public class JournalEntriesApiResource {
@QueryParam("currencyCode") final String currencyCode) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
final OfficeOpeningBalancesData officeOpeningBalancesData = this.journalEntryReadPlatformService.retrieveOfficeOpeningBalances(
officeId, currencyCode);
final OfficeOpeningBalancesData officeOpeningBalancesData = this.journalEntryReadPlatformService
.retrieveOfficeOpeningBalances(officeId, currencyCode);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.apiJsonSerializerService.serialize(settings, officeOpeningBalancesData);
}
@@ -250,19 +275,17 @@ public class JournalEntriesApiResource {
@Produces("application/vnd.ms-excel")
public Response getJournalEntriesTemplate(@QueryParam("officeId") final Long officeId,
@QueryParam("dateFormat") final String dateFormat) {
return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.GL_JOURNAL_ENTRIES.toString(),
officeId,null,dateFormat);
return bulkImportWorkbookPopulatorService.getTemplate(GlobalEntityType.GL_JOURNAL_ENTRIES.toString(), officeId, null, dateFormat);
}
@POST
@Path("uploadtemplate")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String postJournalEntriesTemplate(@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail,
@FormDataParam("locale") final String locale,
@FormDataParam("dateFormat") final String dateFormat){
final Long importDocumentId =this.bulkImportWorkbookService.importWorkbook(GlobalEntityType.GL_JOURNAL_ENTRIES.toString(),
uploadedInputStream,fileDetail, locale,dateFormat);
@FormDataParam("file") FormDataContentDisposition fileDetail, @FormDataParam("locale") final String locale,
@FormDataParam("dateFormat") final String dateFormat) {
final Long importDocumentId = this.bulkImportWorkbookService.importWorkbook(GlobalEntityType.GL_JOURNAL_ENTRIES.toString(),
uploadedInputStream, fileDetail, locale, dateFormat);
return this.apiJsonSerializerService.serialize(importDocumentId);
}
}
}
@@ -25,14 +25,16 @@ import io.swagger.annotations.ApiModelProperty;
* Created by sanyam on 25/7/17.
*/
final class JournalEntriesApiResourceSwagger {
private JournalEntriesApiResourceSwagger(){}
private JournalEntriesApiResourceSwagger() {}
@ApiModel(value = "PostJournalEntriesResponse")
public static final class PostJournalEntriesResponse {
private PostJournalEntriesResponse(){
private PostJournalEntriesResponse() {
}
@ApiModelProperty(value = "1")
public Long officeId;
@ApiModelProperty(value = "RS9MCISID4WK1ZM")
@@ -42,18 +44,22 @@ final class JournalEntriesApiResourceSwagger {
@ApiModel(value = "PostJournalEntriesTransactionIdRequest")
public static final class PostJournalEntriesTransactionIdRequest {
private PostJournalEntriesTransactionIdRequest() {
}
@ApiModelProperty(value = "1")
public Long officeId;
}
@ApiModel(value = "PostJournalEntriesTransactionIdResponse")
public static final class PostJournalEntriesTransactionIdResponse {
private PostJournalEntriesTransactionIdResponse() {
}
@ApiModelProperty(value = "1")
public Long officeId;
}
@@ -25,10 +25,12 @@ import java.util.Set;
* Enum of all parameters passed in while creating/updating a journal Entry
***/
public enum JournalEntryJsonInputParams {
OFFICE_ID("officeId"), TRANSACTION_DATE("transactionDate"), COMMENTS("comments"), CREDITS("credits"), DEBITS("debits"), LOCALE("locale"), DATE_FORMAT(
"dateFormat"), REFERENCE_NUMBER("referenceNumber"), USE_ACCOUNTING_RULE("useAccountingRule"), ACCOUNTING_RULE("accountingRule"), AMOUNT(
"amount"), CURRENCY_CODE("currencyCode"), PAYMENT_TYPE_ID("paymentTypeId"), ACCOUNT_NUMBER("accountNumber"), CHECK_NUMBER(
"checkNumber"), ROUTING_CODE("routingCode"), RECEIPT_NUMBER("receiptNumber"), BANK_NUMBER("bankNumber");
OFFICE_ID("officeId"), TRANSACTION_DATE("transactionDate"), COMMENTS("comments"), CREDITS("credits"), DEBITS("debits"), LOCALE(
"locale"), DATE_FORMAT("dateFormat"), REFERENCE_NUMBER("referenceNumber"), USE_ACCOUNTING_RULE(
"useAccountingRule"), ACCOUNTING_RULE("accountingRule"), AMOUNT("amount"), CURRENCY_CODE(
"currencyCode"), PAYMENT_TYPE_ID("paymentTypeId"), ACCOUNT_NUMBER("accountNumber"), CHECK_NUMBER(
"checkNumber"), ROUTING_CODE("routingCode"), RECEIPT_NUMBER("receiptNumber"), BANK_NUMBER("bankNumber");
private final String value;
@@ -55,4 +57,4 @@ public enum JournalEntryJsonInputParams {
public String getValue() {
return this.value;
}
}
}
@@ -123,8 +123,10 @@ public class JournalEntryCommand {
}
baseDataValidator.reset().parameter("amount").value(this.amount).ignoreIfNull().zeroOrPositiveAmount();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
/**
@@ -168,4 +170,4 @@ public class JournalEntryCommand {
return this.accountingRuleId;
}
}
}
@@ -68,4 +68,4 @@ public class SingleDebitOrCreditEntryCommand {
return this.parametersPassedInRequest;
}
}
}
@@ -21,6 +21,7 @@ package org.apache.fineract.accounting.journalentry.data;
import java.math.BigDecimal;
public class CreditDebit {
private final Long glAccountId;
private final BigDecimal amount;
@@ -78,7 +78,7 @@ public class JournalEntryData {
@SuppressWarnings("unused")
private final TransactionDetailData transactionDetails;
//import fields
// import fields
private transient Integer rowIndex;
private String dateFormat;
private String locale;
@@ -92,34 +92,32 @@ public class JournalEntryData {
private String receiptNumber;
private String bankNumber;
public static JournalEntryData importInstance(Long officeId,LocalDate transactionDate,String currencyCode, Long paymentTypeId,
Integer rowIndex,List<CreditDebit> credits, List<CreditDebit>debits,
String accountNumber,String checkNumber,String routingCode,String receiptNumber,String bankNumber,
String comments,String locale,String dateFormat){
return new JournalEntryData(officeId, transactionDate, currencyCode,
paymentTypeId, rowIndex, credits, debits,accountNumber,checkNumber,routingCode,
receiptNumber,bankNumber,comments,locale,dateFormat);
public static JournalEntryData importInstance(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId,
Integer rowIndex, List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber,
String routingCode, String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
return new JournalEntryData(officeId, transactionDate, currencyCode, paymentTypeId, rowIndex, credits, debits, accountNumber,
checkNumber, routingCode, receiptNumber, bankNumber, comments, locale, dateFormat);
}
private JournalEntryData(Long officeId,LocalDate transactionDate,String currencyCode, Long paymentTypeId,
Integer rowIndex,List<CreditDebit> credits, List<CreditDebit>debits,
String accountNumber,String checkNumber,String routingCode,String receiptNumber,
String bankNumber,String comments,String locale,String dateFormat) {
private JournalEntryData(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId, Integer rowIndex,
List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber, String routingCode,
String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
this.officeId = officeId;
this.dateFormat= dateFormat;
this.locale= locale;
this.dateFormat = dateFormat;
this.locale = locale;
this.transactionDate = transactionDate;
this.currencyCode=currencyCode;
this.currencyCode = currencyCode;
this.rowIndex = rowIndex;
this.credits = credits;
this.debits = debits;
this.paymentTypeId = paymentTypeId;
this.accountNumber=accountNumber;
this.checkNumber=checkNumber;
this.routingCode=routingCode;
this.receiptNumber=receiptNumber;
this.bankNumber=bankNumber;
this.comments=comments;
this.accountNumber = accountNumber;
this.checkNumber = checkNumber;
this.routingCode = routingCode;
this.receiptNumber = receiptNumber;
this.bankNumber = bankNumber;
this.comments = comments;
this.id = null;
this.officeName = null;
this.glAccountName = null;
@@ -157,19 +155,17 @@ public class JournalEntryData {
this.debits.add(debit);
}
public void addCredits(CreditDebit credit) {
this.credits.add(credit);
}
public JournalEntryData(final Long id, final Long officeId, final String officeName, final String glAccountName,
final Long glAccountId, final String glAccountCode, final EnumOptionData glAccountClassification,
final LocalDate transactionDate, final EnumOptionData entryType, final BigDecimal amount, final String transactionId,
final Boolean manualEntry, final EnumOptionData entityType, final Long entityId, final Long createdByUserId,
final LocalDate createdDate, final String createdByUserName, final String comments, final Boolean reversed,
final String referenceNumber, final BigDecimal officeRunningBalance, final BigDecimal organizationRunningBalance,
final Boolean runningBalanceComputed, final TransactionDetailData transactionDetailData, final CurrencyData currency) {
public JournalEntryData(final Long id, final Long officeId, final String officeName, final String glAccountName, final Long glAccountId,
final String glAccountCode, final EnumOptionData glAccountClassification, final LocalDate transactionDate,
final EnumOptionData entryType, final BigDecimal amount, final String transactionId, final Boolean manualEntry,
final EnumOptionData entityType, final Long entityId, final Long createdByUserId, final LocalDate createdDate,
final String createdByUserName, final String comments, final Boolean reversed, final String referenceNumber,
final BigDecimal officeRunningBalance, final BigDecimal organizationRunningBalance, final Boolean runningBalanceComputed,
final TransactionDetailData transactionDetailData, final CurrencyData currency) {
this.id = id;
this.officeId = officeId;
this.officeName = officeName;
@@ -257,4 +253,4 @@ public class JournalEntryData {
public String getTransactionId() {
return transactionId;
}
}
}
@@ -60,8 +60,10 @@ public class JournalEntryDataValidator {
baseDataValidator.reset().parameter(JournalEntryJsonInputParams.OFFICE_ID.getValue()).value(officeId).ignoreIfNull()
.longGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
@@ -133,11 +133,11 @@ public class LoanTransactionDTO {
return this.isAccountTransfer;
}
public void setIsLoanToLoanTransfer(boolean isLoanToLoanTransfer) {
this.isLoanToLoanTransfer = isLoanToLoanTransfer;
}
public void setIsLoanToLoanTransfer(boolean isLoanToLoanTransfer) {
this.isLoanToLoanTransfer = isLoanToLoanTransfer;
}
public boolean isLoanToLoanTransfer(){
return this.isLoanToLoanTransfer;
}
public boolean isLoanToLoanTransfer() {
return this.isLoanToLoanTransfer;
}
}
@@ -38,4 +38,4 @@ public class TransactionTypeEnumData {
return this.id;
}
}
}
@@ -173,6 +173,7 @@ public class JournalEntry extends AbstractAuditableCustom {
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public void setReversalJournalEntry(final JournalEntry reversalJournalEntry) {
this.reversalJournalEntry = reversalJournalEntry;
}
@@ -217,9 +218,8 @@ public class JournalEntry extends AbstractAuditableCustom {
return this.entityType;
}
public Long getShareTransactionId() {
return this.shareTransactionId;
}
}
}
@@ -24,8 +24,8 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry>,
JournalEntryRepositoryCustom {
public interface JournalEntryRepository
extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry>, JournalEntryRepositoryCustom {
@Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.manualEntry=true")
List<JournalEntry> findUnReversedManualJournalEntriesByTransactionId(@Param("transactionId") String transactionId);
@@ -37,14 +37,22 @@ public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long
List<String> findNonReversedContraTansactionIds(@Param("contraId") Long contraId, @Param("officeId") Long officeId);
@Query("select journalEntry from JournalEntry journalEntry where journalEntry.entityId= :entityId and journalEntry.entityType = :entityType")
List<JournalEntry> findProvisioningJournalEntriesByEntityId(@Param("entityId") Long entityId, @Param("entityType") Integer entityType) ;
List<JournalEntry> findProvisioningJournalEntriesByEntityId(@Param("entityId") Long entityId, @Param("entityType") Integer entityType);
@Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.entityType = :entityType")
List<JournalEntry> findJournalEntries(@Param("transactionId") String transactionId, @Param("entityType") Integer entityType);
/*@Query("select journalEntry from JournalEntry journalEntry where glAccount.id= :accountId and transactionId= :transactionId and transactionDate= :transactionDate"
+ " and type= :journalEntryType and entityType=1 and entityId= :loanId and loanTransaction.id= :loanTransactionId")
JournalEntry findLOANJournalEntryWith(@Param("accountId") Long accountId, @Param("transactionId") String transactionId,
@Param("transactionDate") Date transactionDate, @Param("journalEntryType") Integer journalEntryType,
@Param("loanId") Long loanId, @Param("loanTransactionId") Long loanTransactionId);*/
/*
* @Query("select journalEntry from JournalEntry journalEntry where glAccount.id= :accountId and transactionId= :transactionId and transactionDate= :transactionDate"
* +
* " and type= :journalEntryType and entityType=1 and entityId= :loanId and loanTransaction.id= :loanTransactionId"
* ) JournalEntry findLOANJournalEntryWith(@Param("accountId") Long
* accountId, @Param("transactionId") String transactionId,
*
* @Param("transactionDate") Date
* transactionDate, @Param("journalEntryType") Integer journalEntryType,
*
* @Param("loanId") Long loanId, @Param("loanTransactionId") Long
* loanTransactionId);
*/
}
@@ -26,11 +26,12 @@ import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourc
public class JournalEntriesNotFoundException extends AbstractPlatformResourceNotFoundException {
public JournalEntriesNotFoundException(final String transactionId) {
super("error.msg.journalEntries.transactionId.invalid", "Journal Entries with transaction Identifier " + transactionId
+ " does not exist or are not system generated/reversible ", transactionId);
super("error.msg.journalEntries.transactionId.invalid",
"Journal Entries with transaction Identifier " + transactionId + " does not exist or are not system generated/reversible ",
transactionId);
}
public JournalEntriesNotFoundException(final Long entryId) {
super("error.msg.journalEntries.id.invalid", "Journal Entry with entry Id " + entryId + " does not exist ", entryId);
}
}
}
@@ -28,6 +28,7 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
/*** enum of reasons for invalid Journal Entry **/
public static enum GlJournalEntryInvalidReason {
FUTURE_DATE, ACCOUNTING_CLOSED, NO_DEBITS_OR_CREDITS, DEBIT_CREDIT_SUM_MISMATCH_WITH_AMOUNT, DEBIT_CREDIT_SUM_MISMATCH, DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, GL_ACCOUNT_DISABLED, GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED, INVALID_DEBIT_OR_CREDIT_ACCOUNTS;
public String errorMessage() {
@@ -47,7 +48,9 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
return "Target account has been disabled";
} else if (name().toString().equalsIgnoreCase("INVALID_DEBIT_OR_CREDIT_ACCOUNTS")) {
return "Invalid debit or credit accounts are passed";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) { return "Target account does not allow maual adjustments"; }
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) {
return "Target account does not allow maual adjustments";
}
return name().toString();
}
@@ -66,7 +69,9 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
return "error.msg.glJournalEntry.invalid.account.disabled";
} else if (name().toString().equalsIgnoreCase("INVALID_DEBIT_OR_CREDIT_ACCOUNTS")) {
return "error.msg.glJournalEntry.invalid.debit.or.credit.accounts";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) { return "error.msg.glJournalEntry.invalid.account.manual.adjustments.not.permitted"; }
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) {
return "error.msg.glJournalEntry.invalid.account.manual.adjustments.not.permitted";
}
return name().toString();
}
}
@@ -75,4 +80,4 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
final String accountGLCode) {
super(reason.errorCode(), reason.errorMessage(), date, accountName, accountGLCode);
}
}
}
@@ -26,11 +26,12 @@ import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourc
public class JournalEntryNotFoundException extends AbstractPlatformResourceNotFoundException {
public JournalEntryNotFoundException(final String transactionId) {
super("error.msg.journalEntries.transactionId.invalid", "Journal Entries with transaction Identifier " + transactionId
+ " does not exist or are not system generated/reversible ", transactionId);
super("error.msg.journalEntries.transactionId.invalid",
"Journal Entries with transaction Identifier " + transactionId + " does not exist or are not system generated/reversible ",
transactionId);
}
public JournalEntryNotFoundException(final Long entryId) {
super("error.msg.journalEntries.id.invalid", "Journal Entry with entry Id " + entryId + " does not exist ", entryId);
}
}
}
@@ -18,7 +18,6 @@
*/
package org.apache.fineract.accounting.journalentry.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class JournalEntryRuntimeException extends AbstractPlatformDomainRuleException {
@@ -44,4 +44,4 @@ public class CreateJournalEntryCommandHandler implements NewCommandSourceHandler
return this.writePlatformService.createJournalEntry(command);
}
}
}
@@ -43,4 +43,4 @@ public class ReverseJournalEntryCommandHandler implements NewCommandSourceHandle
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.revertJournalEntry(command);
}
}
}
@@ -65,11 +65,11 @@ public final class JournalEntryCommandFromApiJsonDeserializer extends AbstractFr
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long officeId = this.fromApiJsonHelper.extractLongNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue(), element);
final String currencyCode = this.fromApiJsonHelper
.extractStringNamed(JournalEntryJsonInputParams.CURRENCY_CODE.getValue(), element);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(JournalEntryJsonInputParams.CURRENCY_CODE.getValue(),
element);
final String comments = this.fromApiJsonHelper.extractStringNamed(JournalEntryJsonInputParams.COMMENTS.getValue(), element);
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(
JournalEntryJsonInputParams.TRANSACTION_DATE.getValue(), element);
final LocalDate transactionDate = this.fromApiJsonHelper
.extractLocalDateNamed(JournalEntryJsonInputParams.TRANSACTION_DATE.getValue(), element);
final String referenceNumber = this.fromApiJsonHelper.extractStringNamed(JournalEntryJsonInputParams.REFERENCE_NUMBER.getValue(),
element);
final Long accountingRuleId = this.fromApiJsonHelper.extractLongNamed(JournalEntryJsonInputParams.ACCOUNTING_RULE.getValue(),
@@ -93,7 +93,8 @@ public final class JournalEntryCommandFromApiJsonDeserializer extends AbstractFr
if (element.isJsonObject()) {
if (topLevelJsonElement.has(JournalEntryJsonInputParams.CREDITS.getValue())
&& topLevelJsonElement.get(JournalEntryJsonInputParams.CREDITS.getValue()).isJsonArray()) {
credits = populateCreditsOrDebitsArray(topLevelJsonElement, locale, credits, JournalEntryJsonInputParams.CREDITS.getValue());
credits = populateCreditsOrDebitsArray(topLevelJsonElement, locale, credits,
JournalEntryJsonInputParams.CREDITS.getValue());
}
if (topLevelJsonElement.has(JournalEntryJsonInputParams.DEBITS.getValue())
&& topLevelJsonElement.get(JournalEntryJsonInputParams.DEBITS.getValue()).isJsonArray()) {
@@ -126,4 +127,4 @@ public final class JournalEntryCommandFromApiJsonDeserializer extends AbstractFr
}
return debitOrCredits;
}
}
}
@@ -170,7 +170,7 @@ public class AccountingProcessorHelper {
transactionDate, transactionType, amount, principal, interest, fees, penalties, overPayments, reversed,
feePaymentDetails, penaltyPaymentDetails, isAccountTransfer);
Boolean isLoanToLoanTransfer = (Boolean) accountingBridgeData.get("isLoanToLoanTransfer");
if(isLoanToLoanTransfer != null && isLoanToLoanTransfer){
if (isLoanToLoanTransfer != null && isLoanToLoanTransfer) {
transaction.setIsLoanToLoanTransfer(true);
} else {
transaction.setIsLoanToLoanTransfer(false);
@@ -323,14 +323,15 @@ public class AccountingProcessorHelper {
final boolean isPenalty = (Boolean) clientChargePaid.get("isPenalty");
final BigDecimal chargeAmountPaid = (BigDecimal) clientChargePaid.get("amount");
final Long incomeAccountId = (Long) clientChargePaid.get("incomeAccountId");
final ClientChargePaymentDTO clientChargePaymentDTO = new ClientChargePaymentDTO(chargeId, chargeAmountPaid,
clientChargeId, isPenalty, incomeAccountId);
final ClientChargePaymentDTO clientChargePaymentDTO = new ClientChargePaymentDTO(chargeId, chargeAmountPaid, clientChargeId,
isPenalty, incomeAccountId);
clientChargePaymentDTOs.add(clientChargePaymentDTO);
}
}
final ClientTransactionDTO clientTransactionDTO = new ClientTransactionDTO(clientId, transactionOfficeId, paymentTypeId,
transactionId, transactionDate, transactionType, currencyCode, amount, reversed, accountingEnabled, clientChargePaymentDTOs);
transactionId, transactionDate, transactionType, currencyCode, amount, reversed, accountingEnabled,
clientChargePaymentDTOs);
return clientTransactionDTO;
@@ -357,9 +358,8 @@ public class AccountingProcessorHelper {
* @param isReversal
*/
public void createAccrualBasedJournalEntriesAndReversalsForLoan(final Office office, final String currencyCode,
final Integer accountTypeToBeDebited, final Integer accountTypeToBeCredited, final Long loanProductId,
final Long paymentTypeId, final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount,
final Boolean isReversal) {
final Integer accountTypeToBeDebited, final Integer accountTypeToBeCredited, final Long loanProductId, final Long paymentTypeId,
final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount, final Boolean isReversal) {
int accountTypeToDebitId = accountTypeToBeDebited;
int accountTypeToCreditId = accountTypeToBeCredited;
// reverse debits and credits for reversals
@@ -367,8 +367,8 @@ public class AccountingProcessorHelper {
accountTypeToDebitId = accountTypeToBeCredited;
accountTypeToCreditId = accountTypeToBeDebited;
}
createJournalEntriesForLoan(office, currencyCode, accountTypeToDebitId, accountTypeToCreditId, loanProductId, paymentTypeId,
loanId, transactionId, transactionDate, amount);
createJournalEntriesForLoan(office, currencyCode, accountTypeToDebitId, accountTypeToCreditId, loanProductId, paymentTypeId, loanId,
transactionId, transactionDate, amount);
}
/**
@@ -378,17 +378,28 @@ public class AccountingProcessorHelper {
* The target accounts for debits and credits are switched in case of a
* reversal
*
* @param office office
* @param currencyCode currencyCode
* @param accountTypeToBeDebited Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited Enum of the placeholder of the GLAccount to be credited
* @param loanProductId loanProductId
* @param loanId loanId
* @param transactionId transactionId
* @param transactionDate transactionDate
* @param totalAmount totalAmount
* @param isReversal isReversal
* @param chargePaymentDTOs chargePaymentDTOs
* @param office
* office
* @param currencyCode
* currencyCode
* @param accountTypeToBeDebited
* Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited
* Enum of the placeholder of the GLAccount to be credited
* @param loanProductId
* loanProductId
* @param loanId
* loanId
* @param transactionId
* transactionId
* @param transactionDate
* transactionDate
* @param totalAmount
* totalAmount
* @param isReversal
* isReversal
* @param chargePaymentDTOs
* chargePaymentDTOs
*/
public void createAccrualBasedJournalEntriesAndReversalsForLoanCharges(final Office office, final String currencyCode,
final Integer accountTypeToBeDebited, final Integer accountTypeToBeCredited, final Long loanProductId, final Long loanId,
@@ -425,10 +436,12 @@ public class AccountingProcessorHelper {
}
}
if (totalAmount.compareTo(totalCreditedAmount) != 0) { throw new PlatformDataIntegrityException(
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
totalCreditedAmount, totalAmount); }
if (totalAmount.compareTo(totalCreditedAmount) != 0) {
throw new PlatformDataIntegrityException(
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
totalCreditedAmount, totalAmount);
}
}
/**
@@ -487,9 +500,8 @@ public class AccountingProcessorHelper {
* @param isReversal
*/
public void createCashBasedJournalEntriesAndReversalsForLoan(final Office office, final String currencyCode,
final Integer accountTypeToBeDebited, final Integer accountTypeToBeCredited, final Long loanProductId,
final Long paymentTypeId, final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount,
final Boolean isReversal) {
final Integer accountTypeToBeDebited, final Integer accountTypeToBeCredited, final Long loanProductId, final Long paymentTypeId,
final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount, final Boolean isReversal) {
int accountTypeToDebitId = accountTypeToBeDebited;
int accountTypeToCreditId = accountTypeToBeCredited;
// reverse debits and credits for reversals
@@ -497,8 +509,8 @@ public class AccountingProcessorHelper {
accountTypeToDebitId = accountTypeToBeCredited;
accountTypeToCreditId = accountTypeToBeDebited;
}
createJournalEntriesForLoan(office, currencyCode, accountTypeToDebitId, accountTypeToCreditId, loanProductId, paymentTypeId,
loanId, transactionId, transactionDate, amount);
createJournalEntriesForLoan(office, currencyCode, accountTypeToDebitId, accountTypeToCreditId, loanProductId, paymentTypeId, loanId,
transactionId, transactionDate, amount);
}
public void createCreditJournalEntryOrReversalForLoan(final Office office, final String currencyCode,
@@ -527,8 +539,10 @@ public class AccountingProcessorHelper {
* transaction Date
**/
if (latestGLClosure != null) {
if (latestGLClosure.getClosingDate().after(transactionDate) || latestGLClosure.getClosingDate().equals(transactionDate)) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(), null, null); }
if (latestGLClosure.getClosingDate().after(transactionDate) || latestGLClosure.getClosingDate().equals(transactionDate)) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(),
null, null);
}
}
}
@@ -567,8 +581,10 @@ public class AccountingProcessorHelper {
*
* @param office
* @param currencyCode
* @param accountTypeToBeDebited Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited Enum of the placeholder of the GLAccount to be credited
* @param accountTypeToBeDebited
* Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited
* Enum of the placeholder of the GLAccount to be credited
* @param savingsProductId
* @param paymentTypeId
* @param savingsId
@@ -711,10 +727,12 @@ public class AccountingProcessorHelper {
// TODO: Vishwas Temporary validation to be removed before moving to
// release branch
if (totalAmount.compareTo(totalCreditedAmount) != 0) { throw new PlatformDataIntegrityException(
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
totalCreditedAmount, totalAmount); }
if (totalAmount.compareTo(totalCreditedAmount) != 0) {
throw new PlatformDataIntegrityException(
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
"Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction",
totalCreditedAmount, totalAmount);
}
}
/**
@@ -724,18 +742,30 @@ public class AccountingProcessorHelper {
* The target accounts for debits and credits are switched in case of a
* reversal
*
* @param office office
* @param currencyCode currencyCode
* @param accountTypeToBeDebited Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited Enum of the placeholder of the GLAccount to be credited
* @param savingsProductId savingsProductId
* @param paymentTypeId paymentTypeId
* @param loanId loanId
* @param transactionId transactionId
* @param transactionDate transactionDate
* @param totalAmount totalAmount
* @param isReversal isReversal
* @param chargePaymentDTOs chargePaymentDTOs
* @param office
* office
* @param currencyCode
* currencyCode
* @param accountTypeToBeDebited
* Enum of the placeholder GLAccount to be debited
* @param accountTypeToBeCredited
* Enum of the placeholder of the GLAccount to be credited
* @param savingsProductId
* savingsProductId
* @param paymentTypeId
* paymentTypeId
* @param loanId
* loanId
* @param transactionId
* transactionId
* @param transactionDate
* transactionDate
* @param totalAmount
* totalAmount
* @param isReversal
* isReversal
* @param chargePaymentDTOs
* chargePaymentDTOs
*/
public void createCashBasedJournalEntriesAndReversalsForSavingsCharges(final Office office, final String currencyCode,
final CashAccountsForSavings accountTypeToBeDebited, final CashAccountsForSavings accountTypeToBeCredited,
@@ -750,9 +780,10 @@ public class AccountingProcessorHelper {
* changing the expected portfolio behavior would also take care of
* modifying the accounting code appropriately
**/
if (chargePaymentDTOs.size() != 1) { throw new PlatformDataIntegrityException(
"Recent Portfolio changes w.r.t Charges for Savings have Broken the accounting code",
"Recent Portfolio changes w.r.t Charges for Savings have Broken the accounting code"); }
if (chargePaymentDTOs.size() != 1) {
throw new PlatformDataIntegrityException("Recent Portfolio changes w.r.t Charges for Savings have Broken the accounting code",
"Recent Portfolio changes w.r.t Charges for Savings have Broken the accounting code");
}
ChargePaymentDTO chargePaymentDTO = chargePaymentDTOs.get(0);
final GLAccount chargeSpecificAccount = getLinkedGLAccountForSavingsCharges(savingsProductId, accountTypeToBeCredited.getValue(),
@@ -784,7 +815,8 @@ public class AccountingProcessorHelper {
final Long loanProductId, final Long paymentTypeId, final Long loanId, final String transactionId, final Date transactionDate,
final BigDecimal amount, final Boolean isReversal) {
final GLAccount account = getLinkedGLAccountForLoanProduct(loanProductId, accountMappingTypeId, paymentTypeId);
createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate, amount, isReversal, account);
createCreditJournalEntryOrReversalForLoan(office, currencyCode, loanId, transactionId, transactionDate, amount, isReversal,
account);
}
public void createCreditJournalEntryOrReversalForLoan(final Office office, final String currencyCode, final Long loanId,
@@ -811,8 +843,8 @@ public class AccountingProcessorHelper {
String modifiedTransactionId = transactionId.toString();
modifiedTransactionId = CLIENT_TRANSACTION_IDENTIFIER + transactionId;
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.CLIENT.getValue(), clientId,
null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.CLIENT.getValue(), clientId, null,
loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
@@ -836,8 +868,8 @@ public class AccountingProcessorHelper {
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
private void createCreditJournalEntryForLoan(final Office office, final String currencyCode, final GLAccount account,
final Long loanId, final String transactionId, final Date transactionDate, final BigDecimal amount) {
private void createCreditJournalEntryForLoan(final Office office, final String currencyCode, final GLAccount account, final Long loanId,
final String transactionId, final Date transactionDate, final BigDecimal amount) {
final boolean manualEntry = false;
LoanTransaction loanTransaction = null;
SavingsAccountTransaction savingsAccountTransaction = null;
@@ -921,8 +953,8 @@ public class AccountingProcessorHelper {
modifiedTransactionId = SAVINGS_TRANSACTION_IDENTIFIER + transactionId;
}
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId,
null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.SAVING.getValue(), savingsId, null,
loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
@@ -1005,9 +1037,10 @@ public class AccountingProcessorHelper {
totalCreditedAmount = totalCreditedAmount.add(amount);
createCreditJournalEntryForShares(office, currencyCode, account, shareAccountId, transactionId, transactionDate, amount);
}
if (totalAmount.compareTo(totalCreditedAmount) != 0) { throw new PlatformDataIntegrityException(
"Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code",
"Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code"); }
if (totalAmount.compareTo(totalCreditedAmount) != 0) {
throw new PlatformDataIntegrityException("Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code",
"Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code");
}
}
public void revertCashBasedJournalEntryForSharesCharges(final Office office, final String currencyCode,
@@ -1036,9 +1069,10 @@ public class AccountingProcessorHelper {
totalCreditedAmount = totalCreditedAmount.add(amount);
createDebitJournalEntryForShares(office, currencyCode, account, shareAccountId, transactionId, transactionDate, amount);
}
if (totalAmount.compareTo(totalCreditedAmount) != 0) { throw new PlatformDataIntegrityException(
"Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code",
"Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code"); }
if (totalAmount.compareTo(totalCreditedAmount) != 0) {
throw new PlatformDataIntegrityException("Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code",
"Recent Portfolio changes w.r.t Charges for shares have Broken the accounting code");
}
}
private void createDebitJournalEntryForShares(final Office office, final String currencyCode, final GLAccount account,
@@ -1074,8 +1108,8 @@ public class AccountingProcessorHelper {
modifiedTransactionId = SHARE_TRANSACTION_IDENTIFIER + transactionId;
}
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.SHARES.getValue(),
shareAccountId, null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.SHARES.getValue(), shareAccountId,
null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
this.glJournalEntryRepository.save(journalEntry);
}
@@ -1103,8 +1137,10 @@ public class AccountingProcessorHelper {
}
}
if (accountMapping == null) { throw new ProductToGLAccountMappingNotFoundException(PortfolioProductType.LOAN, loanProductId,
AccrualAccountsForLoan.OVERPAYMENT.toString()); }
if (accountMapping == null) {
throw new ProductToGLAccountMappingNotFoundException(PortfolioProductType.LOAN, loanProductId,
AccrualAccountsForLoan.OVERPAYMENT.toString());
}
glAccount = accountMapping.getGlAccount();
}
return glAccount;
@@ -1133,7 +1169,8 @@ public class AccountingProcessorHelper {
return accountMapping.getGlAccount();
}
private GLAccount getLinkedGLAccountForSavingsCharges(final Long savingsProductId, final int accountMappingTypeId, final Long chargeId) {
private GLAccount getLinkedGLAccountForSavingsCharges(final Long savingsProductId, final int accountMappingTypeId,
final Long chargeId) {
ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(savingsProductId,
PortfolioProductType.SAVING.getValue(), accountMappingTypeId);
/*****
@@ -1147,8 +1184,8 @@ public class AccountingProcessorHelper {
if (accountMappingTypeId == CashAccountsForSavings.INCOME_FROM_FEES.getValue()
|| accountMappingTypeId == CashAccountsForLoan.INCOME_FROM_PENALTIES.getValue()) {
final ProductToGLAccountMapping chargeSpecificIncomeAccountMapping = this.accountMappingRepository
.findProductIdAndProductTypeAndFinancialAccountTypeAndChargeId(savingsProductId,
PortfolioProductType.SAVING.getValue(), accountMappingTypeId, chargeId);
.findProductIdAndProductTypeAndFinancialAccountTypeAndChargeId(savingsProductId, PortfolioProductType.SAVING.getValue(),
accountMappingTypeId, chargeId);
if (chargeSpecificIncomeAccountMapping != null) {
accountMapping = chargeSpecificIncomeAccountMapping;
}
@@ -1184,7 +1221,8 @@ public class AccountingProcessorHelper {
return glAccount;
}
private GLAccount getLinkedGLAccountForShareProduct(final Long shareProductId, final int accountMappingTypeId, final Long paymentTypeId) {
private GLAccount getLinkedGLAccountForShareProduct(final Long shareProductId, final int accountMappingTypeId,
final Long paymentTypeId) {
GLAccount glAccount = null;
if (isOrganizationAccount(accountMappingTypeId)) {
FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
@@ -1273,8 +1311,8 @@ public class AccountingProcessorHelper {
public void createDebitJournalEntryOrReversalForClientChargePayments(final Office office, final String currencyCode,
final Long clientId, final Long transactionId, final Date transactionDate, final BigDecimal amount, final Boolean isReversal) {
final GLAccount account = financialActivityAccountRepository.findByFinancialActivityTypeWithNotFoundDetection(
FinancialActivity.ASSET_FUND_SOURCE.getValue()).getGlAccount();
final GLAccount account = financialActivityAccountRepository
.findByFinancialActivityTypeWithNotFoundDetection(FinancialActivity.ASSET_FUND_SOURCE.getValue()).getGlAccount();
if (isReversal) {
createCreditJournalEntryForClientPayments(office, currencyCode, account, clientId, transactionId, transactionDate, amount);
} else {
@@ -72,8 +72,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
else if (loanTransactionDTO.getTransactionType().isRepayment()
|| loanTransactionDTO.getTransactionType().isRepaymentAtDisbursement()
|| loanTransactionDTO.getTransactionType().isChargePayment()) {
createJournalEntriesForRepaymentsAndWriteOffs(loanDTO, loanTransactionDTO, office, false, loanTransactionDTO
.getTransactionType().isRepaymentAtDisbursement());
createJournalEntriesForRepaymentsAndWriteOffs(loanDTO, loanTransactionDTO, office, false,
loanTransactionDTO.getTransactionType().isRepaymentAtDisbursement());
}
/** Logic for handling recovery payments **/
@@ -87,8 +87,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
}
/** Handle Write Offs, waivers and their reversals **/
else if ((loanTransactionDTO.getTransactionType().isWriteOff() || loanTransactionDTO.getTransactionType().isWaiveInterest() || loanTransactionDTO
.getTransactionType().isWaiveCharges())) {
else if ((loanTransactionDTO.getTransactionType().isWriteOff() || loanTransactionDTO.getTransactionType().isWaiveInterest()
|| loanTransactionDTO.getTransactionType().isWaiveCharges())) {
createJournalEntriesForRepaymentsAndWriteOffs(loanDTO, loanTransactionDTO, office, true, false);
}
@@ -123,7 +123,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
// create journal entries for the disbursement (or disbursement
// reversal)
if(loanTransactionDTO.isLoanToLoanTransfer()){
if (loanTransactionDTO.isLoanToLoanTransfer()) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, disbursalAmount, isReversed);
@@ -145,8 +145,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
* <br/>
* <br/>
*
* <b>Principal Repayment</b>: Debits "Fund Source" and Credits
* "Loan Portfolio"<br/>
* <b>Principal Repayment</b>: Debits "Fund Source" and Credits "Loan
* Portfolio"<br/>
*
* <b>Interest Repayment</b>:Debits "Fund Source" and and Credits
* "Receivable Interest" <br/>
@@ -159,8 +159,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
* <br/>
* Handles write offs using the following posting rules <br/>
* <br/>
* <b>Principal Write off</b>: Debits "Losses Written Off" and Credits
* "Loan Portfolio"<br/>
* <b>Principal Write off</b>: Debits "Losses Written Off" and Credits "Loan
* Portfolio"<br/>
*
* <b>Interest Write off</b>:Debits "Losses Written off" and and Credits
* "Receivable Interest" <br/>
@@ -274,8 +274,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
if (overPaymentAmount != null && !(overPaymentAmount.compareTo(BigDecimal.ZERO) == 0)) {
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
AccrualAccountsForLoan.OVERPAYMENT.getValue(), paymentTypeId);
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
paymentTypeId);
if (accountMap.containsKey(account)) {
BigDecimal amount = accountMap.get(account).add(overPaymentAmount);
accountMap.put(account, amount);
@@ -299,10 +299,9 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
AccrualAccountsForLoan.LOSSES_WRITTEN_OFF.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, totalDebitAmount, isReversal);
} else {
if(loanTransactionDTO.isLoanToLoanTransfer()){
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode,
FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, totalDebitAmount, isReversal);
if (loanTransactionDTO.isLoanToLoanTransfer()) {
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, FinancialActivity.ASSET_TRANSFER.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, isReversal);
} else if (loanTransactionDTO.isAccountTransfer()) {
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
@@ -317,8 +316,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
}
/**
* Create a single Debit to fund source and a single credit to
* "Income from Recovery"
* Create a single Debit to fund source and a single credit to "Income from
* Recovery"
*
* In case the loan transaction is a reversal, all debits are turned into
* credits and vice versa
@@ -337,9 +336,9 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
final boolean isReversal = loanTransactionDTO.isReversed();
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
AccrualAccountsForLoan.FUND_SOURCE.getValue(), AccrualAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, amount, isReversal);
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
AccrualAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, amount, isReversal);
}
@@ -384,8 +383,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
// create journal entries for the fees application (or reversal)
if (feesAmount != null && !(feesAmount.compareTo(BigDecimal.ZERO) == 0)) {
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoanCharges(office, currencyCode,
AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(), AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(),
loanProductId, loanId, transactionId, transactionDate, feesAmount, isReversed, loanTransactionDTO.getFeePayments());
AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(), AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(), loanProductId,
loanId, transactionId, transactionDate, feesAmount, isReversed, loanTransactionDTO.getFeePayments());
}
// create journal entries for the penalties application (or reversal)
if (penaltiesAmount != null && !(penaltiesAmount.compareTo(BigDecimal.ZERO) == 0)) {
@@ -411,13 +410,13 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
if (loanTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.OVERPAYMENT.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, refundAmount, isReversal);
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
refundAmount, isReversal);
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.OVERPAYMENT.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, refundAmount, isReversal);
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
refundAmount, isReversal);
}
}
@@ -443,8 +442,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
if (principalAmount != null && !(principalAmount.compareTo(BigDecimal.ZERO) == 0)) {
totalDebitAmount = totalDebitAmount.add(principalAmount);
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO,
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalAmount, !isReversal);
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO, loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, principalAmount, !isReversal);
}
if (interestAmount != null && !(interestAmount.compareTo(BigDecimal.ZERO) == 0)) {
@@ -90,9 +90,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
final BigDecimal principalAmount = loanTransactionDTO.getPrincipal();
if (principalAmount != null && !(principalAmount.compareTo(BigDecimal.ZERO) == 0)) {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.LOSSES_WRITTEN_OFF.getValue(), CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalAmount,
loanTransactionDTO.isReversed());
CashAccountsForLoan.LOSSES_WRITTEN_OFF.getValue(), CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, principalAmount, loanTransactionDTO.isReversed());
}
} else if (loanTransactionDTO.getTransactionType().isInitiateTransfer()
@@ -131,7 +130,7 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
final BigDecimal disbursalAmount = loanTransactionDTO.getAmount();
final boolean isReversal = loanTransactionDTO.isReversed();
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
if(loanTransactionDTO.isLoanToLoanTransfer()){
if (loanTransactionDTO.isLoanToLoanTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, disbursalAmount, isReversal);
@@ -141,8 +140,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
paymentTypeId, loanId, transactionId, transactionDate, disbursalAmount, isReversal);
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, disbursalAmount, isReversal);
CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId,
loanId, transactionId, transactionDate, disbursalAmount, isReversal);
}
}
@@ -172,13 +171,13 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
if (loanTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.OVERPAYMENT.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, refundAmount, isReversal);
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
refundAmount, isReversal);
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.OVERPAYMENT.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, refundAmount, isReversal);
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
refundAmount, isReversal);
}
}
@@ -191,7 +190,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
* In case the loan transaction is a reversal, all debits are turned into
* credits and vice versa
*/
private void createJournalEntriesForRepayments(final LoanDTO loanDTO, final LoanTransactionDTO loanTransactionDTO, final Office office) {
private void createJournalEntriesForRepayments(final LoanDTO loanDTO, final LoanTransactionDTO loanTransactionDTO,
final Office office) {
// loan properties
final Long loanProductId = loanDTO.getLoanProductId();
final Long loanId = loanDTO.getLoanId();
@@ -212,8 +212,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
if (principalAmount != null && !(principalAmount.compareTo(BigDecimal.ZERO) == 0)) {
totalDebitAmount = totalDebitAmount.add(principalAmount);
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO,
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalAmount, isReversal);
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO, loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, principalAmount, isReversal);
}
if (interestAmount != null && !(interestAmount.compareTo(BigDecimal.ZERO) == 0)) {
@@ -243,7 +243,7 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
}
/*** create a single debit entry (or reversal) for the entire amount **/
if(loanTransactionDTO.isLoanToLoanTransfer()){
if (loanTransactionDTO.isLoanToLoanTransfer()) {
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, FinancialActivity.ASSET_TRANSFER.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, isReversal);
} else if (loanTransactionDTO.isAccountTransfer()) {
@@ -256,8 +256,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
}
/**
* Create a single Debit to fund source and a single credit to
* "Income from Recovery"
* Create a single Debit to fund source and a single credit to "Income from
* Recovery"
*
* In case the loan transaction is a reversal, all debits are turned into
* credits and vice versa
@@ -277,8 +277,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode, CashAccountsForLoan.FUND_SOURCE.getValue(),
CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, amount, isReversal);
CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
amount, isReversal);
}
@@ -310,13 +310,13 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
if (loanTransactionDTO.getTransactionType().isInitiateTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), loanProductId,
null, loanId, transactionId, transactionDate, principalAmount, isReversal);
CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), loanProductId, null,
loanId, transactionId, transactionDate, principalAmount, isReversal);
} else if (loanTransactionDTO.getTransactionType().isApproveTransfer()
|| loanTransactionDTO.getTransactionType().isWithdrawTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, currencyCode,
CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), loanProductId,
null, loanId, transactionId, transactionDate, principalAmount, isReversal);
CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), loanProductId, null,
loanId, transactionId, transactionDate, principalAmount, isReversal);
}
}
@@ -341,8 +341,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
if (principalAmount != null && !(principalAmount.compareTo(BigDecimal.ZERO) == 0)) {
totalDebitAmount = totalDebitAmount.add(principalAmount);
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO,
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalAmount, !isReversal);
this.helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO, loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, principalAmount, !isReversal);
}
if (interestAmount != null && !(interestAmount.compareTo(BigDecimal.ZERO) == 0)) {
@@ -356,9 +356,10 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
List<ChargePaymentDTO> chargePaymentDTOs = new ArrayList<>();
for(ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getFeePayments()) {
for (ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getFeePayments()) {
chargePaymentDTOs.add(new ChargePaymentDTO(chargePaymentDTO.getChargeId(), chargePaymentDTO.getLoanChargeId(),
chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1)):chargePaymentDTO.getAmount() ));
chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1))
: chargePaymentDTO.getAmount()));
}
this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, currencyCode,
CashAccountsForLoan.INCOME_FROM_FEES.getValue(), loanProductId, loanId, transactionId, transactionDate, feesAmount,
@@ -369,9 +370,10 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
List<ChargePaymentDTO> chargePaymentDTOs = new ArrayList<>();
for(ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getPenaltyPayments()) {
for (ChargePaymentDTO chargePaymentDTO : loanTransactionDTO.getPenaltyPayments()) {
chargePaymentDTOs.add(new ChargePaymentDTO(chargePaymentDTO.getChargeId(), chargePaymentDTO.getLoanChargeId(),
chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1)):chargePaymentDTO.getAmount() ));
chargePaymentDTO.getAmount().floatValue() < 0 ? chargePaymentDTO.getAmount().multiply(new BigDecimal(-1))
: chargePaymentDTO.getAmount()));
}
this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, currencyCode,
@@ -386,8 +388,8 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
}
/*** create a single debit entry (or reversal) for the entire amount **/
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, !isReversal);
this.helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, CashAccountsForLoan.FUND_SOURCE.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount, !isReversal);
}
}
@@ -63,9 +63,8 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
if (savingsTransactionDTO.getTransactionType().isWithdrawal() && savingsTransactionDTO.isOverdraftTransaction()) {
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
FinancialActivity.LIABILITY_TRANSFER.getValue(), savingsProductId, paymentTypeId, savingsId, transactionId,
transactionDate, overdraftAmount, isReversal);
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(),
@@ -75,21 +74,20 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(), savingsProductId, paymentTypeId, savingsId, transactionId,
transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal);
CashAccountsForSavings.SAVINGS_CONTROL.getValue(), CashAccountsForSavings.SAVINGS_REFERENCE.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
amount.subtract(overdraftAmount), isReversal);
}
}
} else if (savingsTransactionDTO.getTransactionType().isDeposit() && savingsTransactionDTO.isOverdraftTransaction()) {
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(),
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
FinancialActivity.LIABILITY_TRANSFER.getValue(), CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
@@ -103,9 +101,9 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(),
CashAccountsForSavings.SAVINGS_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal);
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
amount.subtract(overdraftAmount), isReversal);
}
}
}
@@ -126,8 +124,8 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
/** Handle Deposits and reversals of Dividend pay outs **/
else if (savingsTransactionDTO.getTransactionType().isDividendPayout()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.PAYABLE_DIVIDENDS.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
FinancialActivity.PAYABLE_DIVIDENDS.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(), savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
}
/** Handle withdrawals and reversals of withdrawals **/
else if (savingsTransactionDTO.getTransactionType().isWithdrawal()) {
@@ -161,9 +159,9 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.INTEREST_ON_SAVINGS.getValue(),
CashAccountsForSavings.SAVINGS_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal);
CashAccountsForSavings.INTEREST_ON_SAVINGS.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
amount.subtract(overdraftAmount), isReversal);
}
}
}
@@ -180,9 +178,8 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
else if (savingsTransactionDTO.getTransactionType().isWithholdTax()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsTax(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL, CashAccountsForSavings.SAVINGS_REFERENCE, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal,
savingsTransactionDTO.getTaxPayments());
CashAccountsForSavings.SAVINGS_CONTROL, CashAccountsForSavings.SAVINGS_REFERENCE, savingsProductId, paymentTypeId,
savingsId, transactionId, transactionDate, amount, isReversal, savingsTransactionDTO.getTaxPayments());
}
/** Handle Fees Deductions and reversals of Fees Deductions **/
@@ -195,15 +192,14 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
penaltyPayments);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL, CashAccountsForSavings.INCOME_FROM_PENALTIES,
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
amount.subtract(overdraftAmount), isReversal, penaltyPayments);
CashAccountsForSavings.SAVINGS_CONTROL, CashAccountsForSavings.INCOME_FROM_PENALTIES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal,
penaltyPayments);
}
} else {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL, CashAccountsForSavings.INCOME_FROM_FEES,
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal,
feePayments);
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL, CashAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal, feePayments);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL, CashAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
@@ -248,13 +244,12 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
} else if (savingsTransactionDTO.getTransactionType().isWrittenoff()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.LOSSES_WRITTEN_OFF.getValue(),
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, amount, isReversal);
CashAccountsForSavings.LOSSES_WRITTEN_OFF.getValue(), CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal);
} else if (savingsTransactionDTO.getTransactionType().isOverdraftFee()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.SAVINGS_REFERENCE, CashAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount, isReversal, feePayments);
CashAccountsForSavings.SAVINGS_REFERENCE, CashAccountsForSavings.INCOME_FROM_FEES, savingsProductId, paymentTypeId,
savingsId, transactionId, transactionDate, amount, isReversal, feePayments);
}
}
}
@@ -118,12 +118,12 @@ public class CashBasedAccountingProcessorForShares implements AccountingProcesso
if (chargeAmount != null && chargeAmount.compareTo(BigDecimal.ZERO) > 0) {
this.helper.revertCashBasedJournalEntryForSharesCharges(office, currencyCode, CashAccountsForShares.INCOME_FROM_FEES,
shareProductId, shareAccountId, transactionId, transactionDate, chargeAmount, feePayments);
this.helper.createDebitJournalEntryForShares(office, currencyCode, CashAccountsForShares.SHARES_SUSPENSE.getValue(), shareProductId, paymentTypeId, shareAccountId,
transactionId, transactionDate, amount.subtract(chargeAmount));
this.helper.createCreditJournalEntryForShares(office, currencyCode, CashAccountsForShares.SHARES_REFERENCE.getValue(), shareProductId, paymentTypeId, shareAccountId,
transactionId, transactionDate, amount);
this.helper.createDebitJournalEntryForShares(office, currencyCode, CashAccountsForShares.SHARES_SUSPENSE.getValue(),
shareProductId, paymentTypeId, shareAccountId, transactionId, transactionDate, amount.subtract(chargeAmount));
this.helper.createCreditJournalEntryForShares(office, currencyCode, CashAccountsForShares.SHARES_REFERENCE.getValue(),
shareProductId, paymentTypeId, shareAccountId, transactionId, transactionDate, amount);
}else{
} else {
this.helper.createJournalEntriesForShares(office, currencyCode, CashAccountsForShares.SHARES_SUSPENSE.getValue(),
CashAccountsForShares.SHARES_REFERENCE.getValue(), shareProductId, paymentTypeId, shareAccountId, transactionId,
transactionDate, amount);
@@ -34,5 +34,5 @@ public interface JournalEntryReadPlatformService {
OfficeOpeningBalancesData retrieveOfficeOpeningBalances(Long officeId, String currencyCode);
Page<JournalEntryData> retrieveJournalEntriesByEntityId(String transactionId, Long entityId, Integer entityType) ;
Page<JournalEntryData> retrieveJournalEntriesByEntityId(String transactionId, Long entityId, Integer entityType);
}
@@ -81,8 +81,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
@Autowired
public JournalEntryReadPlatformServiceImpl(final RoutingDataSource dataSource,
final GLAccountReadPlatformService glAccountReadPlatformService,
final ColumnValidator columnValidator,
final GLAccountReadPlatformService glAccountReadPlatformService, final ColumnValidator columnValidator,
final OfficeReadPlatformService officeReadPlatformService,
final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
@@ -106,8 +105,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
public String schema() {
StringBuilder sb = new StringBuilder();
sb.append(" journalEntry.id as id, glAccount.classification_enum as classification ,")
.append("journalEntry.transaction_id,")
sb.append(" journalEntry.id as id, glAccount.classification_enum as classification ,").append("journalEntry.transaction_id,")
.append(" glAccount.name as glAccountName, glAccount.gl_code as glAccountCode,glAccount.id as glAccountId, ")
.append(" journalEntry.office_id as officeId, office.name as officeName, journalEntry.ref_num as referenceNumber, ")
.append(" journalEntry.manual_entry as manualEntry,journalEntry.entry_date as transactionDate, ")
@@ -187,8 +185,8 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf,
currencyDisplaySymbol, currencyNameCode);
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol,
currencyNameCode);
if (associationParametersData.isRunningBalanceRequired()) {
officeRunningBalance = rs.getBigDecimal("officeRunningBalance");
@@ -225,13 +223,13 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
TransactionTypeEnumData transactionTypeEnumData = null;
if (PortfolioAccountType.fromInt(entityTypeId).isLoanAccount()) {
final LoanTransactionEnumData loanTransactionType = LoanEnumerations.transactionType(JdbcSupport.getInteger(rs,
"loanTransactionType"));
final LoanTransactionEnumData loanTransactionType = LoanEnumerations
.transactionType(JdbcSupport.getInteger(rs, "loanTransactionType"));
transactionTypeEnumData = new TransactionTypeEnumData(loanTransactionType.id(), loanTransactionType.getCode(),
loanTransactionType.getValue());
} else if (PortfolioAccountType.fromInt(entityTypeId).isSavingsAccount()) {
final SavingsAccountTransactionEnumData savingsTransactionType = SavingsEnumerations.transactionType(JdbcSupport
.getInteger(rs, "savingsTransactionType"));
final SavingsAccountTransactionEnumData savingsTransactionType = SavingsEnumerations
.transactionType(JdbcSupport.getInteger(rs, "savingsTransactionType"));
transactionTypeEnumData = new TransactionTypeEnumData(savingsTransactionType.getId(), savingsTransactionType.getCode(),
savingsTransactionType.getValue());
}
@@ -349,9 +347,8 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
whereClose = " and ";
}
if (searchParameters.isSavingsIdPassed()) {
sqlBuilder
.append(whereClose
+ " journalEntry.savings_transaction_id in (select id from m_savings_account_transaction where savings_account_id = ?)");
sqlBuilder.append(whereClose
+ " journalEntry.savings_transaction_id in (select id from m_savings_account_transaction where savings_account_id = ?)");
objectArray[arrayPos] = searchParameters.getSavingsId();
arrayPos = arrayPos + 1;
@@ -404,15 +401,19 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
final FinancialActivityAccount financialActivityAccountId = this.financialActivityAccountRepositoryWrapper
.findByFinancialActivityTypeWithNotFoundDetection(300);
final Long contraId = financialActivityAccountId.getGlAccount().getId();
if (contraId == null) { throw new GeneralPlatformDomainRuleException(
"error.msg.financial.activity.mapping.opening.balance.contra.account.cannot.be.null",
"office-opening-balances-contra-account value can not be null", "office-opening-balances-contra-account"); }
if (contraId == null) {
throw new GeneralPlatformDomainRuleException(
"error.msg.financial.activity.mapping.opening.balance.contra.account.cannot.be.null",
"office-opening-balances-contra-account value can not be null", "office-opening-balances-contra-account");
}
final JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData();
final GLAccountData contraAccount = this.glAccountReadPlatformService.retrieveGLAccountById(contraId, associationParametersData);
if (!GLAccountType.fromInt(contraAccount.getTypeId()).isEquityType()) { throw new GeneralPlatformDomainRuleException(
"error.msg.configuration.opening.balance.contra.account.value.is.invalid.account.type",
"Global configuration 'office-opening-balances-contra-account' value is not an equity type account", contraId); }
if (!GLAccountType.fromInt(contraAccount.getTypeId()).isEquityType()) {
throw new GeneralPlatformDomainRuleException(
"error.msg.configuration.opening.balance.contra.account.value.is.invalid.account.type",
"Global configuration 'office-opening-balances-contra-account' value is not an equity type account", contraId);
}
final OfficeData officeData = this.officeReadPlatformService.retrieveOffice(officeId);
final List<JournalEntryData> allOpeningTransactions = populateAllTransactionsFromGLAccounts(contraId);
@@ -494,8 +495,8 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
final String transactionId = "";
final Page<JournalEntryData> contraJournalEntries = retrieveContraTransactions(officeId, contraId, transactionId, currencyCode);
if (!CollectionUtils.isEmpty(contraJournalEntries.getPageItems())) {
final JournalEntryData contraTransaction = contraJournalEntries.getPageItems().get(
contraJournalEntries.getPageItems().size() - 1);
final JournalEntryData contraTransaction = contraJournalEntries.getPageItems()
.get(contraJournalEntries.getPageItems().size() - 1);
return contraTransaction.getTransactionId();
}
return transactionId;
@@ -524,13 +525,13 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
@Override
public Page<JournalEntryData> retrieveJournalEntriesByEntityId(String transactionId, Long entityId, Integer entityType) {
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(true,
true);
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(true, true);
try {
final GLJournalEntryMapper rm = new GLJournalEntryMapper(associationParametersData);
final String sql = "select " + rm.schema() + " where journalEntry.transaction_id = ? and journalEntry.entity_id = ? and journalEntry.entity_type_enum = ?";
final String sql = "select " + rm.schema()
+ " where journalEntry.transaction_id = ? and journalEntry.entity_id = ? and journalEntry.entity_type_enum = ?";
final String sqlCountRows = "SELECT FOUND_ROWS()";
Object[] data = {transactionId, entityId, entityType} ;
Object[] data = { transactionId, entityId, entityType };
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sql, data, rm);
} catch (final EmptyResultDataAccessException e) {
throw new JournalEntriesNotFoundException(entityId);
@@ -65,29 +65,34 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
private final GLJournalEntryMapper entryMapper = new GLJournalEntryMapper();
// if a limit is not added to the running balance select statements below and the resultset is more than 400,000,
// if a limit is not added to the running balance select statements below
// and the resultset is more than 400,000,
// the script will eat up all of the server memory
private final String selectRunningBalanceSqlLimit = "limit 0, 10000";
private final String officeRunningBalanceSql = "select je.office_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
+ "inner join (select max(id) as id from acc_gl_journal_entry where office_id=? and entry_date < ? group by account_id,entry_date) je2 "
+ "inner join (select max(entry_date) as date from acc_gl_journal_entry where office_id=? and entry_date < ? group by account_id) je3 "
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC " + selectRunningBalanceSqlLimit;
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC "
+ selectRunningBalanceSqlLimit;
private final String organizationRunningBalanceSql = "select je.organization_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
+ "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by account_id,entry_date) je2 "
+ "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by account_id) je3 "
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC " + selectRunningBalanceSqlLimit;
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC "
+ selectRunningBalanceSqlLimit;
private final String officesRunningBalanceSql = "select je.office_running_balance as runningBalance,je.account_id as accountId,je.office_id as officeId "
+ "from acc_gl_journal_entry je "
+ "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by office_id,account_id,entry_date) je2 "
+ "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by office_id,account_id) je3 "
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC " + selectRunningBalanceSqlLimit;
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC "
+ selectRunningBalanceSqlLimit;
@Autowired
public JournalEntryRunningBalanceUpdateServiceImpl(final RoutingDataSource dataSource, final OfficeRepositoryWrapper officeRepositoryWrapper,
final JournalEntryDataValidator dataValidator, final FromJsonHelper fromApiJsonHelper) {
public JournalEntryRunningBalanceUpdateServiceImpl(final RoutingDataSource dataSource,
final OfficeRepositoryWrapper officeRepositoryWrapper, final JournalEntryDataValidator dataValidator,
final FromJsonHelper fromApiJsonHelper) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.officeRepositoryWrapper = officeRepositoryWrapper;
this.dataValidator = dataValidator;
@@ -112,8 +117,8 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
this.dataValidator.validateForUpdateRunningbalance(command);
final Long officeId = this.fromApiJsonHelper.extractLongNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue(),
command.parsedJson());
CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder().withCommandId(command
.commandId());
CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder()
.withCommandId(command.commandId());
if (officeId == null) {
updateRunningBalance();
} else {
@@ -137,7 +142,16 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
List<Map<String, Object>> list = jdbcTemplate.queryForList(organizationRunningBalanceSql, entityDate, entityDate);
for (Map<String, Object> entries : list) {
Long accountId = Long.parseLong(entries.get("accountId").toString()); //Drizzle is returning Big Integer where as MySQL returns Long.
Long accountId = Long.parseLong(entries.get("accountId").toString()); // Drizzle
// is
// returning
// Big
// Integer
// where
// as
// MySQL
// returns
// Long.
if (!runningBalanceMap.containsKey(accountId)) {
runningBalanceMap.put(accountId, (BigDecimal) entries.get("runningBalance"));
}
@@ -166,8 +180,8 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
final Integer batchUpdateSize = 1000;
ArrayList<String> updateSql = new ArrayList<>();
int batchIndex = 0;
for (int index = 0 ; index < entryDatas.size() ; index++) {
JournalEntryData entryData = entryDatas.get(index) ;
for (int index = 0; index < entryDatas.size(); index++) {
JournalEntryData entryData = entryDatas.get(index);
Map<Long, BigDecimal> officeRunningBalanceMap = null;
if (officesRunningBalance.containsKey(entryData.getOfficeId())) {
officeRunningBalanceMap = officesRunningBalance.get(entryData.getOfficeId());
@@ -179,12 +193,12 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
String sql = "UPDATE acc_gl_journal_entry je SET je.is_running_balance_calculated=1, je.organization_running_balance="
+ runningBalance + ",je.office_running_balance=" + officeRunningBalance + " WHERE je.id=" + entryData.getId();
updateSql.add(sql) ;
batchIndex++ ;
if (batchIndex == batchUpdateSize || index == entryDatas.size()-1) {
updateSql.add(sql);
batchIndex++;
if (batchIndex == batchUpdateSize || index == entryDatas.size() - 1) {
// run a batch update of the 1000 update SQL statements
String[] batch = new String[updateSql.size()] ;
updateSql.toArray(batch) ;
String[] batch = new String[updateSql.size()];
updateSql.toArray(batch);
this.jdbcTemplate.batchUpdate(batch);
// reset counter and string array
batchIndex = 0;
@@ -205,8 +219,8 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
runningBalanceMap.put(accountId, (BigDecimal) entries.get("runningBalance"));
}
}
List<JournalEntryData> entryDatas = jdbcTemplate.query(entryMapper.officeRunningBalanceSchema(), entryMapper, new Object[] {
officeId, entityDate });
List<JournalEntryData> entryDatas = jdbcTemplate.query(entryMapper.officeRunningBalanceSchema(), entryMapper,
new Object[] { officeId, entityDate });
String[] updateSql = new String[entryDatas.size()];
int i = 0;
for (JournalEntryData entryData : entryDatas) {
@@ -290,8 +304,8 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
final int entryTypeId = JdbcSupport.getInteger(rs, "entryType");
final EnumOptionData entryType = AccountingEnumerations.journalEntryType(entryTypeId);
return new JournalEntryData(id, officeId, null, null, glAccountId, null, accountType, null, entryType, amount, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null);
return new JournalEntryData(id, officeId, null, null, glAccountId, null, accountType, null, entryType, amount, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null);
}
}
@@ -39,9 +39,9 @@ public interface JournalEntryWritePlatformService {
CommandProcessingResult defineOpeningBalance(JsonCommand command);
public String revertProvisioningJournalEntries(final Date reversalTransactionDate, final Long entityId, final Integer entityType) ;
public String revertProvisioningJournalEntries(final Date reversalTransactionDate, final Long entityId, final Integer entityType);
public String createProvisioningJournalEntries(ProvisioningEntry entry) ;
public String createProvisioningJournalEntries(ProvisioningEntry entry);
void createJournalEntriesForShares(Map<String, Object> accountingBridgeData);
@@ -168,8 +168,9 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
.orElseThrow(() -> new AccountingRuleNotFoundException(accountRuleId));
if (accountingRule.getAccountToCredit() == null) {
if (journalEntryCommand.getCredits() == null) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null); }
if (journalEntryCommand.getCredits() == null) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null);
}
if (journalEntryCommand.getDebits() != null) {
checkDebitOrCreditAccountsAreValid(accountingRule, journalEntryCommand.getCredits(),
journalEntryCommand.getDebits());
@@ -187,8 +188,9 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
}
if (accountingRule.getAccountToDebit() == null) {
if (journalEntryCommand.getDebits() == null) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null); }
if (journalEntryCommand.getDebits() == null) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null);
}
if (journalEntryCommand.getCredits() != null) {
checkDebitOrCreditAccountsAreValid(accountingRule, journalEntryCommand.getCredits(),
journalEntryCommand.getDebits());
@@ -227,11 +229,13 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
* If a glaccount is assigned for a rule the credits or debits array
* should have only one entry and it must be same as existing account
*/
if (creditOrDebits.length != 1) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null); }
if (creditOrDebits.length != 1) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null);
}
for (final SingleDebitOrCreditEntryCommand creditOrDebit : creditOrDebits) {
if (!glaccount.getId().equals(creditOrDebit.getGlAccountId())) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null); }
if (!glaccount.getId().equals(creditOrDebit.getGlAccountId())) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null);
}
}
}
@@ -272,27 +276,31 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
}
}
if (debits.length != validDebits.length) {
throw new JournalEntryRuntimeException("error.msg.glJournalEntry.invalid.debits","Invalid Debits");
throw new JournalEntryRuntimeException("error.msg.glJournalEntry.invalid.debits", "Invalid Debits");
}
}
}
private void checkDebitAndCreditAmounts(final SingleDebitOrCreditEntryCommand[] credits, final SingleDebitOrCreditEntryCommand[] debits) {
private void checkDebitAndCreditAmounts(final SingleDebitOrCreditEntryCommand[] credits,
final SingleDebitOrCreditEntryCommand[] debits) {
// sum of all debits must be = sum of all credits
BigDecimal creditsSum = BigDecimal.ZERO;
BigDecimal debitsSum = BigDecimal.ZERO;
for (final SingleDebitOrCreditEntryCommand creditEntryCommand : credits) {
if (creditEntryCommand.getAmount() == null || creditEntryCommand.getGlAccountId() == null) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null); }
if (creditEntryCommand.getAmount() == null || creditEntryCommand.getGlAccountId() == null) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null);
}
creditsSum = creditsSum.add(creditEntryCommand.getAmount());
}
for (final SingleDebitOrCreditEntryCommand debitEntryCommand : debits) {
if (debitEntryCommand.getAmount() == null || debitEntryCommand.getGlAccountId() == null) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null); }
if (debitEntryCommand.getAmount() == null || debitEntryCommand.getGlAccountId() == null) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY, null, null, null);
}
debitsSum = debitsSum.add(debitEntryCommand.getAmount());
}
if (creditsSum.compareTo(debitsSum) != 0) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.DEBIT_CREDIT_SUM_MISMATCH, null, null, null); }
if (creditsSum.compareTo(debitsSum) != 0) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.DEBIT_CREDIT_SUM_MISMATCH, null, null, null);
}
}
private void validateGLAccountForTransaction(final GLAccount creditOrDebitAccountHead) {
@@ -303,17 +311,18 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
if (creditOrDebitAccountHead.isDisabled()) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.GL_ACCOUNT_DISABLED, null,
creditOrDebitAccountHead.getName(), creditOrDebitAccountHead.getGlCode());
} else if (!creditOrDebitAccountHead.isManualEntriesAllowed()) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED, null, creditOrDebitAccountHead.getName(),
creditOrDebitAccountHead.getGlCode()); }
} else if (!creditOrDebitAccountHead.isManualEntriesAllowed()) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED, null,
creditOrDebitAccountHead.getName(), creditOrDebitAccountHead.getGlCode());
}
}
@Transactional
@Override
public CommandProcessingResult revertJournalEntry(final JsonCommand command) {
// is the transaction Id valid
final List<JournalEntry> journalEntries = this.glJournalEntryRepository.findUnReversedManualJournalEntriesByTransactionId(command
.getTransactionId());
final List<JournalEntry> journalEntries = this.glJournalEntryRepository
.findUnReversedManualJournalEntriesByTransactionId(command.getTransactionId());
String reversalComment = command.stringValueOfParameterNamed("comments");
if (journalEntries.size() <= 1) { throw new JournalEntriesNotFoundException(command.getTransactionId()); }
@@ -330,7 +339,8 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
validateCommentForReversal(reversalComment);
//Before reversal validate accounting closure is done for that branch or not.
// Before reversal validate accounting closure is done for that branch
// or not.
final Date journalEntriesTransactionDate = journalEntries.get(0).getTransactionDate();
final GLClosure latestGLClosureByBranch = this.glClosureRepository.getLatestGLClosureByBranch(officeId);
if (latestGLClosureByBranch != null) {
@@ -477,8 +487,10 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
baseDataValidator.reset().parameter("comments").value(reversalComment).notExceedingLengthOf(500);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
@Transactional
@@ -578,13 +590,16 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
final Date transactionDate = entryLocalDate.toDateTimeAtStartOfDay().toDate();
// shouldn't be in the future
final Date todaysDate = new Date();
if (transactionDate.after(todaysDate)) { throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.FUTURE_DATE,
transactionDate, null, null); }
if (transactionDate.after(todaysDate)) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.FUTURE_DATE, transactionDate, null, null);
}
// shouldn't be before an accounting closure
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(command.getOfficeId());
if (latestGLClosure != null) {
if (latestGLClosure.getClosingDate().after(transactionDate) || latestGLClosure.getClosingDate().equals(transactionDate)) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(), null, null); }
if (latestGLClosure.getClosingDate().after(transactionDate) || latestGLClosure.getClosingDate().equals(transactionDate)) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(),
null, null);
}
}
/*** check if credits and debits are valid **/
@@ -592,16 +607,16 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
final SingleDebitOrCreditEntryCommand[] debits = command.getDebits();
// atleast one debit or credit must be present
if (credits == null || credits.length <= 0 || debits == null || debits.length <= 0) { throw new JournalEntryInvalidException(
GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null); }
if (credits == null || credits.length <= 0 || debits == null || debits.length <= 0) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null);
}
checkDebitAndCreditAmounts(credits, debits);
}
private void saveAllDebitOrCreditEntries(final JournalEntryCommand command, final Office office, final PaymentDetail paymentDetail,
final String currencyCode, final Date transactionDate,
final SingleDebitOrCreditEntryCommand[] singleDebitOrCreditEntryCommands, final String transactionId,
final JournalEntryType type, final String referenceNumber) {
final String currencyCode, final Date transactionDate, final SingleDebitOrCreditEntryCommand[] singleDebitOrCreditEntryCommands,
final String transactionId, final JournalEntryType type, final String referenceNumber) {
final boolean manualEntry = true;
for (final SingleDebitOrCreditEntryCommand singleDebitOrCreditEntryCommand : singleDebitOrCreditEntryCommands) {
final GLAccount glAccount = this.glAccountRepository.findById(singleDebitOrCreditEntryCommand.getGlAccountId())
@@ -655,9 +670,11 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
final FinancialActivityAccount financialActivityAccountId = this.financialActivityAccountRepositoryWrapper
.findByFinancialActivityTypeWithNotFoundDetection(300);
final Long contraId = financialActivityAccountId.getGlAccount().getId();
if (contraId == null) { throw new GeneralPlatformDomainRuleException(
"error.msg.financial.activity.mapping.opening.balance.contra.account.cannot.be.null",
"office-opening-balances-contra-account value can not be null", "office-opening-balances-contra-account"); }
if (contraId == null) {
throw new GeneralPlatformDomainRuleException(
"error.msg.financial.activity.mapping.opening.balance.contra.account.cannot.be.null",
"office-opening-balances-contra-account value can not be null", "office-opening-balances-contra-account");
}
validateJournalEntriesArePostedBefore(contraId);
@@ -697,16 +714,17 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
}
private void saveAllDebitOrCreditOpeningBalanceEntries(final JournalEntryCommand command, final Office office,
final String currencyCode, final Date transactionDate,
final SingleDebitOrCreditEntryCommand[] singleDebitOrCreditEntryCommands, final String transactionId,
final JournalEntryType type, final Long contraAccountId) {
final String currencyCode, final Date transactionDate, final SingleDebitOrCreditEntryCommand[] singleDebitOrCreditEntryCommands,
final String transactionId, final JournalEntryType type, final Long contraAccountId) {
final boolean manualEntry = true;
final GLAccount contraAccount = this.glAccountRepository.findById(contraAccountId)
.orElseThrow(() -> new GLAccountNotFoundException(contraAccountId));
if (!GLAccountType.fromInt(contraAccount.getType()).isEquityType()) { throw new GeneralPlatformDomainRuleException(
"error.msg.configuration.opening.balance.contra.account.value.is.invalid.account.type",
"Global configuration 'office-opening-balances-contra-account' value is not an equity type account", contraAccountId); }
if (!GLAccountType.fromInt(contraAccount.getType()).isEquityType()) {
throw new GeneralPlatformDomainRuleException(
"error.msg.configuration.opening.balance.contra.account.value.is.invalid.account.type",
"Global configuration 'office-opening-balances-contra-account' value is not an equity type account", contraAccountId);
}
validateGLAccountForTransaction(contraAccount);
final JournalEntryType contraType = getContraType(type);
String comments = command.getComments();
@@ -750,9 +768,10 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
private void validateJournalEntriesArePostedBefore(final Long contraId) {
final List<String> transactionIds = this.glJournalEntryRepository.findNonContraTansactionIds(contraId);
if (!CollectionUtils.isEmpty(transactionIds)) { throw new GeneralPlatformDomainRuleException(
"error.msg.journalentry.defining.openingbalance.not.allowed",
"Defining Opening balances not allowed after journal entries posted", transactionIds); }
if (!CollectionUtils.isEmpty(transactionIds)) {
throw new GeneralPlatformDomainRuleException("error.msg.journalentry.defining.openingbalance.not.allowed",
"Defining Opening balances not allowed after journal entries posted", transactionIds);
}
}
@Override
@@ -773,9 +792,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
@Override
public boolean equals(Object obj) {
if (!(obj instanceof OfficeCurrencyKey)) {
return false;
}
if (!(obj instanceof OfficeCurrencyKey)) { return false; }
OfficeCurrencyKey copy = (OfficeCurrencyKey) obj;
return Objects.equals(this.office.getId(), copy.office.getId()) && this.currency.equals(copy.currency);
}
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.Map;
public enum PortfolioProductType {
LOAN(1, "productType.loan"), SAVING(2, "productType.saving"), CLIENT(5, "productType.client"), PROVISIONING(3,
"productType.provisioning"), SHARES(4, "productType.shares");

Some files were not shown because too many files have changed in this diff Show More