FINERACT-1704: Code cleanup - Journal entries

This commit is contained in:
Adam Saghy
2022-08-23 16:25:19 +02:00
committed by Arnold Gálovics
parent 0bbd825a46
commit 5919882a65
16 changed files with 153 additions and 184 deletions
@@ -167,7 +167,7 @@ public class JournalEntriesApiResource {
+ "journalentries/1?transactionDetails=true")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = JournalEntryData.class))) })
public String retreiveJournalEntryById(
public String retrieveJournalEntryById(
@PathParam("journalEntryId") @Parameter(description = "journalEntryId") final Long journalEntryId,
@Context final UriInfo uriInfo,
@QueryParam("runningBalance") @Parameter(description = "runningBalance") final boolean runningBalance,
@@ -197,7 +197,7 @@ public class JournalEntriesApiResource {
public String createGLJournalEntry(@Parameter(hidden = true) final String jsonRequestBody,
@QueryParam("command") @Parameter(description = "command") final String commandParam) {
CommandProcessingResult result = null;
CommandProcessingResult result;
if (is(commandParam, "updateRunningBalance")) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateRunningBalanceForJournalEntry()
.withJson(jsonRequestBody).build();
@@ -225,7 +225,7 @@ public class JournalEntriesApiResource {
public String createReversalJournalEntry(@Parameter(hidden = true) final String jsonRequestBody,
@PathParam("transactionId") @Parameter(description = "transactionId") final String transactionId,
@QueryParam("command") @Parameter(description = "command") final String commandParam) {
CommandProcessingResult result = null;
CommandProcessingResult result;
if (is(commandParam, "reverse")) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().reverseJournalEntry(transactionId).withJson(jsonRequestBody)
.build();
@@ -52,7 +52,7 @@ public enum JournalEntryJsonInputParams {
@Override
public String toString() {
return name().toString().replaceAll("_", " ");
return name().replaceAll("_", " ");
}
public String getValue() {
@@ -21,7 +21,7 @@ package org.apache.fineract.accounting.journalentry.data;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -41,14 +41,14 @@ public class JournalEntryDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private static final Set<String> RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(JournalEntryJsonInputParams.OFFICE_ID.getValue()));
Collections.singletonList(JournalEntryJsonInputParams.OFFICE_ID.getValue()));
@Autowired
public JournalEntryDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForUpdateRunningbalance(final JsonCommand command) {
public void validateForUpdateRunningBalance(final JsonCommand command) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, command.json(), RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
@@ -44,8 +44,8 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
@JoinColumn(name = "office_id", nullable = false)
private Office office;
@ManyToOne(optional = true)
@JoinColumn(name = "payment_details_id", nullable = true)
@ManyToOne()
@JoinColumn(name = "payment_details_id")
private PaymentDetail paymentDetail;
@ManyToOne
@@ -74,7 +74,7 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
@JoinColumn(name = "client_transaction_id", nullable = false)
private ClientTransaction clientTransaction;
@Column(name = "share_transaction_id", nullable = true)
@Column(name = "share_transaction_id")
private Long shareTransactionId;
@Column(name = "reversed", nullable = false)
@@ -31,10 +31,10 @@ public interface JournalEntryRepository
List<JournalEntry> findUnReversedManualJournalEntriesByTransactionId(@Param("transactionId") String transactionId);
@Query("select DISTINCT j.transactionId from JournalEntry j where j.transactionId not in (select DISTINCT je.transactionId from JournalEntry je where je.glAccount.id = :contraId)")
List<String> findNonContraTansactionIds(@Param("contraId") Long contraId);
List<String> findNonContraTransactionIds(@Param("contraId") Long contraId);
@Query("select DISTINCT j.transactionId from JournalEntry j where j.office.id = :officeId and j.glAccount.id = :contraId and j.reversed=false and j.transactionId not in (select DISTINCT je.reversalJournalEntry.transactionId from JournalEntry je where je.reversed=true)")
List<String> findNonReversedContraTansactionIds(@Param("contraId") Long contraId, @Param("officeId") Long officeId);
List<String> findNonReversedContraTransactionIds(@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);
@@ -32,9 +32,8 @@ public class JournalEntryRepositoryImpl implements JournalEntryRepositoryCustom
@Override
@SuppressWarnings("unchecked")
public List<JournalEntry> findFirstJournalEntryForAccount(final long glAccountId) {
final List<JournalEntry> journalEntries = this.entityManager
return (List<JournalEntry>) this.entityManager
.createQuery("SELECT journalEntry FROM JournalEntry journalEntry where journalEntry.glAccount.id= :glAccountId")
.setParameter("glAccountId", glAccountId).setFirstResult(0).setMaxResults(1).getResultList();
return journalEntries;
}
}
@@ -50,13 +50,12 @@ public enum JournalEntryType {
}
public static JournalEntryType fromInt(final int i) {
final JournalEntryType type = intToEnumMap.get(Integer.valueOf(i));
return type;
return intToEnumMap.get(i);
}
@Override
public String toString() {
return name().toString();
return name();
}
public boolean isDebitType() {
@@ -32,47 +32,47 @@ public class JournalEntryInvalidException extends AbstractPlatformDomainRuleExce
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() {
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
if (name().equalsIgnoreCase("FUTURE_DATE")) {
return "The journal entry cannot be made for a future date";
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
} else if (name().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
return "Journal entry cannot be made prior to last account closing date for the branch";
} else if (name().toString().equalsIgnoreCase("NO_DEBITS_OR_CREDITS")) {
return "Journal Entry must have atleast one Debit and one Credit";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH_WITH_AMOUNT")) {
} else if (name().equalsIgnoreCase("NO_DEBITS_OR_CREDITS")) {
return "Journal Entry must have at least one Debit and one Credit";
} else if (name().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH_WITH_AMOUNT")) {
return "Sum of All Debits OR Credits must equal the Amount for a Journal Entry";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH")) {
} else if (name().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH")) {
return "Sum of All Debits must equal the sum of all Credits for a Journal Entry";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY")) {
} else if (name().equalsIgnoreCase("DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY")) {
return "Both account and amount must be specified for all Debits and Credits";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_DISABLED")) {
} else if (name().equalsIgnoreCase("GL_ACCOUNT_DISABLED")) {
return "Target account has been disabled";
} else if (name().toString().equalsIgnoreCase("INVALID_DEBIT_OR_CREDIT_ACCOUNTS")) {
} else if (name().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().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) {
return "Target account does not allow manual adjustments";
}
return name().toString();
return name();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
if (name().equalsIgnoreCase("FUTURE_DATE")) {
return "error.msg.glJournalEntry.invalid.future.date";
} else if (name().toString().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
} else if (name().equalsIgnoreCase("ACCOUNTING_CLOSED")) {
return "error.msg.glJournalEntry.invalid.accounting.closed";
} else if (name().toString().equalsIgnoreCase("NO_DEBITS_OR_CREDITS")) {
} else if (name().equalsIgnoreCase("NO_DEBITS_OR_CREDITS")) {
return "error.msg.glJournalEntry.invalid.no.debits.or.credits";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH")) {
} else if (name().equalsIgnoreCase("DEBIT_CREDIT_SUM_MISMATCH")) {
return "error.msg.glJournalEntry.invalid.mismatch.debits.credits";
} else if (name().toString().equalsIgnoreCase("DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY")) {
} else if (name().equalsIgnoreCase("DEBIT_CREDIT_ACCOUNT_OR_AMOUNT_EMPTY")) {
return "error.msg.glJournalEntry.invalid.empty.account.or.amount";
} else if (name().toString().equalsIgnoreCase("GL_ACCOUNT_DISABLED")) {
} else if (name().equalsIgnoreCase("GL_ACCOUNT_DISABLED")) {
return "error.msg.glJournalEntry.invalid.account.disabled";
} else if (name().toString().equalsIgnoreCase("INVALID_DEBIT_OR_CREDIT_ACCOUNTS")) {
} else if (name().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")) {
} else if (name().equalsIgnoreCase("GL_ACCOUNT_MANUAL_ENTRIES_NOT_PERMITTED")) {
return "error.msg.glJournalEntry.invalid.account.manual.adjustments.not.permitted";
}
return name().toString();
return name();
}
}
@@ -90,12 +90,11 @@ 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, JournalEntryJsonInputParams.CREDITS.getValue());
}
if (topLevelJsonElement.has(JournalEntryJsonInputParams.DEBITS.getValue())
&& topLevelJsonElement.get(JournalEntryJsonInputParams.DEBITS.getValue()).isJsonArray()) {
debits = populateCreditsOrDebitsArray(topLevelJsonElement, locale, debits, JournalEntryJsonInputParams.DEBITS.getValue());
debits = populateCreditsOrDebitsArray(topLevelJsonElement, locale, JournalEntryJsonInputParams.DEBITS.getValue());
}
}
return new JournalEntryCommand(officeId, currencyCode, transactionDate, comments, referenceNumber, accountingRuleId, amount,
@@ -103,14 +102,14 @@ public final class JournalEntryCommandFromApiJsonDeserializer extends AbstractFr
}
/**
* @param comments
* @param topLevelJsonElement
* @param locale
* @param paramName
*/
private SingleDebitOrCreditEntryCommand[] populateCreditsOrDebitsArray(final JsonObject topLevelJsonElement, final Locale locale,
SingleDebitOrCreditEntryCommand[] debitOrCredits, final String paramName) {
final String paramName) {
final JsonArray array = topLevelJsonElement.get(paramName).getAsJsonArray();
debitOrCredits = new SingleDebitOrCreditEntryCommand[array.size()];
SingleDebitOrCreditEntryCommand[] debitOrCredits = new SingleDebitOrCreditEntryCommand[array.size()];
for (int i = 0; i < array.size(); i++) {
final JsonObject creditElement = array.get(i).getAsJsonObject();
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.accounting.closure.domain.GLClosure;
@@ -36,7 +37,7 @@ import org.apache.fineract.accounting.common.AccountingConstants.FinancialActivi
import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount;
import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper;
import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository;
import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO;
import org.apache.fineract.accounting.journalentry.data.ClientChargePaymentDTO;
import org.apache.fineract.accounting.journalentry.data.ClientTransactionDTO;
@@ -60,12 +61,12 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.office.domain.Office;
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
import org.apache.fineract.organisation.office.domain.OfficeRepository;
import org.apache.fineract.portfolio.account.PortfolioAccountType;
import org.apache.fineract.portfolio.account.service.AccountTransfersReadPlatformService;
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.apache.fineract.portfolio.client.domain.ClientTransaction;
import org.apache.fineract.portfolio.client.domain.ClientTransactionRepositoryWrapper;
import org.apache.fineract.portfolio.client.domain.ClientTransactionRepository;
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
@@ -91,10 +92,10 @@ public class AccountingProcessorHelper {
private final ProductToGLAccountMappingRepository accountMappingRepository;
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository;
private final GLClosureRepository closureRepository;
private final GLAccountRepositoryWrapper accountRepositoryWrapper;
private final OfficeRepositoryWrapper officeRepositoryWrapper;
private final GLAccountRepository glAccountRepository;
private final OfficeRepository officeRepository;
private final LoanTransactionRepository loanTransactionRepository;
private final ClientTransactionRepositoryWrapper clientTransactionRepository;
private final ClientTransactionRepository clientTransactionRepository;
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
private final AccountTransfersReadPlatformService accountTransfersReadPlatformService;
private final ChargeRepositoryWrapper chargeRepositoryWrapper;
@@ -154,11 +155,7 @@ public class AccountingProcessorHelper {
transactionDate, transactionType, amount, principal, interest, fees, penalties, overPayments, reversed,
penaltyPaymentDetails, feePaymentDetails, isAccountTransfer, chargeRefundChargeType);
Boolean isLoanToLoanTransfer = (Boolean) accountingBridgeData.get("isLoanToLoanTransfer");
if (isLoanToLoanTransfer != null && isLoanToLoanTransfer) {
transaction.setLoanToLoanTransfer(true);
} else {
transaction.setLoanToLoanTransfer(false);
}
transaction.setLoanToLoanTransfer(isLoanToLoanTransfer != null && isLoanToLoanTransfer);
newLoanTransactions.add(transaction);
}
@@ -212,8 +209,8 @@ public class AccountingProcessorHelper {
final List<TaxPaymentDTO> taxPayments = new ArrayList<>();
if (map.containsKey("taxDetails")) {
@SuppressWarnings("unchecked")
final List<Map<String, Object>> taxDatas = (List<Map<String, Object>>) map.get("taxDetails");
for (final Map<String, Object> taxData : taxDatas) {
final List<Map<String, Object>> taxDataList = (List<Map<String, Object>>) map.get("taxDetails");
for (final Map<String, Object> taxData : taxDataList) {
final BigDecimal taxAmount = (BigDecimal) taxData.get("amount");
final Long creditAccountId = (Long) taxData.get("creditAccountId");
final Long debitAccountId = (Long) taxData.get("debitAccountId");
@@ -313,11 +310,8 @@ public class AccountingProcessorHelper {
}
}
final ClientTransactionDTO clientTransactionDTO = new ClientTransactionDTO(clientId, transactionOfficeId, paymentTypeId,
transactionId, transactionDate, transactionType, currencyCode, amount, reversed, accountingEnabled,
clientChargePaymentDTOs);
return clientTransactionDTO;
return new ClientTransactionDTO(clientId, transactionOfficeId, paymentTypeId, transactionId, transactionDate, transactionType,
currencyCode, amount, reversed, accountingEnabled, clientChargePaymentDTOs);
}
@@ -495,10 +489,6 @@ public class AccountingProcessorHelper {
return this.closureRepository.getLatestGLClosureByBranch(officeId);
}
public Office getOfficeById(final long officeId) {
return this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId);
}
private void createJournalEntriesForLoan(final Office office, final String currencyCode, final int accountTypeToDebitId,
final int accountTypeToCreditId, final Long loanProductId, final Long paymentTypeId, final Long loanId,
final String transactionId, final LocalDate transactionDate, final BigDecimal amount) {
@@ -742,12 +732,20 @@ public class AccountingProcessorHelper {
}
}
public LoanTransaction getLoanTransactionById(final long loanTransactionId) {
return this.loanTransactionRepository.findById(loanTransactionId).orElseThrow();
public LoanTransaction getLoanTransactionById(final Long loanTransactionId) {
return this.loanTransactionRepository.getReferenceById(loanTransactionId);
}
public SavingsAccountTransaction getSavingsTransactionById(final long savingsTransactionId) {
return this.savingsAccountTransactionRepository.findById(savingsTransactionId).orElseThrow();
public SavingsAccountTransaction getSavingsTransactionById(final Long savingsTransactionId) {
return this.savingsAccountTransactionRepository.getReferenceById(savingsTransactionId);
}
public ClientTransaction getClientTransactionById(final Long clientTransactionId) {
return this.clientTransactionRepository.getReferenceById(clientTransactionId);
}
public Office getOfficeById(final long officeId) {
return this.officeRepository.getReferenceById(officeId);
}
private void createCreditJournalEntryOrReversalForLoan(final Office office, final String currencyCode, final int accountMappingTypeId,
@@ -773,14 +771,12 @@ public class AccountingProcessorHelper {
final boolean manualEntry = false;
LoanTransaction loanTransaction = null;
SavingsAccountTransaction savingsAccountTransaction = null;
ClientTransaction clientTransaction = null;
final PaymentDetail paymentDetail = null;
final Long shareTransactionId = null;
clientTransaction = this.clientTransactionRepository.findOneWithNotFoundDetection(clientId, transactionId);
ClientTransaction clientTransaction = getClientTransactionById(transactionId);
String modifiedTransactionId = transactionId.toString();
modifiedTransactionId = CLIENT_TRANSACTION_IDENTIFIER + transactionId;
String 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);
@@ -799,7 +795,7 @@ public class AccountingProcessorHelper {
String modifiedTransactionId = transactionId;
if (StringUtils.isNumeric(transactionId)) {
long id = Long.parseLong(transactionId);
savingsAccountTransaction = this.savingsAccountTransactionRepository.findById(id).orElseThrow();
savingsAccountTransaction = getSavingsTransactionById(id);
modifiedTransactionId = SAVINGS_TRANSACTION_IDENTIFIER + transactionId;
}
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
@@ -820,7 +816,7 @@ public class AccountingProcessorHelper {
String modifiedTransactionId = transactionId;
if (StringUtils.isNumeric(transactionId)) {
long id = Long.parseLong(transactionId);
loanTransaction = this.loanTransactionRepository.findById(id).orElseThrow();
loanTransaction = getLoanTransactionById(id);
modifiedTransactionId = LOAN_TRANSACTION_IDENTIFIER + transactionId;
}
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
@@ -829,7 +825,7 @@ public class AccountingProcessorHelper {
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
public void createProvisioningDebitJournalEntry(LocalDate transactionDate, Long provisioningentryId, Office office, String currencyCode,
public void createProvisioningDebitJournalEntry(LocalDate transactionDate, Long provisioningEntryId, Office office, String currencyCode,
GLAccount account, BigDecimal amount) {
LoanTransaction loanTransaction = null;
SavingsAccountTransaction savingsAccountTransaction = null;
@@ -837,14 +833,14 @@ public class AccountingProcessorHelper {
PaymentDetail paymentDetail = null;
final Long shareTransactionId = null;
final boolean manualEntry = false;
String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + provisioningentryId;
String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + provisioningEntryId;
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.PROVISIONING.getValue(),
provisioningentryId, null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
provisioningEntryId, null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
public void createProvisioningCreditJournalEntry(LocalDate transactionDate, Long provisioningentryId, Office office,
public void createProvisioningCreditJournalEntry(LocalDate transactionDate, Long provisioningEntryId, Office office,
String currencyCode, GLAccount account, BigDecimal amount) {
LoanTransaction loanTransaction = null;
SavingsAccountTransaction savingsAccountTransaction = null;
@@ -852,10 +848,10 @@ public class AccountingProcessorHelper {
PaymentDetail paymentDetail = null;
final Long shareTransactionId = null;
final boolean manualEntry = false;
String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + provisioningentryId;
String modifiedTransactionId = PROVISIONING_TRANSACTION_IDENTIFIER + provisioningEntryId;
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.PROVISIONING.getValue(),
provisioningentryId, null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
provisioningEntryId, null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
@@ -870,7 +866,7 @@ public class AccountingProcessorHelper {
String modifiedTransactionId = transactionId;
if (StringUtils.isNumeric(transactionId)) {
long id = Long.parseLong(transactionId);
loanTransaction = this.loanTransactionRepository.findById(id).orElseThrow();
loanTransaction = getLoanTransactionById(id);
modifiedTransactionId = LOAN_TRANSACTION_IDENTIFIER + transactionId;
}
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
@@ -890,7 +886,7 @@ public class AccountingProcessorHelper {
String modifiedTransactionId = transactionId;
if (StringUtils.isNumeric(transactionId)) {
long id = Long.parseLong(transactionId);
savingsAccountTransaction = this.savingsAccountTransactionRepository.findById(id).orElseThrow();
savingsAccountTransaction = getSavingsTransactionById(id);
modifiedTransactionId = SAVINGS_TRANSACTION_IDENTIFIER + transactionId;
}
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
@@ -903,15 +899,13 @@ public class AccountingProcessorHelper {
private void createDebitJournalEntryForClientPayments(final Office office, final String currencyCode, final GLAccount account,
final Long clientId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
final boolean manualEntry = false;
ClientTransaction clientTransaction = null;
LoanTransaction loanTransaction = null;
SavingsAccountTransaction savingsAccountTransaction = null;
final PaymentDetail paymentDetail = null;
final Long shareTransactionId = null;
clientTransaction = this.clientTransactionRepository.findOneWithNotFoundDetection(clientId, transactionId);
String modifiedTransactionId = transactionId.toString();
modifiedTransactionId = CLIENT_TRANSACTION_IDENTIFIER + transactionId;
ClientTransaction clientTransaction = getClientTransactionById(transactionId);
String modifiedTransactionId = CLIENT_TRANSACTION_IDENTIFIER + transactionId;
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.CLIENT.getValue(), clientId, null,
@@ -1056,7 +1050,7 @@ public class AccountingProcessorHelper {
}
public GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId, final Long paymentTypeId) {
GLAccount glAccount = null;
GLAccount glAccount;
if (isOrganizationAccount(accountMappingTypeId)) {
FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
.findByFinancialActivityTypeWithNotFoundDetection(accountMappingTypeId);
@@ -1143,7 +1137,7 @@ public class AccountingProcessorHelper {
private GLAccount getLinkedGLAccountForSavingsProduct(final Long savingsProductId, final int accountMappingTypeId,
final Long paymentTypeId) {
GLAccount glAccount = null;
GLAccount glAccount;
if (isOrganizationAccount(accountMappingTypeId)) {
FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
.findByFinancialActivityTypeWithNotFoundDetection(accountMappingTypeId);
@@ -1170,7 +1164,7 @@ public class AccountingProcessorHelper {
private GLAccount getLinkedGLAccountForShareProduct(final Long shareProductId, final int accountMappingTypeId,
final Long paymentTypeId) {
GLAccount glAccount = null;
GLAccount glAccount;
if (isOrganizationAccount(accountMappingTypeId)) {
FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
.findByFinancialActivityTypeWithNotFoundDetection(accountMappingTypeId);
@@ -1211,11 +1205,7 @@ public class AccountingProcessorHelper {
}
private boolean isOrganizationAccount(final int accountMappingTypeId) {
boolean isOrganizationAccount = false;
if (FinancialActivity.fromInt(accountMappingTypeId) != null) {
isOrganizationAccount = true;
}
return isOrganizationAccount;
return FinancialActivity.fromInt(accountMappingTypeId) != null;
}
public BigDecimal createCreditJournalEntryOrReversalForClientPayments(final Office office, final String currencyCode,
@@ -1224,25 +1214,25 @@ public class AccountingProcessorHelper {
/***
* Map to track each account affected and the net credit to be made for a particular account
***/
final Map<GLAccount, BigDecimal> creditDetailsMap = new LinkedHashMap<>();
final Map<Long, BigDecimal> creditDetailsMap = new LinkedHashMap<>();
for (final ClientChargePaymentDTO clientChargePaymentDTO : clientChargePaymentDTOs) {
if (clientChargePaymentDTO.getIncomeAccountId() != null) {
final GLAccount chargeSpecificAccount = getGLAccountById(clientChargePaymentDTO.getIncomeAccountId());
final Long accountId = clientChargePaymentDTO.getIncomeAccountId();
BigDecimal chargeSpecificAmount = clientChargePaymentDTO.getAmount();
// adjust net credit amount if the account is already present in
// the map
if (creditDetailsMap.containsKey(chargeSpecificAccount)) {
final BigDecimal existingAmount = creditDetailsMap.get(chargeSpecificAccount);
if (creditDetailsMap.containsKey(accountId)) {
final BigDecimal existingAmount = creditDetailsMap.get(accountId);
chargeSpecificAmount = chargeSpecificAmount.add(existingAmount);
}
creditDetailsMap.put(chargeSpecificAccount, chargeSpecificAmount);
creditDetailsMap.put(accountId, chargeSpecificAmount);
}
}
BigDecimal totalCreditedAmount = BigDecimal.ZERO;
for (final Map.Entry<GLAccount, BigDecimal> entry : creditDetailsMap.entrySet()) {
final GLAccount account = entry.getKey();
for (final Map.Entry<Long, BigDecimal> entry : creditDetailsMap.entrySet()) {
final GLAccount account = getGLAccountById(entry.getKey());
final BigDecimal amount = entry.getValue();
totalCreditedAmount = totalCreditedAmount.add(amount);
if (isReversal) {
@@ -1267,22 +1257,18 @@ public class AccountingProcessorHelper {
}
private GLAccount getGLAccountById(final Long accountId) {
return this.accountRepositoryWrapper.findOneWithNotFoundDetection(accountId);
return this.glAccountRepository.getReferenceById(accountId);
}
public Integer getValueForFeeOrPenaltyIncomeAccount(final String chargeRefundChargeType) {
if (chargeRefundChargeType == null
|| !(chargeRefundChargeType.equalsIgnoreCase("P") || chargeRefundChargeType.equalsIgnoreCase("F"))) {
String errorValue;
if (chargeRefundChargeType == null) {
errorValue = "Null";
} else {
errorValue = chargeRefundChargeType;
}
errorValue = Objects.requireNonNullElse(chargeRefundChargeType, "Null");
throw new PlatformDataIntegrityException("error.msg.chargeRefundChargeType.can.only.be.P.or.F",
"chargeRefundChargeType can only be P (Penalty) or F(Fee) - Value is: " + errorValue);
}
Integer incomeAccount = null;
Integer incomeAccount;
if (chargeRefundChargeType.equalsIgnoreCase("P")) {
incomeAccount = AccrualAccountsForLoan.INCOME_FROM_PENALTIES.getValue();
} else {
@@ -175,22 +175,22 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
*
* <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/>
* <b>Interest Repayment</b>:Debits "Fund Source" and Credits "Receivable Interest" <br/>
*
* <b>Fee Repayment</b>:Debits "Fund Source" (or "Interest on Loans" in case of repayment at disbursement) and and
* <b>Fee Repayment</b>:Debits "Fund Source" (or "Interest on Loans" in case of repayment at disbursement) and
* Credits "Receivable Fees" <br/>
*
* <b>Penalty Repayment</b>: Debits "Fund Source" and and Credits "Receivable Penalties" <br/>
* <b>Penalty Repayment</b>: Debits "Fund Source" and Credits "Receivable Penalties" <br/>
* <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>Interest Write off</b>:Debits "Losses Written off" and and Credits "Receivable Interest" <br/>
* <b>Interest Write off</b>:Debits "Losses Written off" and Credits "Receivable Interest" <br/>
*
* <b>Fee Write off</b>:Debits "Losses Written off" and and Credits "Receivable Fees" <br/>
* <b>Fee Write off</b>:Debits "Losses Written off" and Credits "Receivable Fees" <br/>
*
* <b>Penalty Write off</b>: Debits "Losses Written off" and and Credits "Receivable Penalties" <br/>
* <b>Penalty Write off</b>: Debits "Losses Written off" and Credits "Receivable Penalties" <br/>
* <br/>
* <br/>
* In case the loan transaction has been reversed, all debits are turned into credits and vice versa
@@ -41,8 +41,6 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
@Override
public void createJournalEntriesForLoan(final LoanDTO loanDTO) {
final GLClosure latestGLClosure = this.helper.getLatestClosureByBranch(loanDTO.getOfficeId());
// final Office office =
// this.helper.getOfficeById(loanDTO.getOfficeId());
final Long loanProductId = loanDTO.getLoanProductId();
final String currencyCode = loanDTO.getCurrencyCode();
for (final LoanTransactionDTO loanTransactionDTO : loanDTO.getNewLoanTransactions()) {
@@ -57,11 +57,12 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
this.helper.checkForBranchClosures(latestGLClosure, transactionDate);
if (savingsTransactionDTO.getTransactionType().isWithdrawal() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL.getValue(), FinancialActivity.LIABILITY_TRANSFER.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
@@ -72,7 +73,7 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(), savingsProductId, paymentTypeId, savingsId, transactionId,
transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL.getValue(), CashAccountsForSavings.SAVINGS_REFERENCE.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
@@ -80,11 +81,12 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
}
}
} else if (savingsTransactionDTO.getTransactionType().isDeposit() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
if (savingsTransactionDTO.isAccountTransfer()) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(), CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
FinancialActivity.LIABILITY_TRANSFER.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
@@ -95,7 +97,7 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(),
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.SAVINGS_REFERENCE.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
@@ -145,6 +147,7 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
* Handle Interest Applications and reversals of Interest Applications
**/
else if (savingsTransactionDTO.getTransactionType().isInterestPosting() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
// Post journal entry if earned interest amount is greater than
// zero
if (savingsTransactionDTO.getAmount().compareTo(BigDecimal.ZERO) > 0) {
@@ -152,7 +155,7 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
CashAccountsForSavings.INTEREST_ON_SAVINGS.getValue(),
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), savingsProductId, paymentTypeId, savingsId,
transactionId, transactionDate, overdraftAmount, isReversal);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavings(office, currencyCode,
CashAccountsForSavings.INTEREST_ON_SAVINGS.getValue(), CashAccountsForSavings.SAVINGS_CONTROL.getValue(),
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate,
@@ -179,13 +182,14 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
/** Handle Fees Deductions and reversals of Fees Deductions **/
else if (savingsTransactionDTO.getTransactionType().isFeeDeduction() && savingsTransactionDTO.isOverdraftTransaction()) {
boolean isPositive = amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0;
// Is the Charge a penalty?
if (penaltyPayments.size() > 0) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL, CashAccountsForSavings.INCOME_FROM_PENALTIES,
savingsProductId, paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal,
penaltyPayments);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL, CashAccountsForSavings.INCOME_FROM_PENALTIES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal,
@@ -195,7 +199,7 @@ public class CashBasedAccountingProcessorForSavings implements AccountingProcess
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.OVERDRAFT_PORTFOLIO_CONTROL, CashAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, overdraftAmount, isReversal, feePayments);
if (amount.subtract(overdraftAmount).compareTo(BigDecimal.ZERO) > 0) {
if (isPositive) {
this.helper.createCashBasedJournalEntriesAndReversalsForSavingsCharges(office, currencyCode,
CashAccountsForSavings.SAVINGS_CONTROL, CashAccountsForSavings.INCOME_FROM_FEES, savingsProductId,
paymentTypeId, savingsId, transactionId, transactionDate, amount.subtract(overdraftAmount), isReversal,
@@ -422,7 +422,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
}
final List<JournalEntryData> transactions = populateOpeningBalances(existingOpeningBalanceTransactions, allOpeningTransactions);
final List<JournalEntryData> assetAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> liabityAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> liabilityAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> incomeAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> equityAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> expenseAccountOpeningBalances = new ArrayList<>();
@@ -432,7 +432,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
if (type.isAssetType()) {
assetAccountOpeningBalances.add(journalEntryData);
} else if (type.isLiabilityType()) {
liabityAccountOpeningBalances.add(journalEntryData);
liabilityAccountOpeningBalances.add(journalEntryData);
} else if (type.isEquityType()) {
equityAccountOpeningBalances.add(journalEntryData);
} else if (type.isIncomeType()) {
@@ -445,26 +445,26 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
return OfficeOpeningBalancesData.createNew(officeId, officeData.name(), transactionDate, contraAccount, assetAccountOpeningBalances,
liabityAccountOpeningBalances, incomeAccountOpeningBalances, equityAccountOpeningBalances, expenseAccountOpeningBalances);
liabilityAccountOpeningBalances, incomeAccountOpeningBalances, equityAccountOpeningBalances, expenseAccountOpeningBalances);
}
private List<JournalEntryData> populateOpeningBalances(final List<JournalEntryData> existingOpeningBalanceTransactions,
final List<JournalEntryData> allOpeningTransactions) {
final List<JournalEntryData> allOpeningBalnceTransactions = new ArrayList<>(allOpeningTransactions.size());
final List<JournalEntryData> allOpeningBalanceTransactions = new ArrayList<>(allOpeningTransactions.size());
for (final JournalEntryData newOpeningBalanceTransaction : allOpeningTransactions) {
boolean isNewTransactionAddedToCollection = false;
for (final JournalEntryData existingOpeningBalanceTransaction : existingOpeningBalanceTransactions) {
if (newOpeningBalanceTransaction.getGlAccountId().equals(existingOpeningBalanceTransaction.getGlAccountId())) {
allOpeningBalnceTransactions.add(existingOpeningBalanceTransaction);
allOpeningBalanceTransactions.add(existingOpeningBalanceTransaction);
isNewTransactionAddedToCollection = true;
break;
}
}
if (!isNewTransactionAddedToCollection) {
allOpeningBalnceTransactions.add(newOpeningBalanceTransaction);
allOpeningBalanceTransactions.add(newOpeningBalanceTransaction);
}
}
return allOpeningBalnceTransactions;
return allOpeningBalanceTransactions;
}
private List<JournalEntryData> populateAllTransactionsFromGLAccounts(final Long contraId) {
@@ -81,7 +81,7 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
@Override
public CommandProcessingResult updateOfficeRunningBalance(JsonCommand command) {
this.dataValidator.validateForUpdateRunningbalance(command);
this.dataValidator.validateForUpdateRunningBalance(command);
final Long officeId = this.fromApiJsonHelper.extractLongNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue(),
command.parsedJson());
CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder()
@@ -142,7 +142,7 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
for (Map<String, Object> entries : officesRunningBalanceList) {
Long accountId = Long.parseLong(entries.get("accountId").toString());
Long officeId = Long.parseLong(entries.get("officeId").toString());
Map<Long, BigDecimal> runningBalance = null;
Map<Long, BigDecimal> runningBalance;
if (officesRunningBalance.containsKey(officeId)) {
runningBalance = officesRunningBalance.get(officeId);
} else {
@@ -154,17 +154,17 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
}
}
List<JournalEntryData> entryDatas = jdbcTemplate.query(entryMapper.organizationRunningBalanceSchema(), entryMapper, entityDate);
if (entryDatas.size() > 0) {
List<JournalEntryData> entryDataList = jdbcTemplate.query(entryMapper.organizationRunningBalanceSchema(), entryMapper, entityDate);
if (entryDataList.size() > 0) {
// run a batch update of 1000 SQL statements at a time
final Integer batchUpdateSize = 1000;
final int batchUpdateSize = 1000;
List<Object[]> params = new ArrayList<>();
int batchIndex = 0;
String sql = "UPDATE acc_gl_journal_entry SET is_running_balance_calculated=?, organization_running_balance=?,"
+ "office_running_balance=?, last_modified_by=?, last_modified_on_utc=? WHERE id=?";
for (int index = 0; index < entryDatas.size(); index++) {
JournalEntryData entryData = entryDatas.get(index);
Map<Long, BigDecimal> officeRunningBalanceMap = null;
for (int index = 0; index < entryDataList.size(); index++) {
JournalEntryData entryData = entryDataList.get(index);
Map<Long, BigDecimal> officeRunningBalanceMap;
if (officesRunningBalance.containsKey(entryData.getOfficeId())) {
officeRunningBalanceMap = officesRunningBalance.get(entryData.getOfficeId());
} else {
@@ -177,7 +177,7 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
params.add(new Object[] { Boolean.TRUE, runningBalance, officeRunningBalance,
platformSecurityContext.authenticatedUser().getId(), DateUtils.getOffsetDateTimeOfTenant(), entryData.getId() });
batchIndex++;
if (batchIndex == batchUpdateSize || index == entryDatas.size() - 1) {
if (batchIndex == batchUpdateSize || index == entryDataList.size() - 1) {
this.jdbcTemplate.batchUpdate(sql, params);
// reset counter and string array
batchIndex = 0;
@@ -204,11 +204,12 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
runningBalanceMap.put(accountId, (BigDecimal) entries.get("runningBalance"));
}
}
List<JournalEntryData> entryDatas = jdbcTemplate.query(entryMapper.officeRunningBalanceSchema(), entryMapper, officeId, entityDate);
List<JournalEntryData> entryDataList = jdbcTemplate.query(entryMapper.officeRunningBalanceSchema(), entryMapper, officeId,
entityDate);
List<Object[]> params = new ArrayList<>();
String sql = "UPDATE acc_gl_journal_entry SET office_running_balance=?, last_modified_by=?, last_modified_on_utc=? WHERE id=?";
for (JournalEntryData entryData : entryDatas) {
for (JournalEntryData entryData : entryDataList) {
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
params.add(new Object[] { runningBalance, platformSecurityContext.authenticatedUser().getId(),
DateUtils.getOffsetDateTimeOfTenant(), entryData.getId() });
@@ -221,30 +222,18 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
if (runningBalanceMap.containsKey(entry.getGlAccountId())) {
runningBalance = runningBalanceMap.get(entry.getGlAccountId());
}
GLAccountType accounttype = GLAccountType.fromInt(entry.getGlAccountType().getId().intValue());
GLAccountType accountType = GLAccountType.fromInt(entry.getGlAccountType().getId().intValue());
JournalEntryType entryType = JournalEntryType.fromInt(entry.getEntryType().getId().intValue());
boolean isIncrease = false;
switch (accounttype) {
switch (accountType) {
case ASSET:
if (entryType.isDebitType()) {
isIncrease = true;
}
break;
case EQUITY:
if (entryType.isCreditType()) {
isIncrease = true;
}
break;
case EXPENSE:
if (entryType.isDebitType()) {
isIncrease = true;
}
break;
case EQUITY:
case INCOME:
if (entryType.isCreditType()) {
isIncrease = true;
}
break;
case LIABILITY:
if (entryType.isCreditType()) {
isIncrease = true;
@@ -205,7 +205,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null);
}
for (final SingleDebitOrCreditEntryCommand creditOrDebit : creditOrDebits) {
if (!glaccount.getId().equals(creditOrDebit.getGlAccountId())) {
if (glaccount == null || creditOrDebit == null || !Objects.equals(glaccount.getId(), creditOrDebit.getGlAccountId())) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.INVALID_DEBIT_OR_CREDIT_ACCOUNTS, null, null, null);
}
}
@@ -215,23 +215,22 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
private void checkDebitOrCreditAccountsAreValid(final AccountingRule accountingRule, final SingleDebitOrCreditEntryCommand[] credits,
final SingleDebitOrCreditEntryCommand[] debits) {
// Validate the debit and credit arrays are appropriate accounts
List<GLAccountDataForLookup> allowedCreditGLAccounts = new ArrayList<>();
List<GLAccountDataForLookup> allowedDebitGLAccounts = new ArrayList<>();
final SingleDebitOrCreditEntryCommand[] validCredits = new SingleDebitOrCreditEntryCommand[credits.length];
final SingleDebitOrCreditEntryCommand[] validDebits = new SingleDebitOrCreditEntryCommand[debits.length];
List<GLAccountDataForLookup> allowedCreditGLAccounts;
List<GLAccountDataForLookup> allowedDebitGLAccounts;
int validCreditsNo = 0;
int validDebitsNo = 0;
if (credits != null && credits.length > 0) {
allowedCreditGLAccounts = this.glAccountReadPlatformService.retrieveAccountsByTagId(accountingRule.getId(),
JournalEntryType.CREDIT.getValue());
for (final GLAccountDataForLookup accountDataForLookup : allowedCreditGLAccounts) {
for (int i = 0; i < credits.length; i++) {
final SingleDebitOrCreditEntryCommand credit = credits[i];
for (final SingleDebitOrCreditEntryCommand credit : credits) {
if (credit.getGlAccountId().equals(accountDataForLookup.getId())) {
validCredits[i] = credit;
validCreditsNo++;
}
}
}
if (credits.length != validCredits.length) {
if (credits.length != validCreditsNo) {
throw new JournalEntryRuntimeException("error.msg.glJournalEntry.invalid.credits", "Invalid Credits.");
}
}
@@ -240,14 +239,13 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
allowedDebitGLAccounts = this.glAccountReadPlatformService.retrieveAccountsByTagId(accountingRule.getId(),
JournalEntryType.DEBIT.getValue());
for (final GLAccountDataForLookup accountDataForLookup : allowedDebitGLAccounts) {
for (int i = 0; i < debits.length; i++) {
final SingleDebitOrCreditEntryCommand debit = debits[i];
for (final SingleDebitOrCreditEntryCommand debit : debits) {
if (debit.getGlAccountId().equals(accountDataForLookup.getId())) {
validDebits[i] = debit;
validDebitsNo++;
}
}
}
if (debits.length != validDebits.length) {
if (debits.length != validDebitsNo) {
throw new JournalEntryRuntimeException("error.msg.glJournalEntry.invalid.debits", "Invalid Debits");
}
}
@@ -520,7 +518,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
@Override
public void revertShareAccountJournalEntries(final ArrayList<Long> transactionIds, final LocalDate transactionDate) {
for (Long shareTransactionId : transactionIds) {
String transactionId = AccountingProcessorHelper.SHARE_TRANSACTION_IDENTIFIER + shareTransactionId.longValue();
String transactionId = AccountingProcessorHelper.SHARE_TRANSACTION_IDENTIFIER + shareTransactionId;
List<JournalEntry> journalEntries = this.glJournalEntryRepository.findJournalEntries(transactionId,
PortfolioProductType.SHARES.getValue());
if (journalEntries == null || journalEntries.isEmpty()) {
@@ -559,8 +557,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
private void validateBusinessRulesForJournalEntries(final JournalEntryCommand command) {
/** check if date of Journal entry is valid ***/
final LocalDate entryLocalDate = command.getTransactionDate();
final LocalDate transactionDate = entryLocalDate;
final LocalDate transactionDate = command.getTransactionDate();
// shouldn't be in the future
final LocalDate todaysDate = DateUtils.getBusinessLocalDate();
if (transactionDate.isAfter(todaysDate)) {
@@ -581,7 +578,7 @@ 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) {
if (credits == null || credits.length == 0 || debits == null || debits.length == 0) {
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.NO_DEBITS_OR_CREDITS, null, null, null);
}
@@ -624,13 +621,12 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
final AppUser user = this.context.authenticatedUser();
final Long time = System.currentTimeMillis();
final String uniqueVal = String.valueOf(time) + user.getId() + officeId;
final String transactionId = Long.toHexString(Long.parseLong(uniqueVal));
return transactionId;
return Long.toHexString(Long.parseLong(uniqueVal));
}
private PlatformDataIntegrityException handleJournalEntryDataIntegrityIssues(final Throwable realCause,
final NonTransientDataAccessException dve) {
log.error("Error occured.", dve);
log.error("Error occurred.", dve);
return new PlatformDataIntegrityException("error.msg.glJournalEntry.unknown.data.integrity.issue",
"Unknown data integrity issue with resource Journal Entry: " + realCause.getMessage());
}
@@ -663,7 +659,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
/**
* revert old journal entries
*/
final List<String> transactionIdsToBeReversed = this.glJournalEntryRepository.findNonReversedContraTansactionIds(contraId,
final List<String> transactionIdsToBeReversed = this.glJournalEntryRepository.findNonReversedContraTransactionIds(contraId,
officeId);
for (String transactionId : transactionIdsToBeReversed) {
final List<JournalEntry> journalEntries = this.glJournalEntryRepository
@@ -745,7 +741,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
}
private void validateJournalEntriesArePostedBefore(final Long contraId) {
final List<String> transactionIds = this.glJournalEntryRepository.findNonContraTansactionIds(contraId);
final List<String> transactionIds = this.glJournalEntryRepository.findNonContraTransactionIds(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);
@@ -760,8 +756,8 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
private static class OfficeCurrencyKey {
Office office;
String currency;
final Office office;
final String currency;
OfficeCurrencyKey(Office office, String currency) {
this.office = office;
@@ -770,10 +766,9 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
@Override
public boolean equals(Object obj) {
if (!(obj instanceof OfficeCurrencyKey)) {
if (!(obj instanceof OfficeCurrencyKey copy)) {
return false;
}
OfficeCurrencyKey copy = (OfficeCurrencyKey) obj;
return Objects.equals(this.office.getId(), copy.office.getId()) && this.currency.equals(copy.currency);
}