From 59128a73b974ba88f86b49804cfe0fa86c486f59 Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <reinhold@kainhofer.com>
Date: Sat, 30 Apr 2016 20:34:04 +0200
Subject: [PATCH] Move all calculated contract data to its own list, so we can
 later on easily snapshot it for contract changes (i.e. we can simply copy
 contract$values rather than each individual variable holding any of the
 cached/calculated values)

---
 R/InsuranceContract.R            | 126 ++++++++++++++++---------------
 R/exportInsuranceContract_xlsx.R |  30 ++++----
 2 files changed, 79 insertions(+), 77 deletions(-)

diff --git a/R/InsuranceContract.R b/R/InsuranceContract.R
index 989379c..35dd452 100644
--- a/R/InsuranceContract.R
+++ b/R/InsuranceContract.R
@@ -27,24 +27,26 @@ InsuranceContract = R6Class(
     ),
 
     #### Caching values for this contract, initialized/calculated when the object is created
-    transitionProbabilities = NA,
+    values = list(
+      transitionProbabilities = NA,
 
-    cashFlowsBasic = NA,
-    cashFlows = NA,
-    cashFlowsCosts = NA,
-    premiumSum = 0,
+      cashFlowsBasic = NA,
+      cashFlows = NA,
+      cashFlowsCosts = NA,
+      premiumSum = 0,
 
-    presentValues = NA,
-    presentValuesCosts = NA,
+      presentValues = NA,
+      presentValuesCosts = NA,
 
-    premiumCoefficients = NA,
-    premiums = NA,
-    absCashFlows = NA,
-    absPresentValues = NA,
+      premiumCoefficients = NA,
+      premiums = NA,
+      absCashFlows = NA,
+      absPresentValues = NA,
 
-    reserves = NA,
+      reserves = NA,
 
-    premiumComposition = NA,
+      premiumComposition = NA
+    ),
 
 
     #### The code:
