diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteRepository.java index 4fcf398a2d6..584e7a58b93 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteRepository.java @@ -24,6 +24,8 @@ import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; @@ -53,6 +55,12 @@ public interface NoteRepository extends JpaRepository, JpaSpecificat @Query("select note from Note note where note.savingsTransaction.id = :savingsTransactionId") List findBySavingsTransactionId(@Param("savingsTransactionId") Long savingsTransactionId); + Note findBySavingsTransactionAndId(SavingsAccountTransaction savingsTransaction, Long id); + + Note findByShareAccountAndId(ShareAccount shareAccount, Long id); + + List findByShareAccount(ShareAccount shareAccount); + @Modifying void deleteAllBySavingsAccount(SavingsAccount savingsAccount); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java index 44500747ef3..fb4049d6dd4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java @@ -19,7 +19,6 @@ package org.apache.fineract.portfolio.note.service; import java.util.Map; -import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; @@ -43,9 +42,14 @@ import org.apache.fineract.portfolio.note.serialization.NoteCommandFromApiJsonDeserializer; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository; import org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException; +import org.apache.fineract.portfolio.savings.exception.SavingsAccountTransactionNotFoundException; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountRepositoryWrapper; + -@Slf4j public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatformService { private final NoteRepository noteRepository; @@ -55,11 +59,15 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf private final LoanTransactionRepository loanTransactionRepository; private final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final SavingsAccountRepository savingsAccountRepository; + private final SavingsAccountTransactionRepository savingsAccountTransactionRepository; + private final ShareAccountRepositoryWrapper shareAccountRepository; public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepositoryWrapper clientRepository, final GroupRepository groupRepository, final LoanRepositoryWrapper loanRepository, final LoanTransactionRepository loanTransactionRepository, final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer, - final SavingsAccountRepository savingsAccountRepository) { + final SavingsAccountRepository savingsAccountRepository, + final SavingsAccountTransactionRepository savingsAccountTransactionRepository, + final ShareAccountRepositoryWrapper shareAccountRepository) { this.noteRepository = noteRepository; this.clientRepository = clientRepository; this.groupRepository = groupRepository; @@ -67,6 +75,8 @@ public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteReposi this.loanTransactionRepository = loanTransactionRepository; this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.savingsAccountRepository = savingsAccountRepository; + this.savingsAccountTransactionRepository = savingsAccountTransactionRepository; + this.shareAccountRepository = shareAccountRepository; } private CommandProcessingResult createClientNote(final JsonCommand command) { @@ -174,12 +184,47 @@ private CommandProcessingResult createSavingAccountNote(final JsonCommand comman .build(); } + private CommandProcessingResult createSavingsTransactionNote(final JsonCommand command) { + final Long transactionId = command.subentityId(); + final SavingsAccountTransaction savingsTransaction = this.savingsAccountTransactionRepository.findById(transactionId) + .orElseThrow(() -> new SavingsAccountTransactionNotFoundException(command.getSavingsId(), transactionId)); + + final SavingsAccount savingsAccount = savingsTransaction.getSavingsAccount(); + final String note = command.stringValueOfParameterNamed("note"); + final Note newNote = Note.savingsTransactionNote(savingsAccount, savingsTransaction, note); + + this.noteRepository.saveAndFlush(newNote); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(newNote.getId()) // + .withOfficeId(savingsAccount.getClient().getOffice().getId()) // + .withSavingsId(savingsAccount.getId()) // + .build(); + } + + private CommandProcessingResult createShareAccountNote(final JsonCommand command) { + final Long shareAccountId = command.entityId(); + final ShareAccount shareAccount = this.shareAccountRepository.findOneWithNotFoundDetection(shareAccountId); + + final String note = command.stringValueOfParameterNamed("note"); + final Note newNote = Note.shareNote(shareAccount, note); + + this.noteRepository.saveAndFlush(newNote); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(newNote.getId()) // + .withOfficeId(shareAccount.getClient().getOffice().getId()) // + .build(); + } + @Override public CommandProcessingResult createNote(final JsonCommand command) { this.fromApiJsonDeserializer.validateNote(command.json()); - final String resourceUrl = getResourceUrlFromCommand(command); // command.getSupportedEntityType(); + final String resourceUrl = getResourceUrlFromCommand(command); final NoteType type = NoteType.fromApiUrl(resourceUrl); switch (type) { case CLIENT: { @@ -197,6 +242,12 @@ public CommandProcessingResult createNote(final JsonCommand command) { case SAVING_ACCOUNT: { return createSavingAccountNote(command); } + case SAVINGS_TRANSACTION: { + return createSavingsTransactionNote(command); + } + case SHARE_ACCOUNT: { + return createShareAccountNote(command); + } default: throw new NoteResourceNotSupportedException(resourceUrl); } @@ -230,8 +281,13 @@ private String getResourceUrlFromCommand(JsonCommand command) { resourceUrl = NoteType.LOAN.getApiUrl(); } } else if (command.getSavingsId() != null) { - // TODO: SAVING_TRANSACTION type need to be add. - resourceUrl = NoteType.SAVING_ACCOUNT.getApiUrl(); + if (command.subentityId() != null) { + resourceUrl = NoteType.SAVINGS_TRANSACTION.getApiUrl(); + } else { + resourceUrl = NoteType.SAVING_ACCOUNT.getApiUrl(); + } + } else if (command.getUrl() != null && command.getUrl().contains("accounts/share")) { + resourceUrl = NoteType.SHARE_ACCOUNT.getApiUrl(); } else { resourceUrl = ""; } @@ -372,12 +428,59 @@ private CommandProcessingResult updateSavingAccountNote(final JsonCommand comman .build(); } + private CommandProcessingResult updateSavingsTransactionNote(final JsonCommand command) { + final Long transactionId = command.subentityId(); + final Long noteId = command.entityId(); + final NoteType type = NoteType.SAVINGS_TRANSACTION; + final SavingsAccountTransaction savingsTransaction = this.savingsAccountTransactionRepository.findById(transactionId) + .orElseThrow(() -> new SavingsAccountTransactionNotFoundException(command.getSavingsId(), transactionId)); + + final Note noteForUpdate = this.noteRepository.findBySavingsTransactionAndId(savingsTransaction, noteId); + if (noteForUpdate == null) { + throw new NoteNotFoundException(noteId, transactionId, type.name().toLowerCase()); + } + final Map changes = noteForUpdate.update(command); + if (!changes.isEmpty()) { + this.noteRepository.saveAndFlush(noteForUpdate); + } + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(noteForUpdate.getId()) // + .withSavingsId(savingsTransaction.getSavingsAccount().getId()) // + .with(changes) // + .build(); + } + + private CommandProcessingResult updateShareAccountNote(final JsonCommand command) { + final Long shareAccountId = command.entityId(); + final Long noteId = command.subentityId(); + final NoteType type = NoteType.SHARE_ACCOUNT; + final ShareAccount shareAccount = this.shareAccountRepository.findOneWithNotFoundDetection(shareAccountId); + + final Note noteForUpdate = this.noteRepository.findByShareAccountAndId(shareAccount, noteId); + if (noteForUpdate == null) { + throw new NoteNotFoundException(noteId, shareAccountId, type.name().toLowerCase()); + } + final Map changes = noteForUpdate.update(command); + if (!changes.isEmpty()) { + this.noteRepository.saveAndFlush(noteForUpdate); + } + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(noteForUpdate.getId()) // + .withOfficeId(shareAccount.getClient().getOffice().getId()) // + .with(changes) // + .build(); + } + @Override public CommandProcessingResult updateNote(final JsonCommand command) { this.fromApiJsonDeserializer.validateNote(command.json()); - final String resourceUrl = getResourceUrlFromCommand(command); // command.getSupportedEntityType(); + final String resourceUrl = getResourceUrlFromCommand(command); final NoteType type = NoteType.fromApiUrl(resourceUrl); switch (type) { @@ -396,6 +499,12 @@ public CommandProcessingResult updateNote(final JsonCommand command) { case SAVING_ACCOUNT: { return updateSavingAccountNote(command); } + case SAVINGS_TRANSACTION: { + return updateSavingsTransactionNote(command); + } + case SHARE_ACCOUNT: { + return updateShareAccountNote(command); + } default: throw new NoteResourceNotSupportedException(resourceUrl); } @@ -455,11 +564,20 @@ private Note getNoteForDelete(final JsonCommand command) { noteForUpdate = this.noteRepository.findBySavingsAccountAndId(savingAccount, noteId); } break; - case SHARE_ACCOUNT: - log.error("TODO Implement getNoteForDelete for SHARE_ACCOUNT"); + case SAVINGS_TRANSACTION: { + final Long transactionId = command.subentityId(); + resourceId = transactionId; + final Long savingsAccountId = command.getSavingsId(); + final SavingsAccountTransaction savingsTransaction = this.savingsAccountTransactionRepository.findById(transactionId) + .orElseThrow(() -> new SavingsAccountTransactionNotFoundException(savingsAccountId, transactionId)); + noteForUpdate = this.noteRepository.findBySavingsTransactionAndId(savingsTransaction, noteId); + } break; - case SAVINGS_TRANSACTION: - log.error("TODO Implement getNoteForDelete for SAVINGS_TRANSACTION"); + case SHARE_ACCOUNT: { + resourceId = command.entityId(); + final ShareAccount shareAccount = this.shareAccountRepository.findOneWithNotFoundDetection(resourceId); + noteForUpdate = this.noteRepository.findByShareAccountAndId(shareAccount, noteId); + } break; } if (noteForUpdate == null) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/starter/NoteAutoConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/starter/NoteAutoConfiguration.java index 8fab6f156e9..75ae8a73a0d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/starter/NoteAutoConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/starter/NoteAutoConfiguration.java @@ -29,6 +29,8 @@ import org.apache.fineract.portfolio.note.service.NoteWritePlatformService; import org.apache.fineract.portfolio.note.service.NoteWritePlatformServiceJpaRepositoryImpl; import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository; +import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountRepositoryWrapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -47,8 +49,11 @@ public NoteReadPlatformService noteReadPlatformService(JdbcTemplate jdbcTemplate @ConditionalOnMissingBean public NoteWritePlatformService noteWritePlatformService(NoteRepository noteRepository, ClientRepositoryWrapper clientRepository, GroupRepository groupRepository, LoanRepositoryWrapper loanRepository, LoanTransactionRepository loanTransactionRepository, - NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer, SavingsAccountRepository savingsAccountRepository) { + NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer, SavingsAccountRepository savingsAccountRepository, + SavingsAccountTransactionRepository savingsAccountTransactionRepository, + ShareAccountRepositoryWrapper shareAccountRepository) { return new NoteWritePlatformServiceJpaRepositoryImpl(noteRepository, clientRepository, groupRepository, loanRepository, - loanTransactionRepository, fromApiJsonDeserializer, savingsAccountRepository); + loanTransactionRepository, fromApiJsonDeserializer, savingsAccountRepository, savingsAccountTransactionRepository, + shareAccountRepository); } }