Ejemplo n.º 1
0
 /// <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);
 }
Ejemplo n.º 2
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)));
        }
Ejemplo n.º 4
0
        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)));
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 8
0
 protected override double DoFunWork(HH hh, List <Person> tu)
 {
     return(parFormula.GetValue(hh, tu));
 }