public ActionResult Create([Bind(Include = "ID,CustomerID,Year,Quantity")] MeterReading meterReading)
        {
            if (ModelState.IsValid)
            {

                // check to ensure there is not already a reading for that customer and year

                var readings = from c in db.MeterReadings
                             select c;
                readings = readings.Where(s => s.CustomerID.Equals(meterReading.CustomerID));
                if (readings.Where(t => t.Year.Equals(meterReading.Year)).Count() > 0)
                {
                    return RedirectToAction("Index", new { error = "error" });
                    //return RedirectToAction("Index");
                }

                db.MeterReadings.Add(meterReading);
                db.SaveChanges();

                // generate invoice using usage
                // rates are caled from Application state rather than querying DB
                RatesObject rates = (RatesObject)HttpContext.Application["Rates"];
                Invoice newInvoice = new Invoice();
                newInvoice.CustomerID = meterReading.CustomerID;
                newInvoice.Year = meterReading.Year;
                // calculations of usage per band and subtotals; currently hardcoded for 5 bands
                // calculation method based on spreadsheet sheet 2 billing rates, not 2013 data
                if (meterReading.Quantity > 0 )
                {
                    if (meterReading.Quantity >= rates.BandA)
                    {
                        newInvoice.QtyRateA = rates.BandA;  // default 115
                    }
                    else
                    {
                        newInvoice.QtyRateA = meterReading.Quantity;
                    }
                    newInvoice.SubtotalA = newInvoice.QtyRateA * rates.RateA; //usually zero unless rate for Band A changes
                }

                if (meterReading.Quantity > rates.BandA)
                {
                    if (meterReading.Quantity >= rates.BandB)
                    {
                        newInvoice.QtyRateB = rates.BandB - rates.BandA; // maximum for band B 400-115 = 285
                    }
                    else
                    {
                        newInvoice.QtyRateB = meterReading.Quantity - rates.BandA;
                    }
                    newInvoice.SubtotalB = newInvoice.QtyRateB * rates.RateB;
                }

                if (meterReading.Quantity > rates.BandB)
                {
                    if (meterReading.Quantity >= rates.BandC)
                    {
                        newInvoice.QtyRateC = rates.BandC - rates.BandB; // 800-400 = 400
                    }
                    else
                    {
                        newInvoice.QtyRateC = meterReading.Quantity - rates.BandB;
                    }
                    newInvoice.SubtotalC = newInvoice.QtyRateC * rates.RateC;
                }

                if (meterReading.Quantity > rates.BandC)
                {
                    if (meterReading.Quantity >= rates.BandD)
                    {
                        newInvoice.QtyRateD = rates.BandD - rates.BandC; // 1500-800 = 700
                    }
                    else
                    {
                        newInvoice.QtyRateD = meterReading.Quantity - rates.BandC;
                    }
                    newInvoice.SubtotalD = newInvoice.QtyRateD * rates.RateD;
                }

                if (meterReading.Quantity > rates.BandD)
                {
                    newInvoice.QtyRateE = meterReading.Quantity - rates.BandD;
                    newInvoice.SubtotalE = newInvoice.QtyRateE * rates.RateE;
                }

                newInvoice.Total = newInvoice.SubtotalA + newInvoice.SubtotalB + newInvoice.SubtotalC + newInvoice.SubtotalD + newInvoice.SubtotalE;
                newInvoice.GrandTotal = newInvoice.Total + newInvoice.Arrears;
                db.Invoices.Add(newInvoice);

                // create a new note
                Note newNote = new Note();
                newNote.CustomerID = meterReading.CustomerID;
                newNote.NoteText = "Meter Reading added and Invoice Calculated at " + DateTime.Now + ".";
                db.Notes.Add(newNote);

                db.SaveChanges();
                return RedirectToAction("Index");

            }

            ViewBag.CustomerID = new SelectList(db.Customers, "ID", "FullName", meterReading.CustomerID);
            return View(meterReading);
        }
        public async Task<ActionResult> Mail(int? id)
        {

            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Invoice invoice = db.Invoices.Find(id);
            if (invoice == null)
            {
                return HttpNotFound();
            }
            
            Customer customer = db.Customers.Find(invoice.CustomerID);
       
            var body = "<p>Email From: Meter Matters </p><p>Message: Dear " + customer.FirstName +", here is your invoice for " + invoice.Year + ".</p><p></p>";
            var message = new MailMessage();
            message.To.Add(new MailAddress(customer.Email));   
            message.From = new MailAddress("*****@*****.**");  
            message.Subject = "GWS Invoice Mailer";
            message.Body = string.Format(body);
            message.IsBodyHtml = true;
            try
            {
                message.Attachments.Add(new Attachment(HttpContext.Server.MapPath("~/pdf/" + +customer.ID + customer.FullName + " Invoice " + invoice.Year + ".pdf")));
                
            }
            catch
            {
                //darn, there was an error, try creating invoice
                try
                {
                    bool pdfSuccess = MakePdfInvoice(invoice);
                    message.Attachments.Add(new Attachment(HttpContext.Server.MapPath("~/pdf/" + +customer.ID + customer.FullName + " Invoice " + invoice.Year + ".pdf")));
                }
                catch
                {
                    //dammit, looks like we can't send the invoice
                    return RedirectToAction("Index", new { mail = "error" });
                }
            }
                using (var smtp = new SmtpClient())
                {
                    var credential = new NetworkCredential
                    {
                        UserName = "******",  
                        Password = "******"  
                    };
                    smtp.Credentials = credential;
                    smtp.Host = "smtp.gmail.com";
                    smtp.Port = 587;
                    smtp.EnableSsl = true;
                    await smtp.SendMailAsync(message);

                    // create a new note to record that email was sent
                    Note newNote = new Note();
                    newNote.CustomerID = customer.ID;
                    newNote.NoteText = "Invoice was issued to " + customer.FullName + " by email at " + DateTime.Now + ".";
                    db.Notes.Add(newNote);
                    db.SaveChanges();
                }


                return RedirectToAction("Index", new { mail = "mail" });
        }
 public ActionResult Edit([Bind(Include = "ID,CustomerID,Year,QtyRateA,QtyRateB,QtyRateC,QtyRateD,QtyRateE,SubtotalA,SubtotalB,SubtotalC,SubtotalD,SubtotalE,Total,Arrears,GrandTotal,AmountPaid")] Invoice invoice)
 {
     if (ModelState.IsValid)
     {
         if (invoice.GrandTotal == invoice.AmountPaid)
         {
             invoice._Paid = true;
             // create a new note to record that invoice was paid
             Customer customer = db.Customers.Find(invoice.CustomerID);
             Note newNote = new Note();
             newNote.CustomerID = customer.ID;
             newNote.NoteText = "Invoice of " + customer.FullName + " for year " + invoice.Year + " has been paid in full.";
             db.Notes.Add(newNote);
             db.SaveChanges();
         }
         db.Entry(invoice).State = EntityState.Modified;
         db.SaveChanges();
         return RedirectToAction("Index");
     }
     ViewBag.CustomerID = new SelectList(db.Customers, "ID", "LastName", invoice.CustomerID);
     return View(invoice);
 }
        public ActionResult Create([Bind(Include = "ID,CustomerID,Year,Quantity")] MeterReading meterReading)
        {
            if (ModelState.IsValid)
            {

                // check to ensure there is not already a reading for that customer and year

                var readings = from c in db.MeterReadings
                             select c;
                readings = readings.Where(s => s.CustomerID.Equals(meterReading.CustomerID));
                if (readings.Where(t => t.Year.Equals(meterReading.Year)).Count() > 0)
                {
                    return RedirectToAction("Index", new { error = "error" });
                    //return RedirectToAction("Index");
                }

                db.MeterReadings.Add(meterReading);
                db.SaveChanges();

                // generate invoice using usage
                CalculateInvoice(meterReading);
                // create a new note
                Note newNote = new Note();
                newNote.CustomerID = meterReading.CustomerID;
                newNote.NoteText = "Meter Reading of " + meterReading.Quantity + " added and Invoice Calculated at " + DateTime.Now + ".";
                db.Notes.Add(newNote);
                db.SaveChanges();

                return RedirectToAction("Index");

            }

            ViewBag.CustomerID = new SelectList(db.Customers, "ID", "FullName", meterReading.CustomerID);
            return View(meterReading);
        }
        public ActionResult Edit([Bind(Include = "ID,CustomerID,Year,Quantity")] MeterReading meterReading)
        {
            if (ModelState.IsValid)
            {
                db.Entry(meterReading).State = EntityState.Modified;
                db.SaveChanges();

                // now that meterreadng has been edited, need to make a fresh invoice
                // find previous invoice and delete
                var invoices = from c in db.Invoices
                               select c;
                invoices = invoices.Where(s => s.CustomerID.Equals(meterReading.CustomerID));
                invoices = invoices.Where(t => t.Year.Equals(meterReading.Year));
                foreach (var invoice in invoices)
                {
                    db.Invoices.Remove(invoice);
                }
                db.SaveChanges();

                //now create fresh invoice with updated reading
                CalculateInvoice(meterReading);

                // create a new note to record changes
                Note newNote = new Note();
                newNote.CustomerID = meterReading.CustomerID;
                newNote.NoteText = "Meter Reading edited to " + meterReading.Quantity + " and fresh Invoice Calculated at " + DateTime.Now + ".";
                db.Notes.Add(newNote);
                db.SaveChanges();

                return RedirectToAction("Index");
            }

            ViewBag.CustomerID = new SelectList(db.Customers, "ID", "FullName", meterReading.CustomerID);
            return View(meterReading);
        }
        public ActionResult DeleteConfirmed(int id)
        {
            MeterReading meterReading = db.MeterReadings.Find(id);
            db.MeterReadings.Remove(meterReading);
            db.SaveChanges();

            // find invoice and delete
            var invoices = from c in db.Invoices
                           select c;
            invoices = invoices.Where(s => s.CustomerID.Equals(meterReading.CustomerID));
            invoices = invoices.Where(t => t.Year.Equals(meterReading.Year));
            foreach (var invoice in invoices)
            {
                db.Invoices.Remove(invoice);
            }
            db.SaveChanges();

            // create a new note to record changes
            Note newNote = new Note();
            newNote.CustomerID = meterReading.CustomerID;
            newNote.NoteText = "Meter Reading and associated Invoice deleted at " + DateTime.Now + ".";
            db.Notes.Add(newNote);
            db.SaveChanges();

            return RedirectToAction("Index");
        }