Skip to content

Commit

Permalink
Fix to use notes in Savings Accounts (#2857)
Browse files Browse the repository at this point in the history
Co-authored-by: Jose Alberto Hernandez <[email protected]>
  • Loading branch information
josehernandezfintecheandomx and Jose Alberto Hernandez authored Jan 6, 2023
1 parent 0e391ed commit a25acf0
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ public class NotesApiResource {
public static final String GROUPNOTE = "GROUPNOTE";
public static final String INVALIDNOTE = "INVALIDNOTE";
private static final Set<String> NOTE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList("id", "clientId", "groupId", "loanId", "loanTransactionId", "depositAccountId", "savingAccountId", "noteType",
"note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn"));
Arrays.asList("id", "resourceId", "clientId", "groupId", "loanId", "loanTransactionId", "depositAccountId", "savingAccountId",
"noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn"));
private final PlatformSecurityContext context;
private final NoteReadPlatformService readPlatformService;
private final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ public interface NoteRepository extends JpaRepository<Note, Long>, JpaSpecificat

List<Note> findBySavingsAccount(SavingsAccount savingAccount);

// Note findBySavingsAccountIdAndId(Long savingAccountId, Long id);
Note findBySavingsAccountAndId(SavingsAccount savingAccount, Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public static String getResourceCondition(final NoteType noteType, List<Object>
case SAVING_ACCOUNT:
paramList.add(NoteType.SAVING_ACCOUNT.getValue());
paramList.add(NoteType.SAVINGS_TRANSACTION.getValue());
conditionSql = " n.saving_account_id = ? and ( n.note_type_enum = ? or n.note_type_enum = ? ) ";
conditionSql = " n.savings_account_id = ? and ( n.note_type_enum = ? or n.note_type_enum = ? ) ";
break;
case SAVINGS_TRANSACTION:
conditionSql = " n.savings_account_transaction_id = ? ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
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;
Expand All @@ -40,28 +41,32 @@
import org.apache.fineract.portfolio.note.exception.NoteNotFoundException;
import org.apache.fineract.portfolio.note.exception.NoteResourceNotSupportedException;
import org.apache.fineract.portfolio.note.serialization.NoteCommandFromApiJsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
import org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException;

@Slf4j
public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatformService {

private static final Logger LOG = LoggerFactory.getLogger(NoteWritePlatformServiceJpaRepositoryImpl.class);
private final NoteRepository noteRepository;
private final ClientRepositoryWrapper clientRepository;
private final GroupRepository groupRepository;
private final LoanRepositoryWrapper loanRepository;
private final LoanTransactionRepository loanTransactionRepository;
private final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final SavingsAccountRepository savingsAccountRepository;

public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepositoryWrapper clientRepository,
final GroupRepository groupRepository, final LoanRepositoryWrapper loanRepository,
final LoanTransactionRepository loanTransactionRepository, final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
final LoanTransactionRepository loanTransactionRepository, final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final SavingsAccountRepository savingsAccountRepository) {
this.noteRepository = noteRepository;
this.clientRepository = clientRepository;
this.groupRepository = groupRepository;
this.loanRepository = loanRepository;
this.loanTransactionRepository = loanTransactionRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.savingsAccountRepository = savingsAccountRepository;
}

private CommandProcessingResult createClientNote(final JsonCommand command) {
Expand Down Expand Up @@ -151,26 +156,23 @@ private CommandProcessingResult createLoanTransactionNote(final JsonCommand comm
.build();
}

// private CommandProcessingResult createSavingAccountNote(final JsonCommand
// command) {
//
// final Long resourceId = command.getSupportedEntityId();
//
// final SavingAccount savingAccount =
// this.savingAccountRepository.findOne(resourceId);
// if (savingAccount == null) { throw new
// SavingAccountNotFoundException(resourceId); }
//
// final String note = command.stringValueOfParameterNamed("note");
// final Note newNote = Note.savingNote(savingAccount, note);
//
// this.noteRepository.save(newNote);
//
// return new CommandProcessingResultBuilder() //
// .withCommandId(command.commandId()) //
// .withEntityId(newNote.getId()) //
// .withClientId(savingAccount.getClient().getId()).withOfficeId(savingAccount.getClient().getOffice().getId()).build();
// }
private CommandProcessingResult createSavingAccountNote(final JsonCommand command) {
final Long resourceId = command.getSavingsId();
final SavingsAccount savingAccount = this.savingsAccountRepository.findById(resourceId)
.orElseThrow(() -> new SavingsAccountNotFoundException(resourceId));

final String note = command.stringValueOfParameterNamed("note");
final Note newNote = Note.savingNote(savingAccount, note);

this.noteRepository.saveAndFlush(newNote);

return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(newNote.getId()) //
.withOfficeId(savingAccount.getClient().getOffice().getId()) //
.withSavingsId(savingAccount.getId()) //
.build();
}

@Override
public CommandProcessingResult createNote(final JsonCommand command) {
Expand All @@ -192,9 +194,9 @@ public CommandProcessingResult createNote(final JsonCommand command) {
case LOAN_TRANSACTION: {
return createLoanTransactionNote(command);
}
// case SAVING_ACCOUNT: {
// return createSavingAccountNote(command);
// }
case SAVING_ACCOUNT: {
return createSavingAccountNote(command);
}
default:
throw new NoteResourceNotSupportedException(resourceUrl);
}
Expand Down Expand Up @@ -333,41 +335,30 @@ private CommandProcessingResult updateLoanTransactionNote(final JsonCommand comm
.withLoanId(loan.getId()).withOfficeId(loan.getOfficeId()).with(changes).build();
}

// private CommandProcessingResult updateSavingAccountNote(final JsonCommand
// command) {
//
// final Long resourceId = command.getSupportedEntityId();
// final Long noteId = command.entityId();
// final String resourceUrl = command.getSupportedEntityType();
//
// final NoteType type = NoteType.fromApiUrl(resourceUrl);
//
// final SavingAccount savingAccount =
// this.savingAccountRepository.findOne(resourceId);
// if (savingAccount == null) { throw new
// SavingAccountNotFoundException(resourceId); }
//
// final Note noteForUpdate =
// this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId);
//
// if (noteForUpdate == null) { throw new NoteNotFoundException(noteId,
// resourceId, type.name().toLowerCase()); }
//
// final Map<String, Object> changes = noteForUpdate.update(command);
//
// if (!changes.isEmpty()) {
// this.noteRepository.saveAndFlush(noteForUpdate);
// }
//
// return new CommandProcessingResultBuilder()
// //
// .withCommandId(command.commandId())
// //
// .withEntityId(noteForUpdate.getId())
// //
// .withClientId(savingAccount.getClient().getId()).withOfficeId(savingAccount.getClient().getOffice().getId()).with(changes)
// .build();
// }
private CommandProcessingResult updateSavingAccountNote(final JsonCommand command) {
final Long resourceId = command.getSavingsId();
final Long noteId = command.entityId();
final NoteType type = NoteType.SAVING_ACCOUNT;
final SavingsAccount savingAccount = this.savingsAccountRepository.findById(resourceId)
.orElseThrow(() -> new SavingsAccountNotFoundException(resourceId));

final Note noteForUpdate = this.noteRepository.findBySavingsAccountAndId(savingAccount, noteId);
if (noteForUpdate == null) {
throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase());
}
final Map<String, Object> changes = noteForUpdate.update(command);
if (!changes.isEmpty()) {
this.noteRepository.saveAndFlush(noteForUpdate);
}

return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(noteForUpdate.getId()) //
.withOfficeId(savingAccount.getClient().getOffice().getId()) //
.withSavingsId(savingAccount.getId()) //
.with(changes) //
.build();
}

@Override
public CommandProcessingResult updateNote(final JsonCommand command) {
Expand All @@ -390,9 +381,9 @@ public CommandProcessingResult updateNote(final JsonCommand command) {
case LOAN_TRANSACTION: {
return updateLoanTransactionNote(command);
}
// case SAVING_ACCOUNT: {
// return updateSavingAccountNote(command);
// }
case SAVING_ACCOUNT: {
return updateSavingAccountNote(command);
}
default:
throw new NoteResourceNotSupportedException(resourceUrl);
}
Expand Down Expand Up @@ -444,19 +435,19 @@ private Note getNoteForDelete(final JsonCommand command) {
noteForUpdate = this.noteRepository.findByLoanTransactionAndId(loanTransaction, noteId);
}
break;
// case SAVING_ACCOUNT: {
// noteForUpdate =
// this.noteRepository.findBySavingAccountIdAndId(resourceId,
// noteId);
// }
// break;
case SAVING_ACCOUNT:
case SAVING_ACCOUNT: {
final Long savinsAccountId = command.getSavingsId();
final SavingsAccount savingAccount = this.savingsAccountRepository.findById(savinsAccountId)
.orElseThrow(() -> new SavingsAccountNotFoundException(savinsAccountId));

noteForUpdate = this.noteRepository.findBySavingsAccountAndId(savingAccount, noteId);
}
break;
case SHARE_ACCOUNT:
LOG.error("TODO Implement getNoteForDelete for SHARE_ACCOUNT");
log.error("TODO Implement getNoteForDelete for SHARE_ACCOUNT");
break;
case SAVINGS_TRANSACTION:
LOG.error("TODO Implement getNoteForDelete for SAVINGS_TRANSACTION");
log.error("TODO Implement getNoteForDelete for SAVINGS_TRANSACTION");
break;
}
if (noteForUpdate == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.fineract.portfolio.note.service.NoteReadPlatformServiceImpl;
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.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -46,8 +47,8 @@ public NoteReadPlatformService noteReadPlatformService(JdbcTemplate jdbcTemplate
@ConditionalOnMissingBean
public NoteWritePlatformService noteWritePlatformService(NoteRepository noteRepository, ClientRepositoryWrapper clientRepository,
GroupRepository groupRepository, LoanRepositoryWrapper loanRepository, LoanTransactionRepository loanTransactionRepository,
NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer, SavingsAccountRepository savingsAccountRepository) {
return new NoteWritePlatformServiceJpaRepositoryImpl(noteRepository, clientRepository, groupRepository, loanRepository,
loanTransactionRepository, fromApiJsonDeserializer);
loanTransactionRepository, fromApiJsonDeserializer, savingsAccountRepository);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.fineract.client.models.GetResourceTypeResourceIdNotesNoteIdResponse;
import org.apache.fineract.client.models.PostResourceTypeResourceIdNotesResponse;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
import org.apache.fineract.integrationtests.common.GroupHelper;
Expand All @@ -36,6 +38,8 @@
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -47,6 +51,8 @@ public class NotesTest {
private RequestSpecification requestSpec;
private ResponseSpecification responseSpec404;
private LoanTransactionHelper loanTransactionHelper;
private SavingsProductHelper savingsProductHelper;
private SavingsAccountHelper savingsAccountHelper;

@BeforeEach
public void setup() {
Expand All @@ -56,6 +62,8 @@ public void setup() {
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.responseSpec404 = new ResponseSpecBuilder().expectStatusCode(404).build();
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
this.savingsProductHelper = new SavingsProductHelper();
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
}

@Test
Expand Down Expand Up @@ -190,6 +198,33 @@ public void testCreateLoanNote() {

}

@Test
public void testCreateSavingsNote() {
final String noteText = "this is a test Savings note";
final String testDate = "01 January 2012";

final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, testDate);
// Savings Account
final String savingsProductJSON = this.savingsProductHelper.withInterestCompoundingPeriodTypeAsDaily()
.withInterestPostingPeriodTypeAsDaily().withInterestCalculationPeriodTypeAsDailyBalance().build();
final Integer savingsProductId = SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientID, savingsProductId, "INDIVIDUAL",
testDate);
Assertions.assertNotNull(savingsId);

// Notes
final String payload = "{\"note\": \"" + noteText + "\"}";
final PostResourceTypeResourceIdNotesResponse postNoteResponse = NotesHelper.createSavingsNote(requestSpec, responseSpec, savingsId,
payload);
Assertions.assertNotNull(postNoteResponse);
Assertions.assertNotNull(postNoteResponse.getResourceId());

final GetResourceTypeResourceIdNotesNoteIdResponse getNoteResponse = NotesHelper.getSavingsNote(requestSpec, responseSpec,
savingsId, postNoteResponse.getResourceId());
Assertions.assertNotNull(getNoteResponse);
Assertions.assertEquals(noteText, getNoteResponse.getNote());
}

private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID) {
List<HashMap> collaterals = new ArrayList<>();
final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@
*/
package org.apache.fineract.integrationtests.common;

import com.google.gson.Gson;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import org.apache.fineract.client.models.GetResourceTypeResourceIdNotesNoteIdResponse;
import org.apache.fineract.client.models.PostResourceTypeResourceIdNotesResponse;
import org.apache.fineract.client.util.JSON;

@SuppressWarnings({ "rawtypes", "unchecked" })
public final class NotesHelper {

private static final Gson GSON = new JSON().getGson();

private NotesHelper() {

}
Expand Down Expand Up @@ -134,4 +140,20 @@ public static void deleteLoanTransactionNote(RequestSpecification requestSpec, R
Utils.performServerDelete(requestSpec, responseSpec, deleteLoanTransactionNoteURL, "");
}

private static final String SAVINGS_URL = "/fineract-provider/api/v1/savings";

public static PostResourceTypeResourceIdNotesResponse createSavingsNote(RequestSpecification requestSpec,
ResponseSpecification responseSpec, Integer savingsId, String request) {
final String noteURL = SAVINGS_URL + "/" + savingsId + "/notes?" + Utils.TENANT_IDENTIFIER;
final String response = Utils.performServerPost(requestSpec, responseSpec, noteURL, request);
return GSON.fromJson(response, PostResourceTypeResourceIdNotesResponse.class);
}

public static GetResourceTypeResourceIdNotesNoteIdResponse getSavingsNote(RequestSpecification requestSpec,
ResponseSpecification responseSpec, Integer savingsId, Integer noteId) {
final String noteURL = SAVINGS_URL + "/" + savingsId + "/notes/" + noteId + "?" + Utils.TENANT_IDENTIFIER;
final String response = Utils.performServerGet(requestSpec, responseSpec, noteURL);
return GSON.fromJson(response, GetResourceTypeResourceIdNotesNoteIdResponse.class);
}

}

0 comments on commit a25acf0

Please sign in to comment.