FINERACT-1704: Code cleanup - Journal entries
This commit is contained in:
committed by
Arnold Gálovics
parent
0bbd825a46
commit
5919882a65
+3
-3
@@ -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();
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ public enum JournalEntryJsonInputParams {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toString().replaceAll("_", " ");
|
||||
return name().replaceAll("_", " ");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
|
||||
+3
-3
@@ -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<>();
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
+1
-2
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -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() {
|
||||
|
||||
+21
-21
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -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();
|
||||
|
||||
+52
-66
@@ -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 {
|
||||
|
||||
+6
-6
@@ -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
|
||||
|
||||
-2
@@ -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()) {
|
||||
|
||||
+11
-7
@@ -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,
|
||||
|
||||
+7
-7
@@ -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) {
|
||||
|
||||
+15
-26
@@ -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;
|
||||
|
||||
+21
-26
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user