@@ -93,91 +95,91 @@ InsuranceContract = R6Class(
 
 
     determineTransitionProbabilities = function() {
-      self$transitionProbabilities = do.call(self$tarif$getTransitionProbabilities, self$params);
-      self$transitionProbabilities
+      self$values$transitionProbabilities = do.call(self$tarif$getTransitionProbabilities, self$params);
+      self$values$transitionProbabilities
     },
 
     determineCashFlows = function() {
-      self$cashFlowsBasic = do.call(self$tarif$getBasicCashFlows, self$params);
-      self$cashFlows = do.call(self$tarif$getCashFlows, c(self$params, "basicCashFlows" = self$cashFlowsBasic));
-      self$premiumSum = sum(self$cashFlows$premiums_advance + self$cashFlows$premiums_arrears);
-      self$cashFlowsCosts = do.call(self$tarif$getCashFlowsCosts, self$params);
-      list("benefits"= self$cashFlows, "costs"=self$cashFlowCosts, "premiumSum" = self$premiumSum)
+      self$values$cashFlowsBasic = do.call(self$tarif$getBasicCashFlows, self$params);
+      self$values$cashFlows = do.call(self$tarif$getCashFlows, c(self$params, "basicCashFlows" = self$values$cashFlowsBasic));
+      self$values$premiumSum = sum(self$values$cashFlows$premiums_advance + self$values$cashFlows$premiums_arrears);
+      self$values$cashFlowsCosts = do.call(self$tarif$getCashFlowsCosts, self$params);
+      list("benefits"= self$values$cashFlows, "costs"=self$values$cashFlowCosts, "premiumSum" = self$values$premiumSum)
     },
 
     calculatePresentValues = function() {
-      self$presentValues = do.call(self$tarif$presentValueCashFlows,
-                                   c(list("cashflows"=self$cashFlows), self$params));
-      self$presentValuesCosts = do.call(self$tarif$presentValueCashFlowsCosts,
-                                        c(list("cashflows"=self$cashFlowsCosts), self$params));
-      list("benefits" = self$presentValues, "costs" = self$presentValuesCosts)
+      self$values$presentValues = do.call(self$tarif$presentValueCashFlows,
+                                   c(list("cashflows"=self$values$cashFlows), self$params));
+      self$values$presentValuesCosts = do.call(self$tarif$presentValueCashFlowsCosts,
+                                        c(list("cashflows"=self$values$cashFlowsCosts), self$params));
+      list("benefits" = self$values$presentValues, "costs" = self$values$presentValuesCosts)
     },
 
     calculatePremiums = function() {
       # the premiumCalculation function returns the premiums AND the cofficients,
       # so we have to extract the coefficients and store them in a separate variable
       res = do.call(self$tarif$premiumCalculation,
-                    c(list(pvBenefits=self$presentValues,
-                      pvCosts=self$presentValuesCosts,
-                      premiumSum = self$premiumSum),
+                    c(list(pvBenefits=self$values$presentValues,
+                      pvCosts=self$values$presentValuesCosts,
+                      premiumSum = self$values$premiumSum),
                       self$params));
-      self$premiumCoefficients = res[["coefficients"]];
-      self$premiums = res[["premiums"]]
-      self$premiums
+      self$values$premiumCoefficients = res[["coefficients"]];
+      self$values$premiums = res[["premiums"]]
+      self$values$premiums
     },
 
     updatePresentValues = function() {
       pvAllBenefits = do.call(self$tarif$presentValueBenefits,
-                              c(list(presentValues = self$presentValues,
-                                     presentValuesCosts = self$presentValuesCosts,
-                                     premiums = self$premiums,
-                                     premiumSum = self$premiumSum),
+                              c(list(presentValues = self$values$presentValues,
+                                     presentValuesCosts = self$values$presentValuesCosts,
+                                     premiums = self$values$premiums,
+                                     premiumSum = self$values$premiumSum),
                                 self$params));
-      self$presentValues = cbind(self$presentValues, pvAllBenefits)
-      self$presentValue
+      self$values$presentValues = cbind(self$values$presentValues, pvAllBenefits)
+      self$values$presentValue
     },
 
     calculateAbsCashFlows = function() {
       absCashFlows = do.call(self$tarif$getAbsCashFlows,
-                             c(list(premiums = self$premiums,
-                                    premiumSum = self$premiumSum,
-                                    cashflows = self$cashFlows,
-                                    cashflowsCosts = self$cashFlowsCosts),
+                             c(list(premiums = self$values$premiums,
+                                    premiumSum = self$values$premiumSum,
+                                    cashflows = self$values$cashFlows,
+                                    cashflowsCosts = self$values$cashFlowsCosts),
                                self$params));
-      self$absCashFlows = absCashFlows
-      self$absCashFlows
+      self$values$absCashFlows = absCashFlows
+      self$values$absCashFlows
     },
 
     calculateAbsPresentValues = function() {
       absPresentValues = do.call(self$tarif$getAbsPresentValues,
-                                 c(list(premiums = self$premiums,
-                                        premiumSum = self$premiumSum,
-                                        presentValues = self$presentValues,
-                                        presentValuesCosts = self$presentValuesCosts),
+                                 c(list(premiums = self$values$premiums,
+                                        premiumSum = self$values$premiumSum,
+                                        presentValues = self$values$presentValues,
+                                        presentValuesCosts = self$values$presentValuesCosts),
                                    self$params));
-      self$absPresentValues = absPresentValues
-      self$absPresentValues
+      self$values$absPresentValues = absPresentValues
+      self$values$absPresentValues
     },
 
     calculateReserves = function() {
-      self$reserves = do.call(self$tarif$reserveCalculation,
-                              c(list(premiums=self$premiums,
-                                presentValues=self$absPresentValues,
-                                cashflows = self$absCashFlows,
-                                premiumSum = self$premiumSum),
+      self$values$reserves = do.call(self$tarif$reserveCalculation,
+                              c(list(premiums=self$values$premiums,
+                                presentValues=self$values$absPresentValues,
+                                cashflows = self$values$absCashFlows,
+                                premiumSum = self$values$premiumSum),
                                 self$params));
-      self$reserves
+      self$values$reserves
     },
 
     premiumAnalysis = function() {
-      self$premiumComposition = do.call(self$tarif$premiumDecomposition,
-                                        c(list(premiums=self$premiums,
-                                               reserves=self$reserves,
-                                               cashflows=self$absCashFlows,
-                                               presentValues=self$absPresentValues,
-                                               q=self$transitionProbabilities),
+      self$values$premiumComposition = do.call(self$tarif$premiumDecomposition,
+                                        c(list(premiums=self$values$premiums,
+                                               reserves=self$values$reserves,
+                                               cashflows=self$values$absCashFlows,
+                                               presentValues=self$values$absPresentValues,
+                                               q=self$values$transitionProbabilities),
                                           self$params));
-      self$premiumComposition
+      self$values$premiumComposition
     },
 
     dummy=NULL
diff --git a/R/exportInsuranceContract_xlsx.R b/R/exportInsuranceContract_xlsx.R
index 0fc0daf..fee81b9 100644
--- a/R/exportInsuranceContract_xlsx.R
+++ b/R/exportInsuranceContract_xlsx.R
@@ -126,8 +126,8 @@ exportInsuranceContract.xlsx = function(contract, filename) {
   # TODO: argument checking for contract and filename
 
   ###
-  nrrows = dim(contract$cashFlows)[[1]]; # Some vectors are longer (e.g. qx), so determine the max nr or rows
-  qp = contract$transitionProbabilities[1:nrrows,]; # extract the probabilities once, will be needed in every sheet
+  nrrows = dim(contract$values$cashFlows)[[1]]; # Some vectors are longer (e.g. qx), so determine the max nr or rows
+  qp = contract$values$transitionProbabilities[1:nrrows,]; # extract the probabilities once, will be needed in every sheet
 
   ################################################
   # Style information
@@ -200,8 +200,8 @@ exportInsuranceContract.xlsx = function(contract, filename) {
 
   # Premiums
   writeData(wb, sheet, "Prämien", startCol=1, startRow=crow);
-  mergeCells(wb, sheet, cols=1:length(contract$premiums), rows=crow:crow);
-  writeDataTable(wb, sheet, setInsuranceValuesLabels(as.data.frame(t(contract$premiums))),
+  mergeCells(wb, sheet, cols=1:length(contract$values$premiums), rows=crow:crow);
+  writeDataTable(wb, sheet, setInsuranceValuesLabels(as.data.frame(t(contract$values$premiums))),
                  startCol=1, startRow=crow+1, colNames=TRUE, rowNames=FALSE,
                  tableStyle="TableStyleMedium3", withFilter = FALSE, headerStyle = styles$tableHeader);
   crow = crow + 4;
@@ -223,10 +223,10 @@ exportInsuranceContract.xlsx = function(contract, filename) {
   sheet = "Reserven";
 
   ccol = ccol + writeAgeQTable(wb, sheet, probs=qp, crow=crow, ccol=1, styles=styles);
-  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$reserves)),
+  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$values$reserves)),
                                  crow=crow, ccol=ccol, tableName="Reserves", styles=styles,
                                  caption="Reserven", valueStyle=styles$currency0) + 1;
-  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$premiumComposition)),
+  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$values$premiumComposition)),
                                  crow=crow, ccol=ccol, tableName="Premium_Decomposition", styles=styles,
                                  caption = "Prämienzerlegung", valueStyle=styles$currency0) + 1;
   setColWidths(wb, sheet, cols = 1:50, widths = "auto", ignoreMergedCells = TRUE)
@@ -242,7 +242,7 @@ exportInsuranceContract.xlsx = function(contract, filename) {
   sheet = "abs.Barwerte";
   ccol = ccol + writeAgeQTable(wb, sheet, probs=qp, crow=crow, ccol=1, styles=styles);
 
-  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$absPresentValues)),
+  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$values$absPresentValues)),
                                  crow=crow, ccol=ccol, tableName="PresentValues_absolute", styles=styles,
                                  caption = "abs. Leistungs- und Kostenbarwerte", valueStyle=styles$currency0) + 1;
   setColWidths(wb, sheet, cols = 1:50, widths = "auto", ignoreMergedCells = TRUE)
