lmi-commits
[Top][All Lists]
Advanced

[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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]