[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 1020a23 2/2: Add list-bill input and output
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 1020a23 2/2: Add list-bill input and output |
Date: |
Sat, 10 Jun 2017 20:15:52 -0400 (EDT) |
branch: master
commit 1020a2338df5605572872028716f4146d972eae0
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Add list-bill input and output
The motivation is to use the illustration system to generate list bills
for speculative scenarios. Billing is generally a task for an admin
system, but admin systems generally lack the flexibility required.
Only input and output have been implemented in this commit; calculations
will follow soon. The calculations are complicated because list bills
use a common billing date for contracts that generally don't have a
common anniversary.
Input: Added one new field representing list-bill date. It defaults to
the *nix epoch, chosen on the assumption that no supported inforce
policy was issued on or before that date. Logically, this date cannot
precede InforceAsOfDate: historical list bills cannot be generated
because they'd require historical data that are unavailable. As a
practical matter, though, the input range is not so constrained, and an
illogical date (such as the default) simply results in a billed premium
of zero (which is the most reasonable default outcome, because almost
all end users have zero interest in list bills and will feel least
uncomfortable if "mystery" columns are all zero).
Output: Notionally, one date and one scalar premium have been added.
Following existing practice for similar fields, the date is represented
in two equivalent ways, and the premium is represented as separate
employer and employee portions, and also as their total.
---
cell.rnc | 5 ++++-
cell.xsd | 9 ++++++++-
input.cpp | 2 ++
input.hpp | 1 +
ledger_invariant.cpp | 12 ++++++++++++
ledger_invariant.hpp | 5 +++++
ledger_text_formats.cpp | 6 ++++++
ledger_xml_io.cpp | 4 ++++
sample.cns | 3 +++
sample.ill | 1 +
skin.xrc | 19 +++++++++++++++++++
skin_group_carveout.xrc | 21 +++++++++++++++++++++
yare_input.cpp | 1 +
yare_input.hpp | 1 +
14 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/cell.rnc b/cell.rnc
index 0049f20..fec2e9b 100644
--- a/cell.rnc
+++ b/cell.rnc
@@ -193,7 +193,7 @@ cell_element = element cell
## processing. Some admin systems find it more convenient to
## provide values as of the last moment of the preceding day; in
## that case, this field should indicate the day following that
- ## preceding day.
+ ## preceding day, i.e., the day monthiversary processing occurs.
element InforceAsOfDate {calendar_date_int}
,## Inforce account value before last material change, for 7702A.
element InforceAvBeforeLastMc {nonnegative_double}
@@ -308,6 +308,9 @@ cell_element = element cell
,## Date of most recent 7702A material change. Default: effective
## date, for contracts that have never had a material change.
element LastMaterialChangeDate {calendar_date_int}
+ ,## Date of a list bill generated by the illustration system.
+ ## Default: the value of 'InforceAsOfDate'.
+ element ListBillDate {calendar_date_int}?
,## * [obsolete]
element LoanAmount {nonnegative_double}?
,## * [obsolete]
diff --git a/cell.xsd b/cell.xsd
index 0618fc7..5cd0272 100644
--- a/cell.xsd
+++ b/cell.xsd
@@ -151,6 +151,7 @@
<xs:element ref="IssueAge"/>
<xs:element ref="LastCoiReentryDate"/>
<xs:element ref="LastMaterialChangeDate"/>
+ <xs:element minOccurs="0" ref="ListBillDate"/>
<xs:element minOccurs="0" ref="LoanAmount"/>
<xs:element minOccurs="0" ref="LoanFromAge"/>
<xs:element minOccurs="0" ref="LoanFromAlternative"/>
@@ -636,7 +637,7 @@ refer to the first moment of the day, before monthiversary
processing. Some admin systems find it more convenient to
provide values as of the last moment of the preceding day; in
that case, this field should indicate the day following that
-preceding day.</xs:documentation>
+preceding day, i.e., the day monthiversary processing
occurs.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="InforceAvBeforeLastMc" type="nonnegative_double">
@@ -881,6 +882,12 @@ Default: effective date, for contracts with no
reentry.</xs:documentation>
date, for contracts that have never had a material change.</xs:documentation>
</xs:annotation>
</xs:element>
+ <xs:element name="ListBillDate" type="calendar_date_int">
+ <xs:annotation>
+ <xs:documentation>Date of a list bill generated by the illustration
system.
+Default: the value of 'InforceAsOfDate'.</xs:documentation>
+ </xs:annotation>
+ </xs:element>
<xs:element name="LoanAmount" type="nonnegative_double">
<xs:annotation>
<xs:documentation>* [obsolete]</xs:documentation>
diff --git a/input.cpp b/input.cpp
index 080bf5d..b1f3297 100644
--- a/input.cpp
+++ b/input.cpp
@@ -113,6 +113,7 @@ Input::Input()
// ,RetireesCanEnroll ("")
// ,GroupUnderwritingType ("")
// ,LastCoiReentryDate ("")
+ ,ListBillDate ("2440588") // Assume no inforce so old
// ,BlendGender ("")
// ,BlendSmoking ("")
,MaleProportion ("1")
@@ -358,6 +359,7 @@ void Input::AscribeMembers()
ascribe("RetireesCanEnroll" ,
&Input::RetireesCanEnroll );
ascribe("GroupUnderwritingType" ,
&Input::GroupUnderwritingType );
ascribe("LastCoiReentryDate" ,
&Input::LastCoiReentryDate );
+ ascribe("ListBillDate" , &Input::ListBillDate
);
ascribe("BlendGender" , &Input::BlendGender
);
ascribe("BlendSmoking" , &Input::BlendSmoking
);
ascribe("MaleProportion" , &Input::MaleProportion
);
diff --git a/input.hpp b/input.hpp
index ebe218d..6c99e2e 100644
--- a/input.hpp
+++ b/input.hpp
@@ -313,6 +313,7 @@ class LMI_SO Input final
mce_yes_or_no RetireesCanEnroll ;
mce_uw_basis GroupUnderwritingType ;
tnr_date LastCoiReentryDate ;
+ tnr_date ListBillDate ;
mce_yes_or_no BlendGender ;
mce_yes_or_no BlendSmoking ;
tnr_proportion MaleProportion ;
diff --git a/ledger_invariant.cpp b/ledger_invariant.cpp
index f0b6f24..ba6571f 100644
--- a/ledger_invariant.cpp
+++ b/ledger_invariant.cpp
@@ -133,6 +133,9 @@ void LedgerInvariant::Alloc(int len)
ScalableScalars ["InitGLP" ] = &InitGLP ;
ScalableScalars ["InitTgtPrem" ] = &InitTgtPrem ;
ScalableScalars ["InitMinPrem" ] = &InitMinPrem ;
+ ScalableScalars ["ListBillPremium" ] = &ListBillPremium ;
+ ScalableScalars ["EeListBillPremium" ] = &EeListBillPremium ;
+ ScalableScalars ["ErListBillPremium" ] = &ErListBillPremium ;
ScalableScalars ["ModalMinimumDumpin" ] = &ModalMinimumDumpin ;
ScalableScalars ["Dumpin" ] = &Dumpin ;
ScalableScalars ["External1035Amount" ] = &External1035Amount ;
@@ -184,6 +187,7 @@ void LedgerInvariant::Alloc(int len)
OtherScalars ["Has1035ExchCharge" ] = &Has1035ExchCharge ;
OtherScalars ["EffDateJdn" ] = &EffDateJdn ;
OtherScalars ["DateOfBirthJdn" ] = &DateOfBirthJdn ;
+ OtherScalars ["ListBillDateJdn" ] = &ListBillDateJdn ;
OtherScalars ["InforceAsOfDateJdn" ] = &InforceAsOfDateJdn ;
OtherScalars ["SplitFundAllocation" ] = &SplitFundAllocation ;
OtherScalars ["GenAcctAllocation" ] = &GenAcctAllocation ;
@@ -402,6 +406,7 @@ void LedgerInvariant::Copy(LedgerInvariant const& obj)
// Scalars of type not compatible with double.
EffDate = obj.EffDate ;
DateOfBirth = obj.DateOfBirth ;
+ ListBillDate = obj.ListBillDate ;
InforceAsOfDate = obj.InforceAsOfDate ;
InitErMode = obj.InitErMode ;
InitDBOpt = obj.InitDBOpt ;
@@ -620,6 +625,9 @@ void LedgerInvariant::Init(BasicValues const* b)
// InitSevenPayPrem =
// InitTgtPrem =
// InitMinPrem =
+// ListBillPremium =
+// EeListBillPremium =
+// ErListBillPremium =
// ModalMinimumDumpin =
MaleProportion = b->yare_input_.MaleProportion;
@@ -886,6 +894,8 @@ void LedgerInvariant::Init(BasicValues const* b)
EffDateJdn = calendar_date(b->yare_input_.EffectiveDate
).julian_day_number();
DateOfBirth = calendar_date(b->yare_input_.DateOfBirth
).str();
DateOfBirthJdn = calendar_date(b->yare_input_.DateOfBirth
).julian_day_number();
+ ListBillDate = calendar_date(b->yare_input_.ListBillDate
).str();
+ ListBillDateJdn = calendar_date(b->yare_input_.ListBillDate
).julian_day_number();
InforceAsOfDate =
calendar_date(b->yare_input_.InforceAsOfDate).str();
InforceAsOfDateJdn =
calendar_date(b->yare_input_.InforceAsOfDate).julian_day_number();
InitErMode = mc_str(b->Outlay_->er_premium_modes()[0]);
@@ -1012,6 +1022,8 @@ LedgerInvariant& LedgerInvariant::PlusEq(LedgerInvariant
const& a_Addend)
EffDateJdn = a_Addend.EffDateJdn;
DateOfBirth = a_Addend.DateOfBirth;
DateOfBirthJdn = a_Addend.DateOfBirthJdn;
+ ListBillDate = a_Addend.ListBillDate;
+ ListBillDateJdn = a_Addend.ListBillDateJdn;
InforceAsOfDate = a_Addend.InforceAsOfDate;
InforceAsOfDateJdn = a_Addend.InforceAsOfDateJdn;
InitErMode = a_Addend.InitErMode;
diff --git a/ledger_invariant.hpp b/ledger_invariant.hpp
index abfc5f2..39de0ee 100644
--- a/ledger_invariant.hpp
+++ b/ledger_invariant.hpp
@@ -150,6 +150,9 @@ class LMI_SO LedgerInvariant
double InitGLP;
double InitTgtPrem;
double InitMinPrem;
+ double ListBillPremium;
+ double EeListBillPremium;
+ double ErListBillPremium;
double ModalMinimumDumpin;
double Dumpin;
double External1035Amount;
@@ -201,6 +204,7 @@ class LMI_SO LedgerInvariant
double Has1035ExchCharge;
double EffDateJdn;
double DateOfBirthJdn;
+ double ListBillDateJdn;
double InforceAsOfDateJdn;
double SplitFundAllocation;
double GenAcctAllocation;
@@ -385,6 +389,7 @@ class LMI_SO LedgerInvariant
// JDNs are used in UpdateCRC() and Spew().
std::string EffDate;
std::string DateOfBirth;
+ std::string ListBillDate;
std::string InforceAsOfDate;
// Arguably enumerative members such as 'ErMode' should be of type
diff --git a/ledger_text_formats.cpp b/ledger_text_formats.cpp
index 9a723f9..18d6367 100644
--- a/ledger_text_formats.cpp
+++ b/ledger_text_formats.cpp
@@ -717,6 +717,9 @@ void PrintRosterHeaders(std::string const& file_name)
,"ModalMinimumDumpin"
,"EeModalMinimumPremium"
,"ErModalMinimumPremium"
+ ,"ListBillPremium"
+ ,"EeListBillPremium"
+ ,"ErListBillPremium"
,"EeMode"
,"ErMode"
,"CorpName"
@@ -801,6 +804,9 @@ void PrintRosterTabDelimited
<< Invar.value_str("ModalMinimumDumpin" ) << '\t'
<< Invar.value_str("EeModalMinimumPremium",d) << '\t'
<< Invar.value_str("ErModalMinimumPremium",d) << '\t'
+ << Invar.value_str("ListBillPremium" ) << '\t'
+ << Invar.value_str("EeListBillPremium" ) << '\t'
+ << Invar.value_str("ErListBillPremium" ) << '\t'
<< Invar.EeMode [d] << '\t'
<< Invar.ErMode [d] << '\t'
<< Invar.value_str("CorpName" ) << '\t'
diff --git a/ledger_xml_io.cpp b/ledger_xml_io.cpp
index 4a36492..70826f2 100644
--- a/ledger_xml_io.cpp
+++ b/ledger_xml_io.cpp
@@ -102,6 +102,7 @@ bool unavailable(std::string const& s)
static std::string const a[] =
{"DateOfBirthJdn" // used by group quotes
,"EffDateJdn" // used by group quotes
+ ,"ListBillDateJdn" // probably not needed
,"InforceAsOfDateJdn" // probably not needed
,"InitDacTaxRate" // used by PrintRosterTabDelimited(); not
cents
,"InitPremTaxRate" // used by PrintRosterTabDelimited(); not
cents
@@ -351,6 +352,8 @@ void Ledger::write(xml::element& x) const
// > Format as a number with thousand separators and two decimal places
(#,###,###.00)
// >
format_map["CurrentCoiMultiplier" ] = f2;
+ format_map["EeListBillPremium" ] = f2;
+ format_map["ErListBillPremium" ] = f2;
format_map["GuarPrem" ] = f2;
format_map["InforceTaxBasis" ] = f2;
format_map["InforceUnloanedAV" ] = f2;
@@ -360,6 +363,7 @@ void Ledger::write(xml::element& x) const
format_map["InitSevenPayPrem" ] = f2;
format_map["InitTgtPrem" ] = f2;
format_map["InitMinPrem" ] = f2;
+ format_map["ListBillPremium" ] = f2;
format_map["ModalMinimumDumpin" ] = f2;
// >
// F1: zero decimals, commas
diff --git a/sample.cns b/sample.cns
index 23aec27..d0d2d58 100644
--- a/sample.cns
+++ b/sample.cns
@@ -107,6 +107,7 @@
<IssueAge>45</IssueAge>
<LastCoiReentryDate>2454040</LastCoiReentryDate>
<LastMaterialChangeDate>2454040</LastMaterialChangeDate>
+ <ListBillDate>2440588</ListBillDate>
<LoanRate>0.06</LoanRate>
<LoanRateType>Fixed loan rate</LoanRateType>
<MaleProportion>1</MaleProportion>
@@ -304,6 +305,7 @@
<IssueAge>45</IssueAge>
<LastCoiReentryDate>2454040</LastCoiReentryDate>
<LastMaterialChangeDate>2454040</LastMaterialChangeDate>
+ <ListBillDate>2440588</ListBillDate>
<LoanRate>0.06</LoanRate>
<LoanRateType>Fixed loan rate</LoanRateType>
<MaleProportion>1</MaleProportion>
@@ -501,6 +503,7 @@
<IssueAge>45</IssueAge>
<LastCoiReentryDate>2454040</LastCoiReentryDate>
<LastMaterialChangeDate>2454040</LastMaterialChangeDate>
+ <ListBillDate>2440588</ListBillDate>
<LoanRate>0.06</LoanRate>
<LoanRateType>Fixed loan rate</LoanRateType>
<MaleProportion>1</MaleProportion>
diff --git a/sample.ill b/sample.ill
index 7271ac3..6caecde 100644
--- a/sample.ill
+++ b/sample.ill
@@ -106,6 +106,7 @@
<IssueAge>45</IssueAge>
<LastCoiReentryDate>2454040</LastCoiReentryDate>
<LastMaterialChangeDate>2454040</LastMaterialChangeDate>
+ <ListBillDate>2440588</ListBillDate>
<LoanRate>0.06</LoanRate>
<LoanRateType>Fixed loan rate</LoanRateType>
<MaleProportion>1</MaleProportion>
diff --git a/skin.xrc b/skin.xrc
index 56696f8..3370499 100644
--- a/skin.xrc
+++ b/skin.xrc
@@ -431,6 +431,25 @@
</object>
<object class="sizeritem">
<flag>wxGROW|wxALL</flag>
+ <object class="wxFlexGridSizer">
+ <rows>1</rows>
+ <growablecols>1</growablecols>
+ <object class="sizeritem">
+ <flag>wxALIGN_CENTER_VERTICAL|wxALL</flag>
+ <object class="wxStaticText">
+ <label>List bill date </label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxGROW|wxALIGN_CENTER_VERTICAL</flag>
+ <object class="wxDatePickerCtrl"
name="ListBillDate">
+ <help>List bill date</help>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxGROW|wxALL</flag>
<object class="wxCheckBox"
name="IncludeInComposite">
<help>Include this individual in any group
composite</help>
<label>Include in composite</label>
diff --git a/skin_group_carveout.xrc b/skin_group_carveout.xrc
index 4867eb2..c0d5615 100644
--- a/skin_group_carveout.xrc
+++ b/skin_group_carveout.xrc
@@ -229,6 +229,27 @@
</object>
<object class="sizeritem">
<flag>wxGROW|wxALL</flag>
+ <border>4</border>
+ <object class="wxFlexGridSizer">
+ <rows>1</rows>
+ <object class="sizeritem">
+ <flag>wxALIGN_CENTER_VERTICAL|wxALL</flag>
+ <border>2</border>
+ <object class="wxStaticText">
+ <label>List bill date</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxGROW</flag>
+ <border>2</border>
+ <object class="wxDatePickerCtrl"
name="ListBillDate">
+ <help>List bill date</help>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxGROW|wxALL</flag>
<object class="wxFlexGridSizer">
<rows>1</rows>
<object class="sizeritem">
diff --git a/yare_input.cpp b/yare_input.cpp
index 2470207..5f3e706 100644
--- a/yare_input.cpp
+++ b/yare_input.cpp
@@ -95,6 +95,7 @@ yare_input::yare_input(Input const& z)
RetireesCanEnroll = z.RetireesCanEnroll
.value();
GroupUnderwritingType = z.GroupUnderwritingType
.value();
LastCoiReentryDate = z.LastCoiReentryDate
.value();
+ ListBillDate = z.ListBillDate
.value();
BlendGender = z.BlendGender
.value();
BlendSmoking = z.BlendSmoking
.value();
MaleProportion = z.MaleProportion
.value();
diff --git a/yare_input.hpp b/yare_input.hpp
index 44322c7..01db7eb 100644
--- a/yare_input.hpp
+++ b/yare_input.hpp
@@ -136,6 +136,7 @@ class yare_input final
bool RetireesCanEnroll ;
mcenum_uw_basis GroupUnderwritingType ;
calendar_date LastCoiReentryDate ;
+ calendar_date ListBillDate ;
bool BlendGender ;
bool BlendSmoking ;
double MaleProportion ;