FINERACT-1926: External owner accounting
This commit is contained in:
committed by
Arnold Gálovics
parent
437b8e9cae
commit
582f36ad34
+140
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* 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.investor.accounting.journalentry.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.accounting.closure.domain.GLClosure;
|
||||
import org.apache.fineract.accounting.closure.domain.GLClosureRepository;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants;
|
||||
import org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
|
||||
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.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
|
||||
import org.apache.fineract.accounting.journalentry.exception.JournalEntryInvalidException;
|
||||
import org.apache.fineract.accounting.journalentry.exception.JournalEntryInvalidException.GlJournalEntryInvalidReason;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioProductType;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class InvestorAccountingHelper {
|
||||
|
||||
public static final String INVESTOR_TRANSFER_IDENTIFIER = "I";
|
||||
|
||||
private final JournalEntryRepository glJournalEntryRepository;
|
||||
private final ProductToGLAccountMappingRepository accountMappingRepository;
|
||||
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository;
|
||||
private final GLClosureRepository closureRepository;
|
||||
|
||||
/**
|
||||
* @param officeId
|
||||
* @param transactionDate
|
||||
*/
|
||||
public void checkForBranchClosures(Long officeId, final LocalDate transactionDate) {
|
||||
/**
|
||||
* check if an accounting closure has happened for this branch after the transaction Date
|
||||
**/
|
||||
GLClosure gLClosure = getLatestClosureByBranch(officeId);
|
||||
if (gLClosure != null) {
|
||||
if (gLClosure.getClosingDate().isAfter(transactionDate) || gLClosure.getClosingDate().isEqual(transactionDate)) {
|
||||
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, gLClosure.getClosingDate(), null,
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JournalEntry createDebitJournalEntryOrReversalForInvestor(final Office office, final String currencyCode,
|
||||
final int accountMappingTypeId, final Long loanProductId, final Long loanId, final Long transactionId,
|
||||
final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversalOrder) {
|
||||
final GLAccount account = getLinkedGLAccountForLoanProduct(loanProductId, accountMappingTypeId);
|
||||
if (isReversalOrder) {
|
||||
return createCreditJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
|
||||
} else {
|
||||
return createDebitJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
|
||||
}
|
||||
}
|
||||
|
||||
public JournalEntry createCreditJournalEntryOrReversalForInvestor(final Office office, final String currencyCode, final Long loanId,
|
||||
final Long transactionId, final LocalDate transactionDate, final BigDecimal amount, final Boolean isReversalOrder,
|
||||
final GLAccount account) {
|
||||
if (isReversalOrder) {
|
||||
return createDebitJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
|
||||
} else {
|
||||
return createCreditJournalEntryForInvestor(office, currencyCode, account, loanId, transactionId, transactionDate, amount);
|
||||
}
|
||||
}
|
||||
|
||||
private JournalEntry createCreditJournalEntryForInvestor(final Office office, final String currencyCode, final GLAccount account,
|
||||
final Long loanId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
|
||||
final boolean manualEntry = false;
|
||||
final String modifiedTransactionId = INVESTOR_TRANSFER_IDENTIFIER + transactionId;
|
||||
final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
|
||||
transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null, null, null,
|
||||
null, null);
|
||||
return this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
||||
}
|
||||
|
||||
private JournalEntry createDebitJournalEntryForInvestor(final Office office, final String currencyCode, final GLAccount account,
|
||||
final Long loanId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
|
||||
final boolean manualEntry = false;
|
||||
String modifiedTransactionId = INVESTOR_TRANSFER_IDENTIFIER + transactionId;
|
||||
|
||||
final JournalEntry journalEntry = JournalEntry.createNew(office, null, account, currencyCode, modifiedTransactionId, manualEntry,
|
||||
transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.LOAN.getValue(), loanId, null, null, null, null,
|
||||
null);
|
||||
return this.glJournalEntryRepository.saveAndFlush(journalEntry);
|
||||
}
|
||||
|
||||
public GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId) {
|
||||
GLAccount glAccount;
|
||||
if (isOrganizationAccount(accountMappingTypeId)) {
|
||||
FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
|
||||
.findByFinancialActivityTypeWithNotFoundDetection(accountMappingTypeId);
|
||||
glAccount = financialActivityAccount.getGlAccount();
|
||||
} else {
|
||||
ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(loanProductId,
|
||||
PortfolioProductType.LOAN.getValue(), accountMappingTypeId);
|
||||
|
||||
if (accountMapping == null) {
|
||||
throw new ProductToGLAccountMappingNotFoundException(PortfolioProductType.LOAN, loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.fromInt(accountMappingTypeId).toString());
|
||||
}
|
||||
glAccount = accountMapping.getGlAccount();
|
||||
}
|
||||
return glAccount;
|
||||
}
|
||||
|
||||
private boolean isOrganizationAccount(final int accountMappingTypeId) {
|
||||
return FinancialActivity.fromInt(accountMappingTypeId) != null;
|
||||
}
|
||||
|
||||
public GLClosure getLatestClosureByBranch(final long officeId) {
|
||||
return this.closureRepository.getLatestGLClosureByBranch(officeId);
|
||||
}
|
||||
|
||||
}
|
||||
+49
-6
@@ -40,17 +40,19 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext;
|
||||
import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
|
||||
import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
|
||||
import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
|
||||
import org.apache.fineract.investor.data.ExternalTransferData;
|
||||
import org.apache.fineract.investor.data.ExternalTransferResponseData;
|
||||
import org.apache.fineract.investor.service.ExternalAssetOwnersReadService;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -58,13 +60,11 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
@Tag(name = "External Asset Owners", description = "External Asset Owners")
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(value = "fineract.module.external-asset-owner.enabled", havingValue = "true")
|
||||
@Conditional(InvestorModuleIsEnabledCondition.class)
|
||||
public class ExternalAssetOwnersApiResource {
|
||||
|
||||
private final PlatformUserRightsContext platformUserRightsContext;
|
||||
private final ExternalAssetOwnersReadService externalAssetOwnersReadService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final DefaultToApiJsonSerializer<ExternalTransferData> apiJsonSerializerService;
|
||||
private final DefaultToApiJsonSerializer<ExternalTransferResponseData> postApiJsonSerializerService;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final LoanReadPlatformServiceCommon loanReadPlatformService;
|
||||
@@ -106,7 +106,7 @@ public class ExternalAssetOwnersApiResource {
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(tags = {
|
||||
"External Asset Owners" }, summary = "Retrieve External Asset Owner Transfers", description = "Retrieve External Asset Owner Transfer items by transferExternalId, loanId or loanExternalId")
|
||||
public Page<ExternalTransferData> getTransfer(
|
||||
public Page<ExternalTransferData> getTransfers(
|
||||
@QueryParam("transferExternalId") @Parameter(description = "transferExternalId") final String transferExternalId,
|
||||
@QueryParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
||||
@QueryParam("loanExternalId") @Parameter(description = "loanExternalId") final String loanExternalId,
|
||||
@@ -117,6 +117,49 @@ public class ExternalAssetOwnersApiResource {
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/transfers/active-transfer")
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(tags = {
|
||||
"External Asset Owners" }, summary = "Retrieve Active Asset Owner Transfer", description = "Retrieve Active External Asset Owner Transfer by transferExternalId, loanId or loanExternalId")
|
||||
public ExternalTransferData getActiveTransfer(
|
||||
@QueryParam("transferExternalId") @Parameter(description = "transferExternalId") final String transferExternalId,
|
||||
@QueryParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
||||
@QueryParam("loanExternalId") @Parameter(description = "loanExternalId") final String loanExternalId,
|
||||
@Context final UriInfo uriInfo) {
|
||||
platformUserRightsContext.isAuthenticated();
|
||||
return externalAssetOwnersReadService.retrieveActiveTransferData(loanId, loanExternalId, transferExternalId);
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/transfers/{transferId}/journal-entries")
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(tags = {
|
||||
"External Asset Owners" }, summary = "Retrieve Journal Entries of Transfer", description = "Retrieve Journal entries of transfer by transferId")
|
||||
public ExternalOwnerTransferJournalEntryData getJournalEntriesOfTransfer(
|
||||
@PathParam("transferId") @Parameter(description = "transferId") final Long transferId,
|
||||
@QueryParam("offset") @Parameter(description = "offset") final Integer offset,
|
||||
@QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) {
|
||||
platformUserRightsContext.isAuthenticated();
|
||||
return externalAssetOwnersReadService.retrieveJournalEntriesOfTransfer(transferId, offset, limit);
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/owners/external-id/{ownerExternalId}/journal-entries")
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(tags = {
|
||||
"External Asset Owners" }, summary = "Retrieve Journal Entries of Owner", description = "Retrieve Journal entries of owner by owner externalId")
|
||||
public ExternalOwnerJournalEntryData getJournalEntriesOfOwner(
|
||||
@PathParam("ownerExternalId") @Parameter(description = "ownerExternalId") final String ownerExternalId,
|
||||
@QueryParam("offset") @Parameter(description = "offset") final Integer offset,
|
||||
@QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) {
|
||||
platformUserRightsContext.isAuthenticated();
|
||||
return externalAssetOwnersReadService.retrieveJournalEntriesOfOwner(ownerExternalId, offset, limit);
|
||||
|
||||
}
|
||||
|
||||
private String getResult(Long loanId, String apiRequestBodyAsJson, String commandParam) {
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
CommandWrapper commandRequest = null;
|
||||
|
||||
+7
-2
@@ -26,6 +26,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.cob.loan.LoanCOBBusinessStep;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
|
||||
import org.apache.fineract.investor.data.ExternalTransferStatus;
|
||||
import org.apache.fineract.investor.data.ExternalTransferSubStatus;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
|
||||
@@ -33,18 +34,22 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferDetails;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
|
||||
import org.apache.fineract.investor.service.AccountingService;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Conditional(InvestorModuleIsEnabledCondition.class)
|
||||
public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep {
|
||||
|
||||
public static final LocalDate FUTURE_DATE_9999_12_31 = LocalDate.of(9999, 12, 31);
|
||||
private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
|
||||
private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
|
||||
private final AccountingService accountingService;
|
||||
|
||||
@Override
|
||||
public Loan execute(Loan loan) {
|
||||
@@ -109,7 +114,7 @@ public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep
|
||||
externalAssetOwnerTransferRepository.save(activeExternalAssetOwnerTransfer);
|
||||
buybackExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository.save(buybackExternalAssetOwnerTransfer);
|
||||
externalAssetOwnerTransferLoanMappingRepository.deleteByLoanIdAndOwnerTransfer(loan.getId(), activeExternalAssetOwnerTransfer);
|
||||
// TODO: create asset ownership accounting entries
|
||||
accountingService.createJournalEntriesForBuybackAssetTransfer(loan, buybackExternalAssetOwnerTransfer);
|
||||
return buybackExternalAssetOwnerTransfer;
|
||||
}
|
||||
|
||||
@@ -121,7 +126,7 @@ public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep
|
||||
createActiveMapping(loan.getId(), newExternalAssetOwnerTransfer);
|
||||
newExternalAssetOwnerTransfer
|
||||
.setExternalAssetOwnerTransferDetails(createAssetOwnerTransferDetails(loan, newExternalAssetOwnerTransfer));
|
||||
// TODO: create asset ownership accounting entries
|
||||
accountingService.createJournalEntriesForSaleAssetTransfer(loan, newExternalAssetOwnerTransfer);
|
||||
} else {
|
||||
ExternalTransferSubStatus subStatus = ExternalTransferSubStatus.BALANCE_ZERO;
|
||||
if (loan.getTotalOverpaid().compareTo(BigDecimal.ZERO) > 0) {
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.investor.config;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.condition.PropertiesCondition;
|
||||
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
||||
|
||||
public class InvestorModuleIsEnabledCondition extends PropertiesCondition {
|
||||
|
||||
@Override
|
||||
protected boolean matches(FineractProperties properties) {
|
||||
return properties.getModule().getInvestor().isEnabled();
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.investor.data;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
@Data
|
||||
public class ExternalOwnerJournalEntryData {
|
||||
|
||||
private ExternalTransferOwnerData ownerData;
|
||||
private Page<JournalEntryData> journalEntryData;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.investor.data;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
@Data
|
||||
public class ExternalOwnerTransferJournalEntryData {
|
||||
|
||||
private ExternalTransferData transferData;
|
||||
private Page<JournalEntryData> journalEntryData;
|
||||
}
|
||||
+1
-1
@@ -26,7 +26,7 @@ public class ExternalTransferData {
|
||||
|
||||
private Long transferId;
|
||||
private ExternalTransferOwnerData owner;
|
||||
private ExternalTransferLoanMappingData loan;
|
||||
private ExternalTransferLoanData loan;
|
||||
private ExternalTransferDataDetails details;
|
||||
private String transferExternalId;
|
||||
private String purchasePriceRatio;
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ package org.apache.fineract.investor.data;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ExternalTransferLoanMappingData {
|
||||
public class ExternalTransferLoanData {
|
||||
|
||||
private final Long loanId;
|
||||
private final String externalId;
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* 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.investor.domain;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(name = "m_external_asset_owner_journal_entry_mapping")
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
public class ExternalAssetOwnerJournalEntryMapping extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "journal_entry_id", nullable = false)
|
||||
private JournalEntry journalEntry;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "owner_id", nullable = false)
|
||||
private ExternalAssetOwner owner;
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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.investor.domain;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface ExternalAssetOwnerJournalEntryMappingRepository extends JpaRepository<ExternalAssetOwnerJournalEntryMapping, Long>,
|
||||
JpaSpecificationExecutor<ExternalAssetOwnerJournalEntryMapping> {
|
||||
|
||||
@Query("SELECT mapping FROM ExternalAssetOwnerJournalEntryMapping mapping WHERE mapping.owner.externalId = :ownerExternalId")
|
||||
Page<ExternalAssetOwnerJournalEntryMapping> findByExternalOwnerId(@Param("ownerExternalId") ExternalId ownerExternalId,
|
||||
PageRequest pageRequest);
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* 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.investor.domain;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(name = "m_external_asset_owner_transfer_journal_entry_mapping")
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
public class ExternalAssetOwnerTransferJournalEntryMapping extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "journal_entry_id", nullable = false)
|
||||
private JournalEntry journalEntry;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "owner_transfer_id", nullable = false)
|
||||
private ExternalAssetOwnerTransfer ownerTransfer;
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.investor.domain;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface ExternalAssetOwnerTransferJournalEntryMappingRepository
|
||||
extends JpaRepository<ExternalAssetOwnerTransferJournalEntryMapping, Long>,
|
||||
JpaSpecificationExecutor<ExternalAssetOwnerTransferJournalEntryMapping> {
|
||||
|
||||
@Query("SELECT mapping FROM ExternalAssetOwnerTransferJournalEntryMapping mapping WHERE mapping.ownerTransfer.id =:transferId")
|
||||
Page<ExternalAssetOwnerTransferJournalEntryMapping> findByTransferId(@Param("transferId") Long transferId, PageRequest pageable);
|
||||
}
|
||||
+12
@@ -18,11 +18,23 @@
|
||||
*/
|
||||
package org.apache.fineract.investor.domain;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
public interface ExternalAssetOwnerTransferLoanMappingRepository extends JpaRepository<ExternalAssetOwnerTransferLoanMapping, Long>,
|
||||
JpaSpecificationExecutor<ExternalAssetOwnerTransferLoanMapping> {
|
||||
|
||||
void deleteByLoanIdAndOwnerTransfer(Long loanId, ExternalAssetOwnerTransfer externalAssetOwnerTransfer);
|
||||
|
||||
Optional<ExternalAssetOwnerTransferLoanMapping> findByLoanId(Long loanId);
|
||||
|
||||
@Query("SELECT mapping FROM ExternalAssetOwnerTransferLoanMapping mapping WHERE mapping.ownerTransfer.externalLoanId =:externalLoanId")
|
||||
Optional<ExternalAssetOwnerTransferLoanMapping> findByLoanExternalId(@Param("externalLoanId") ExternalId externalLoanId);
|
||||
|
||||
@Query("SELECT mapping FROM ExternalAssetOwnerTransferLoanMapping mapping WHERE mapping.ownerTransfer.externalId =:externalTransferId")
|
||||
Optional<ExternalAssetOwnerTransferLoanMapping> findByTransferExternalId(@Param("externalTransferId") ExternalId externalTransferId);
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 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.investor.internal;
|
||||
|
||||
public class InternalAPIForTesting {}
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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.investor.service;
|
||||
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
|
||||
public interface AccountingService {
|
||||
|
||||
void createJournalEntriesForSaleAssetTransfer(Loan loan, ExternalAssetOwnerTransfer transfer);
|
||||
|
||||
void createJournalEntriesForBuybackAssetTransfer(Loan loan, ExternalAssetOwnerTransfer transfer);
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* 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.investor.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
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.fineract.accounting.common.AccountingConstants;
|
||||
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.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
|
||||
import org.apache.fineract.investor.accounting.journalentry.service.InvestorAccountingHelper;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMappingRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMappingRepository;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AccountingServiceImpl implements AccountingService {
|
||||
|
||||
private final InvestorAccountingHelper helper;
|
||||
private final ExternalAssetOwnerTransferJournalEntryMappingRepository externalAssetOwnerTransferJournalEntryMappingRepository;
|
||||
private final ExternalAssetOwnerJournalEntryMappingRepository externalAssetOwnerJournalEntryMappingRepository;
|
||||
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository;
|
||||
|
||||
private static boolean participateInTransfer(FinancialActivityAccount financialActivityAccount, JournalEntry journalEntry,
|
||||
JournalEntryType filterType) {
|
||||
return filterType.getValue().equals(journalEntry.getType())
|
||||
&& !Objects.equals(financialActivityAccount.getGlAccount().getId(), journalEntry.getGlAccount().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createJournalEntriesForSaleAssetTransfer(final Loan loan, final ExternalAssetOwnerTransfer transfer) {
|
||||
List<JournalEntry> journalEntryList = createJournalEntries(loan, transfer, true);
|
||||
createMappingToTransfer(transfer, journalEntryList);
|
||||
createMappingToOwner(transfer, journalEntryList, JournalEntryType.DEBIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createJournalEntriesForBuybackAssetTransfer(final Loan loan, final ExternalAssetOwnerTransfer transfer) {
|
||||
List<JournalEntry> journalEntryList = createJournalEntries(loan, transfer, false);
|
||||
createMappingToTransfer(transfer, journalEntryList);
|
||||
createMappingToOwner(transfer, journalEntryList, JournalEntryType.CREDIT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JournalEntry> createJournalEntries(Loan loan, ExternalAssetOwnerTransfer transfer, boolean isReversalOrder) {
|
||||
this.helper.checkForBranchClosures(loan.getOffice().getId(), transfer.getSettlementDate());
|
||||
// loan properties
|
||||
final Long loanProductId = loan.getLoanProduct().getId();
|
||||
final Long loanId = loan.getId();
|
||||
final Office office = loan.getOffice();
|
||||
final String currencyCode = loan.getCurrencyCode();
|
||||
// transaction properties
|
||||
final Long transactionId = transfer.getId();
|
||||
final LocalDate transactionDate = transfer.getSettlementDate();
|
||||
final BigDecimal principalAmount = loan.getLoanSummary().getTotalPrincipalOutstanding();
|
||||
final BigDecimal interestAmount = loan.getLoanSummary().getTotalInterestOutstanding();
|
||||
final BigDecimal feesAmount = loan.getLoanSummary().getTotalFeeChargesOutstanding();
|
||||
final BigDecimal penaltiesAmount = loan.getLoanSummary().getTotalPenaltyChargesOutstanding();
|
||||
final BigDecimal overPaymentAmount = loan.getTotalOverpaid();
|
||||
|
||||
// Moving money to asset transfer account
|
||||
List<JournalEntry> journalEntryList = createJournalEntries(loanProductId, loanId, office, currencyCode, transactionId,
|
||||
transactionDate, principalAmount, interestAmount, feesAmount, penaltiesAmount, overPaymentAmount, !isReversalOrder);
|
||||
// Moving money from asset transfer account
|
||||
journalEntryList.addAll(createJournalEntries(loanProductId, loanId, office, currencyCode, transactionId, transactionDate,
|
||||
principalAmount, interestAmount, feesAmount, penaltiesAmount, overPaymentAmount, isReversalOrder));
|
||||
return journalEntryList;
|
||||
}
|
||||
|
||||
private void createMappingToOwner(ExternalAssetOwnerTransfer transfer, List<JournalEntry> journalEntryList,
|
||||
JournalEntryType filterType) {
|
||||
FinancialActivityAccount financialActivityAccount = this.financialActivityAccountRepository
|
||||
.findByFinancialActivityTypeWithNotFoundDetection(AccountingConstants.FinancialActivity.ASSET_TRANSFER.getValue());
|
||||
journalEntryList.forEach(journalEntry -> {
|
||||
if (participateInTransfer(financialActivityAccount, journalEntry, filterType)) {
|
||||
ExternalAssetOwnerJournalEntryMapping mapping = new ExternalAssetOwnerJournalEntryMapping();
|
||||
mapping.setJournalEntry(journalEntry);
|
||||
mapping.setOwner(transfer.getOwner());
|
||||
externalAssetOwnerJournalEntryMappingRepository.saveAndFlush(mapping);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createMappingToTransfer(ExternalAssetOwnerTransfer transfer, List<JournalEntry> journalEntryList) {
|
||||
journalEntryList.forEach(journalEntry -> {
|
||||
ExternalAssetOwnerTransferJournalEntryMapping mapping = new ExternalAssetOwnerTransferJournalEntryMapping();
|
||||
mapping.setJournalEntry(journalEntry);
|
||||
mapping.setOwnerTransfer(transfer);
|
||||
externalAssetOwnerTransferJournalEntryMappingRepository.saveAndFlush(mapping);
|
||||
});
|
||||
}
|
||||
|
||||
private List<JournalEntry> createJournalEntries(Long loanProductId, Long loanId, Office office, String currencyCode, Long transactionId,
|
||||
LocalDate transactionDate, BigDecimal principalAmount, BigDecimal interestAmount, BigDecimal feesAmount,
|
||||
BigDecimal penaltiesAmount, BigDecimal overPaymentAmount, boolean isReversalOrder) {
|
||||
List<JournalEntry> journalEntryList = new ArrayList<>();
|
||||
BigDecimal totalDebitAmount = BigDecimal.ZERO;
|
||||
Map<GLAccount, BigDecimal> accountMap = new LinkedHashMap<>();
|
||||
// principal entry
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue());
|
||||
accountMap.put(account, principalAmount);
|
||||
}
|
||||
// interest entry
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
totalDebitAmount = totalDebitAmount.add(interestAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(interestAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, interestAmount);
|
||||
}
|
||||
}
|
||||
// fee entry
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
totalDebitAmount = totalDebitAmount.add(feesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.FEES_RECEIVABLE.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(feesAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, feesAmount);
|
||||
}
|
||||
}
|
||||
// penalty entry
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(penaltiesAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, penaltiesAmount);
|
||||
}
|
||||
}
|
||||
// overpaid entry
|
||||
if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.OVERPAYMENT.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(overPaymentAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, overPaymentAmount);
|
||||
}
|
||||
}
|
||||
// asset transfer entry
|
||||
for (Map.Entry<GLAccount, BigDecimal> entry : accountMap.entrySet()) {
|
||||
journalEntryList.add(this.helper.createCreditJournalEntryOrReversalForInvestor(office, currencyCode, loanId, transactionId,
|
||||
transactionDate, entry.getValue(), isReversalOrder, entry.getKey()));
|
||||
}
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
journalEntryList.add(this.helper.createDebitJournalEntryOrReversalForInvestor(office, currencyCode,
|
||||
AccountingConstants.FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId, loanId, transactionId, transactionDate,
|
||||
totalDebitAmount, isReversalOrder));
|
||||
}
|
||||
return journalEntryList;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 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.investor.service;
|
||||
|
||||
public interface ExternalAssetOwnerJournalEntryService {}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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.investor.service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.journalentry.LoanJournalEntryCreatedBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMappingRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Conditional(InvestorModuleIsEnabledCondition.class)
|
||||
public class ExternalAssetOwnerJournalEntryServiceImpl implements ExternalAssetOwnerJournalEntryService {
|
||||
|
||||
private final BusinessEventNotifierService businessEventNotifierService;
|
||||
private final ExternalAssetOwnerJournalEntryMappingRepository externalAssetOwnerJournalEntryMappingRepository;
|
||||
private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
|
||||
private final LoanTransactionRepository loanTransactionRepository;
|
||||
|
||||
@PostConstruct
|
||||
public void addListeners() {
|
||||
businessEventNotifierService.addPostBusinessEventListener(LoanJournalEntryCreatedBusinessEvent.class,
|
||||
new HandleLoanJournalEntryCreatedBusinessEvent());
|
||||
}
|
||||
|
||||
private class HandleLoanJournalEntryCreatedBusinessEvent implements BusinessEventListener<LoanJournalEntryCreatedBusinessEvent> {
|
||||
|
||||
@Override
|
||||
public void onBusinessEvent(LoanJournalEntryCreatedBusinessEvent event) {
|
||||
JournalEntry journalEntry = event.get();
|
||||
createMapping(journalEntry);
|
||||
}
|
||||
|
||||
private void createMapping(JournalEntry journalEntry) {
|
||||
Long loanId = loanTransactionRepository.findLoanIdById(journalEntry.getLoanTransactionId()).orElseThrow();
|
||||
externalAssetOwnerTransferLoanMappingRepository.findByLoanId(loanId).ifPresent(transferLoanMapping -> {
|
||||
ExternalAssetOwnerJournalEntryMapping mapping = new ExternalAssetOwnerJournalEntryMapping();
|
||||
mapping.setJournalEntry(journalEntry);
|
||||
mapping.setOwner(transferLoanMapping.getOwnerTransfer().getOwner());
|
||||
externalAssetOwnerJournalEntryMappingRepository.saveAndFlush(mapping);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.fineract.investor.service;
|
||||
|
||||
import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
|
||||
import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
|
||||
import org.apache.fineract.investor.data.ExternalTransferData;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
@@ -25,4 +27,10 @@ public interface ExternalAssetOwnersReadService {
|
||||
|
||||
Page<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId, Integer offset,
|
||||
Integer limit);
|
||||
|
||||
ExternalTransferData retrieveActiveTransferData(Long loanId, String externalLoanId, String transferExternalId);
|
||||
|
||||
ExternalOwnerTransferJournalEntryData retrieveJournalEntriesOfTransfer(Long transferId, Integer offset, Integer limit);
|
||||
|
||||
ExternalOwnerJournalEntryData retrieveJournalEntriesOfOwner(String ownerExternalId, Integer offset, Integer limit);
|
||||
}
|
||||
|
||||
+68
-7
@@ -18,10 +18,20 @@
|
||||
*/
|
||||
package org.apache.fineract.investor.service;
|
||||
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.accounting.journalentry.JournalEntryMapper;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
|
||||
import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
|
||||
import org.apache.fineract.investor.data.ExternalTransferData;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMappingRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMappingRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -35,19 +45,17 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
public class ExternalAssetOwnersReadServiceImpl implements ExternalAssetOwnersReadService {
|
||||
|
||||
private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
|
||||
private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
|
||||
private final ExternalAssetOwnerTransferJournalEntryMappingRepository externalAssetOwnerTransferJournalEntryMappingRepository;
|
||||
private final ExternalAssetOwnerJournalEntryMappingRepository externalAssetOwnerJournalEntryMappingRepository;
|
||||
private final ExternalAssetOwnersTransferMapper mapper;
|
||||
private final JournalEntryMapper journalEntryMapper;
|
||||
|
||||
@Override
|
||||
public Page<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId, Integer offset,
|
||||
Integer limit) {
|
||||
Page<ExternalAssetOwnerTransfer> result;
|
||||
if (offset == null) {
|
||||
offset = 0;
|
||||
}
|
||||
if (limit == null) {
|
||||
limit = 100;
|
||||
}
|
||||
PageRequest pageRequest = PageRequest.of(offset, limit, Sort.by("id"));
|
||||
PageRequest pageRequest = getPageRequest(offset, limit);
|
||||
if (loanId != null) {
|
||||
result = externalAssetOwnerTransferRepository.findAllByLoanId(loanId, pageRequest);
|
||||
} else if (externalLoanId != null) {
|
||||
@@ -61,4 +69,57 @@ public class ExternalAssetOwnersReadServiceImpl implements ExternalAssetOwnersRe
|
||||
return result.map(mapper::mapTransfer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalTransferData retrieveActiveTransferData(Long loanId, String externalLoanId, String transferExternalId) {
|
||||
Optional<ExternalAssetOwnerTransferLoanMapping> result;
|
||||
if (loanId != null) {
|
||||
result = externalAssetOwnerTransferLoanMappingRepository.findByLoanId(loanId);
|
||||
} else if (externalLoanId != null) {
|
||||
result = externalAssetOwnerTransferLoanMappingRepository.findByLoanExternalId(ExternalIdFactory.produce(externalLoanId));
|
||||
} else if (transferExternalId != null) {
|
||||
result = externalAssetOwnerTransferLoanMappingRepository
|
||||
.findByTransferExternalId(ExternalIdFactory.produce(transferExternalId));
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"At least one of the following parameters must be provided: loanId, externalLoanId, transferExternalId");
|
||||
}
|
||||
return result.map(transferLoanMapping -> mapper.mapTransfer(transferLoanMapping.getOwnerTransfer())).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalOwnerTransferJournalEntryData retrieveJournalEntriesOfTransfer(Long transferId, Integer offset, Integer limit) {
|
||||
PageRequest pageRequest = getPageRequest(offset, limit);
|
||||
Page<ExternalAssetOwnerTransferJournalEntryMapping> result = externalAssetOwnerTransferJournalEntryMappingRepository
|
||||
.findByTransferId(transferId, pageRequest);
|
||||
ExternalOwnerTransferJournalEntryData mappedResult = new ExternalOwnerTransferJournalEntryData();
|
||||
if (result.hasContent()) {
|
||||
mappedResult.setJournalEntryData(result.map(entry -> journalEntryMapper.map(entry.getJournalEntry())));
|
||||
mappedResult.setTransferData(mapper.mapTransfer(result.stream().findFirst().get().getOwnerTransfer()));
|
||||
}
|
||||
return mappedResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalOwnerJournalEntryData retrieveJournalEntriesOfOwner(String ownerExternalId, Integer offset, Integer limit) {
|
||||
PageRequest pageRequest = getPageRequest(offset, limit);
|
||||
Page<ExternalAssetOwnerJournalEntryMapping> result = externalAssetOwnerJournalEntryMappingRepository
|
||||
.findByExternalOwnerId(ExternalIdFactory.produce(ownerExternalId), pageRequest);
|
||||
ExternalOwnerJournalEntryData mappedResult = new ExternalOwnerJournalEntryData();
|
||||
if (result.hasContent()) {
|
||||
mappedResult.setJournalEntryData(result.map(entry -> journalEntryMapper.map(entry.getJournalEntry())));
|
||||
mappedResult.setOwnerData(mapper.mapOwner(result.stream().findFirst().get().getOwner()));
|
||||
}
|
||||
return mappedResult;
|
||||
}
|
||||
|
||||
private PageRequest getPageRequest(Integer offset, Integer limit) {
|
||||
if (offset == null) {
|
||||
offset = 0;
|
||||
}
|
||||
if (limit == null) {
|
||||
limit = 100;
|
||||
}
|
||||
return PageRequest.of(offset, limit, Sort.by("id"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.investor.service;
|
||||
|
||||
import org.apache.fineract.accounting.journalentry.JournalEntryMapper;
|
||||
import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
|
||||
import org.apache.fineract.investor.data.ExternalTransferData;
|
||||
import org.apache.fineract.investor.data.ExternalTransferDataDetails;
|
||||
@@ -28,7 +29,7 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferDetails;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
@Mapper(config = MapstructMapperConfig.class)
|
||||
@Mapper(config = MapstructMapperConfig.class, uses = JournalEntryMapper.class)
|
||||
public interface ExternalAssetOwnersTransferMapper {
|
||||
|
||||
@Mapping(target = "transferId", source = "id")
|
||||
|
||||
-2
@@ -51,7 +51,6 @@ import org.apache.fineract.investor.data.ExternalTransferStatus;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwner;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
|
||||
import org.apache.fineract.investor.exception.ExternalAssetOwnerInitiateTransferException;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
|
||||
@@ -70,7 +69,6 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
||||
private static final List<ExternalTransferStatus> BUYBACK_READY_STATUSES = List.of(ExternalTransferStatus.PENDING,
|
||||
ExternalTransferStatus.ACTIVE);
|
||||
private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
|
||||
private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
|
||||
private final ExternalAssetOwnerRepository externalAssetOwnerRepository;
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final LoanRepository loanRepository;
|
||||
|
||||
+1
@@ -29,4 +29,5 @@
|
||||
<include relativeToChangelogFile="true" file="parts/0005_add_sale_and_buyback_command.xml"/>
|
||||
<include relativeToChangelogFile="true" file="parts/0006_asset_schemas.xml"/>
|
||||
<include relativeToChangelogFile="true" file="parts/0007_add_external_asset_owner_transfer_details.xml"/>
|
||||
<include relativeToChangelogFile="true" file="parts/0008_add_mappings.xml"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!-- Create table m_external_asset_owner_transfer_journal_entry_mapping -->
|
||||
<changeSet author="fineract" id="1" context="mysql">
|
||||
<createTable tableName="m_external_asset_owner_transfer_journal_entry_mapping">
|
||||
<column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="owner_transfer_id" type="bigint" remarks="Owner transfer">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_by" type="bigint" remarks=""/>
|
||||
<column name="created_on_utc" type="DATETIME" remarks=""/>
|
||||
<column name="last_modified_by" type="bigint" remarks=""/>
|
||||
<column name="last_modified_on_utc" type="DATETIME" remarks=""/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="1" context="postgresql">
|
||||
<createTable tableName="m_external_asset_owner_transfer_journal_entry_mapping">
|
||||
<column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="owner_transfer_id" type="bigint" remarks="Owner transfer">
|
||||
</column>
|
||||
<column name="created_by" type="bigint" remarks=""/>
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
|
||||
<column name="last_modified_by" type="bigint" remarks=""/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="2">
|
||||
<addForeignKeyConstraint baseColumnNames="created_by"
|
||||
baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_transfer_je_mapping_created_by" deferrable="false"
|
||||
initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="last_modified_by"
|
||||
baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_transfer_je_mapping_modified_by" deferrable="false"
|
||||
initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
|
||||
<addForeignKeyConstraint baseColumnNames="journal_entry_id"
|
||||
baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_transfer_je_mapping_journal_entry_id" deferrable="false"
|
||||
initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="acc_gl_journal_entry" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="owner_transfer_id"
|
||||
baseTableName="m_external_asset_owner_transfer_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_transfer_je_mapping_owner_transfer_id"
|
||||
deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_external_asset_owner_transfer" validate="true"/>
|
||||
</changeSet>
|
||||
|
||||
<!-- Create table m_external_asset_owner_journal_entry_mapping -->
|
||||
<changeSet author="fineract" id="3" context="mysql">
|
||||
<createTable tableName="m_external_asset_owner_journal_entry_mapping">
|
||||
<column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="owner_id" type="bigint" remarks="Owner">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_by" type="bigint" remarks=""/>
|
||||
<column name="created_on_utc" type="DATETIME" remarks=""/>
|
||||
<column name="last_modified_by" type="bigint" remarks=""/>
|
||||
<column name="last_modified_on_utc" type="DATETIME" remarks=""/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="3" context="postgresql">
|
||||
<createTable tableName="m_external_asset_owner_journal_entry_mapping">
|
||||
<column autoIncrement="true" name="id" type="BIGINT" remarks="Internal ID">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="journal_entry_id" type="bigint" remarks="Journal entry ID">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="owner_id" type="bigint" remarks="Owner">
|
||||
</column>
|
||||
<column name="created_by" type="bigint" remarks=""/>
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
|
||||
<column name="last_modified_by" type="bigint" remarks=""/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE" remarks=""/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="fineract" id="4">
|
||||
<addForeignKeyConstraint baseColumnNames="created_by"
|
||||
baseTableName="m_external_asset_owner_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_je_mapping_created_by" deferrable="false"
|
||||
initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="last_modified_by"
|
||||
baseTableName="m_external_asset_owner_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_je_mapping_modified_by" deferrable="false"
|
||||
initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
|
||||
<addForeignKeyConstraint baseColumnNames="journal_entry_id"
|
||||
baseTableName="m_external_asset_owner_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_je_mapping_journal_entry_id" deferrable="false"
|
||||
initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="acc_gl_journal_entry" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="owner_id"
|
||||
baseTableName="m_external_asset_owner_journal_entry_mapping"
|
||||
constraintName="FK_ext_asset_owner_je_mapping_owner_id"
|
||||
deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_external_asset_owner" validate="true"/>
|
||||
</changeSet>
|
||||
<!-- Add index to m_external_asset_owner_transfer_loan_mapping of loan_id -->
|
||||
<changeSet id="5" author="fineract">
|
||||
<createIndex tableName="m_external_asset_owner_transfer_loan_mapping"
|
||||
indexName="IND_m_ext_asset_owner_transfer_loan_mapping_loan_id">
|
||||
<column name="loan_id"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -30,6 +30,7 @@
|
||||
<persistence-unit name="jpa-pu" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
||||
<class>org.apache.fineract.accounting.glaccount.domain.GLAccount</class>
|
||||
<class>org.apache.fineract.accounting.journalentry.domain.JournalEntry</class>
|
||||
<class>org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom</class>
|
||||
<class>org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom</class>
|
||||
<class>org.apache.fineract.infrastructure.codes.domain.Code</class>
|
||||
|
||||
Reference in New Issue
Block a user