Exemple #1
0
        public CalculationResult Calculate(decimal DesignKindergarten, decimal DesignElementary, decimal DesignSecondary, int LowestGrade, int HighestGrade)
        {
            tracingService.Trace("{0}", "Starting OperatingCapacity.Calculate");
            tracingService.Trace("K:{0}, E: {1}, S: {2}", DesignKindergarten, DesignElementary, DesignSecondary);
            tracingService.Trace("Grade Low:{0}, High: {1}", LowestGrade, HighestGrade);

            CalculationResult result = new CalculationResult();

            //Calculate Kindergarten Capacity
            if (DesignKindergarten != 0)
            {
                result.KindergartenCapacity = Math.Round(DesignKindergarten / Capacity.DesignKindergarten * Capacity.OperatingKindergarten, 0, MidpointRounding.AwayFromZero);
            }

            //Calculate Secondary Capacity
            if (DesignSecondary != 0)
            {
                result.SecondaryCapacity = Math.Round(DesignSecondary / Capacity.DesignSecondary * Capacity.OperatingSecondary, 0, MidpointRounding.AwayFromZero);
            }

            //Calculate Elementary Capacity
            //Get Grade Range
            int lowGrade  = LowestGrade - 100000000;
            int highGrade = HighestGrade - 100000000;

            int lowECount  = 0;
            int highECount = 0;

            if (lowGrade < 8 && highGrade > 0)
            {
                //we need to calculate elementary
                //get number of low and high elementary grades
                for (int x = 1; x <= 7; x++)
                {
                    if (x >= lowGrade && x <= highGrade)
                    {
                        if (x <= 3)
                        {
                            lowECount++;
                        }
                        else
                        {
                            highECount++;
                        }
                    }
                }

                if (lowECount == 0)
                {
                    // all high E
                    result.ElementaryCapacity = Math.Round(DesignElementary / Capacity.DesignElementary * Capacity.OperatingHighElementary, 0, MidpointRounding.AwayFromZero);
                }
                else if (highECount == 0)
                {
                    result.ElementaryCapacity = Math.Round(DesignElementary / Capacity.DesignElementary * Capacity.OperatingLowElementary, 0, MidpointRounding.AwayFromZero);
                }
                else
                {
                    var calcOperatingCapacity = ((lowECount * Capacity.OperatingLowElementary) + (highECount * Capacity.OperatingHighElementary)) / (lowECount + highECount);

                    result.ElementaryCapacity = Math.Round(DesignElementary / Capacity.DesignElementary * calcOperatingCapacity, 0, MidpointRounding.AwayFromZero);
                }
            }

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Function to calculate schedule b total
        /// </summary>
        /// <returns>Schedule B Total</returns>
        internal CalculationResult Calculate()
        {
            CalculationResult result = new CalculationResult();

            tracingService.Trace("{0}", "Starting ScheduleB.Calculate");

            //variables
            decimal constructionNewReplacement           = 0;
            decimal spaceAllocationExisting              = 0;
            decimal constructionRenovations              = 0;
            decimal constructionSiteDevelopmentAllowance = 0;
            decimal softCostContingencyRenovations       = 0;
            decimal softCostContingencySeismic           = 0;
            decimal softCostEquipmentAllowance           = 0;
            decimal constructionTotalConstructionBudget  = 0;
            decimal spaceAllocationNewReplacement        = 0;
            decimal softCostWrapUpLiabilityInsurance     = 0;
            decimal softCostDesignFees = 0;
            decimal softCostContingencyNewReplacement = 0;
            decimal NLCAmount = 0;

            //Default some numbers to 0, cased on Budget Calculation type
            //if partial seismic, set NLC to 0
            //if (BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic)
            //{
            //    NLC = 0;
            //}

            if (BudgetCalculationType == (int)caps_BudgetCalculationType.New ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.Replacement ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.Addition ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.PartialReplacement)
            {
                //default seismic fields to 0
                ConstructionSeismicUpgrade = 0;
                //ConstructionSPIRAdjustment = 0;
                //ConstructionNonStructuralSeismicUpgrade = 0;
            }

            //Get School Type
            var schoolTypeRecord = GetSchoolType(SchoolType);

            #region 2. Space Allocations for Capital Budget -- DONE
            tracingService.Trace("{0}", "Section 2");
            spaceAllocationNewReplacement = CalculateSpaceAllocation(ApprovedDesignCapacity, SchoolType, schoolTypeRecord.caps_Name);

            //Get existing space allocation for addition and partial replacement less any reductions
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.Addition ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.PartialReplacement ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic)
            {
                spaceAllocationExisting       = CalculateSpaceAllocation(ExistingAndDecreaseDesignCapacity, SchoolType, schoolTypeRecord.caps_Name);
                spaceAllocationNewReplacement = spaceAllocationNewReplacement - spaceAllocationExisting;
            }

            tracingService.Trace("Space Allocation - New/Replacement: {0}", spaceAllocationNewReplacement);


            result.SpaceAllocationNewReplacement = spaceAllocationNewReplacement;

            //add extra space allocation
            spaceAllocationNewReplacement += ExtraSpaceAllocation.GetValueOrDefault(0);
            //Get total square meterage
            decimal spaceAllocationTotalNewReplacement = spaceAllocationNewReplacement;

            tracingService.Trace("Space Allocation - Total New/Replacement: {0}", spaceAllocationTotalNewReplacement);
            //DB: Total space allocation doesn't seem to be needed
            //decimal spaceAllocationTotal = spaceAllocationExisting + spaceAllocationTotalNewReplacement;
            #endregion

            #region 3. Construction Unit Rate -- DONE
            tracingService.Trace("{0}", "Section 3");
            //Get Base Budget Rate based on School Type
            decimal constructionBaseBudgetRate = schoolTypeRecord.caps_BaseBudgetRate.Value;

            result.BaseBudgetRate = constructionBaseBudgetRate;
            tracingService.Trace("Base Budget Rate: {0}", constructionBaseBudgetRate);

            //Get Project Size Factor based on square meterage and school type
            decimal constructionProjectSizeFactor = CalculateProjectSizeFactor(SchoolType, schoolTypeRecord.caps_Name, spaceAllocationNewReplacement);

            tracingService.Trace("Project Size Factor: {0}", constructionProjectSizeFactor);
            tracingService.Trace("Project Location Factor: {0}", ProjectLocationFactor);
            result.ProjectSizeFactor     = constructionProjectSizeFactor;
            result.ProjectLocationFactor = ProjectLocationFactor;

            //Set Unit Rate = Base Budget Rate * Project Size Factor * Project Location Factor
            decimal constructionUnitRate = constructionBaseBudgetRate * constructionProjectSizeFactor * ProjectLocationFactor;

            tracingService.Trace("Unit Rate: {0}", constructionUnitRate);
            result.UnitRate = constructionUnitRate;
            #endregion

            #region 4. Construction Items -- DONE
            tracingService.Trace("{0}", "Section 4");
            //Set Construction: New/Replacement = total space allocation * unit rate
            if (BudgetCalculationType != (int)caps_BudgetCalculationType.SeismicUpgrade)
            {
                constructionNewReplacement = spaceAllocationTotalNewReplacement * constructionUnitRate;
            }

            tracingService.Trace("Construction - New/Replacement: {0}", constructionNewReplacement);
            result.ConstructionNewReplacement = constructionNewReplacement;

            //Only for Addition/Partial Replacement & Partial Seismic (4.2)
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.Addition ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.PartialReplacement ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic)
            {
                constructionRenovations = CalculateConstructionRenovationFactor(SchoolType, schoolTypeRecord.caps_Name, spaceAllocationNewReplacement) * constructionNewReplacement;
            }

            tracingService.Trace("Construction - Renovations: {0}", constructionRenovations);
            result.ConstructionRenovation = constructionRenovations;

            //Get Site Development Allowance based on Project Type, School Type and Square meterage (4.3)
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.New)
            {
                if (ApprovedDesignCapacity.Total() >= 1500)
                {
                    constructionSiteDevelopmentAllowance = schoolTypeRecord.caps_NewSchoolGreaterThan1500.Value;
                }
                else
                {
                    constructionSiteDevelopmentAllowance = schoolTypeRecord.caps_NewSchoolLessThan1500.Value;
                }
            }
            else if (BudgetCalculationType == (int)caps_BudgetCalculationType.Replacement ||
                     BudgetCalculationType == (int)caps_BudgetCalculationType.PartialReplacement)
            {
                constructionSiteDevelopmentAllowance = schoolTypeRecord.caps_Replacement.Value;
            }
            else if (BudgetCalculationType == (int)caps_BudgetCalculationType.Addition ||
                     BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic)
            {
                if (spaceAllocationNewReplacement > 2000)
                {
                    constructionSiteDevelopmentAllowance = schoolTypeRecord.caps_Additionfor2000m2.Value;
                }
                else if (spaceAllocationNewReplacement > 1000)
                {
                    constructionSiteDevelopmentAllowance = schoolTypeRecord.caps_Additionfor1000m2.Value;
                }
                else if (spaceAllocationNewReplacement > 500)
                {
                    constructionSiteDevelopmentAllowance = schoolTypeRecord.caps_Additionfor500m2.Value;
                }
            }

            tracingService.Trace("Site Development Allowance: {0}", constructionSiteDevelopmentAllowance);
            result.SiteDevelopmentAllowance = constructionSiteDevelopmentAllowance;

            //Set Site Development Location Allowance = (Project Location Factor -1) * Site Development Allowance (4.4)
            decimal constructionSiteDevelopmentLocationAllowance = (ProjectLocationFactor - 1) * constructionSiteDevelopmentAllowance;

            tracingService.Trace("Site Development Location Allowance: {0}", constructionSiteDevelopmentLocationAllowance);
            result.SiteDevelopmentLocationAllowance = constructionSiteDevelopmentLocationAllowance;

            //Set Total Construction Budget = All fields in region
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.SeismicUpgrade)
            {
                constructionTotalConstructionBudget = ConstructionSeismicUpgrade.GetValueOrDefault(0);
            }
            else
            {
                constructionTotalConstructionBudget = constructionNewReplacement + constructionRenovations + constructionSiteDevelopmentAllowance + constructionSiteDevelopmentLocationAllowance + ConstructionSeismicUpgrade.GetValueOrDefault(0);
            }

            tracingService.Trace("Total Construction Budget: {0}", constructionTotalConstructionBudget);
            #endregion

            #region 5. Owner's Cost Items
            tracingService.Trace("{0}", "Section 5");
            //Set Design Fees = Reports and Studies Allowance % * Total Construction Budget + Base Reports and Studies Allowance (5.1a)
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.SeismicUpgrade)
            {
                softCostDesignFees = (schoolTypeRecord.caps_SeismicReportsandStudiesDesignFees.GetValueOrDefault(0) * constructionTotalConstructionBudget) + GetBudgetCalculationValue("Reports and Studies Allowance");
            }
            else
            {
                softCostDesignFees = (schoolTypeRecord.caps_ReportsandStudiesDesignFees.GetValueOrDefault(0) * constructionTotalConstructionBudget) + GetBudgetCalculationValue("Reports and Studies Allowance");
            }

            tracingService.Trace("Design Fees: {0}", softCostDesignFees);
            result.DesignFees = softCostDesignFees;

            //Set Post-Contract Contingency = Construction % * Total Construction Budget (5.2)

            if (BudgetCalculationType == (int)caps_BudgetCalculationType.New ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.Replacement)
            {
                softCostContingencyNewReplacement = GetBudgetCalculationValue("Post Contract Contingency New/Replacement Space") * constructionTotalConstructionBudget;
            }
            else if (BudgetCalculationType == (int)caps_BudgetCalculationType.Addition ||
                     BudgetCalculationType == (int)caps_BudgetCalculationType.PartialReplacement ||
                     BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic
                     )
            {
                softCostContingencyNewReplacement = GetBudgetCalculationValue("Post Contract Contingency New/Replacement Space") * (constructionNewReplacement + constructionSiteDevelopmentAllowance + constructionSiteDevelopmentLocationAllowance);
            }

            tracingService.Trace("Post-Contract Contingency - New/Replacement: {0}", softCostContingencyNewReplacement);
            result.PostContractNewReplacement = softCostContingencyNewReplacement;

            //Set Post-Contract Contingency - Renovations (5.3)
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.Addition ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.PartialReplacement ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic)
            {
                softCostContingencyRenovations = GetBudgetCalculationValue("Post Contract Contingency Renovations") * constructionRenovations;
            }

            //Set Post-Contract Contingency - Seismic (5.3a)
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.SeismicUpgrade)
            {
                softCostContingencySeismic = GetBudgetCalculationValue("Post Contract Contingency Seismic") * (ConstructionSeismicUpgrade.GetValueOrDefault(0));
            }

            tracingService.Trace("Post-Contract Contingency - Renovations: {0}", softCostContingencyRenovations);
            tracingService.Trace("Post-Contract Contingency - Seismic: {0}", softCostContingencySeismic);
            result.PostContractRenovation = softCostContingencyRenovations;
            result.PostContractSeismic    = softCostContingencySeismic;


            //**Get Equipment Allowance Percentage
            //**Get School District Location Freight Percentage
            //Set Equipment Allowance - New Space (5.5)
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.New ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.Addition)
            {
                softCostEquipmentAllowance = (constructionBaseBudgetRate * spaceAllocationNewReplacement * schoolTypeRecord.caps_EquipmentAllowanceNewSpace.Value) + (constructionBaseBudgetRate * spaceAllocationNewReplacement * schoolTypeRecord.caps_EquipmentAllowanceNewSpace.Value * FreightRateAllowance);
                result.EquipmentNew        = softCostEquipmentAllowance;
            }
            else if (BudgetCalculationType == (int)caps_BudgetCalculationType.Replacement ||
                     BudgetCalculationType == (int)caps_BudgetCalculationType.PartialReplacement ||
                     BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic)
            {
                softCostEquipmentAllowance  = (constructionBaseBudgetRate * spaceAllocationNewReplacement * schoolTypeRecord.caps_EquipmentAllowanceReplacementSpace.Value) + (constructionBaseBudgetRate * spaceAllocationNewReplacement * schoolTypeRecord.caps_EquipmentAllowanceNewSpace.Value * FreightRateAllowance);
                result.EquipmentReplacement = softCostEquipmentAllowance;
            }

            tracingService.Trace("Equipment Allowance: {0}", softCostEquipmentAllowance);

            //Wrap-Up Liability Insurance (5.8)
            if (BudgetCalculationType == (int)caps_BudgetCalculationType.PartialSeismic ||
                BudgetCalculationType == (int)caps_BudgetCalculationType.SeismicUpgrade)
            {
                softCostWrapUpLiabilityInsurance = constructionTotalConstructionBudget / 1000 * GetBudgetCalculationValue("Wrap Up Liability Insurance Renovations or Seismic");
            }
            else
            {
                softCostWrapUpLiabilityInsurance = constructionTotalConstructionBudget / 1000 * GetBudgetCalculationValue("Wrap Up Liability Insurance New or Replacement");
            }

            tracingService.Trace("Liability Insurance: {0}", softCostWrapUpLiabilityInsurance);
            result.LiabilityInsurance = softCostWrapUpLiabilityInsurance;

            decimal softCostPayableTaxes = (constructionTotalConstructionBudget + softCostDesignFees + softCostContingencyNewReplacement + softCostContingencyRenovations + softCostContingencySeismic + softCostEquipmentAllowance) * GetBudgetCalculationValue("Payable Taxes");

            tracingService.Trace("Payable Taxes: {0}", softCostPayableTaxes);
            result.PayableTaxes = softCostPayableTaxes;

            decimal totalOwnersCost = softCostDesignFees + softCostContingencyNewReplacement + softCostContingencyRenovations + softCostContingencySeismic + MunicipalFees + softCostEquipmentAllowance + softCostWrapUpLiabilityInsurance + softCostPayableTaxes;

            tracingService.Trace("Total Owners Costs: {0}", totalOwnersCost);


            var projectManagementFee = CalculateProjectManagementFeeAllowance(totalOwnersCost + constructionTotalConstructionBudget);
            result.ProjectManagement = projectManagementFee;
            tracingService.Trace("Project Management Fee: {0}", projectManagementFee);
            #endregion

            decimal supplementalCosts = Demolition + AbnormalTopography + TempAccommodation + OtherSupplemental;

            //UPDATE: Add NLC to supplemental
            if ((BudgetCalculationType == (int)caps_BudgetCalculationType.New || BudgetCalculationType == (int)caps_BudgetCalculationType.Replacement) &&
                IncludeNLC)
            {
                //get ProjectLocationFactor and NLC Amount
                NLCAmount = CalculateNLCAmount(ApprovedDesignCapacity, SchoolType, schoolTypeRecord.caps_Name);
                NLCAmount = NLCAmount * ProjectLocationFactor;
            }
            result.NLCBudgetAmount = NLCAmount;

            tracingService.Trace("Supplemental Costs: {0}", supplementalCosts);

            var subTotal = totalOwnersCost + constructionTotalConstructionBudget + projectManagementFee + supplementalCosts + NLCAmount;

            var riskReservePercent = GetBudgetCalculationValue("Risk Reserve and Escalation");
            var riskReserve        = subTotal * riskReservePercent;

            result.RiskReserve        = riskReserve;
            result.RiskReservePercent = riskReservePercent * 100;

            result.Total = subTotal + riskReserve;

            return(result);
        }