FINERACT-241 Include Add Note to Deposit and Withdrawal screen in savings account

This commit is contained in:
Nazeer Hussain Shaik
2017-12-05 10:24:19 +05:30
parent cef41855a2
commit 7368b1f047
9 changed files with 169 additions and 115 deletions
@@ -35,6 +35,7 @@ import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount; 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.apache.fineract.portfolio.shareaccounts.domain.ShareAccount;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
@@ -68,6 +69,10 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
@JoinColumn(name = "savings_account_id", nullable = true) @JoinColumn(name = "savings_account_id", nullable = true)
private SavingsAccount savingsAccount; private SavingsAccount savingsAccount;
@ManyToOne
@JoinColumn(name = "savings_account_transaction_id", nullable = true)
private SavingsAccountTransaction savingsTransaction;
@ManyToOne @ManyToOne
@JoinColumn(name = "share_account_id", nullable = true) @JoinColumn(name = "share_account_id", nullable = true)
private ShareAccount shareAccount; private ShareAccount shareAccount;
@@ -95,6 +100,19 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
return new Note(account, note); return new Note(account, note);
} }
public static Note savingsTransactionNote(final SavingsAccount savingsAccount, final SavingsAccountTransaction savingsTransaction,
final String note) {
return new Note(savingsAccount, savingsTransaction, note);
}
private Note(final SavingsAccount savingsAccount, final SavingsAccountTransaction savingsTransaction, final String note) {
this.savingsAccount = savingsAccount;
this.savingsTransaction = savingsTransaction;
this.client = savingsAccount.getClient();
this.note = note;
this.noteTypeId = NoteType.SAVINGS_TRANSACTION.getValue();
}
public static Note shareNote(final ShareAccount account, final String note) { public static Note shareNote(final ShareAccount account, final String note) {
return new Note(account, note); return new Note(account, note);
} }
@@ -28,7 +28,8 @@ public enum NoteType {
LOAN_TRANSACTION(300, "noteType.loan.transaction", "loanTransactions"), // LOAN_TRANSACTION(300, "noteType.loan.transaction", "loanTransactions"), //
SAVING_ACCOUNT(500, "noteType.saving", "savings"), // SAVING_ACCOUNT(500, "noteType.saving", "savings"), //
GROUP(600, "noteType.group", "groups"), GROUP(600, "noteType.group", "groups"),
SHARE_ACCOUNT(700, "noteType.shares", "accounts/share"); SHARE_ACCOUNT(700, "noteType.shares", "accounts/share"),
SAVINGS_TRANSACTION(800, "noteType.savings.transaction", "savingsTransactions");
private Integer value; private Integer value;
private String code; private String code;
@@ -133,8 +133,13 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
conditionSql = " n.loan_transaction_id = ? "; conditionSql = " n.loan_transaction_id = ? ";
break; break;
case SAVING_ACCOUNT: case SAVING_ACCOUNT:
conditionSql = " n.saving_account_id = ? "; 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 = ? ) ";
break; break;
case SAVINGS_TRANSACTION:
conditionSql = " n.savings_account_transaction_id = ? " ;
break ;
case GROUP: case GROUP:
conditionSql = " n.group_id = ? "; conditionSql = " n.group_id = ? ";
break; break;
@@ -69,7 +69,7 @@ public class SavingsApiSetConstants extends SavingsApiConstants {
protected static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>( protected static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, "accountId", accountNoParamName, "currency", "amount", dateParamName, Arrays.asList(idParamName, "accountId", accountNoParamName, "currency", "amount", dateParamName,
paymentDetailDataParamName, runningBalanceParamName, reversedParamName)); paymentDetailDataParamName, runningBalanceParamName, reversedParamName, noteParamName));
protected static final Set<String> SAVINGS_ACCOUNT_CHARGES_RESPONSE_DATA_PARAMETERS = new HashSet<>( protected static final Set<String> SAVINGS_ACCOUNT_CHARGES_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(chargeIdParamName, savingsAccountChargeIdParamName, chargeNameParamName, penaltyParamName, Arrays.asList(chargeIdParamName, savingsAccountChargeIdParamName, chargeNameParamName, penaltyParamName,
@@ -53,7 +53,7 @@ public class SavingsAccountConstant extends SavingsApiConstants {
protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<>( protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName, Arrays.asList(localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName,
paymentTypeIdParamName, transactionAccountNumberParamName, checkNumberParamName, paymentTypeIdParamName, transactionAccountNumberParamName, checkNumberParamName,
routingCodeParamName, receiptNumberParamName, bankNumberParamName)); routingCodeParamName, receiptNumberParamName, bankNumberParamName, noteParamName));
protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>( protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, accountNoParamName)); Arrays.asList(idParamName, accountNoParamName));
@@ -51,28 +51,30 @@ public class SavingsAccountTransactionData {
private final AccountTransferData transfer; private final AccountTransferData transfer;
private final LocalDate submittedOnDate; private final LocalDate submittedOnDate;
private final boolean interestedPostedAsOn; private final boolean interestedPostedAsOn;
private final String submittedByUsername;
private final String note ;
// templates // templates
final Collection<PaymentTypeData> paymentTypeOptions; final Collection<PaymentTypeData> paymentTypeOptions;
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType, public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount,final BigDecimal runningBalance, final boolean reversed, final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount,final BigDecimal runningBalance, final boolean reversed,
final AccountTransferData transfer, final boolean interestedPostedAsOn) { final AccountTransferData transfer, final boolean interestedPostedAsOn, final String submittedByUsername, final String note) {
final Collection<PaymentTypeData> paymentTypeOptions = null; final Collection<PaymentTypeData> paymentTypeOptions = null;
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
amount, outstandingChargeAmount,runningBalance, reversed, transfer, paymentTypeOptions, interestedPostedAsOn); amount, outstandingChargeAmount,runningBalance, reversed, transfer, paymentTypeOptions, interestedPostedAsOn, submittedByUsername, note);
} }
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType, public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount,
final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer, final LocalDate submittedOnDate, final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer, final LocalDate submittedOnDate,
final boolean interestedPostedAsOn) { final boolean interestedPostedAsOn, final String submittedByUsername, final String note) {
final Collection<PaymentTypeData> paymentTypeOptions = null; final Collection<PaymentTypeData> paymentTypeOptions = null;
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
amount, outstandingChargeAmount, runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate, amount, outstandingChargeAmount, runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate,
interestedPostedAsOn); interestedPostedAsOn, submittedByUsername, note);
} }
public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo, public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
@@ -86,8 +88,10 @@ public class SavingsAccountTransactionData {
final PaymentDetailData paymentDetailData = null; final PaymentDetailData paymentDetailData = null;
final Collection<CodeValueData> paymentTypeOptions = null; final Collection<CodeValueData> paymentTypeOptions = null;
final boolean interestedPostedAsOn = false; final boolean interestedPostedAsOn = false;
final String submittedByUsername = null;
final String note = null ;
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate, return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate,
currency, amount, outstandingChargeAmount, runningBalance, reversed, null, null, interestedPostedAsOn); currency, amount, outstandingChargeAmount, runningBalance, reversed, null, null, interestedPostedAsOn, submittedByUsername, note);
} }
public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData, public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
@@ -96,24 +100,25 @@ public class SavingsAccountTransactionData {
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId, savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency, savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency,
savingsAccountTransactionData.amount,savingsAccountTransactionData.outstandingChargeAmount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed, savingsAccountTransactionData.amount,savingsAccountTransactionData.outstandingChargeAmount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
savingsAccountTransactionData.transfer, paymentTypeOptions, savingsAccountTransactionData.interestedPostedAsOn); savingsAccountTransactionData.transfer, paymentTypeOptions, savingsAccountTransactionData.interestedPostedAsOn,
savingsAccountTransactionData.submittedByUsername, savingsAccountTransactionData.note);
} }
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType, private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount,
final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer, final BigDecimal runningBalance, final boolean reversed, final AccountTransferData transfer,
final Collection<PaymentTypeData> paymentTypeOptions, final boolean interestedPostedAsOn) { final Collection<PaymentTypeData> paymentTypeOptions, final boolean interestedPostedAsOn, final String submittedByUsername, final String note) {
this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, outstandingChargeAmount, this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, outstandingChargeAmount,
runningBalance, reversed, transfer, paymentTypeOptions, null, interestedPostedAsOn); runningBalance, reversed, transfer, paymentTypeOptions, null, interestedPostedAsOn, submittedByUsername, note);
} }
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType, private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date, final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
final CurrencyData currency, final BigDecimal amount,final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance, final boolean reversed, final CurrencyData currency, final BigDecimal amount,final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance, final boolean reversed,
final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions, final LocalDate submittedOnDate, final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions, final LocalDate submittedOnDate,
final boolean interestedPostedAsOn) { final boolean interestedPostedAsOn, final String submittedByUsername, final String note) {
this.id = id; this.id = id;
this.transactionType = transactionType; this.transactionType = transactionType;
this.paymentDetailData = paymentDetailData; this.paymentDetailData = paymentDetailData;
@@ -129,6 +134,8 @@ public class SavingsAccountTransactionData {
this.paymentTypeOptions = paymentTypeOptions; this.paymentTypeOptions = paymentTypeOptions;
this.submittedOnDate = submittedOnDate; this.submittedOnDate = submittedOnDate;
this.interestedPostedAsOn = interestedPostedAsOn; this.interestedPostedAsOn = interestedPostedAsOn;
this.submittedByUsername = submittedByUsername ;
this.note = note ;
} }
public static SavingsAccountTransactionData withWithDrawalTransactionDetails( public static SavingsAccountTransactionData withWithDrawalTransactionDetails(
@@ -144,6 +151,6 @@ public class SavingsAccountTransactionData {
savingsAccountTransactionData.amount, savingsAccountTransactionData.outstandingChargeAmount, savingsAccountTransactionData.amount, savingsAccountTransactionData.outstandingChargeAmount,
savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
savingsAccountTransactionData.transfer, savingsAccountTransactionData.paymentTypeOptions, savingsAccountTransactionData.transfer, savingsAccountTransactionData.paymentTypeOptions,
savingsAccountTransactionData.interestedPostedAsOn); savingsAccountTransactionData.interestedPostedAsOn,savingsAccountTransactionData.submittedByUsername, savingsAccountTransactionData.note);
} }
} }
@@ -974,6 +974,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
sqlBuilder.append("totran.transaction_date as toTransferDate, totran.amount as toTransferAmount,"); sqlBuilder.append("totran.transaction_date as toTransferDate, totran.amount as toTransferAmount,");
sqlBuilder.append("totran.description as toTransferDescription,"); sqlBuilder.append("totran.description as toTransferDescription,");
sqlBuilder.append("sa.id as savingsId, sa.account_no as accountNo,"); sqlBuilder.append("sa.id as savingsId, sa.account_no as accountNo,");
sqlBuilder.append(" au.username as submittedByUsername, ");
sqlBuilder.append("pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, "); sqlBuilder.append("pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
sqlBuilder.append("pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, "); sqlBuilder.append("pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, ");
sqlBuilder sqlBuilder
@@ -988,7 +989,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
sqlBuilder.append("left join m_account_transfer_transaction totran on totran.to_savings_transaction_id = tr.id "); sqlBuilder.append("left join m_account_transfer_transaction totran on totran.to_savings_transaction_id = tr.id ");
sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id "); sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id ");
sqlBuilder.append("left join m_payment_type pt on pd.payment_type_id = pt.id "); sqlBuilder.append("left join m_payment_type pt on pd.payment_type_id = pt.id ");
sqlBuilder.append("left join m_appuser au on au.id=tr.appuser_id ");
this.schemaSql = sqlBuilder.toString(); this.schemaSql = sqlBuilder.toString();
} }
@@ -1057,8 +1058,10 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
toTransferDescription, toTransferReversed); toTransferDescription, toTransferReversed);
} }
final boolean postInterestAsOn = false; final boolean postInterestAsOn = false;
final String submittedByUsername = rs.getString("submittedByUsername");
final String note = null ;
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency, return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
amount, outstandingChargeAmount, runningBalance, reversed, transfer, postInterestAsOn); amount, outstandingChargeAmount, runningBalance, reversed, transfer, postInterestAsOn, submittedByUsername, note);
} }
} }
@@ -1453,8 +1456,10 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final AccountTransferData transfer = null; final AccountTransferData transfer = null;
final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "runningBalance"); final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "runningBalance");
final boolean postInterestAsOn = false; final boolean postInterestAsOn = false;
final String submittedByUsername = null ;
final String note = null ;
return SavingsAccountTransactionData.create(savingsId, transactionType, paymentDetailData, savingsId, accountNo, duedate, return SavingsAccountTransactionData.create(savingsId, transactionType, paymentDetailData, savingsId, accountNo, duedate,
currency, dueamount, outstandingChargeAmount, runningBalance, false, transfer, postInterestAsOn); currency, dueamount, outstandingChargeAmount, runningBalance, false, transfer, postInterestAsOn, submittedByUsername, note);
} }
} }
@@ -782,6 +782,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, "); sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,"); sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
sqlBuilder.append("tr.created_date as submittedOnDate,"); sqlBuilder.append("tr.created_date as submittedOnDate,");
sqlBuilder.append(" au.username as submittedByUsername, ");
sqlBuilder.append(" nt.note as transactionNote, ") ;
sqlBuilder.append("tr.running_balance_derived as runningBalance, tr.is_reversed as reversed,"); sqlBuilder.append("tr.running_balance_derived as runningBalance, tr.is_reversed as reversed,");
sqlBuilder.append("fromtran.id as fromTransferId, fromtran.is_reversed as fromTransferReversed,"); sqlBuilder.append("fromtran.id as fromTransferId, fromtran.is_reversed as fromTransferReversed,");
sqlBuilder.append("fromtran.transaction_date as fromTransferDate, fromtran.amount as fromTransferAmount,"); sqlBuilder.append("fromtran.transaction_date as fromTransferDate, fromtran.amount as fromTransferAmount,");
@@ -805,7 +807,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
sqlBuilder.append("left join m_account_transfer_transaction totran on totran.to_savings_transaction_id = tr.id "); sqlBuilder.append("left join m_account_transfer_transaction totran on totran.to_savings_transaction_id = tr.id ");
sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id "); sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id ");
sqlBuilder.append("left join m_payment_type pt on pd.payment_type_id = pt.id "); sqlBuilder.append("left join m_payment_type pt on pd.payment_type_id = pt.id ");
sqlBuilder.append(" left join m_appuser au on au.id=tr.appuser_id ");
sqlBuilder.append(" left join m_note nt ON nt.savings_account_transaction_id=tr.id ") ;
this.schemaSql = sqlBuilder.toString(); this.schemaSql = sqlBuilder.toString();
} }
@@ -877,9 +880,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
transfer = AccountTransferData.transferBasicDetails(toTransferId, currency, toTransferAmount, toTransferDate, transfer = AccountTransferData.transferBasicDetails(toTransferId, currency, toTransferAmount, toTransferDate,
toTransferDescription, toTransferReversed); toTransferDescription, toTransferReversed);
} }
final String submittedByUsername = rs.getString("submittedByUsername");
final String note = rs.getString("transactionNote") ;
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency, return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
amount, outstandingChargeAmount, runningBalance, reversed, transfer, submittedOnDate, postInterestAsOn); amount, outstandingChargeAmount, runningBalance, reversed, transfer, submittedOnDate, postInterestAsOn, submittedByUsername, note);
} }
} }
@@ -125,16 +125,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
final JournalEntryWritePlatformService journalEntryWritePlatformService, final JournalEntryWritePlatformService journalEntryWritePlatformService,
final SavingsAccountDomainService savingsAccountDomainService, final NoteRepository noteRepository, final SavingsAccountDomainService savingsAccountDomainService, final NoteRepository noteRepository,
final AccountTransfersReadPlatformService accountTransfersReadPlatformService, final AccountTransfersReadPlatformService accountTransfersReadPlatformService, final HolidayRepositoryWrapper holidayRepository,
final HolidayRepositoryWrapper holidayRepository, final WorkingDaysRepositoryWrapper workingDaysRepository, final WorkingDaysRepositoryWrapper workingDaysRepository,
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService, final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
final ChargeRepositoryWrapper chargeRepository, final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository, final ChargeRepositoryWrapper chargeRepository, final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository,
final SavingsAccountDataValidator fromApiJsonDeserializer, final SavingsAccountDataValidator fromApiJsonDeserializer, final StaffRepositoryWrapper staffRepository,
final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService, final ConfigurationDomainService configurationDomainService,
final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository, final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository,
final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, final EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService,
final AppUserRepositoryWrapper appuserRepository, final AppUserRepositoryWrapper appuserRepository, final StandingInstructionRepository standingInstructionRepository,
final StandingInstructionRepository standingInstructionRepository,
final BusinessEventNotifierService businessEventNotifierService) { final BusinessEventNotifierService businessEventNotifierService) {
this.context = context; this.context = context;
this.savingAccountRepositoryWrapper = savingAccountRepositoryWrapper; this.savingAccountRepositoryWrapper = savingAccountRepositoryWrapper;
@@ -179,8 +178,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final Map<String, Object> changes = account.activate(user, command, DateUtils.getLocalDateOfTenant()); final Map<String, Object> changes = account.activate(user, command, DateUtils.getLocalDateOfTenant());
entityDatatableChecksWritePlatformService.runTheCheckForProduct(savingsId, EntityTables.SAVING.getName(), entityDatatableChecksWritePlatformService.runTheCheckForProduct(savingsId, EntityTables.SAVING.getName(),
StatusEnum.ACTIVATE.getCode().longValue(),EntityTables.SAVING.getForeignKeyColumnNameOnDatatable(), StatusEnum.ACTIVATE.getCode().longValue(), EntityTables.SAVING.getForeignKeyColumnNameOnDatatable(), account.productId());
account.productId());
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
final Locale locale = command.extractLocale(); final Locale locale = command.extractLocale();
@@ -255,6 +253,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate,
transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction); transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction);
final String noteText = command.stringValueOfParameterNamed("note");
if (StringUtils.isNotBlank(noteText)) {
final Note note = Note.savingsTransactionNote(account, deposit, noteText);
this.noteRepository.save(note) ;
}
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(deposit.getId()) // .withEntityId(deposit.getId()) //
.withOfficeId(account.officeId()) // .withOfficeId(account.officeId()) //
@@ -287,7 +291,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
final boolean isAccountTransfer = false; final boolean isAccountTransfer = false;
final boolean isRegularTransaction = true; final boolean isRegularTransaction = true;
final boolean isApplyWithdrawFee = true; final boolean isApplyWithdrawFee = true;
@@ -298,6 +302,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate, final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
transactionAmount, paymentDetail, transactionBooleanValues); transactionAmount, paymentDetail, transactionBooleanValues);
final String noteText = command.stringValueOfParameterNamed("note");
if (StringUtils.isNotBlank(noteText)) {
final Note note = Note.savingsTransactionNote(account, withdrawal, noteText);
this.noteRepository.save(note) ;
}
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(withdrawal.getId()) // .withEntityId(withdrawal.getId()) //
.withOfficeId(account.officeId()) // .withOfficeId(account.officeId()) //
@@ -314,8 +324,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
AppUser user = getAppUserIfPresent(); AppUser user = getAppUserIfPresent();
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
savingsAccountChargeId, accountId); .findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy"); final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
@@ -344,7 +354,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null; final LocalDate postInterestOnDate = null;
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,postInterestOnDate); financialYearBeginningMonth, postInterestOnDate);
this.savingAccountRepositoryWrapper.save(account); this.savingAccountRepositoryWrapper.save(account);
@@ -356,16 +366,17 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
.withSavingsId(savingsId) // .withSavingsId(savingsId) //
.build(); .build();
} }
@Override @Override
public CommandProcessingResult postInterest(final JsonCommand command) { public CommandProcessingResult postInterest(final JsonCommand command) {
Long savingsId=command.getSavingsId(); Long savingsId = command.getSavingsId();
final boolean postInterestAs =command.booleanPrimitiveValueOfParameterNamed("isPostInterestAsOn"); final boolean postInterestAs = command.booleanPrimitiveValueOfParameterNamed("isPostInterestAsOn");
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
if (postInterestAs == true) { if (postInterestAs == true) {
if (transactionDate == null) { if (transactionDate == null) {
throw new PostInterestAsOnDateException(PostInterestAsOnException_TYPE.VALID_DATE); } throw new PostInterestAsOnDateException(PostInterestAsOnException_TYPE.VALID_DATE); }
@@ -373,15 +384,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
PostInterestAsOnException_TYPE.ACTIVATION_DATE); } PostInterestAsOnException_TYPE.ACTIVATION_DATE); }
List<SavingsAccountTransaction> savingTransactions = account.getTransactions(); List<SavingsAccountTransaction> savingTransactions = account.getTransactions();
for (SavingsAccountTransaction savingTransaction : savingTransactions) { for (SavingsAccountTransaction savingTransaction : savingTransactions) {
if (transactionDate.toDate().before(savingTransaction.getDateOf())) { throw new PostInterestAsOnDateException( if (transactionDate.toDate().before(savingTransaction
PostInterestAsOnException_TYPE.LAST_TRANSACTION_DATE); } .getDateOf())) { throw new PostInterestAsOnDateException(PostInterestAsOnException_TYPE.LAST_TRANSACTION_DATE); }
} }
LocalDate today = DateUtils.getLocalDateOfTenant(); LocalDate today = DateUtils.getLocalDateOfTenant();
if (transactionDate.isAfter(today)) { throw new PostInterestAsOnDateException(PostInterestAsOnException_TYPE.FUTURE_DATE); } if (transactionDate.isAfter(today)) { throw new PostInterestAsOnDateException(PostInterestAsOnException_TYPE.FUTURE_DATE); }
} }
postInterest(account,postInterestAs,transactionDate); postInterest(account, postInterestAs, transactionDate);
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_POST_INTEREST, this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_POST_INTEREST,
constructEntityMap(BUSINESS_ENTITY.SAVING, account)); constructEntityMap(BUSINESS_ENTITY.SAVING, account));
@@ -396,7 +407,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
@Transactional @Transactional
@Override @Override
public void postInterest(final SavingsAccount account,final boolean postInterestAs,final LocalDate transactionDate) { public void postInterest(final SavingsAccount account, final boolean postInterestAs, final LocalDate transactionDate) {
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
.isSavingsInterestPostingAtCurrentPeriodEnd(); .isSavingsInterestPostingAtCurrentPeriodEnd();
@@ -409,17 +420,18 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode()); final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null; LocalDate postInterestOnDate = null;
if (postInterestAs) { if (postInterestAs) {
postInterestOnDate = transactionDate; postInterestOnDate = transactionDate;
} }
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate);
// for generating transaction id's // for generating transaction id's
List<SavingsAccountTransaction> transactions = account.getTransactions(); List<SavingsAccountTransaction> transactions = account.getTransactions();
for (SavingsAccountTransaction accountTransaction : transactions) { for (SavingsAccountTransaction accountTransaction : transactions) {
if (accountTransaction.getId() == null) { if (accountTransaction.getId() == null) {
this.savingsAccountTransactionRepository.save(accountTransaction); this.savingsAccountTransactionRepository.save(accountTransaction);
} }
} }
this.savingAccountRepositoryWrapper.saveAndFlush(account); this.savingAccountRepositoryWrapper.saveAndFlush(account);
@@ -427,7 +439,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
} }
} }
@Override @Override
public CommandProcessingResult undoTransaction(final Long savingsId, final Long transactionId, public CommandProcessingResult undoTransaction(final Long savingsId, final Long transactionId,
final boolean allowAccountTransferModification) { final boolean allowAccountTransferModification) {
@@ -445,14 +457,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
.findOneByIdAndSavingsAccountId(transactionId, savingsId); .findOneByIdAndSavingsAccountId(transactionId, savingsId);
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); } if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
if (!allowAccountTransferModification if (!allowAccountTransferModification && this.accountTransfersReadPlatformService.isAccountTransfer(transactionId,
&& this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException( PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Savings account transaction:" + transactionId "error.msg.saving.account.transfer.transaction.update.not.allowed",
+ " update not allowed as it involves in account transfer", transactionId); } "Savings account transaction:" + transactionId + " update not allowed as it involves in account transfer",
transactionId); }
if (!account.allowModify()) { throw new PlatformServiceUnavailableException( if (!account
"error.msg.saving.account.transaction.update.not.allowed", "Savings account transaction:" + transactionId .allowModify()) { throw new PlatformServiceUnavailableException("error.msg.saving.account.transaction.update.not.allowed",
+ " update not allowed for this savings type", transactionId); } "Savings account transaction:" + transactionId + " update not allowed for this savings type", transactionId); }
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode()); final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
@@ -476,10 +489,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired() if (savingsAccountTransaction.isPostInterestCalculationRequired()
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { && account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate);
} else { } else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,postInterestOnDate); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -512,12 +526,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
.findOneByIdAndSavingsAccountId(transactionId, savingsId); .findOneByIdAndSavingsAccountId(transactionId, savingsId);
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); } if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException( if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal())
savingsId, transactionId); } || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(savingsId, transactionId); }
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException( if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId,
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Savings account transaction:" + transactionId PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
+ " update not allowed as it involves in account transfer", transactionId); } "error.msg.saving.account.transfer.transaction.update.not.allowed",
"Savings account transaction:" + transactionId + " update not allowed as it involves in account transfer",
transactionId); }
this.savingsAccountTransactionDataValidator.validate(command); this.savingsAccountTransactionDataValidator.validate(command);
@@ -527,9 +543,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
if (account.isNotActive()) { if (account.isNotActive()) {
throwValidationForActiveStatus(SavingsApiConstants.adjustTransactionAction); throwValidationForActiveStatus(SavingsApiConstants.adjustTransactionAction);
} }
if (!account.allowModify()) { throw new PlatformServiceUnavailableException( if (!account
"error.msg.saving.account.transaction.update.not.allowed", "Savings account transaction:" + transactionId .allowModify()) { throw new PlatformServiceUnavailableException("error.msg.saving.account.transaction.update.not.allowed",
+ " update not allowed for this savings type", transactionId); } "Savings account transaction:" + transactionId + " update not allowed for this savings type", transactionId); }
final Set<Long> existingTransactionIds = new HashSet<>(); final Set<Long> existingTransactionIds = new HashSet<>();
final Set<Long> existingReversedTransactionIds = new HashSet<>(); final Set<Long> existingReversedTransactionIds = new HashSet<>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -565,10 +581,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate postInterestOnDate = null; final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(transactionDate) if (account.isBeforeLastPostingPeriod(transactionDate)
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { || account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate);
} else { } else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,postInterestOnDate); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -614,10 +631,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
@Override @Override
public CommandProcessingResult close(final Long savingsId, final JsonCommand command) { public CommandProcessingResult close(final Long savingsId, final JsonCommand command) {
final AppUser user = this.context.authenticatedUser(); final AppUser user = this.context.authenticatedUser();
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
this.savingsAccountTransactionDataValidator.validateClosing(command, account); this.savingsAccountTransactionDataValidator.validateClosing(command, account);
final boolean isLinkedWithAnyActiveLoan = this.accountAssociationsReadPlatformService.isLinkedWithAnyActiveAccount(savingsId); final boolean isLinkedWithAnyActiveLoan = this.accountAssociationsReadPlatformService.isLinkedWithAnyActiveAccount(savingsId);
if (isLinkedWithAnyActiveLoan) { if (isLinkedWithAnyActiveLoan) {
@@ -627,8 +644,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
} }
entityDatatableChecksWritePlatformService.runTheCheckForProduct(savingsId, EntityTables.SAVING.getName(), entityDatatableChecksWritePlatformService.runTheCheckForProduct(savingsId, EntityTables.SAVING.getName(),
StatusEnum.CLOSE.getCode().longValue(),EntityTables.SAVING.getForeignKeyColumnNameOnDatatable(), StatusEnum.CLOSE.getCode().longValue(), EntityTables.SAVING.getForeignKeyColumnNameOnDatatable(), account.productId());
account.productId());
final boolean isWithdrawBalance = command.booleanPrimitiveValueOfParameterNamed(withdrawBalanceParamName); final boolean isWithdrawBalance = command.booleanPrimitiveValueOfParameterNamed(withdrawBalanceParamName);
@@ -636,29 +652,26 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName); final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
final boolean isPostInterest = command.booleanPrimitiveValueOfParameterNamed(SavingsApiConstants.postInterestValidationOnClosure); final boolean isPostInterest = command.booleanPrimitiveValueOfParameterNamed(SavingsApiConstants.postInterestValidationOnClosure);
// postInterest(account,closedDate,flag); // postInterest(account,closedDate,flag);
if (isPostInterest) { if (isPostInterest) {
boolean postInterestOnClosingDate = false; boolean postInterestOnClosingDate = false;
List<SavingsAccountTransaction> savingTransactions = account.getTransactions(); List<SavingsAccountTransaction> savingTransactions = account.getTransactions();
for (SavingsAccountTransaction savingTransaction : savingTransactions) { for (SavingsAccountTransaction savingTransaction : savingTransactions) {
if (savingTransaction.isInterestPosting() && savingTransaction.isNotReversed() if (savingTransaction.isInterestPosting() && savingTransaction.isNotReversed()
&& closedDate.isEqual(savingTransaction.getTransactionLocalDate())) { && closedDate.isEqual(savingTransaction.getTransactionLocalDate())) {
postInterestOnClosingDate = true; postInterestOnClosingDate = true;
break; break;
} }
} }
if (postInterestOnClosingDate == false) { throw new PostInterestClosingDateException(); } if (postInterestOnClosingDate == false) { throw new PostInterestClosingDateException(); }
} }
final Map<String, Object> changes = new LinkedHashMap<>(); final Map<String, Object> changes = new LinkedHashMap<>();
if (isWithdrawBalance && account.getSummary().getAccountBalance(account.getCurrency()).isGreaterThanZero()) { if (isWithdrawBalance && account.getSummary().getAccountBalance(account.getCurrency()).isGreaterThanZero()) {
final BigDecimal transactionAmount = account.getSummary().getAccountBalance(); final BigDecimal transactionAmount = account.getSummary().getAccountBalance();
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
final boolean isAccountTransfer = false; final boolean isAccountTransfer = false;
@@ -686,7 +699,6 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
} }
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_CLOSE, this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.SAVINGS_CLOSE,
constructEntityMap(BUSINESS_ENTITY.SAVING, account)); constructEntityMap(BUSINESS_ENTITY.SAVING, account));
// disable all standing orders linked to the savings account // disable all standing orders linked to the savings account
@@ -830,11 +842,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
Integer chargeTimeType = chargeDefinition.getChargeTimeType(); Integer chargeTimeType = chargeDefinition.getChargeTimeType();
LocalDate dueAsOfDateParam = command.localDateValueOfParameterNamed(dueAsOfDateParamName); LocalDate dueAsOfDateParam = command.localDateValueOfParameterNamed(dueAsOfDateParamName);
if((chargeTimeType.equals(ChargeTimeType.WITHDRAWAL_FEE.getValue()) if ((chargeTimeType.equals(ChargeTimeType.WITHDRAWAL_FEE.getValue())
|| chargeTimeType.equals(ChargeTimeType.SAVINGS_NOACTIVITY_FEE.getValue())) || chargeTimeType.equals(ChargeTimeType.SAVINGS_NOACTIVITY_FEE.getValue())) && dueAsOfDateParam != null) {
&& dueAsOfDateParam != null){
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(dueAsOfDateParam.toString(fmt)) baseDataValidator.reset().parameter(dueAsOfDateParamName).value(dueAsOfDateParam.toString(fmt))
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.invalid.for." + ChargeTimeType.fromInt(chargeTimeType).getCode()); .failWithCodeNoParameterAddedToErrorCode(
"charge.due.date.is.invalid.for." + ChargeTimeType.fromInt(chargeTimeType).getCode());
} }
final SavingsAccountCharge savingsAccountCharge = SavingsAccountCharge.createNewFromJson(savingsAccount, chargeDefinition, command); final SavingsAccountCharge savingsAccountCharge = SavingsAccountCharge.createNewFromJson(savingsAccount, chargeDefinition, command);
@@ -930,8 +942,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
.isSavingsInterestPostingAtCurrentPeriodEnd(); .isSavingsInterestPostingAtCurrentPeriodEnd();
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth(); final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
savingsAccountChargeId, savingsAccountId); .findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
// Get Savings account from savings charge // Get Savings account from savings charge
final SavingsAccount account = savingsAccountCharge.savingsAccount(); final SavingsAccount account = savingsAccountCharge.savingsAccount();
@@ -948,7 +960,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) { if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate); postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
@@ -983,8 +995,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsAccountId); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsAccountId);
checkClientOrGroupActive(savingsAccount); checkClientOrGroupActive(savingsAccount);
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
savingsAccountChargeId, savingsAccountId); .findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
savingsAccount.removeCharge(savingsAccountCharge); savingsAccount.removeCharge(savingsAccountCharge);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1009,8 +1021,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(amountParamName); final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(amountParamName);
final LocalDate transactionDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName); final LocalDate transactionDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName);
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
savingsAccountChargeId, savingsAccountId); .findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
@@ -1049,8 +1061,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
AppUser user = null; AppUser user = null;
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant(); final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
savingsAccountChargeId, accountId); .findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy"); final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
fmt.withZone(DateUtils.getDateTimeZoneOfTenant()); fmt.withZone(DateUtils.getDateTimeZoneOfTenant());
@@ -1081,7 +1093,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
if (account.isBeforeLastPostingPeriod(transactionDate)) { if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate); postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
@@ -1123,8 +1135,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.context.authenticatedUser(); this.context.authenticatedUser();
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
savingsAccountChargeId, savingsAccountId); .findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
final SavingsAccount account = savingsAccountCharge.savingsAccount(); final SavingsAccount account = savingsAccountCharge.savingsAccount();
this.savingAccountAssembler.assignSavingAccountHelpers(account); this.savingAccountAssembler.assignSavingAccountHelpers(account);
@@ -1202,16 +1214,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate dateOfSavingsOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate"); final LocalDate dateOfSavingsOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate");
if (fromSavingsOfficerId != null) { if (fromSavingsOfficerId != null) {
fromSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(fromSavingsOfficerId, savingsForUpdate fromSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(fromSavingsOfficerId,
.office().getHierarchy()); savingsForUpdate.office().getHierarchy());
} }
if (toSavingsOfficerId != null) { if (toSavingsOfficerId != null) {
toSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(toSavingsOfficerId, savingsForUpdate toSavingsOfficer = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(toSavingsOfficerId,
.office().getHierarchy()); savingsForUpdate.office().getHierarchy());
actualChanges.put("toSavingsOfficerId", toSavingsOfficer.getId()); actualChanges.put("toSavingsOfficerId", toSavingsOfficer.getId());
} }
if (!savingsForUpdate.hasSavingsOfficer(fromSavingsOfficer)) { throw new SavingsOfficerAssignmentException(savingsAccountId, if (!savingsForUpdate.hasSavingsOfficer(
fromSavingsOfficerId); } fromSavingsOfficer)) { throw new SavingsOfficerAssignmentException(savingsAccountId, fromSavingsOfficerId); }
savingsForUpdate.reassignSavingsOfficer(toSavingsOfficer, dateOfSavingsOfficerAssignment); savingsForUpdate.reassignSavingsOfficer(toSavingsOfficer, dateOfSavingsOfficerAssignment);
@@ -1281,7 +1293,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
@Override @Override
@Transactional @Transactional
public void setSubStatusInactive(Long savingsId){ public void setSubStatusInactive(Long savingsId) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
final Set<Long> existingTransactionIds = new HashSet<>(); final Set<Long> existingTransactionIds = new HashSet<>();
final Set<Long> existingReversedTransactionIds = new HashSet<>(); final Set<Long> existingReversedTransactionIds = new HashSet<>();
@@ -1293,15 +1305,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
@Override @Override
@Transactional @Transactional
public void setSubStatusDormant(Long savingsId){ public void setSubStatusDormant(Long savingsId) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
account.setSubStatusDormant(); account.setSubStatusDormant();
this.savingAccountRepositoryWrapper.save(account); this.savingAccountRepositoryWrapper.save(account);
} }
@Override @Override
@Transactional @Transactional
public void escheat(Long savingsId){ public void escheat(Long savingsId) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
final Set<Long> existingTransactionIds = new HashSet<>(); final Set<Long> existingTransactionIds = new HashSet<>();
final Set<Long> existingReversedTransactionIds = new HashSet<>(); final Set<Long> existingReversedTransactionIds = new HashSet<>();
@@ -1310,8 +1322,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.savingAccountRepositoryWrapper.saveAndFlush(account); this.savingAccountRepositoryWrapper.saveAndFlush(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
} }
private AppUser getAppUserIfPresent() { private AppUser getAppUserIfPresent() {
AppUser user = null; AppUser user = null;
if (this.context != null) { if (this.context != null) {
user = this.context.getAuthenticatedUserIfPresent(); user = this.context.getAuthenticatedUserIfPresent();
@@ -1319,10 +1331,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
return user; return user;
} }
/** /**
* Disable all standing instructions linked to the savings account if the status is "closed" * Disable all standing instructions linked to the savings account if the
* status is "closed"
* *
* @param savingsAccount -- the savings account object * @param savingsAccount
* -- the savings account object
* *
**/ **/
@Transactional @Transactional
@@ -1331,7 +1345,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final Integer standingInstructionStatus = StandingInstructionStatus.ACTIVE.getValue(); final Integer standingInstructionStatus = StandingInstructionStatus.ACTIVE.getValue();
final Collection<AccountTransferStandingInstruction> accountTransferStandingInstructions = this.standingInstructionRepository final Collection<AccountTransferStandingInstruction> accountTransferStandingInstructions = this.standingInstructionRepository
.findBySavingsAccountAndStatus(savingsAccount, standingInstructionStatus); .findBySavingsAccountAndStatus(savingsAccount, standingInstructionStatus);
if (!accountTransferStandingInstructions.isEmpty()) { if (!accountTransferStandingInstructions.isEmpty()) {
for (AccountTransferStandingInstruction accountTransferStandingInstruction : accountTransferStandingInstructions) { for (AccountTransferStandingInstruction accountTransferStandingInstruction : accountTransferStandingInstructions) {
accountTransferStandingInstruction.updateStatus(StandingInstructionStatus.DISABLED.getValue()); accountTransferStandingInstruction.updateStatus(StandingInstructionStatus.DISABLED.getValue());
@@ -1346,7 +1360,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
map.put(entityEvent, entity); map.put(entityEvent, entity);
return map; return map;
} }
@Override @Override
public CommandProcessingResult blockAccount(final Long savingsId) { public CommandProcessingResult blockAccount(final Long savingsId) {