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 })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@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(
|
||||
@PathParam("glAccountId") @Parameter(description = "glAccountId") final Long glAccountId) {
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteGLAccount(glAccountId).build();
|
||||
|
||||
+6
-6
@@ -203,23 +203,23 @@ final class GLAccountsApiResourceSwagger {
|
||||
public PutGLAccountsResponsechangesSwagger changes;
|
||||
}
|
||||
|
||||
@Schema(description = "DeleteGLAccountsRequest")
|
||||
public static final class DeleteGLAccountsRequest {
|
||||
@Schema(description = "DeleteGLAccountsResponse")
|
||||
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")
|
||||
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 **/
|
||||
public enum GlAccountInvalidDeleteReason {
|
||||
|
||||
TRANSACTIONS_LOGGED, HAS_CHILDREN;
|
||||
TRANSACTIONS_LOGGED, HAS_CHILDREN, PRODUCT_MAPPING;
|
||||
|
||||
public String errorMessage() {
|
||||
if (name().equalsIgnoreCase("TRANSACTIONS_LOGGED")) {
|
||||
return "This GL Account cannot be deleted as it has transactions logged against it";
|
||||
} else if (name().equalsIgnoreCase("HAS_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();
|
||||
}
|
||||
@@ -44,6 +46,8 @@ public class GLAccountInvalidDeleteException extends AbstractPlatformDomainRuleE
|
||||
return "error.msg.glaccount.glcode.invalid.delete.transactions.logged";
|
||||
} else if (name().equalsIgnoreCase("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();
|
||||
}
|
||||
|
||||
+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.serialization.GLAccountCommandFromApiJsonDeserializer;
|
||||
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.CodeValueRepositoryWrapper;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
@@ -61,6 +62,7 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
||||
|
||||
private final GLAccountRepository glAccountRepository;
|
||||
private final JournalEntryRepository glJournalEntryRepository;
|
||||
private final ProductToGLAccountMappingRepository productToGLAccountMappingRepository;
|
||||
private final GLAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
private final CodeValueRepositoryWrapper codeValueRepositoryWrapper;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
@@ -147,7 +149,7 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
||||
if (changesOnly.containsKey(GLAccountJsonInputParams.USAGE.getValue())) {
|
||||
if (glAccount.isHeaderAccount()) {
|
||||
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) {
|
||||
throw new GLAccountInvalidUpdateException(GlAccountInvalidUpdateReason.TRANSANCTIONS_LOGGED, glAccountId);
|
||||
}
|
||||
@@ -186,16 +188,22 @@ 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) {
|
||||
if (glAccount.isHeaderAccount() && !glAccount.getChildren().isEmpty()) {
|
||||
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.HAS_CHILDREN, glAccountId);
|
||||
}
|
||||
|
||||
// does this account have transactions logged against it
|
||||
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) {
|
||||
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);
|
||||
|
||||
return new CommandProcessingResultBuilder().withEntityId(glAccountId).build();
|
||||
|
||||
+2
@@ -52,6 +52,8 @@ public class JournalEntryCommand {
|
||||
|
||||
private final SingleDebitOrCreditEntryCommand[] credits;
|
||||
private final SingleDebitOrCreditEntryCommand[] debits;
|
||||
private final String locale;
|
||||
private final String dateFormat;
|
||||
|
||||
public void validateForCreate() {
|
||||
|
||||
|
||||
+3
-2
@@ -73,7 +73,7 @@ public final class JournalEntryCommandFromApiJsonDeserializer extends AbstractFr
|
||||
element);
|
||||
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||
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,
|
||||
locale);
|
||||
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());
|
||||
}
|
||||
}
|
||||
String dateFormat = this.fromApiJsonHelper.extractStringNamed(JournalEntryJsonInputParams.DATE_FORMAT.getValue(), element);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user