@@ -257,7 +257,7 @@ exportInsuranceContract.xlsx = function(contract, filename) {
   crow = 4;
   sheet = "abs.Cash-Flows";
   ccol = ccol + writeAgeQTable(wb, sheet, probs=qp, crow=crow, ccol=1, styles=styles);
-  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$absCashFlows)),
+  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$values$absCashFlows)),
                                  crow=crow, ccol=ccol, tableName="CashFlows_absolute", styles=styles,
                                  caption="abs. Leistungs- und Kostencashflows", withFilter=TRUE, valueStyle=styles$currency0) + 1;
   setColWidths(wb, sheet, cols = 1:50, widths = "auto", ignoreMergedCells = TRUE)
@@ -268,7 +268,7 @@ exportInsuranceContract.xlsx = function(contract, filename) {
   ################################################
 
   # Age, death and survival probabilities
-  costPV = as.data.frame(contract$tarif$costValuesAsMatrix(setInsuranceValuesLabels(contract$presentValuesCosts)));
+  costPV = as.data.frame(contract$tarif$costValuesAsMatrix(setInsuranceValuesLabels(contract$values$presentValuesCosts)));
   ccol = 1;
   crow = 4;
   sheet = "Barwerte";
@@ -276,14 +276,14 @@ exportInsuranceContract.xlsx = function(contract, filename) {
   ccol = ccol + writeAgeQTable(wb, sheet, probs=qp, crow=crow+6, ccol=1, styles=styles);
 
   # Store the start/end columns of the coefficients, since we need them later in the formula for the premiums!
-  w1 = writePremiumCoefficients(wb, sheet, contract$premiumCoefficients, type="benefits", crow=crow, ccol=ccol-2, tarif=contract$tarif);
+  w1 = writePremiumCoefficients(wb, sheet, contract$values$premiumCoefficients, type="benefits", crow=crow, ccol=ccol-2, tarif=contract$tarif);
   area.premiumcoeff = paste0(int2col(ccol), "%d:", int2col(ccol+w1-1), "%d");
   area.premiumvals  = paste0("$", int2col(ccol), "$", crow+6+2, ":$", int2col(ccol+w1-1), "$", crow+6+2);
-  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$presentValues)),
+  ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(setInsuranceValuesLabels(contract$values$presentValues)),
                                  crow=crow+6, ccol=ccol, tableName="PresentValues_Benefits", styles=styles,
                                  caption = "Leistungsbarwerte", valueStyle=styles$pv0) + 1;
 
