FINERACT-2268: Fix GL account deletion logic
This commit is contained in:
+1
-1
@@ -213,7 +213,7 @@ public class GLAccountsApiResource {
|
|||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
@Operation(tags = { "General Ledger Account" }, summary = "Delete a GL Account", description = "Deletes a GL Account")
|
@Operation(tags = { "General Ledger Account" }, summary = "Delete a GL Account", description = "Deletes a GL Account")
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.DeleteGLAccountsRequest.class)))
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GLAccountsApiResourceSwagger.DeleteGLAccountsResponse.class)))
|
||||||
public CommandProcessingResult deleteGLAccount(
|
public CommandProcessingResult deleteGLAccount(
|
||||||
@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId) {
|
@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId) {
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
|
||||||
|
|||||||
+6
-6
@@ -203,23 +203,23 @@ final class GLAccountsApiResourceSwagger {
|
|||||||
public PutGLAccountsResponsechangesSwagger changes;
|
public PutGLAccountsResponsechangesSwagger changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "DeleteGLAccountsRequest")
|
@Schema(description = "DeleteGLAccountsResponse")
|
||||||
public static final class DeleteGLAccountsRequest {
|
public static final class DeleteGLAccountsResponse {
|
||||||
|
|
||||||
private DeleteGLAccountsRequest() {
|
private DeleteGLAccountsResponse() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class DeleteGLAccountsRequestchangesSwagger {
|
private static final class DeleteGLAccountsResponseChangesSwagger {
|
||||||
|
|
||||||
private DeleteGLAccountsRequestchangesSwagger() {}
|
private DeleteGLAccountsResponseChangesSwagger() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
public Long resourceId;
|
public Long resourceId;
|
||||||
|
|
||||||
private DeleteGLAccountsRequestchangesSwagger changes;
|
private DeleteGLAccountsResponseChangesSwagger changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -28,13 +28,15 @@ public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleE
|
|||||||
/*** Enum of reasons for invalid delete **/
|
/*** Enum of reasons for invalid delete **/
|
||||||
public enum GlAccountInvalidDeleteReason {
|
public enum GlAccountInvalidDeleteReason {
|
||||||
|
|
||||||
TRANSACTIONS_LOGGED, HAS_CHILDREN;
|
TRANSACTIONS_LOGGED, HAS_CHILDREN, PRODUCT_MAPPING;
|
||||||
|
|
||||||
public String errorMessage() {
|
public String errorMessage() {
|
||||||
if (name().equalsIgnoreCase("TRANSACTIONS_LOGGED")) {
|
if (name().equalsIgnoreCase("TRANSACTIONS_LOGGED")) {
|
||||||
return "This GL Account cannot be deleted as it has transactions logged against it";
|
return "This GL Account cannot be deleted as it has transactions logged against it";
|
||||||
} else if (name().equalsIgnoreCase("HAS_CHILDREN")) {
|
} else if (name().equalsIgnoreCase("HAS_CHILDREN")) {
|
||||||
return "Cannot delete this Header GL Account without first deleting or reassigning its children";
|
return "Cannot delete this Header GL Account without first deleting or reassigning its children";
|
||||||
|
} else if (name().equalsIgnoreCase("PRODUCT_MAPPING")) {
|
||||||
|
return "Cannot delete this GL Account as it is mapped to a Product";
|
||||||
}
|
}
|
||||||
return name();
|
return name();
|
||||||
}
|
}
|
||||||
@@ -44,6 +46,8 @@ public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleE
|
|||||||
return "error.msg.glaccount.glcode.invalid.delete.transactions.logged";
|
return "error.msg.glaccount.glcode.invalid.delete.transactions.logged";
|
||||||
} else if (name().equalsIgnoreCase("HAS_CHILDREN")) {
|
} else if (name().equalsIgnoreCase("HAS_CHILDREN")) {
|
||||||
return "error.msg.glaccount.glcode.invalid.delete.has.children";
|
return "error.msg.glaccount.glcode.invalid.delete.has.children";
|
||||||
|
} else if (name().equalsIgnoreCase("PRODUCT_MAPPING")) {
|
||||||
|
return "error.msg.glaccount.glcode.invalid.delete.product.mapping";
|
||||||
}
|
}
|
||||||
return name();
|
return name();
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-3
@@ -37,6 +37,7 @@ import org.apache.fineract.accounting.glaccount.exception.GLAccountNotFoundExcep
|
|||||||
import org.apache.fineract.accounting.glaccount.exception.InvalidParentGLAccountHeadException;
|
import org.apache.fineract.accounting.glaccount.exception.InvalidParentGLAccountHeadException;
|
||||||
import org.apache.fineract.accounting.glaccount.serialization.GLAccountCommandFromApiJsonDeserializer;
|
import org.apache.fineract.accounting.glaccount.serialization.GLAccountCommandFromApiJsonDeserializer;
|
||||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
|
import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
|
||||||
|
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||||
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
@@ -61,6 +62,7 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
|||||||
|
|
||||||
private final GLAccountRepository glAccountRepository;
|
private final GLAccountRepository glAccountRepository;
|
||||||
private final JournalEntryRepository glJournalEntryRepository;
|
private final JournalEntryRepository glJournalEntryRepository;
|
||||||
|
private final ProductToGLAccountMappingRepository productToGLAccountMappingRepository;
|
||||||
private final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
private final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||||
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
|
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
@@ -147,7 +149,7 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
|||||||
if (changesOnly.containsKey(GLAccountJsonInputParams.USAGE.getValue())) {
|
if (changesOnly.containsKey(GLAccountJsonInputParams.USAGE.getValue())) {
|
||||||
if (glAccount.isHeaderAccount()) {
|
if (glAccount.isHeaderAccount()) {
|
||||||
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
||||||
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
|
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccount").get("id"), glAccountId));
|
||||||
if (journalEntriesForAccountExist) {
|
if (journalEntriesForAccountExist) {
|
||||||
throw new GLAccountInvalidUpdateException(GlAccountInvalidUpdateReason.TRANSANCTIONS_LOGGED, glAccountId);
|
throw new GLAccountInvalidUpdateException(GlAccountInvalidUpdateReason.TRANSANCTIONS_LOGGED, glAccountId);
|
||||||
}
|
}
|
||||||
@@ -186,16 +188,22 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
|||||||
.orElseThrow(() -> new GLAccountNotFoundException(glAccountId));
|
.orElseThrow(() -> new GLAccountNotFoundException(glAccountId));
|
||||||
|
|
||||||
// validate this isn't a header account that has children
|
// validate this isn't a header account that has children
|
||||||
if (glAccount.isHeaderAccount() && glAccount.getChildren().size() > 0) {
|
if (glAccount.isHeaderAccount() && !glAccount.getChildren().isEmpty()) {
|
||||||
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.HAS_CHILDREN, glAccountId);
|
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.HAS_CHILDREN, glAccountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// does this account have transactions logged against it
|
// does this account have transactions logged against it
|
||||||
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
||||||
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
|
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccount").get("id"), glAccountId));
|
||||||
if (journalEntriesForAccountExist) {
|
if (journalEntriesForAccountExist) {
|
||||||
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.TRANSACTIONS_LOGGED, glAccountId);
|
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.TRANSACTIONS_LOGGED, glAccountId);
|
||||||
}
|
}
|
||||||
|
// does this account mapped to product
|
||||||
|
final boolean accountMappingForAccountExists = this.productToGLAccountMappingRepository
|
||||||
|
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccount").get("id"), glAccountId));
|
||||||
|
if (accountMappingForAccountExists) {
|
||||||
|
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.PRODUCT_MAPPING, glAccountId);
|
||||||
|
}
|
||||||
this.glAccountRepository.delete(glAccount);
|
this.glAccountRepository.delete(glAccount);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder().withEntityId(glAccountId).build();
|
return new CommandProcessingResultBuilder().withEntityId(glAccountId).build();
|
||||||
|
|||||||
+2
@@ -52,6 +52,8 @@ public class JournalEntryCommand {
|
|||||||
|
|
||||||
private final SingleDebitOrCreditEntryCommand[] credits;
|
private final SingleDebitOrCreditEntryCommand[] credits;
|
||||||
private final SingleDebitOrCreditEntryCommand[] debits;
|
private final SingleDebitOrCreditEntryCommand[] debits;
|
||||||
|
private final String locale;
|
||||||
|
private final String dateFormat;
|
||||||
|
|
||||||
public void validateForCreate() {
|
public void validateForCreate() {
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -73,7 +73,7 @@ public final class JournalEntryCommandFromApiJsonDeserializer extends AbstractFr
|
|||||||
element);
|
element);
|
||||||
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||||
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
|
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
|
||||||
|
final String localeStr = locale.getLanguage() + "_" + locale.getCountry() + '_' + locale.getVariant();
|
||||||
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(JournalEntryJsonInputParams.AMOUNT.getValue(), element,
|
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(JournalEntryJsonInputParams.AMOUNT.getValue(), element,
|
||||||
locale);
|
locale);
|
||||||
final Long paymentTypeId = this.fromApiJsonHelper.extractLongNamed(JournalEntryJsonInputParams.PAYMENT_TYPE_ID.getValue(), element);
|
final Long paymentTypeId = this.fromApiJsonHelper.extractLongNamed(JournalEntryJsonInputParams.PAYMENT_TYPE_ID.getValue(), element);
|
||||||
@@ -97,8 +97,9 @@ public final class JournalEntryCommandFromApiJsonDeserializer extends AbstractFr
|
|||||||
debits = populateCreditsOrDebitsArray(topLevelJsonElement, locale, JournalEntryJsonInputParams.DEBITS.getValue());
|
debits = populateCreditsOrDebitsArray(topLevelJsonElement, locale, JournalEntryJsonInputParams.DEBITS.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String dateFormat = this.fromApiJsonHelper.extractStringNamed(JournalEntryJsonInputParams.DATE_FORMAT.getValue(), element);
|
||||||
return new JournalEntryCommand(officeId, currencyCode, transactionDate, comments, referenceNumber, accountingRuleId, amount,
|
return new JournalEntryCommand(officeId, currencyCode, transactionDate, comments, referenceNumber, accountingRuleId, amount,
|
||||||
paymentTypeId, accountNumber, checkNumber, receiptNumber, bankNumber, routingCode, credits, debits);
|
paymentTypeId, accountNumber, checkNumber, receiptNumber, bankNumber, routingCode, credits, debits, localeStr, dateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -193,4 +193,5 @@
|
|||||||
<include file="parts/0172_create_loan_capitalized_income_balance.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0172_create_loan_capitalized_income_balance.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0173_user_change_pwd.xml" relativeToChangelogFile="true" />
|
<include file="parts/0173_user_change_pwd.xml" relativeToChangelogFile="true" />
|
||||||
<include file="parts/0174_loan_product_add_capitalized_income_type.xml" relativeToChangelogFile="true" />
|
<include file="parts/0174_loan_product_add_capitalized_income_type.xml" relativeToChangelogFile="true" />
|
||||||
|
<include file="parts/0175_add_fk_acc_product_mapping.xml" relativeToChangelogFile="true" />
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
|
||||||
|
<changeSet author="fineract" id="1">
|
||||||
|
<addForeignKeyConstraint baseColumnNames="gl_account_id" baseTableName="acc_product_mapping"
|
||||||
|
constraintName="FK_acc_product_mapping_gl_account_id" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||||
|
referencedTableName="acc_gl_account" validate="true"/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+132
@@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.integrationtests.accounting;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||||
|
import org.apache.fineract.client.models.GetGLAccountsResponse;
|
||||||
|
import org.apache.fineract.client.models.JournalEntryCommand;
|
||||||
|
import org.apache.fineract.client.models.PostGLAccountsRequest;
|
||||||
|
import org.apache.fineract.client.models.PostGLAccountsResponse;
|
||||||
|
import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||||
|
import org.apache.fineract.client.models.PutGLAccountsRequest;
|
||||||
|
import org.apache.fineract.client.models.SingleDebitOrCreditEntryCommand;
|
||||||
|
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||||
|
import org.apache.fineract.integrationtests.BaseLoanIntegrationTest;
|
||||||
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
|
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class GLAccountIntegrationTest extends BaseLoanIntegrationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createUpdateDeleteGLAccountTest() {
|
||||||
|
// CREATE
|
||||||
|
String uniqueString = Utils.uniqueRandomStringGenerator("UNIQUE_FEE_INCOME" + Calendar.getInstance().getTimeInMillis(), 5);
|
||||||
|
final PostGLAccountsResponse newAccount = createGLAccount(uniqueString);
|
||||||
|
GetGLAccountsResponse accountDetails = AccountHelper.getGLAccount(newAccount.getResourceId());
|
||||||
|
Assertions.assertEquals(uniqueString, accountDetails.getGlCode());
|
||||||
|
Assertions.assertEquals(uniqueString, accountDetails.getName());
|
||||||
|
Assertions.assertEquals(true, accountDetails.getManualEntriesAllowed());
|
||||||
|
Assertions.assertEquals((long) GLAccountType.INCOME.getValue(), accountDetails.getType().getId());
|
||||||
|
Assertions.assertEquals(1L, accountDetails.getUsage().getId());
|
||||||
|
Assertions.assertEquals(uniqueString, accountDetails.getDescription());
|
||||||
|
// UPDATE
|
||||||
|
AccountHelper.updateGLAccount(newAccount.getResourceId(), new PutGLAccountsRequest().description("newDescription").name("newName")
|
||||||
|
.glCode("newGLCode").type(GLAccountType.ASSET.getValue()).manualEntriesAllowed(false).usage(2));
|
||||||
|
accountDetails = AccountHelper.getGLAccount(newAccount.getResourceId());
|
||||||
|
Assertions.assertEquals("newDescription", accountDetails.getDescription());
|
||||||
|
Assertions.assertEquals("newName", accountDetails.getName());
|
||||||
|
Assertions.assertEquals("newGLCode", accountDetails.getGlCode());
|
||||||
|
Assertions.assertEquals((long) GLAccountType.ASSET.getValue(), accountDetails.getType().getId());
|
||||||
|
Assertions.assertEquals(2L, accountDetails.getUsage().getId());
|
||||||
|
// DELETE
|
||||||
|
AccountHelper.deleteGLAccount(newAccount.getResourceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteGLAccountWhileThereAreChildren() {
|
||||||
|
String uniqueNameForParent = Utils.uniqueRandomStringGenerator("UNIQUE_FEE_INCOME" + Calendar.getInstance().getTimeInMillis(), 5);
|
||||||
|
final PostGLAccountsResponse newParentAccount = AccountHelper
|
||||||
|
.createGLAccount(new PostGLAccountsRequest().type(GLAccountType.INCOME.getValue()).glCode(uniqueNameForParent)
|
||||||
|
.manualEntriesAllowed(true).usage(2).description(uniqueNameForParent).name(uniqueNameForParent));
|
||||||
|
String uniqueNameForChild = Utils.uniqueRandomStringGenerator("UNIQUE_FEE_INCOME" + Calendar.getInstance().getTimeInMillis(), 5);
|
||||||
|
final PostGLAccountsResponse newChildAccount = AccountHelper.createGLAccount(
|
||||||
|
new PostGLAccountsRequest().type(GLAccountType.INCOME.getValue()).glCode(uniqueNameForChild).manualEntriesAllowed(true)
|
||||||
|
.usage(1).parentId(newParentAccount.getResourceId()).description(uniqueNameForChild).name(uniqueNameForChild));
|
||||||
|
// DELETE
|
||||||
|
CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
|
||||||
|
() -> AccountHelper.deleteGLAccount(newParentAccount.getResourceId()));
|
||||||
|
assertEquals(403, exception.getResponse().code());
|
||||||
|
assertTrue(exception.getMessage().contains("error.msg.glaccount.glcode.invalid.delete.has.children"));
|
||||||
|
AccountHelper.deleteGLAccount(newChildAccount.getResourceId());
|
||||||
|
AccountHelper.deleteGLAccount(newParentAccount.getResourceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteGLAccountWhileMappedToProduct() {
|
||||||
|
String uniqueString = Utils.uniqueRandomStringGenerator("UNIQUE_FEE_INCOME" + Calendar.getInstance().getTimeInMillis(), 5);
|
||||||
|
final PostGLAccountsResponse newAccount = createGLAccount(uniqueString);
|
||||||
|
loanProductHelper.createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
|
||||||
|
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
|
||||||
|
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
|
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
|
||||||
|
.incomeFromCapitalizationAccountId(newAccount.getResourceId())
|
||||||
|
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE));
|
||||||
|
|
||||||
|
// DELETE
|
||||||
|
CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
|
||||||
|
() -> AccountHelper.deleteGLAccount(newAccount.getResourceId()));
|
||||||
|
assertEquals(403, exception.getResponse().code());
|
||||||
|
assertTrue(exception.getMessage().contains("error.msg.glaccount.glcode.invalid.delete.product.mapping"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteGLAccountWhileThereIsJournalEntry() {
|
||||||
|
runAt("01 January 2024", () -> {
|
||||||
|
String uniqueString = Utils.uniqueRandomStringGenerator("UNIQUE_FEE_INCOME" + Calendar.getInstance().getTimeInMillis(), 5);
|
||||||
|
final PostGLAccountsResponse newAccount = createGLAccount(uniqueString);
|
||||||
|
uniqueString = Utils.uniqueRandomStringGenerator("UNIQUE_FEE_INCOME" + Calendar.getInstance().getTimeInMillis(), 5);
|
||||||
|
final PostGLAccountsResponse newAccount2 = createGLAccount(uniqueString);
|
||||||
|
JournalEntryHelper.createJournalEntry("", new JournalEntryCommand().amount(BigDecimal.TEN).officeId(1L).currencyCode("USD")
|
||||||
|
.locale("en").dateFormat("uuuu-MM-dd").transactionDate(LocalDate.of(2024, 1, 1))
|
||||||
|
.addCreditsItem(new SingleDebitOrCreditEntryCommand().glAccountId(newAccount.getResourceId()).amount(BigDecimal.TEN))
|
||||||
|
.addDebitsItem(new SingleDebitOrCreditEntryCommand().glAccountId(newAccount2.getResourceId()).amount(BigDecimal.TEN)));
|
||||||
|
// DELETE
|
||||||
|
CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
|
||||||
|
() -> AccountHelper.deleteGLAccount(newAccount.getResourceId()));
|
||||||
|
assertEquals(403, exception.getResponse().code());
|
||||||
|
assertTrue(exception.getMessage().contains("error.msg.glaccount.glcode.invalid.delete.transactions.logged"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private PostGLAccountsResponse createGLAccount(String uniqueString) {
|
||||||
|
return AccountHelper.createGLAccount(new PostGLAccountsRequest().type(GLAccountType.INCOME.getValue()).glCode(uniqueString)
|
||||||
|
.manualEntriesAllowed(true).usage(1).description(uniqueString).name(uniqueString));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -107,7 +107,7 @@ public class ClientHelper {
|
|||||||
return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, requestBody, "clientId");
|
return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, requestBody, "clientId");
|
||||||
}
|
}
|
||||||
|
|
||||||
public PostClientsResponse createClient(final PostClientsRequest request) {
|
public static PostClientsResponse createClient(final PostClientsRequest request) {
|
||||||
return Calls.ok(FineractClientHelper.getFineractClient().clients.create6(request));
|
return Calls.ok(FineractClientHelper.getFineractClient().clients.create6(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-1
@@ -22,8 +22,12 @@ import io.restassured.specification.RequestSpecification;
|
|||||||
import io.restassured.specification.ResponseSpecification;
|
import io.restassured.specification.ResponseSpecification;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import org.apache.fineract.client.models.DeleteGLAccountsResponse;
|
||||||
|
import org.apache.fineract.client.models.GetGLAccountsResponse;
|
||||||
import org.apache.fineract.client.models.PostGLAccountsRequest;
|
import org.apache.fineract.client.models.PostGLAccountsRequest;
|
||||||
import org.apache.fineract.client.models.PostGLAccountsResponse;
|
import org.apache.fineract.client.models.PostGLAccountsResponse;
|
||||||
|
import org.apache.fineract.client.models.PutGLAccountsRequest;
|
||||||
|
import org.apache.fineract.client.models.PutGLAccountsResponse;
|
||||||
import org.apache.fineract.client.util.Calls;
|
import org.apache.fineract.client.util.Calls;
|
||||||
import org.apache.fineract.integrationtests.common.FineractClientHelper;
|
import org.apache.fineract.integrationtests.common.FineractClientHelper;
|
||||||
import org.apache.fineract.integrationtests.common.Utils;
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
@@ -142,8 +146,19 @@ public class AccountHelper {
|
|||||||
return accountRunningBalance;
|
return accountRunningBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PostGLAccountsResponse createGLAccount(final PostGLAccountsRequest request) {
|
public static PostGLAccountsResponse createGLAccount(final PostGLAccountsRequest request) {
|
||||||
return Calls.ok(FineractClientHelper.getFineractClient().glAccounts.createGLAccount1(request));
|
return Calls.ok(FineractClientHelper.getFineractClient().glAccounts.createGLAccount1(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DeleteGLAccountsResponse deleteGLAccount(final Long requestId) {
|
||||||
|
return Calls.ok(FineractClientHelper.getFineractClient().glAccounts.deleteGLAccount1(requestId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PutGLAccountsResponse updateGLAccount(final Long requestId, final PutGLAccountsRequest request) {
|
||||||
|
return Calls.ok(FineractClientHelper.getFineractClient().glAccounts.updateGLAccount1(requestId, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GetGLAccountsResponse getGLAccount(final Long glAccountId) {
|
||||||
|
return Calls.ok(FineractClientHelper.getFineractClient().glAccounts.retreiveAccount(glAccountId, false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -27,7 +27,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
|
import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
|
||||||
|
import org.apache.fineract.client.models.JournalEntryCommand;
|
||||||
|
import org.apache.fineract.client.models.PostJournalEntriesResponse;
|
||||||
|
import org.apache.fineract.client.util.Calls;
|
||||||
import org.apache.fineract.client.util.JSON;
|
import org.apache.fineract.client.util.JSON;
|
||||||
|
import org.apache.fineract.integrationtests.common.FineractClientHelper;
|
||||||
import org.apache.fineract.integrationtests.common.Utils;
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
|
||||||
@@ -185,4 +189,7 @@ public class JournalEntryHelper {
|
|||||||
return GSON.fromJson(response, GetJournalEntriesTransactionIdResponse.class);
|
return GSON.fromJson(response, GetJournalEntriesTransactionIdResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PostJournalEntriesResponse createJournalEntry(String command, JournalEntryCommand request) {
|
||||||
|
return Calls.ok(FineractClientHelper.getFineractClient().journalEntries.createGLJournalEntry(command, request));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user