[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 88e55b9 2/4: Implement DB_FirstWdMonth
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 88e55b9 2/4: Implement DB_FirstWdMonth |
Date: |
Fri, 21 May 2021 09:05:43 -0400 (EDT) |
branch: master
commit 88e55b939b87282fc0ead3a9478d89b56b3cceae
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Implement DB_FirstWdMonth
Although lmi supports one group UL product whose specifications allow
withdrawals and loans immediately for 1035 exchanges, illustrating that
has never actually been allowed, and nobody has ever complained.
---
basic_values.hpp | 2 ++
dbnames.xpp | 2 +-
ihs_avmly.cpp | 8 ++++++--
ihs_basicval.cpp | 2 ++
input_realization.cpp | 20 ++++++++++++++++++++
5 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/basic_values.hpp b/basic_values.hpp
index 12bed55..938a224 100644
--- a/basic_values.hpp
+++ b/basic_values.hpp
@@ -366,6 +366,8 @@ class LMI_SO BasicValues
currency MinWD;
currency WDFee;
double WDFeeRate;
+ bool AllowWd;
+ int FirstWdMonth;
bool AllowChangeToDBO2;
bool AllowSAIncr;
diff --git a/dbnames.xpp b/dbnames.xpp
index 10d20bb..3a481ba 100644
--- a/dbnames.xpp
+++ b/dbnames.xpp
@@ -282,7 +282,7 @@
{DB_WdDecrSpecAmtDboLvl,DB_Topic_Withdrawals,"WdDecrSpecAmtDboLvl","Withdrawals
decrease specified amount for level death benefit option",}, \
{DB_WdDecrSpecAmtDboInc,DB_Topic_Withdrawals,"WdDecrSpecAmtDboInc","Withdrawals
decrease specified amount for increasing death benefit option",}, \
{DB_WdDecrSpecAmtDboRop,DB_Topic_Withdrawals,"WdDecrSpecAmtDboRop","Withdrawals
decrease specified amount for return of premium death benefit option",}, \
-{DB_FirstWdMonth,DB_Topic_Withdrawals,"FirstWdMonth","Number of months
withdrawals not allowed [not supported yet]",}, \
+{DB_FirstWdMonth,DB_Topic_Withdrawals,"FirstWdMonth","Number of months until
withdrawals allowed",}, \
{DB_Topic_Loans,DB_FIRST,"Loans","Loan rates, spreads, options, and
restrictions",}, \
{DB_AllowLoan,DB_Topic_Loans,"AllowLoan","Allow loans: 0=no, 1=yes",}, \
{DB_AllowPrefLoan,DB_Topic_Loans,"AllowPrefLoan","Preferred loans permitted:
0=no, 1=yes",}, \
diff --git a/ihs_avmly.cpp b/ihs_avmly.cpp
index b782815..2a22548 100644
--- a/ihs_avmly.cpp
+++ b/ihs_avmly.cpp
@@ -2338,8 +2338,12 @@ void AccountValue::SetMaxWD()
void AccountValue::TxTakeWD()
{
- // Illustrations allow withdrawals only on anniversary.
- if(0 != Month)
+ // Illustrations allow withdrawals only on anniversary; products
+ // may forbid them altogether, or for the first N months. On the
+ // issue date, the maximum withdrawal is zero anyway, because not
+ // even 1035 funds have been credited when this function is first
+ // called; arguably 1035 processing should occur earlier.
+ if(0 != Month || !AllowWd || (Month + 12 * Year) < FirstWdMonth)
{
return;
}
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index f09f6a3..a220763 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -584,6 +584,8 @@ void BasicValues::SetPermanentInvariants()
LMI_ASSERT(round_withdrawal().c(MinWD) == MinWD);
LMI_ASSERT(round_withdrawal().c(WDFee) == WDFee);
database().query_into(DB_WdFeeRate , WDFeeRate);
+ database().query_into(DB_AllowWd , AllowWd);
+ database().query_into(DB_FirstWdMonth , FirstWdMonth);
database().query_into(DB_AllowChangeToDbo2 , AllowChangeToDBO2);
database().query_into(DB_AllowSpecAmtIncr , AllowSAIncr);
database().query_into(DB_NoLapseAlwaysActive , NoLapseAlwaysActive);
diff --git a/input_realization.cpp b/input_realization.cpp
index b97eff9..bd4830c 100644
--- a/input_realization.cpp
+++ b/input_realization.cpp
@@ -32,6 +32,7 @@
#include "global_settings.hpp"
#include "handle_exceptions.hpp" // report_exception()
#include "input_sequence_aux.hpp" // convert_vector()
+#include "math_functions.hpp" // outward_quotient()
#include "miscellany.hpp" // each_equal()
#include "round_to.hpp"
#include "ssize_lmi.hpp"
@@ -869,6 +870,9 @@ std::string Input::RealizeWithdrawal()
return s;
}
+ int FirstWdMonth;
+ database_->query_into(DB_FirstWdMonth, FirstWdMonth);
+
if(!database_->query<bool>(DB_AllowWd))
{
if(!each_equal(WithdrawalRealized_, 0.0))
@@ -876,6 +880,22 @@ std::string Input::RealizeWithdrawal()
return "Withdrawals may not be illustrated on this policy form.";
}
}
+ else if(0 != FirstWdMonth)
+ {
+ int const first_wd_year = outward_quotient(FirstWdMonth, 12);
+ auto const first = WithdrawalRealized_.begin();
+ auto const nth = first + first_wd_year;
+ if(!each_equal(first, nth, 0.0))
+ {
+ std::ostringstream oss;
+ oss
+ << "This policy form does not allow withdrawals for the first "
+ << FirstWdMonth
+ << " months."
+ ;
+ return oss.str();
+ }
+ }
else
{
double lowest_allowed_withdrawal = database_->query<double>(DB_MinWd);