-  w2 = writePremiumCoefficients(wb, sheet, contract$premiumCoefficients, type="costs", crow=crow, ccol=ccol-2, tarif=contract$tarif);
+  w2 = writePremiumCoefficients(wb, sheet, contract$values$premiumCoefficients, type="costs", crow=crow, ccol=ccol-2, tarif=contract$tarif);
   area.costcoeff = paste0(int2col(ccol), "%d:", int2col(ccol+w2-1), "%d");
   area.costvals  = paste0("$", int2col(ccol), "$", crow+6+2, ":$", int2col(ccol+w2-1), "$", crow+6+2);
   ccol = ccol + writeValuesTable(wb, sheet, as.data.frame(costPV),
@@ -291,7 +291,7 @@ exportInsuranceContract.xlsx = function(contract, filename) {
                                  caption = "Kostenbarwerte", valueStyle=styles$cost0) + 1;
 
   # Now print out the formulas for premium calculation into the columns 2 and 3:
-  writeData(wb, sheet, as.data.frame(c("Nettoprämie", contract$premiums[["net"]],"Zillmerprämie", contract$premiums[["Zillmer"]], "Bruttoprämie", contract$premiums[["gross"]])), startCol = 1, startRow=crow, colNames = FALSE, borders = "rows");
+  writeData(wb, sheet, as.data.frame(c("Nettoprämie", contract$values$premiums[["net"]],"Zillmerprämie", contract$values$premiums[["Zillmer"]], "Bruttoprämie", contract$values$premiums[["gross"]])), startCol = 1, startRow=crow, colNames = FALSE, borders = "rows");
   for (i in 0:5) {
     writeFormula(wb, sheet, paste0("SUMPRODUCT(", sprintf(area.premiumcoeff, crow+i, crow+i), ", ", area.premiumvals, ") + SUMPRODUCT(", sprintf(area.costcoeff, crow+i, crow+i), ", ", area.costvals, ")"), startCol = 3, startRow = crow+i);
     addStyle(wb, sheet, style=styles$pv0, rows = crow+i, cols = 3, stack = TRUE);
@@ -312,12 +312,12 @@ exportInsuranceContract.xlsx = function(contract, filename) {
   ################################################
 
   # Age, death and survival probabilities
-  costCF = as.data.frame(contract$tarif$costValuesAsMatrix(setInsuranceValuesLabels(contract$cashFlowsCosts)));
+  costCF = as.data.frame(contract$tarif$costValuesAsMatrix(setInsuranceValuesLabels(contract$values$cashFlowsCosts)));
   ccol = 1;
   crow = 4;
   sheet = "Cash-Flows";
   ccol = ccol + writeAgeQTable(wb, sheet, probs=qp, crow=crow, ccol=1, styles=styles);
-  ccol = ccol + writeValuesTable(wb, sheet, setInsuranceValuesLabels(contract$cashFlows),
+  ccol = ccol + writeValuesTable(wb, sheet, setInsuranceValuesLabels(contract$values$cashFlows),
                                  crow=crow, ccol=ccol, tableName="CashFlows_Benefits", styles=styles,
                                  caption="Leistungscashflows", withFilter=TRUE, valueStyle=styles$hide0) + 1;
   ccol = ccol + writeValuesTable(wb, sheet, costCF,
-- 
GitLab