/// <summary>
        /// Calculates the energy in kWh for a given meter reading.  Previous reading is retrieved from the Register of the meter and
        /// used in the calculation.  NB kWh calculated to nearest whole number, rounding away from zero.
        /// </summary>
        /// <param name="reading">the MeterReading object of the current reading</param>
        /// <param name="meter">the Id of the meter the reading belongs to</param>
        /// <returns>kWh consumed as integer</returns>
        public int calculatekWh(MeterReading reading, Meter meter)
        {
            int kWh = 0;
            ///find the most recent reading before this one
            ///caculate the units consumed
            ///calculate the energy consumed --> need to know which meter this reading belongs to

            MeterReading previousReading = getPreviousReadingOnMeter(reading, meter);
            int unitsConsumed = calculateUnits(previousReading, reading, meter);

            ///to determine kWh need to know type of meter
            var elecMeter = meter as ElectricityMeter;
            if (elecMeter != null)
            {
                ///must be an electricity meter
                ///only coeff is scaling factor
                ///
                kWh = (int)Math.Round((double)unitsConsumed * elecMeter.ScalingFactor, MidpointRounding.AwayFromZero);
            }
            else
            {
                ///must be a gas meter
                var gasMeter = meter as GasMeter;
                kWh = (int)Math.Round(
                    (double)unitsConsumed
                    * gasMeter.MeterCoefficient     ///converts from units on meter to m3 (defined in constructor)
                    * gasMeter.CalorificValue       ///converts from m3 into joules (defined in constructor)
                    * gasMeter.CorrectionFactor     ///corrects joules for standard room temp and pressure
                    / EMConverter.fromJoulesTokWh,  ///converts from joules to kWh, static property of EMConverter class
                    MidpointRounding.AwayFromZero);
            }

            return kWh;
        }
 public void forecastInvoiceThrowsTargetInvocationException345()
 {
     ForecastingManager forecastingManager;
     Invoice invoice;
     forecastingManager = new ForecastingManager();
     forecastingManager.mediator = (EMMediator)null;
     Invoice s0 = new Invoice();
     s0.Id = 0;
     s0.PresentRead = 0;
     s0.PreviousRead = 0;
     s0.KWh = 0;
     s0.StandingCharge = 0;
     s0.ConsumptionCharge = 0;
     s0.OtherCharge = 0;
     s0.Checked = false;
     s0.ConsumptionIsValid = false;
     s0.CostIsValid = false;
     s0.BillDate = default(DateTime);
     s0.StartDate = new DateTime(4611686018427387903L & 563247985000448L,
                         (DateTimeKind)(563247985000448uL >> 62));
     s0.EndDate = new DateTime(4611686018427387903L & 563247985000448L,
                       (DateTimeKind)(563247985000448uL >> 62));
     s0.CostVariance = 0;
     s0.KWhVariance = 0;
     s0.CostCanBeValidated = default(bool?);
     s0.ConsumptionCanBeValidated = default(bool?);
     Meter s1 = new Meter();
     s1.Id = 0;
     s1.SerialNo = (string)null;
     s1.KWhtoCO2ConversionFactor = 0;
     s1.NumbDigits = 0;
     s1.Fuel = (string)null;
     s1.StartDate = default(DateTime);
     s1.Invoices = (ICollection<Invoice>)null;
     s1.Notes = (ICollection<Annotation>)null;
     s1.Tariffs = (ICollection<Tariff>)null;
     s1.Register = (ICollection<MeterReading>)null;
     s0.Meter = s1;
     invoice = this.forecastInvoice(forecastingManager, s0);
 }
        //
        // GET: /Reading/
        public ActionResult Index(int meterId, int propertyId, string fuel)
        {
            MeterReadingListViewModel model = new MeterReadingListViewModel();
            Meter meter = new Meter();

            try
            {
                ///retreive data form emAPI and set up MeterReadingListViewModel object
                model.Readings = ResponseReader.convertTo<List<MeterReading>>(emAPI.getMeterReadings(meterId));
                meter = ResponseReader.convertTo<Meter>(emAPI.getDetailsForMeter(meterId));

                model.Readings = model.Readings.OrderByDescending(rdg => rdg.Date).ToList();
                model.MeterDetails = new MeterViewModel(meter);
                model.MeterDetails.Meter.Id = meterId;
                model.MeterDetails.Meter.Fuel = fuel;
                model.MeterDetails.BelongsToProperty = propertyId;
                return View(model);
            }
            catch
            {
                return View("Error");
            }
        }
 //EDIT METHODS - for amending exisiting data
 public abstract Meter editMeter(int meterId, Meter newMeter);
 public abstract int saveMeter(Meter meter);
        /// <summary>
        /// Gets the previous reading on this meter, using the date of the reading object passed in
        /// </summary>
        /// <param name="currentReading"></param>
        /// <param name="meter"></param>
        /// <returns></returns>
        private MeterReading getPreviousReadingOnMeter(MeterReading currentReading, Meter meter)
        {
            MeterReading previousReading = new MeterReading();
            meter.Register = meter.Register.OrderByDescending(rdg => rdg.Date).ToList();

            foreach (MeterReading rdg in meter.Register)
            {
                ///where there is only one other reading, the other reading is the start date of the meter
                ///it is acceptable to have a reading on the start date so currentReading date >= rdg date
                if (meter.Register.Count == 1)
                {
                    if (rdg.Date <= currentReading.Date)
                        return rdg;
                }
                else
                {
                    ///there are other non-zero readings, so currentReading date > rdg date
                    if (rdg.Date < currentReading.Date)
                        return rdg;
                }
            }

            ///
            return null;
        }
        private MeterReading getNextReading(Meter meter, MeterReading reading)
        {
            ///deal with no meter readings
            if (meter.Register == null | meter.Register.Count == 0)
            {
                return null;
            }
            else
            {
                meter.Register = meter.Register.OrderBy(rdg => rdg.Date).ToList();
                foreach (MeterReading rdg in meter.Register)
                {
                    ///register is in ascending date order so the first reading with a date greater than the
                    ///submitted reading is the required reading
                    if (rdg.Date > reading.Date)
                        return rdg;
                }

                ///if all readings are younger than the submitted reading return null
                return null;
            }
        }
        private int calculateUnits(MeterReading previousReading, MeterReading rdg, Meter meter)
        {
            int unitsConsumed = 0;
            string readingAsString = rdg.Reading.ToString();
            ///truncate reading length if greater than no digits on meter
            if (readingAsString.Length > meter.NumbDigits)
            {
                readingAsString = readingAsString.Substring(0, meter.NumbDigits);
                rdg.Reading = int.Parse(readingAsString);
            }

            ///get max possible reading on this meter
            StringBuilder maxRead = new StringBuilder();
            maxRead.Append('9', meter.NumbDigits);
            int maxPossibleReading = int.Parse(maxRead.ToString());

            ///check if the meter has 'ticked over', ie gone past max reading
            if (previousReading.Reading > rdg.Reading)
            {
                ///meter has gone past the max read and started again
                ///therefore need units from previous --> max
                ///and from 0 --> current reading
                ///+1 for max --> 0 (eg 999999 + 1 will take the meter back to 0)
                unitsConsumed = maxPossibleReading - previousReading.Reading + rdg.Reading + 1;
            }
            else
            {
                ///units consumed is just the difference between prev and present
                unitsConsumed = rdg.Reading - previousReading.Reading;
            }

            return unitsConsumed;
        }
        public MeterViewModel(Meter m)
        {
            ///populate fiel specific properties
            ///

            ElectricityMeter elecMeter = m as ElectricityMeter;
            GasMeter gasMeter = m as GasMeter;

            if (elecMeter != null)
            {
                this.ScalingFactor = elecMeter.ScalingFactor;
            }
            else if ( gasMeter != null)
            {
                this.MeterCoefficient = gasMeter.MeterCoefficient;
                this.CorrectionFactor = gasMeter.CorrectionFactor;
                this.CalorificValue = gasMeter.CalorificValue;

                if (gasMeter.MeterCoefficient == 0.028316846)
                {
                    this.MeterUnits = "cubic feet";
                }
                if (gasMeter.MeterCoefficient == 0.28316846)
                {
                    this.MeterUnits = "10s of cubic feet";
                }
                if (gasMeter.MeterCoefficient == 2.8316846)
                {
                    this.MeterUnits = "100s of cubic feet";
                }
                if (gasMeter.MeterCoefficient == 1)
                {
                    this.MeterUnits = "cubic meters";
                }
            }

            ///load tariff view model with data from meter
            ///

            Meter = m;
            Tariff = new TariffViewModel();

            if (Meter.Tariffs.Count == 0)
            {
                ///no tariff set yet
                ///
                Tariff = null;
            }
            else
            {
                ///get most recent tariff
                ///
                Meter.Tariffs = Meter.Tariffs.OrderByDescending(t => t.StartDate).ToList();

                Tariff currentTariff = Meter.Tariffs.ElementAt(0);
                currentTariff.Bands = Meter.Tariffs.ElementAt(0).Bands.ToList();

                ///convert model to viewModel
                ///

                Tariff = TariffConverter.createTariffViewFromTariff(currentTariff, false);
            }
        }
 /// <summary>
 /// Store the meter object in the database
 /// </summary>
 /// <param name="meter"></param>
 public override int saveMeter(Meter meter)
 {
     emdb.Meters.Add(meter);
     emdb.SaveChanges();
     return meter.Id;
 }
        //* * * EDIT METHODS - for amending existing data
        /// <summary>
        /// Updates meter with specified id.  Child objects ARE NOT affected.
        /// </summary>
        /// <param name="meterId">id of meter to update</param>
        /// <param name="newMeter">meter object with replacement data</param>
        public override Meter editMeter(int meterId, Meter newMeter)
        {
            Meter oldMeter = emdb.Meters.Single(m => m.Id == meterId);

            oldMeter.KWhtoCO2ConversionFactor = newMeter.KWhtoCO2ConversionFactor;
            oldMeter.SerialNo = newMeter.SerialNo;
            oldMeter.NumbDigits = newMeter.NumbDigits;

            emdb.SaveChanges();
            return oldMeter;
        }