MarimerLLC / cslaforum

Discussion forum for CSLA .NET
https://cslanet.com
Other
31 stars 6 forks source link

Business Rule #185

Open africaninternetgroup opened 8 years ago

africaninternetgroup commented 8 years ago

I have a business object called the taxpaysliplineitem which calculates the tax payable by a employee on his income. when the object is created the it calculates the correct amount of tax. When I save the object and retrieve it from the data base the business rules are not being run and the amount of tax is zero. Below is the code I am using .I am trying to invoke the Business rules manually in the Child_OnDataPortalInvokeComplete when I retrieve the object from the database, Where I am I going wrong.

protected override void AddBusinessRules() { base.AddBusinessRules(); BusinessRules.AddRule(new TaxableIncomeYTDCalculator(TaxableIncomeYTDProperty) { Priority = 0 }); BusinessRules.AddRule(new TaxPeriodDeterminer(TaxPeriodProperty) { Priority = 1 }); BusinessRules.AddRule(new TaxPayableCalculator(TaxPayableProperty) { Priority = 2 }); BusinessRules.AddRule(new TaxDueCalculator(AmountProperty) { Priority = 3 });

    }

    private class TaxableIncomeYTDCalculator :Csla.Rules.BusinessRule
    {
        public TaxableIncomeYTDCalculator(Csla.Core.IPropertyInfo primaryProperty)
            :base(primaryProperty)
        {
            InputProperties = new List<Csla.Core.IPropertyInfo>();
            InputProperties.Add(primaryProperty);
        }
        protected override void Execute(Csla.Rules.RuleContext context)
        {
            var target = (TaxPayslipLineItem)context.Target;
            var grosspay = (double)ReadProperty(target.Parent.Parent, Payslip.GrossPayProperty);
            var ytdincome = target.TaxableIncomeBFWD;

            context.AddOutValue(PrimaryProperty, grosspay + ytdincome);

        }
    }

    private class TaxPeriodDeterminer :Csla.Rules.BusinessRule
    {
        public TaxPeriodDeterminer(Csla.Core.IPropertyInfo primaryProperty)
            :base(primaryProperty)
        {
            InputProperties = new List<Csla.Core.IPropertyInfo>();
            InputProperties.Add(primaryProperty);
        }
        protected override void Execute(Csla.Rules.RuleContext context)
        {
            var target = (TaxPayslipLineItem)context.Target;
            var to = ReadProperty(((Payslip)target.Parent.Parent).Parent.Parent, Payroll.ToProperty);
            var taxperiod =Convert.ToDateTime(to).Month;
            context.AddOutValue(PrimaryProperty, taxperiod);
        }
    }

    private class TaxPayableCalculator :Csla.Rules.BusinessRule
    {
        public TaxPayableCalculator(Csla.Core.IPropertyInfo primaryProperty)
            :base(primaryProperty)
        {
            InputProperties = new List<Csla.Core.IPropertyInfo>();
            InputProperties.Add(primaryProperty);
        }
        protected override void Execute(Csla.Rules.RuleContext context)
        {
            var target = (TaxPayslipLineItem)context.Target;
            var taxbands = target.TaxBands;
            var taxableincome = target.TaxableIncomeYTD;
            var taxperiod = target.TaxPeriod;
            var taxcredit = target.TaxCredit;

            double taxpayable = 0d;

            foreach(var item in taxbands)
            {
                if(taxableincome>=((item.HigherIncomeBand-item.LowerIncomeBand)/12)*taxperiod)
                {
                    taxpayable += (item.HigherIncomeBand - item.LowerIncomeBand) / 12 * taxperiod * item.TaxRate;
                    taxableincome -= (item.HigherIncomeBand - item.LowerIncomeBand) / 12 * taxperiod;
                }
                else
                {
                    taxpayable += taxableincome * item.TaxRate;
                    break;
                }
            }
            if (taxcredit / 12 * taxperiod > taxpayable)
                taxpayable = 0;
            else
                taxpayable -= taxcredit / 12 * taxperiod;
            context.AddOutValue(PrimaryProperty, taxpayable);

        }
    }

    private class TaxDueCalculator:Csla.Rules.BusinessRule
    {
        public TaxDueCalculator(Csla.Core.IPropertyInfo primaryProperty)
            :base(primaryProperty)
        {
            InputProperties = new List<Csla.Core.IPropertyInfo>();
            InputProperties.Add(primaryProperty);
        }
        protected override void Execute(Csla.Rules.RuleContext context)
        {
            var target = (TaxPayslipLineItem)context.Target;
            var taxpaidytd = target.TaxPaidYTD;
            var taxpayable = target.TaxPayable;

            context.AddOutValue(PrimaryProperty, taxpayable > taxpaidytd ? taxpayable - taxpaidytd : 0);
        }
    }

    private void Child_Create(EmployeeTaxInfo info,PayslipLineItems parent)
    {
        SetParent(parent);
        using(BypassPropertyChecks)
        {
            Id = info.Id;
            Name = info.Name;
            TaxCredit = info.TaxCredit;
            TaxBands = TaxBandList.GetTaxBandList(Id);
        }
        base.Child_Create();
    }

private void Child_Fetch(TaxPayslipLineItemDto item,PayslipLineItems parent) { SetParent(Parent); using(BypassPropertyChecks) { Id = item.TaxId; Name = item.Name; TaxableIncomeBFWD = item.TaxableIncomeBFWD; TaxPaidBFWD = item.TaxPaidBFWD; TaxCredit = item.TaxCredit; TimeStamp = item.LastChanged; } TaxBands = TaxBandList.GetTaxBandList(Id);

        //BusinessRules.CheckRules();

    }

    protected override void Child_OnDataPortalInvokeComplete(DataPortalEventArgs e)
    {
        if (e.Operation == DataPortalOperations.Fetch)
        {

            BusinessRules.CheckRules();
        }

    }
rockfordlhotka commented 8 years ago

Generally you'd want to call BusinessRules.CheckRules at the bottom of your DataPortal_Fetch or Child_Fetch method (or both).

Keep in mind that CheckRules checks the rules for an object, not for the entire graph.

africaninternetgroup commented 8 years ago

Thanks for your quick response