/// <summary> /// get whether the condition is true for a specific person /// note: this is strictly individual, that means that e.g. incomelists and monetary-variables are evaluated for the person /// </summary> internal bool GetPersonValue(HH hh, Person person) { return(parFormula.GetValue(hh, new List <Person>() { person }, person) != 0); }
void GetValues(HH hh, List <Person> tu, out OpItem selItem, out bool noAction) { double formulaOperandValue = 0; selItem = null; noAction = false; if (opTask == OPERAND_TYPE.FORMULA) { formulaOperandValue = formulaOperand.GetValue(hh, tu); } double max = double.MinValue, min = double.MaxValue; foreach (OpItem oi in opItems) { oi.numOperator = hh.GetPersonValue(oi.varOperator.index, tu[0].indexInHH); if (opTask == OPERAND_TYPE.FORMULA) { oi.numOperand = formulaOperandValue; } if (opTask == OPERAND_TYPE.IL) { oi.numOperand = hh.GetPersonValue(oi.varOperand.index, tu[0].indexInHH); } // remark: the behaviour of the old executable cannot be completely reproduced if there are equal mins/maxs // the old executable does the operation only on one item, but which depends on the order of content ... switch (selVar) { case DefPar.Value.ILVAROP_ALL: continue; case DefPar.Value.ILVAROP_MAX: if (oi.numOperator > max) { max = oi.numOperator; selItem = oi; } ; break; case DefPar.Value.ILVAROP_MIN: if (oi.numOperator < min) { min = oi.numOperator; selItem = oi; } ; break; case DefPar.Value.ILVAROP_MINPOS: if (oi.numOperator <= min && oi.numOperator > 0) { min = oi.numOperator; selItem = oi; } ; break; } } if (selVar == DefPar.Value.ILVAROP_MINPOS && selItem == null) { noAction = true; } }
private double ApplyLowUpLimits(double val, HH hh, List <Person> tu, out double ll, out double ul) { ll = coParLowLim != null?coParLowLim.GetValue(hh, tu) : lowLim; ul = coParUpLim != null?coParUpLim.GetValue(hh, tu) : upLim; if (doRunTimeLimCheck) { CheckLimits(ref ll, ref ul, hh); } return(Math.Min(ul, Math.Max(ll, val))); }
protected double ApplyLimits(double value, HH hh, List <Person> tu, Person person) { double ll = pLowLim != null?pLowLim.GetValue(hh, tu, person) : lowLim; double ul = pUpLim != null?pUpLim.GetValue(hh, tu, person) : upLim; if (doRunTimeLimCheck) { CheckLimits(ref ll, ref ul, hh); } return(Math.Min(ul, Math.Max(ll, value))); }
protected override double DoFunWork(HH hh, List <Person> tu) { double amountToShare = parShare.GetValue(hh, tu); List <byte> shareBetween = new List <byte>(); if (parShareBetween != null) { shareBetween = (from p in parShareBetween.GetTUValues(hh, tu) where p.Value select p.Key).ToList(); if (shareBetween.Count == 0 && !shareAllIfNoElig) { base.SetOutVars(0, hh, tu); return(0); } } if (shareBetween.Count == 0) { shareBetween = (from p in tu select p.indexInHH).ToList(); } Dictionary <byte, double> pShares = new Dictionary <byte, double>(); double sumShares = 0; if (parShareProp != null) { foreach (var pers in tu) { double share = 0; if (shareBetween.Contains(pers.indexInHH)) { share = parShareProp.GetValue(hh, tu, pers); if (ignoreNegProp && share < 0) { share = 0; } sumShares += share; } pShares.Add(pers.indexInHH, share); } if (sumShares == 0) { if (!shareEquIfZero && amountToShare != 0) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { // only report if there is anything to share isWarning = true, runTimeErrorId = description.funID, message = $"{description.Get()}: HH {infoStore.GetIDHH(hh)}: {parShareProp.xmlValue} is 0 for all eligible persons - equal sharing is applied" }); } pShares.Clear(); } } if (sumShares == 0) { sumShares = shareBetween.Count; foreach (var pers in tu) { pShares.Add(pers.indexInHH, shareBetween.Contains(pers.indexInHH) ? 1 : 0); } } double oneShare = amountToShare / sumShares; foreach (var ps in pShares) { double v = oneShare * ps.Value; hh.SetPersonValue(value: v, varIndex: coParOutVar.Item1.index, personIndex: ps.Key, addTo: coParOutVar.Item2); if (coParResultVar != null) { hh.SetPersonValue(value: v, varIndex: coParResultVar.index, personIndex: ps.Key); } } return(0); }
protected override double DoFunWork(HH hh, List <Person> tu) { double val = 0; foreach (Component comp in components) { double elig = 0; foreach (var persElig in comp.pCond.GetTUValues(hh, tu)) { if (persElig.Value) { if (comp.perElig) { ++elig; } else { elig = 1; break; } // note: even for perTU just one person (not necessarily the head) } // must fulfill the condition (even if it is individual, like age < x) } if (elig == 0) { continue; } double valComp = comp.pFormula.GetValue(hh, tu); double ll = comp.pLowLim != null?comp.pLowLim.GetValue(hh, tu) : comp.lowLim; double ul = comp.pUpLim != null?comp.pUpLim.GetValue(hh, tu) : comp.upLim; if (comp.doRunTimeLimCheck) { CheckComponentLimits(ref ll, ref ul, comp.pCond.description.parID, hh); } valComp = Math.Min(ul, Math.Max(ll, valComp)); val += elig * valComp; } if (withdraw_Base != null) // if there is a withdraw base, calculate withdrawal { double withdraw_RateVal = 0; double withdraw_BaseVal = withdraw_Base.GetValue(hh, tu); double withdraw_StartVal = (withdraw_Start == null) ? 0 : withdraw_Start.GetValue(hh, tu); if (withdraw_End != null) // if there is a withdraw_End, calculate the withdraw_Rate { double withdraw_EndVal = withdraw_End.GetValue(hh, tu); withdraw_RateVal = val / (withdraw_EndVal - withdraw_StartVal); } else if (withdraw_Rate != null) // else get withdraw_End from the parameter (if both missing, rate is left to 0, so nothing is withdrawed) { withdraw_RateVal = withdraw_Rate.GetValue(hh, tu); } val -= Math.Max(withdraw_BaseVal - withdraw_StartVal, 0) * withdraw_RateVal; val = Math.Max(val, 0); } return(val); }
protected override double DoFunWork(HH hh, List <Person> tu) { // first make a run-time copy of all bands (for thread-safety) List <Band> rtBands = new List <Band>(bands.Count); bands.ForEach((b) => rtBands.Add(b.Clone() as Band)); double safeBaseThreshold = baseThreshold; double safeQuotient = quotient; // do the rouding and check the threshold & quotient double baseVal = basePar.GetValue(hh, tu); if (!double.IsNaN(roundBase)) { baseVal = Math.Round(baseVal / roundBase) * roundBase; } if (baseThresholdPar != null && !baseThresholdPar.IsGlobal(true)) { safeBaseThreshold = baseThresholdPar.GetValue(hh, tu); } if (quotientPar != null && !quotientPar.IsGlobal(true)) { safeQuotient = quotientPar.GetValue(hh, tu); } if (baseVal < safeBaseThreshold) { return(0); // if base is under the threshold, return 0 } // calculate and check the limits - we only need to calculate the upLim of each Band at runtime, except for Band 1 if (doRunTimeLimCheck) { if (rtBands[0].pLowLim != null) { rtBands[0].lowLim = rtBands[0].pLowLim.GetValue(hh, tu); } foreach (Band band in rtBands) { if (band.pUpLim != null) { band.upLim = band.pUpLim.GetValue(hh, tu); } } CheckGroupLimits(rtBands, description.funID, hh); } // then check if we need to calculate any rates/amounts if (doRunTimeRateCheck) { foreach (Band band in rtBands) { if (band.pRate != null) { band.rate = band.pRate.GetValue(hh, tu); } else if (band.pAmount != null) { band.amount = band.pAmount.GetValue(hh, tu); } } } baseVal = baseVal / safeQuotient; double tax = 0; if (simpleProg) // apply the max rate/amount to all income { if (rtBands.Count > 0 && baseVal > rtBands.Last().upLim) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, runTimeErrorId = description.funID, message = $"{description.Get()}: '{DefPar.SchedCalc.Base}' exceeds '{DefPar.SchedCalc.Band_UpLim}' of highest band ({baseVal}>{rtBands.Last().upLim}) - '{(double.IsNaN(rtBands.Last().rate) ? DefPar.SchedCalc.Band_Amount : DefPar.SchedCalc.Band_Rate)}' of highest band is applied" }); } // get the highest band Band hb = null; foreach (Band b in rtBands) { if (b.lowLim <= baseVal) { hb = b; } if (b.upLim > baseVal) { break; } } if (hb == null) { tax = 0; } else if (!double.IsNaN(hb.rate)) { tax = baseVal * hb.rate; } else { tax = hb.amount; } } else // apply each rate/amount to the equivalent band { double prevLim = Math.Max(rtBands[0].lowLim, 0); // start taxing at the lowest limit of the first band foreach (Band b in rtBands) { if (prevLim > baseVal) { break; } if (!double.IsNaN(b.rate)) { tax += (Math.Max(Math.Min(baseVal, b.upLim) - prevLim, 0)) * b.rate; } else { tax += b.amount; } prevLim = b.upLim; } } tax = tax * safeQuotient; return(tax); }
protected override double DoFunWork(HH hh, List <Person> tu) { return(parFormula.GetValue(hh, tu)); }