FINERACT-1926: External owner accounting
This commit is contained in:
committed by
Arnold Gálovics
parent
437b8e9cae
commit
582f36ad34
@@ -21,6 +21,7 @@ dependencies {
|
||||
implementation(project(':custom:acme:note:service'))
|
||||
implementation('org.springframework.boot:spring-boot-starter')
|
||||
testImplementation(project(':fineract-core'))
|
||||
testImplementation(project(':fineract-loan'))
|
||||
testImplementation(project(':fineract-provider'))
|
||||
testImplementation('org.springframework.boot:spring-boot-starter-jdbc')
|
||||
testImplementation('org.springframework.boot:spring-boot-starter-data-jpa')
|
||||
|
||||
@@ -23,6 +23,9 @@ dependencies {
|
||||
// Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library.
|
||||
// We also (normally should have) no need to ever use 'compileOnly'.
|
||||
|
||||
implementation(
|
||||
project(path: ':fineract-avro-schemas')
|
||||
)
|
||||
|
||||
// implementation dependencies are directly used (compiled against) in src/main (and src/test)
|
||||
//
|
||||
@@ -30,8 +33,11 @@ dependencies {
|
||||
'org.springframework.boot:spring-boot-starter-web',
|
||||
'org.springframework.boot:spring-boot-starter-security',
|
||||
'org.springframework.boot:spring-boot-starter-validation',
|
||||
'org.springframework.boot:spring-boot-starter-batch',
|
||||
'org.springframework.batch:spring-batch-integration',
|
||||
'jakarta.ws.rs:jakarta.ws.rs-api',
|
||||
'org.glassfish.jersey.media:jersey-media-multipart',
|
||||
'org.apache.avro:avro',
|
||||
|
||||
'com.google.guava:guava',
|
||||
'com.google.code.gson:gson',
|
||||
@@ -49,6 +55,7 @@ dependencies {
|
||||
'org.mapstruct:mapstruct',
|
||||
|
||||
'io.github.resilience4j:resilience4j-spring-boot2',
|
||||
'org.apache.httpcomponents:httpcore',
|
||||
)
|
||||
implementation ('org.springframework.boot:spring-boot-starter-data-jpa') {
|
||||
exclude group: 'org.hibernate'
|
||||
|
||||
+1
-2
@@ -32,11 +32,10 @@ import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.guarantor.command.GuarantorCommand;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for {@link GuarantorCommand}'s.
|
||||
* Implementation of {@link FromApiJsonDeserializer}
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
+1
-2
@@ -31,11 +31,10 @@ import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.guarantor.command.GuarantorCommand;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for {@link GuarantorCommand}'s.
|
||||
* Implementation of {@link FromApiJsonDeserializer}
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
+6
-7
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.apache.fineract.accounting.glaccount.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants;
|
||||
@@ -37,7 +36,6 @@ import org.apache.fineract.accounting.glaccount.exception.GLAccountInvalidUpdate
|
||||
import org.apache.fineract.accounting.glaccount.exception.GLAccountNotFoundException;
|
||||
import org.apache.fineract.accounting.glaccount.exception.InvalidParentGLAccountHeadException;
|
||||
import org.apache.fineract.accounting.glaccount.serialization.GLAccountCommandFromApiJsonDeserializer;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
|
||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||
@@ -148,9 +146,9 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
||||
**/
|
||||
if (changesOnly.containsKey(GLAccountJsonInputParams.USAGE.getValue())) {
|
||||
if (glAccount.isHeaderAccount()) {
|
||||
final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository
|
||||
.findFirstJournalEntryForAccount(glAccountId);
|
||||
if (journalEntriesForAccount.size() > 0) {
|
||||
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
||||
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
|
||||
if (journalEntriesForAccountExist) {
|
||||
throw new GLAccountInvalidUpdateException(GlAccountInvalidUpdateReason.TRANSANCTIONS_LOGGED, glAccountId);
|
||||
}
|
||||
}
|
||||
@@ -193,8 +191,9 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
|
||||
}
|
||||
|
||||
// does this account have transactions logged against it
|
||||
final List<JournalEntry> journalEntriesForAccount = this.glJournalEntryRepository.findFirstJournalEntryForAccount(glAccountId);
|
||||
if (journalEntriesForAccount.size() > 0) {
|
||||
final boolean journalEntriesForAccountExist = this.glJournalEntryRepository
|
||||
.exists((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("glAccountId"), glAccountId));
|
||||
if (journalEntriesForAccountExist) {
|
||||
throw new GLAccountInvalidDeleteException(GlAccountInvalidDeleteReason.TRANSANCTIONS_LOGGED, glAccountId);
|
||||
}
|
||||
this.glAccountRepository.delete(glAccount);
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.accounting.journalentry;
|
||||
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||
import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
|
||||
@Mapper(config = MapstructMapperConfig.class)
|
||||
public interface JournalEntryMapper {
|
||||
|
||||
@Mapping(target = "id", source = "id")
|
||||
@Mapping(target = "officeId", source = "office.id")
|
||||
@Mapping(target = "officeName", source = "office.name")
|
||||
@Mapping(target = "glAccountId", source = "glAccount.id")
|
||||
@Mapping(target = "glAccountCode", source = "glAccount.glCode")
|
||||
@Mapping(target = "glAccountName", source = "glAccount.name")
|
||||
@Mapping(target = "glAccountType", source = "glAccount.type", qualifiedByName = "glAccountType")
|
||||
@Mapping(target = "transactionDate", source = "transactionDate")
|
||||
@Mapping(target = "entryType", source = "type", qualifiedByName = "journalEntryType")
|
||||
@Mapping(target = "amount", source = "amount")
|
||||
@Mapping(target = "entityType", source = "entityType", qualifiedByName = "entityType")
|
||||
@Mapping(target = "entityId", source = "entityId")
|
||||
@Mapping(target = "submittedOnDate", source = "submittedOnDate")
|
||||
@Mapping(target = "transactionId", source = "transactionId")
|
||||
@Mapping(target = "currency", source = "currencyCode")
|
||||
@Mapping(target = "manualEntry", source = "manualEntry")
|
||||
@Mapping(target = "reversed", source = "reversed")
|
||||
@Mapping(target = "referenceNumber", source = "referenceNumber")
|
||||
@Mapping(target = "paymentTypeId", source = "paymentDetail.paymentType.id")
|
||||
@Mapping(target = "accountNumber", source = "paymentDetail.accountNumber")
|
||||
@Mapping(target = "checkNumber", source = "paymentDetail.checkNumber")
|
||||
@Mapping(target = "routingCode", source = "paymentDetail.routingCode")
|
||||
@Mapping(target = "receiptNumber", source = "paymentDetail.receiptNumber")
|
||||
@Mapping(target = "bankNumber", source = "paymentDetail.bankNumber")
|
||||
@Mapping(target = "createdDate", ignore = true)
|
||||
@Mapping(target = "createdByUserId", ignore = true)
|
||||
@Mapping(target = "createdByUserName", ignore = true)
|
||||
@Mapping(target = "comments", ignore = true)
|
||||
@Mapping(target = "officeRunningBalance", ignore = true)
|
||||
@Mapping(target = "organizationRunningBalance", ignore = true)
|
||||
@Mapping(target = "runningBalanceComputed", ignore = true)
|
||||
@Mapping(target = "rowIndex", ignore = true)
|
||||
@Mapping(target = "dateFormat", ignore = true)
|
||||
@Mapping(target = "locale", ignore = true)
|
||||
@Mapping(target = "credits", ignore = true)
|
||||
@Mapping(target = "debits", ignore = true)
|
||||
@Mapping(target = "transactionDetails", ignore = true)
|
||||
@Mapping(target = "savingTransactionId", ignore = true)
|
||||
JournalEntryData map(JournalEntry journalEntry);
|
||||
|
||||
@Named("entityType")
|
||||
default PortfolioProductType mapEntityType(Integer entityTypeId) {
|
||||
return PortfolioProductType.fromInt(entityTypeId);
|
||||
}
|
||||
|
||||
@Named("glAccountType")
|
||||
default GLAccountType mapGlAccountType(Integer typeId) {
|
||||
return GLAccountType.fromInt(typeId);
|
||||
}
|
||||
|
||||
@Named("journalEntryType")
|
||||
default JournalEntryType mapJournalEntryType(Integer typeId) {
|
||||
return JournalEntryType.fromInt(typeId);
|
||||
}
|
||||
|
||||
default EnumOptionData mapGlAccountType(GLAccountType accountType) {
|
||||
return new EnumOptionData((long) accountType.getValue(), accountType.getCode(), accountType.name());
|
||||
}
|
||||
|
||||
default EnumOptionData mapJournalEntryType(JournalEntryType journalEntryType) {
|
||||
return new EnumOptionData((long) journalEntryType.getValue(), journalEntryType.getCode(), journalEntryType.name());
|
||||
}
|
||||
|
||||
default EnumOptionData mapEntityType(PortfolioProductType entityType) {
|
||||
return new EnumOptionData((long) entityType.getValue(), entityType.getCode(), entityType.name());
|
||||
}
|
||||
|
||||
default CurrencyData mapCurrency(String currencyCode) {
|
||||
return new CurrencyData(currencyCode);
|
||||
}
|
||||
}
|
||||
+59
-57
@@ -21,7 +21,7 @@ package org.apache.fineract.accounting.journalentry.data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.Data;
|
||||
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
@@ -31,55 +31,55 @@ import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
*
|
||||
* Note: no getter/setters required as google will produce json from fields of object.
|
||||
*/
|
||||
@Getter
|
||||
@Data
|
||||
public class JournalEntryData {
|
||||
|
||||
private final Long id;
|
||||
private final Long officeId;
|
||||
private Long id;
|
||||
private Long officeId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String officeName;
|
||||
private String officeName;
|
||||
@SuppressWarnings("unused")
|
||||
private final String glAccountName;
|
||||
private final Long glAccountId;
|
||||
private String glAccountName;
|
||||
private Long glAccountId;
|
||||
@SuppressWarnings("unused")
|
||||
private final String glAccountCode;
|
||||
private final EnumOptionData glAccountType;
|
||||
private String glAccountCode;
|
||||
private EnumOptionData glAccountType;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate transactionDate;
|
||||
private final EnumOptionData entryType;
|
||||
private final BigDecimal amount;
|
||||
private LocalDate transactionDate;
|
||||
private EnumOptionData entryType;
|
||||
private BigDecimal amount;
|
||||
@SuppressWarnings("unused")
|
||||
private final CurrencyData currency;
|
||||
private final String transactionId;
|
||||
private CurrencyData currency;
|
||||
private String transactionId;
|
||||
@SuppressWarnings("unused")
|
||||
private final Boolean manualEntry;
|
||||
private Boolean manualEntry;
|
||||
@SuppressWarnings("unused")
|
||||
private final EnumOptionData entityType;
|
||||
private EnumOptionData entityType;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long entityId;
|
||||
private Long entityId;
|
||||
@SuppressWarnings("unused")
|
||||
private final Long createdByUserId;
|
||||
private Long createdByUserId;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate createdDate;
|
||||
private LocalDate createdDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final String createdByUserName;
|
||||
private String createdByUserName;
|
||||
@SuppressWarnings("unused")
|
||||
private final String comments;
|
||||
private String comments;
|
||||
@SuppressWarnings("unused")
|
||||
private final Boolean reversed;
|
||||
private Boolean reversed;
|
||||
@SuppressWarnings("unused")
|
||||
private final String referenceNumber;
|
||||
private String referenceNumber;
|
||||
@SuppressWarnings("unused")
|
||||
private final BigDecimal officeRunningBalance;
|
||||
private BigDecimal officeRunningBalance;
|
||||
@SuppressWarnings("unused")
|
||||
private final BigDecimal organizationRunningBalance;
|
||||
private BigDecimal organizationRunningBalance;
|
||||
@SuppressWarnings("unused")
|
||||
private final Boolean runningBalanceComputed;
|
||||
private Boolean runningBalanceComputed;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final TransactionDetailData transactionDetails;
|
||||
private TransactionDetailData transactionDetails;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate submittedOnDate;
|
||||
private LocalDate submittedOnDate;
|
||||
|
||||
// import fields
|
||||
private transient Integer rowIndex;
|
||||
@@ -96,6 +96,8 @@ public class JournalEntryData {
|
||||
private String bankNumber;
|
||||
private transient Long savingTransactionId;
|
||||
|
||||
public JournalEntryData() {}
|
||||
|
||||
// for opening bal bulk import
|
||||
public JournalEntryData(Long officeId, LocalDate transactionDate, String currencyCode, List<CreditDebit> credits,
|
||||
List<CreditDebit> debits, String locale, String dateFormat) {
|
||||
@@ -139,18 +141,6 @@ public class JournalEntryData {
|
||||
this.submittedOnDate = null;
|
||||
}
|
||||
|
||||
public static JournalEntryData importInstance(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId,
|
||||
Integer rowIndex, List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber,
|
||||
String routingCode, String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
|
||||
return new JournalEntryData(officeId, transactionDate, currencyCode, paymentTypeId, rowIndex, credits, debits, accountNumber,
|
||||
checkNumber, routingCode, receiptNumber, bankNumber, comments, locale, dateFormat);
|
||||
}
|
||||
|
||||
public static JournalEntryData importInstance1(Long officeId, LocalDate transactionDate, String currencyCode, List<CreditDebit> credits,
|
||||
List<CreditDebit> debits, String locale, String dateFormat) {
|
||||
return new JournalEntryData(officeId, transactionDate, currencyCode, credits, debits, locale, dateFormat);
|
||||
}
|
||||
|
||||
private JournalEntryData(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId, Integer rowIndex,
|
||||
List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber, String routingCode,
|
||||
String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
|
||||
@@ -195,23 +185,6 @@ public class JournalEntryData {
|
||||
this.transactionDetails = null;
|
||||
}
|
||||
|
||||
public Integer getRowIndex() {
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return transactionDate;
|
||||
}
|
||||
|
||||
public void addDebits(CreditDebit debit) {
|
||||
|
||||
this.debits.add(debit);
|
||||
}
|
||||
|
||||
public void addCredits(CreditDebit credit) {
|
||||
this.credits.add(credit);
|
||||
}
|
||||
|
||||
public JournalEntryData(final Long id, final Long officeId, final String officeName, final String glAccountName, final Long glAccountId,
|
||||
final String glAccountCode, final EnumOptionData glAccountClassification, final LocalDate transactionDate,
|
||||
final EnumOptionData entryType, final BigDecimal amount, final String transactionId, final Boolean manualEntry,
|
||||
@@ -247,6 +220,18 @@ public class JournalEntryData {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public static JournalEntryData importInstance(Long officeId, LocalDate transactionDate, String currencyCode, Long paymentTypeId,
|
||||
Integer rowIndex, List<CreditDebit> credits, List<CreditDebit> debits, String accountNumber, String checkNumber,
|
||||
String routingCode, String receiptNumber, String bankNumber, String comments, String locale, String dateFormat) {
|
||||
return new JournalEntryData(officeId, transactionDate, currencyCode, paymentTypeId, rowIndex, credits, debits, accountNumber,
|
||||
checkNumber, routingCode, receiptNumber, bankNumber, comments, locale, dateFormat);
|
||||
}
|
||||
|
||||
public static JournalEntryData importInstance1(Long officeId, LocalDate transactionDate, String currencyCode, List<CreditDebit> credits,
|
||||
List<CreditDebit> debits, String locale, String dateFormat) {
|
||||
return new JournalEntryData(officeId, transactionDate, currencyCode, credits, debits, locale, dateFormat);
|
||||
}
|
||||
|
||||
public static JournalEntryData fromGLAccountData(final GLAccountData glAccountData) {
|
||||
|
||||
final Long id = null;
|
||||
@@ -279,4 +264,21 @@ public class JournalEntryData {
|
||||
createdByUserName, comments, reversed, referenceNumber, officeRunningBalance, organizationRunningBalance,
|
||||
runningBalanceComputed, transactionDetailData, currency);
|
||||
}
|
||||
|
||||
public Integer getRowIndex() {
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return transactionDate;
|
||||
}
|
||||
|
||||
public void addDebits(CreditDebit debit) {
|
||||
|
||||
this.debits.add(debit);
|
||||
}
|
||||
|
||||
public void addCredits(CreditDebit credit) {
|
||||
this.credits.add(credit);
|
||||
}
|
||||
}
|
||||
+22
-104
@@ -26,17 +26,16 @@ import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientTransaction;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Table(name = "acc_gl_journal_entry")
|
||||
public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
@@ -62,17 +61,14 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
@Column(name = "transaction_id", nullable = false, length = 50)
|
||||
private String transactionId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "loan_transaction_id", nullable = false)
|
||||
private LoanTransaction loanTransaction;
|
||||
@Column(name = "loan_transaction_id")
|
||||
private Long loanTransactionId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "savings_transaction_id", nullable = false)
|
||||
private SavingsAccountTransaction savingsTransaction;
|
||||
@Column(name = "savings_transaction_id")
|
||||
private Long savingsTransactionId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "client_transaction_id", nullable = false)
|
||||
private ClientTransaction clientTransaction;
|
||||
@Column(name = "client_transaction_id")
|
||||
private Long clientTransactionId;
|
||||
|
||||
@Column(name = "share_transaction_id")
|
||||
private Long shareTransactionId;
|
||||
@@ -107,16 +103,6 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
@Column(name = "submitted_on_date", nullable = false)
|
||||
private LocalDate submittedOnDate;
|
||||
|
||||
public static JournalEntry createNew(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount,
|
||||
final String currencyCode, final String transactionId, final boolean manualEntry, final LocalDate transactionDate,
|
||||
final JournalEntryType journalEntryType, final BigDecimal amount, final String description, final Integer entityType,
|
||||
final Long entityId, final String referenceNumber, final LoanTransaction loanTransaction,
|
||||
final SavingsAccountTransaction savingsTransaction, final ClientTransaction clientTransaction, Long shareTransactionId) {
|
||||
return new JournalEntry(office, paymentDetail, glAccount, currencyCode, transactionId, manualEntry, transactionDate,
|
||||
journalEntryType.getValue(), amount, description, entityType, entityId, referenceNumber, loanTransaction,
|
||||
savingsTransaction, clientTransaction, shareTransactionId);
|
||||
}
|
||||
|
||||
protected JournalEntry() {
|
||||
//
|
||||
}
|
||||
@@ -124,8 +110,7 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
public JournalEntry(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount, final String currencyCode,
|
||||
final String transactionId, final boolean manualEntry, final LocalDate transactionDate, final Integer type,
|
||||
final BigDecimal amount, final String description, final Integer entityType, final Long entityId, final String referenceNumber,
|
||||
final LoanTransaction loanTransaction, final SavingsAccountTransaction savingsTransaction,
|
||||
final ClientTransaction clientTransaction, final Long shareTransactionId) {
|
||||
final Long loanTransactionId, final Long savingsTransactionId, final Long clientTransactionId, final Long shareTransactionId) {
|
||||
this.office = office;
|
||||
this.glAccount = glAccount;
|
||||
this.reversalJournalEntry = null;
|
||||
@@ -140,42 +125,28 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
this.entityId = entityId;
|
||||
this.referenceNumber = referenceNumber;
|
||||
this.currencyCode = currencyCode;
|
||||
this.loanTransaction = loanTransaction;
|
||||
this.savingsTransaction = savingsTransaction;
|
||||
this.clientTransaction = clientTransaction;
|
||||
this.loanTransactionId = loanTransactionId;
|
||||
this.savingsTransactionId = savingsTransactionId;
|
||||
this.clientTransactionId = clientTransactionId;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.shareTransactionId = shareTransactionId;
|
||||
this.submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||
}
|
||||
|
||||
public static JournalEntry createNew(final Office office, final PaymentDetail paymentDetail, final GLAccount glAccount,
|
||||
final String currencyCode, final String transactionId, final boolean manualEntry, final LocalDate transactionDate,
|
||||
final JournalEntryType journalEntryType, final BigDecimal amount, final String description, final Integer entityType,
|
||||
final Long entityId, final String referenceNumber, final Long loanTransaction, final Long savingsTransaction,
|
||||
final Long clientTransaction, Long shareTransactionId) {
|
||||
return new JournalEntry(office, paymentDetail, glAccount, currencyCode, transactionId, manualEntry, transactionDate,
|
||||
journalEntryType.getValue(), amount, description, entityType, entityId, referenceNumber, loanTransaction,
|
||||
savingsTransaction, clientTransaction, shareTransactionId);
|
||||
}
|
||||
|
||||
public boolean isDebitEntry() {
|
||||
return JournalEntryType.DEBIT.getValue().equals(this.type);
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Office getOffice() {
|
||||
return this.office;
|
||||
}
|
||||
|
||||
public GLAccount getGlAccount() {
|
||||
return this.glAccount;
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public void setReversalJournalEntry(final JournalEntry reversalJournalEntry) {
|
||||
this.reversalJournalEntry = reversalJournalEntry;
|
||||
}
|
||||
@@ -183,57 +154,4 @@ public class JournalEntry extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
public void setReversed(final boolean reversed) {
|
||||
this.reversed = reversed;
|
||||
}
|
||||
|
||||
public String getReferenceNumber() {
|
||||
return this.referenceNumber;
|
||||
}
|
||||
|
||||
public String getCurrencyCode() {
|
||||
return this.currencyCode;
|
||||
}
|
||||
|
||||
public LoanTransaction getLoanTransaction() {
|
||||
return this.loanTransaction;
|
||||
}
|
||||
|
||||
public SavingsAccountTransaction getSavingsTransaction() {
|
||||
return this.savingsTransaction;
|
||||
}
|
||||
|
||||
public PaymentDetail getPaymentDetails() {
|
||||
return this.paymentDetail;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public ClientTransaction getClientTransaction() {
|
||||
return this.clientTransaction;
|
||||
}
|
||||
|
||||
public Long getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
public Integer getEntityType() {
|
||||
return this.entityType;
|
||||
}
|
||||
|
||||
public Long getShareTransactionId() {
|
||||
return this.shareTransactionId;
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public LocalDate getSubmittedOnDate() {
|
||||
return this.submittedOnDate;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-13
@@ -24,8 +24,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface JournalEntryRepository
|
||||
extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry>, JournalEntryRepositoryCustom {
|
||||
public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry> {
|
||||
|
||||
@Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.manualEntry=true")
|
||||
List<JournalEntry> findUnReversedManualJournalEntriesByTransactionId(@Param("transactionId") String transactionId);
|
||||
@@ -42,15 +41,4 @@ public interface JournalEntryRepository
|
||||
@Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.entityType = :entityType")
|
||||
List<JournalEntry> findJournalEntries(@Param("transactionId") String transactionId, @Param("entityType") Integer entityType);
|
||||
|
||||
/*
|
||||
* @Query("select journalEntry from JournalEntry journalEntry where glAccount.id= :accountId and transactionId= :transactionId and transactionDate= :transactionDate"
|
||||
* +
|
||||
* " and type= :journalEntryType and entityType=1 and entityId= :loanId and loanTransaction.id= :loanTransactionId"
|
||||
* ) JournalEntry findLOANJournalEntryWith(@Param("accountId") Long accountId, @Param("transactionId") String
|
||||
* transactionId,
|
||||
*
|
||||
* @Param("transactionDate") Date transactionDate, @Param("journalEntryType") Integer journalEntryType,
|
||||
*
|
||||
* @Param("loanId") Long loanId, @Param("loanTransactionId") Long loanTransactionId);
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.exception;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.ext.ExceptionMapper;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformInternalServerException;
|
||||
import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
|
||||
import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformApiDataValidationExceptionMapper;
|
||||
import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformDataIntegrityExceptionMapper;
|
||||
import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformDomainRuleExceptionMapper;
|
||||
import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformInternalServerExceptionMapper;
|
||||
import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformResourceNotFoundExceptionMapper;
|
||||
import org.apache.fineract.infrastructure.core.exceptionmapper.UnsupportedParameterExceptionMapper;
|
||||
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.dao.NonTransientDataAccessException;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
|
||||
/**
|
||||
* Provides an Error Handler method that returns an object of type {@link ErrorInfo} to the CommandStrategy which raised
|
||||
* the exception. This class uses various subclasses of RuntimeException to check the kind of exception raised and
|
||||
* provide appropriate status and error codes for each one of the raised exception.
|
||||
*
|
||||
* @author Rishabh Shukla
|
||||
* @see org.apache.fineract.batch.command.CommandStrategy
|
||||
*/
|
||||
public final class ErrorHandler {
|
||||
|
||||
private static final Gson JSON_HELPER = GoogleGsonSerializerHelper.createGsonBuilder(true).create();
|
||||
|
||||
private static final LinkedHashMap<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> EXCEPTION_HANDLERS = new LinkedHashMap<>();
|
||||
private static final Map.Entry<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> DEFAULT_ERROR_HANDLER = Map.entry(
|
||||
RuntimeException.class,
|
||||
runtimeException -> new ErrorInfo(500, 9999, "{\"Exception\": %s}".formatted(runtimeException.getMessage())));
|
||||
|
||||
static {
|
||||
EXCEPTION_HANDLERS.put(AbstractPlatformResourceNotFoundException.class,
|
||||
runtimeException -> handleException(runtimeException, new PlatformResourceNotFoundExceptionMapper(), 1001));
|
||||
EXCEPTION_HANDLERS.put(UnsupportedParameterException.class,
|
||||
runtimeException -> handleException(runtimeException, new UnsupportedParameterExceptionMapper(), 2001));
|
||||
EXCEPTION_HANDLERS.put(PlatformApiDataValidationException.class,
|
||||
runtimeException -> handleException(runtimeException, new PlatformApiDataValidationExceptionMapper(), 2002));
|
||||
EXCEPTION_HANDLERS.put(PlatformDataIntegrityException.class,
|
||||
runtimeException -> handleException(runtimeException, new PlatformDataIntegrityExceptionMapper(), 3001));
|
||||
EXCEPTION_HANDLERS.put(AbstractPlatformDomainRuleException.class,
|
||||
runtimeException -> handleException(runtimeException, new PlatformDomainRuleExceptionMapper(), 9999));
|
||||
EXCEPTION_HANDLERS.put(TransactionException.class, runtimeException -> new ErrorInfo(HttpStatus.SC_BAD_REQUEST, 4001,
|
||||
"{\"Exception\": %s}".formatted(runtimeException.getMessage())));
|
||||
EXCEPTION_HANDLERS.put(PlatformInternalServerException.class,
|
||||
runtimeException -> handleException(runtimeException, new PlatformInternalServerExceptionMapper(), 5001));
|
||||
EXCEPTION_HANDLERS.put(NonTransientDataAccessException.class, runtimeException -> new ErrorInfo(HttpStatus.SC_BAD_REQUEST, 4002,
|
||||
"{\"Exception\": %s}".formatted(runtimeException.getMessage())));
|
||||
EXCEPTION_HANDLERS.put(DEFAULT_ERROR_HANDLER.getKey(), DEFAULT_ERROR_HANDLER.getValue());
|
||||
}
|
||||
|
||||
private ErrorHandler() {}
|
||||
|
||||
public static void registerNewErrorHandler(final Class<? extends RuntimeException> exceptionClass, final ExceptionMapper mapper,
|
||||
int errorCode) {
|
||||
LinkedHashMap<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> newHandlers = new LinkedHashMap<>();
|
||||
newHandlers.put(exceptionClass, runtimeException -> handleException(runtimeException, mapper, errorCode));
|
||||
EXCEPTION_HANDLERS.forEach(newHandlers::putIfAbsent);
|
||||
}
|
||||
|
||||
public static void registerNewErrorHandler(final Class<? extends RuntimeException> exceptionClass,
|
||||
Function<RuntimeException, ErrorInfo> function) {
|
||||
LinkedHashMap<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> newHandlers = new LinkedHashMap<>();
|
||||
newHandlers.put(exceptionClass, function);
|
||||
EXCEPTION_HANDLERS.forEach(newHandlers::putIfAbsent);
|
||||
}
|
||||
|
||||
private static ErrorInfo handleException(final RuntimeException exception, final ExceptionMapper mapper, final int errorCode) {
|
||||
final Response response = mapper.toResponse(exception);
|
||||
final String errorBody = JSON_HELPER.toJson(response.getEntity());
|
||||
return new ErrorInfo(response.getStatus(), errorCode, errorBody);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object of ErrorInfo type containing the information regarding the raised error.
|
||||
*
|
||||
* @param exception
|
||||
* @return ErrorInfo
|
||||
*/
|
||||
public static ErrorInfo handler(final RuntimeException exception) {
|
||||
Map.Entry<Class<? extends Exception>, Function<RuntimeException, ErrorInfo>> errorhandler = EXCEPTION_HANDLERS.entrySet().stream()
|
||||
.filter(e -> e.getKey().isAssignableFrom(exception.getClass())).findFirst().orElse(DEFAULT_ERROR_HANDLER);
|
||||
return errorhandler.getValue().apply(exception);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user