Пример #1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="invoiceLine"></param>
 /// <returns></returns>
 public InvoiceLine SaveInvoiceLine(InvoiceLine invoiceLine)
 {
     invoiceLine.ChangeTracker.ChangeTrackingEnabled = true;
     using (var db = _trexContextProvider.TrexEntityContext)
     {
         if (invoiceLine.ID == 0)
         {
             invoiceLine.ChangeTracker.State = ObjectState.Added;
         }
         else
         {
             invoiceLine.ChangeTracker.State = ObjectState.Modified;
         }
         db.InvoiceLines.ApplyChanges(invoiceLine);
         db.SaveChanges();
     }
     return(invoiceLine);
 }
        public bool Update(InvoiceLine invoiceLine)
        {
            if (!InvoiceLineExists(invoiceLine.InvoiceLineId))
            {
                return(false);
            }

            try
            {
                using var cn = Connection;
                cn.Open();
                return(cn.Update(invoiceLine));
            }
            catch (Exception)
            {
                return(false);
            }
        }
Пример #3
0
        public ActionResult Details(string name)
        {
            if (name == null)
            {
                return(new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest));
            }
            //Product product = db.Products.Find(id);



            //Stockitem query
            var       my        = (from c in db.StockItems where c.StockItemName == name select c.StockItemID).FirstOrDefault();
            StockItem stockitem = db.StockItems.Find((int)my);

            //Supplier query
            var      my2      = (from c in db.StockItems where c.StockItemName == name select c.SupplierID).FirstOrDefault();
            Supplier supplier = db.Suppliers.Find((int)my2);

            //Person Query
            var my3 = (from s in db.StockItems
                       join sp in db.Suppliers
                       on s.SupplierID equals sp.SupplierID
                       where s.StockItemName == name
                       join p in db.People
                       on sp.PrimaryContactPersonID equals p.PersonID
                       select p.PersonID).FirstOrDefault();

            Person person = db.People.Find((int)my3);

            //InvoiceLine query
            var my4 = (from c in db.StockItems
                       join i in db.InvoiceLines
                       on c.StockItemID equals i.StockItemID
                       where c.StockItemName == name
                       select i.StockItemID).FirstOrDefault();

            InvoiceLine invoiceLine = db.InvoiceLines.Find((int)my4);



            ProductDetailsViewModel viewmodel = new ProductDetailsViewModel(stockitem, supplier, person, invoiceLine);

            return(View(viewmodel));
        }
Пример #4
0
 protected void Page_Init(object sender, EventArgs e)
 {
     ctx = new AriClinicContext("AriClinicContext");
     // security control, it must be a user logged
     if (Session["User"] == null)
     {
         Response.Redirect("Default.aspx");
     }
     else
     {
         user = CntAriCli.GetUser((Session["User"] as User).UserId, ctx);
         Process proc = (from p in ctx.Processes
                         where p.Code == "invoice"
                         select p).FirstOrDefault <Process>();
         per = CntAriCli.GetPermission(user.UserGroup, proc, ctx);
         btnAccept.Visible = per.Modify;
     }
     //
     if (Request.QueryString["InvoiceId"] != null)
     {
         invoiceId = Int32.Parse(Request.QueryString["InvoiceId"]);
         inv       = CntAriCli.GetInvoice(invoiceId, ctx);
         LoadInvoiceData();
     }
     else
     {
         //TODO: What to do if there is not an invoice
     }
     if (Session["Clinic"] != null)
     {
         cl = (Clinic)Session["Clinic"];
     }
     //
     if (Request.QueryString["InvoiceLineId"] != null)
     {
         invoiceLineId = Int32.Parse(Request.QueryString["InvoiceLineId"]);
         invl          = CntAriCli.GetInvoiceLine(invoiceLineId, ctx);
         LoadData(invl);
     }
     else
     {
         LoadTaxTypeCombo(null);
     }
 }
Пример #5
0
        public async Task <List <InvoiceLine> > GetAllAsync(CancellationToken ct = default(CancellationToken))
        {
            IList <InvoiceLine> list = new List <InvoiceLine>();
            var invoiceLines         = await _context.InvoiceLine.ToListAsync(ct);

            foreach (var i in invoiceLines)
            {
                var invoiceLine = new InvoiceLine
                {
                    InvoiceLineId = i.InvoiceLineId,
                    InvoiceId     = i.InvoiceId,
                    TrackId       = i.TrackId,
                    UnitPrice     = i.UnitPrice,
                    Quantity      = i.Quantity
                };
                list.Add(invoiceLine);
            }
            return(list.ToList());
        }
Пример #6
0
        public async Task <List <InvoiceLine> > GetByTrackIdAsync(int id, CancellationToken ct = default(CancellationToken))
        {
            IList <InvoiceLine> list = new List <InvoiceLine>();
            var current = await _context.InvoiceLine.Where(a => a.TrackId == id).ToListAsync(ct);

            foreach (var i in current)
            {
                var newisd = new InvoiceLine
                {
                    InvoiceLineId = i.InvoiceLineId,
                    InvoiceId     = i.InvoiceId,
                    TrackId       = i.TrackId,
                    UnitPrice     = i.UnitPrice,
                    Quantity      = i.Quantity
                };
                list.Add(newisd);
            }
            return(list.ToList());
        }
        public async Task <InvoiceLine> AddAsync(InvoiceLine newInvoiceLine, CancellationToken ct = default(CancellationToken))
        {
            using (var cn = Connection)
            {
                cn.Open();

                newInvoiceLine.InvoiceLineId = cn.InsertAsync(
                    new InvoiceLine
                {
                    InvoiceLineId = newInvoiceLine.InvoiceLineId,
                    InvoiceId     = newInvoiceLine.InvoiceId,
                    TrackId       = newInvoiceLine.TrackId,
                    UnitPrice     = newInvoiceLine.UnitPrice,
                    Quantity      = newInvoiceLine.Quantity
                }).Result;
            }

            return(newInvoiceLine);
        }
Пример #8
0
 /// <summary>
 /// Merge all values from one Entity into another one.
 /// </summary>
 /// <param name="source">Source Entity. Will be copied to the target.</param>
 /// <param name="target">Target Entity. Will receive the values from the source.</param>
 /// <returns>void.</returns>
 public static void Merge(InvoiceLine source, InvoiceLine target)
 {
     // this method merges 2 Entities.
     #region Merge Values
     target.InvoiceLineID  = source.InvoiceLineID;
     target.InvoiceID      = source.InvoiceID;
     target.StockItemID    = source.StockItemID;
     target.Description    = source.Description;
     target.PackageTypeID  = source.PackageTypeID;
     target.Quantity       = source.Quantity;
     target.UnitPrice      = source.UnitPrice;
     target.TaxRate        = source.TaxRate;
     target.TaxAmount      = source.TaxAmount;
     target.LineProfit     = source.LineProfit;
     target.ExtendedPrice  = source.ExtendedPrice;
     target.LastEditedBy   = source.LastEditedBy;
     target.LastEditedWhen = source.LastEditedWhen;
     #endregion
 }
Пример #9
0
        private async Task CreateProductIfNotExistsAsync(InvoiceLine line)
        {
            var api = await GetApiAsync();

            var exists = api.Product.Get().FirstOrDefault(p => p.Code == line.ProductCode) != null;

            if (!exists)
            {
                Product product = new Product
                {
                    Code         = line.ProductCode,
                    Name         = line.Description,
                    Description  = line.ProductDescription,
                    SalesPrice   = line.Price,
                    SalesAccount = 3100
                };
                await api.Product.SaveAsync(product);
            }
        }
Пример #10
0
 protected void LoadData(InvoiceLine invl)
 {
     txtInvoiceLineId.Text = invl.InvoiceLineId.ToString();
     inv = invl.Invoice;
     LoadInvoiceData();
     tck = invl.Ticket;
     if (tck != null)
     {
         txtTicketId.Text   = tck.TicketId.ToString();
         txtTicketData.Text = String.Format("{0} ({1}: {2:###,##0.00})"
                                            , tck.Policy.Customer.FullName
                                            , tck.Description
                                            , tck.Amount);
     }
     LoadTaxTypeCombo(invl.TaxType);
     txtDescription.Text   = invl.Description;
     txtTaxPercentage.Text = String.Format("{0:##0.00}", invl.TaxPercentage);
     txtAmount.Text        = String.Format("{0:###,##0.00}", invl.Amount);
 }
Пример #11
0
        public ActionResult EditInvoiceL(int invoicelineid, int invoiceid, int trackid, decimal?unitprice, int quantity)
        {
            InvoiceLine newEntry = new InvoiceLine();

            newEntry.InvoiceLineId = invoicelineid;
            newEntry.InvoiceId     = invoiceid;
            newEntry.TrackId       = trackid;
            newEntry.UnitPrice     = unitprice;
            newEntry.Quantity      = quantity;

            InvoiceLine entryData = rs.InvoiceLines.SingleOrDefault(invoiceline => invoiceline.InvoiceLineId == invoicelineid);

            rs.Entry(entryData).CurrentValues.SetValues(newEntry);
            rs.SaveChanges();

            Response.Write("<script>alert('Data inserted successfully')</script>");

            return(RedirectToAction("DetailsInvoiceLine"));
        }
Пример #12
0
        public InvoiceLine Add(InvoiceLine newInvoiceLine)
        {
            using (var cn = Connection)
            {
                cn.Open();

                newInvoiceLine.InvoiceLineId = (int)cn.Insert(
                    new InvoiceLine
                {
                    InvoiceLineId = newInvoiceLine.InvoiceLineId,
                    InvoiceId     = newInvoiceLine.InvoiceId,
                    TrackId       = newInvoiceLine.TrackId,
                    UnitPrice     = newInvoiceLine.UnitPrice,
                    Quantity      = newInvoiceLine.Quantity
                });
            }

            return(newInvoiceLine);
        }
Пример #13
0
 protected bool CreateChange()
 {
     if (!DataOk())
     {
         return(false);
     }
     if (invl == null)
     {
         invl = new InvoiceLine();
         UnloadData(invl);
         ctx.Add(invl);
     }
     else
     {
         invl = CntAriCli.GetInvoiceLine(invoiceLineId, ctx);
         UnloadData(invl);
     }
     ctx.SaveChanges();
     return(true);
 }
Пример #14
0
        public async Task <bool> UpdateAsync(InvoiceLine invoiceLine, CancellationToken ct = default(CancellationToken))
        {
            if (!await InvoiceLineExists(invoiceLine.InvoiceLineId, ct))
            {
                return(false);
            }
            var changing = await _context.InvoiceLine.FindAsync(invoiceLine.InvoiceLineId);

            _context.InvoiceLine.Update(changing);

            changing.InvoiceLineId = invoiceLine.InvoiceLineId;
            changing.InvoiceId     = invoiceLine.InvoiceId;
            changing.TrackId       = invoiceLine.TrackId;
            changing.UnitPrice     = invoiceLine.UnitPrice;
            changing.Quantity      = invoiceLine.Quantity;

            await _context.SaveChangesAsync(ct);

            return(true);
        }
        public async Task <bool> UpdateAsync(InvoiceLine invoiceLine, CancellationToken ct = default(CancellationToken))
        {
            if (!await InvoiceLineExists(invoiceLine.InvoiceLineId, ct))
            {
                return(false);
            }

            try
            {
                using (var cn = Connection)
                {
                    cn.Open();
                    return(cn.UpdateAsync(invoiceLine).Result);
                }
            }
            catch (Exception ex)
            {
                return(false);
            }
        }
Пример #16
0
        public void Constructor_should_assign_properties()
        {
            // Arrange
            var          lineNumber  = new LineNumber(1);
            var          quantity    = new Quantity(1);
            var          itemPrice   = new Amount(10m);
            const string description = "description";

            // Act
            var actual = new InvoiceLine(lineNumber,
                                         quantity,
                                         itemPrice,
                                         description);

            // Assert
            Assert.Equal(lineNumber, actual.LineNumber);
            Assert.Equal(quantity, actual.Quantity);
            Assert.Equal(itemPrice, actual.ItemPrice);
            Assert.Equal(description, actual.Description);
        }
Пример #17
0
        void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 0)
            {
                InvoiceLine InvoiceLine = (InvoiceLine)bsInvoiceLines.Current;



                DataGridViewProductCell DataGridCell = (DataGridViewProductCell)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];

                InvoiceLine.ProductUnitRefId = (Guid)DataGridCell.CellValue;

                ProductService pService = new ProductService();

                ProductUnit ProductUnit = pService.GetProductUnit(InvoiceLine.ProductUnitRefId);

                InvoiceLine.Price = ProductUnit.Price;
            }
            this.dataGridView1.Refresh();
        }
        protected void RadGrid1_ItemCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
        {
            try
            {
                // we only process commands with a datasource (our image buttons)
                if (e.CommandSource == null)
                {
                    return;
                }
                string typeOfControl = e.CommandSource.GetType().ToString();
                if (typeOfControl.Equals("System.Web.UI.WebControls.ImageButton"))
                {
                    int         id   = 0;
                    ImageButton imgb = (ImageButton)e.CommandSource;
                    if (imgb.ID != "New" && imgb.ID != "Exit")
                    {
                        id = (int)e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex][e.Item.OwnerTableView.DataKeyNames[0]];
                    }
                    switch (imgb.ID)
                    {
                    case "Select":
                        break;

                    case "Edit":
                        break;

                    case "Delete":
                        invl = CntAriCli.GetInvoiceLine(id, ctx);
                        ctx.Delete(invl);
                        ctx.SaveChanges();
                        RefreshGrid(true);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Label lbl = (Label)this.Parent.FindControl("lblMessage");
                lbl.Text = ex.Message;
            }
        }
Пример #19
0
        public void InsertInvoiceLinesInDatabase(Invoice input, List <TimeEntry> timeEntries, int projectId)
        {
            //Beregn hvor mange forskellige priser der er
            var allETs = GetTimeEntriesByInvoice(input);

            //Opret ny invoiceLine for hver af dem
            var ETLines = new Dictionary <double, double>();

            //Add distinct prices to a dictionary
            foreach (var te in allETs)
            {
                if (!ETLines.ContainsKey(te.Price))
                {
                    ETLines.Add(te.Price, te.BillableTime);
                }

                else
                {
                    ETLines[te.Price] += te.BillableTime;
                }
            }

            //Indsæt data i dem og bind til relevant Invoice
            foreach (var distincts in ETLines)
            {
                var newLine = new InvoiceLine
                {
                    InvoiceID     = input.ID,
                    PricePrUnit   = distincts.Key,
                    Units         = distincts.Value,
                    Unit          = "timer",
                    UnitType      = 0,
                    VatPercentage = input.VAT,
                    IsExpense     = true,
                    Text          = string.Empty
                };

                entityContext.InvoiceLines.ApplyChanges(newLine);
                entityContext.SaveChanges();
            }
        }
Пример #20
0
        public void RemoveValidInvoiceLines()
        {
            //arrange
            var invoice      = new Invoice();
            var invoiceItem1 = new InvoiceLine()
            {
                InvoiceLineId = 1,
                Cost          = 10.21,
                Quantity      = 4,
                Description   = "Banana"
            };


            //act
            invoice.AddInvoiceLine(invoiceItem1);
            var result = invoice.RemoveInvoiceLine(1);

            //assert
            Assert.IsTrue(invoice.LineItems.Count == 0, "LineItems was not removed successfully ");
            Assert.IsTrue(result.Success, "LineItems was not removed successfully ");
        }
Пример #21
0
        public async Task <IActionResult> Delete([FromBody] InvoiceLine _InvoiceLine)
        {
            InvoiceLine _InvoiceLineq = new InvoiceLine();

            try
            {
                _InvoiceLineq = _context.InvoiceLine
                                .Where(x => x.InvoiceLineId == (Int64)_InvoiceLine.InvoiceLineId)
                                .FirstOrDefault();

                _context.InvoiceLine.Remove(_InvoiceLineq);
                await _context.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError($"Ocurrio un error: { ex.ToString() }");
                return(await Task.Run(() => BadRequest($"Ocurrio un error:{ex.Message}")));
            }

            return(await Task.Run(() => Ok(_InvoiceLineq)));
        }
Пример #22
0
        public InvoiceLine Create(Invoice invoice, double units, double pricePrUnit, string unit, string text, InvoiceLine.UnitTypes unitType, bool isExpense, double vat)
        {
            if (invoice == null)
            {
                throw new ParameterNullOrEmptyException("Invoice cannot be null");
            }

            var invoiceLine = new InvoiceLine
            {
                Units         = units,
                PricePrUnit   = pricePrUnit,
                Text          = text,
                Unit          = unit,
                Invoice       = invoice,
                UnitType      = unitType,
                IsExpense     = isExpense,
                VatPercentage = vat
            };

            return(invoiceLine);
        }
Пример #23
0
    public static InvoiceLine LoadAll(DataRow row)
    {
        InvoiceLine line = Load(row);

        if (row["offering_id"] != DBNull.Value)
        {
            line.Offering = OfferingDB.Load(row);
        }
        if (row["credit_id"] != DBNull.Value)
        {
            line.Credit = CreditDB.Load(row, "credit_");
        }
        if (row["patient_id"] != DBNull.Value)
        {
            line.Patient              = PatientDB.Load(row, "patient_");
            line.Patient.Person       = PersonDB.Load(row, "patient_person_");
            line.Patient.Person.Title = IDandDescrDB.Load(row, "title_patient_title_id", "title_patient_descr");
        }

        return(line);
    }
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        if (!IsValidFormID())
        {
            HideTableAndSetErrorMessage();
            return;
        }

        InvoiceLine invLine = InvoiceLineDB.GetByID(GetFormID());

        if (invLine == null)
        {
            HideTableAndSetErrorMessage("Invalid InvoiceLine ID");
            return;
        }

        InvoiceLineDB.UpdateAreaTreated(invLine.InvoiceLineID, txtFlashingText.Text);

        //close this window
        Page.ClientScript.RegisterStartupScript(this.GetType(), "close", "<script language=javascript>window.returnValue=false;self.close();</script>");
    }
Пример #25
0
        public void AddInvoiceLine_Add_Success()
        {
            var invoice = new Invoice()
            {
                InvoiceNumber = 1210,
                InvoiceDate   = DateTime.Now
            };
            var invoiceLine = new InvoiceLine()
            {
                InvoiceLineId = 1234,
                Description   = "Test Invoice Item",
                Quantity      = 1,
                Cost          = 10
            };

            invoice.AddInvoiceLine(invoiceLine);
            var expected = invoiceLine;
            var actual   = invoice.LineItems.First();

            Assert.Equal(expected, actual);
        }
Пример #26
0
        /// <summary>
        /// Creates InvoiceLines marked as 'manual' for an invoice
        /// </summary>
        /// <param name="invoiceId">The invoice's ID</param>
        /// <param name="VAT">Amount of VAT on the InvoiceLine</param>
        public void CreateNewInvoiceLine(int invoiceId, double VAT)
        {
            using (var entity = _trexContextProvider.TrexEntityContext)
            {
                var invoiceLine = new InvoiceLine
                {
                    Text          = "",
                    PricePrUnit   = 0,
                    InvoiceID     = invoiceId,
                    Units         = 0,
                    UnitType      = 1,
                    SortIndex     = 0,
                    IsExpense     = false,
                    VatPercentage = VAT,
                    Unit          = ""
                };

                entity.InvoiceLines.ApplyChanges(invoiceLine);
                entity.SaveChanges();
            }
        }
Пример #27
0
        public IActionResult Update(UpdateModel model)
        {
            if (ModelState.IsValid)
            {
                var persistedInvoice = Context.Invoice
                                       .Include(i => i.Lines)
                                       .SingleOrDefault(i => i.Id == model.Item.Id);
                if (persistedInvoice == null)
                {
                    persistedInvoice = new Invoice();
                    Context.Invoice.Add(persistedInvoice);
                }
                Context.Entry(persistedInvoice).CurrentValues.SetValues(model.Item);
                foreach (var line in model.Item.Lines)
                {
                    line.InvoiceId = persistedInvoice.Id;
                    var persistedInvoiceLine = persistedInvoice.Lines.SingleOrDefault(l => l.Id == line.Id && line.Id != 0);
                    if (persistedInvoiceLine == null)
                    {
                        persistedInvoiceLine = new InvoiceLine()
                        {
                            Invoice = persistedInvoice
                        };
                        Context.InvoiceLine.Add(persistedInvoiceLine);
                    }
                    Context.Entry(persistedInvoiceLine).CurrentValues.SetValues(line);
                }
                foreach (var line in persistedInvoice.Lines.Where(l => !model.Item.Lines.Select(ll => ll.Id).Contains(l.Id)))
                {
                    Context.Remove(line);
                }
                Context.SaveChanges();

                return(Back(false));
            }
            else
            {
                return(UpdateView(model));
            }
        }
Пример #28
0
        private int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine, DbManager db)
        {
            if (invoiceLine.InvoiceID <= 0 || invoiceLine.InvoiceItemID <= 0)
            {
                throw new ArgumentException();
            }

            if (db.ExecuteScalar <int>(Query("crm_invoice_line").SelectCount().Where(Exp.Eq("id", invoiceLine.ID))) == 0)
            {
                invoiceLine.ID = db.ExecuteScalar <int>(
                    Insert("crm_invoice_line")
                    .InColumnValue("id", 0)
                    .InColumnValue("invoice_id", invoiceLine.InvoiceID)
                    .InColumnValue("invoice_item_id", invoiceLine.InvoiceItemID)
                    .InColumnValue("invoice_tax1_id", invoiceLine.InvoiceTax1ID)
                    .InColumnValue("invoice_tax2_id", invoiceLine.InvoiceTax2ID)
                    .InColumnValue("sort_order", invoiceLine.SortOrder)
                    .InColumnValue("description", invoiceLine.Description)
                    .InColumnValue("quantity", invoiceLine.Quantity)
                    .InColumnValue("price", invoiceLine.Price)
                    .InColumnValue("discount", invoiceLine.Discount)
                    .Identity(1, 0, true));
            }
            else
            {
                db.ExecuteNonQuery(
                    Update("crm_invoice_line")
                    .Set("invoice_id", invoiceLine.InvoiceID)
                    .Set("invoice_item_id", invoiceLine.InvoiceItemID)
                    .Set("invoice_tax1_id", invoiceLine.InvoiceTax1ID)
                    .Set("invoice_tax2_id", invoiceLine.InvoiceTax2ID)
                    .Set("sort_order", invoiceLine.SortOrder)
                    .Set("description", invoiceLine.Description)
                    .Set("quantity", invoiceLine.Quantity)
                    .Set("price", invoiceLine.Price)
                    .Set("discount", invoiceLine.Discount)
                    .Where(Exp.Eq("id", invoiceLine.ID)));
            }
            return(invoiceLine.ID);
        }
Пример #29
0
        private static Invoice GetInvoice(dynamic json)
        {
            if (json is JArray)
            {
                return(null);
            }


            var address = new InvoiceAddress((string)json.address_1, (string)json.address_2,
                                             (string)json.address_3, (string)json.address_4, (string)json.address_5, (string)json.address_6);

            var invoice = new Invoice((DateTime)json.date, (string)json.number, (decimal)json.total,
                                      (decimal)json.tax, (string)json.pdf_url, address);

            foreach (var iL in json.invoice_lines)
            {
                var invoiceLine = new InvoiceLine((int)iL.quantity, (string)iL.details, (decimal)iL.unit_price, (decimal)iL.subtotal);
                invoice.AddLine(invoiceLine);
            }

            return(invoice);
        }
        public void ToStringTest()
        {
            ICRUDTestDBContextProvider cRUDTestDBContextProvider = new CRUDTestDBContextProvider(Guid.NewGuid().ToString());
            var context = cRUDTestDBContextProvider.GetContext();
            var invoiceLineToStringTest = new InvoiceLine {
                InvoiceLineId = 1, TrackId = 1, Quantity = 10
            };
            var trackToStringTest = new Track {
                TrackId = 1, Name = "TestTrackName"
            };

            context.Add(invoiceLineToStringTest);
            context.Add(trackToStringTest);
            context.SaveChanges();

            InvoiceLineBE invoiceLineBE = new InvoiceLineBE(cRUDTestDBContextProvider);

            invoiceLineBE.Load(1);


            Assert.IsTrue(invoiceLineBE.ToString() == "Track Name: TestTrackName Quantity: 10");
        }
    protected void CreatInvoices_Standard()
    {
        try
        {
            ///////////////
            // validation
            ///////////////

            Booking booking = BookingDB.GetByID(GetFormBookingID());
            if (booking == null)
                throw new CustomMessageException("Invalid booking");
            if (booking.BookingStatus.ID != 0)
                throw new CustomMessageException("Booking already set as : " + BookingDB.GetStatusByID(booking.BookingStatus.ID).Descr);
            if (InvoiceDB.GetCountByBookingID(booking.BookingID) > 0) // shouldnt get here since should have been set as completed and thrown in error above
                throw new CustomMessageException("Booking already has an invoice");

            ///////////////////
            // create invoice
            ///////////////////

            decimal GST_Percent = Convert.ToDecimal(((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["GST_Percent"].Value);

            // keep id's to delete if exception and need to roll back

            ArrayList invIDs     = new ArrayList();
            ArrayList invLineIDs = new ArrayList();

            // get list of patients and associated info

            BookingPatient[] bookingPatients = BookingPatientDB.GetByBookingID(booking.BookingID);
            if (bookingPatients.Length == 0)
                throw new CustomMessageException("No patients added");
            Hashtable offeringsHash = OfferingDB.GetHashtable(true, -1, null, true);
            PatientDB.AddACOfferings(ref offeringsHash, ref bookingPatients);

            int[] patientIDs        = new int[bookingPatients.Length];
            int[] bookingPatientIDs = new int[bookingPatients.Length];
            for (int i = 0; i < bookingPatients.Length; i++)
            {
                if (bookingPatients[i].Patient.ACInvOffering == null || bookingPatients[i].Patient.ACPatOffering == null)
                {
                    SetErrorMessage(bookingPatients[i].Patient.Person.FullnameWithoutMiddlename + " does not have an 'PT Type' set. Please set one before completing.");
                    return;
                }

                bookingPatientIDs[i] = bookingPatients[i].BookingPatientID;
                patientIDs[i]        = bookingPatients[i].Patient.PatientID;
            }

            // caches for less db lookups to handle many patients
            Hashtable bpoHash                            = BookingPatientOfferingDB.GetHashtable(bookingPatientIDs);
            Hashtable patientHealthCardCache             = PatientsHealthCardsCacheDB.GetBullkActive(patientIDs);
            Hashtable epcRemainingCache                  = GetEPCRemainingCache(patientHealthCardCache);
            Hashtable patientsMedicareCountThisYearCache = PatientsMedicareCardCountThisYearCacheDB.GetBullk(patientIDs, DateTime.Today.Year);
            Hashtable patientsEPCRemainingCache          = PatientsEPCRemainingCacheDB.GetBullk(patientIDs, DateTime.Today.AddYears(-1));
            Hashtable patientReferrerCache               = PatientReferrerDB.GetEPCReferrersOf(patientIDs, true);
            int       MedicareMaxNbrServicesPerYear      = Convert.ToInt32(SystemVariableDB.GetByDescr("MedicareMaxNbrServicesPerYear").Value);

            Hashtable offeringsHashPrices = GetOfferingHashtable(booking);

            /*
             [done] LCF            - combined inv's   [fac]                            -
             [done] LC             - individual inv's [pt]  [fac if no pt addr]        -
             [done] HC             - combined inv's   [fac]                            -

             [done] DVA            - combined inv's   [dva]                            -
             [done] Medicare       - combined inv's   [medicare]                       - only medicare .. if aditinoal items, create seperate invoice for patient

             [done] LC Emergency   - individual inv's [pt]  [fac if no pt addr]        -
             [done] HC Emergency   - individual inv's [fac]
            */

            /*
            delete InvoiceLine where invoice_id > 130904
            delete Invoice where booking_id = 93602
            update Booking set booking_status_id = 0 where booking_id = 93602

            select * from Invoice where booking_id = 93602
            select * from InvoiceLine where invoice_id > 130902
            */

            int       MC_Invoice_NextID    = 1;
            ArrayList MC_Invoices          = new ArrayList();
            Hashtable MC_InvoiceLines      = new Hashtable();

            ArrayList EPCRemaining_Changes = new ArrayList(); // Tuple<int,int,int> (epcRemaining.ID, curNum, newNum)
            ArrayList EPCRefLetterInfo     = new ArrayList(); // Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, Healthcard, int> (bookingPatient, fieldID, ptReferrer, invType, hc, epcremainingAfter)

            int       DVA_Invoice_NextID   = 1;
            ArrayList DVA_Invoices         = new ArrayList();
            Hashtable DVA_InvoiceLines     = new Hashtable();

            int       LC_Invoice_NextID    = 1;
            ArrayList LC_Invoices          = new ArrayList();
            Hashtable LC_InvoiceLines      = new Hashtable();

            ArrayList LCF_InvoiceLines     = new ArrayList();
            ArrayList HC_InvoiceLines      = new ArrayList();

            int       LCE_Invoice_NextID   = 1;
            ArrayList LCE_Invoices         = new ArrayList();
            Hashtable LCE_InvoiceLines     = new Hashtable();

            int       HCE_Invoice_NextID   = 1;
            ArrayList HCE_Invoices         = new ArrayList();
            Hashtable HCE_InvoiceLines     = new Hashtable();

            // used to check update stock and check warning level emails sent
            ArrayList invoiceLinesExtras = new ArrayList();

            for (int i = 0; i < bookingPatients.Length; i++)
            {
                BookingPatient           bp   = bookingPatients[i];
                BookingPatientOffering[] bpos = bpoHash[bp.BookingPatientID] == null ? new BookingPatientOffering[] { } : (BookingPatientOffering[])((ArrayList)bpoHash[bp.BookingPatientID]).ToArray(typeof(BookingPatientOffering));

                // change to use org specific price
                for (int j = 0; j < bpos.Length; j++)
                    if (offeringsHashPrices[bpos[j].Offering.OfferingID] != null)
                        bpos[j].Offering = (Offering)offeringsHashPrices[bpos[j].Offering.OfferingID];

                // change to use org specific price - but keep IsGstExempt
                if (offeringsHashPrices[bp.Patient.ACInvOffering.OfferingID] != null)
                {
                    bool isGstExempt = bp.Patient.ACInvOffering.IsGstExempt;
                    bp.Patient.ACInvOffering = (Offering)offeringsHashPrices[bp.Patient.ACInvOffering.OfferingID];
                    bp.Patient.ACInvOffering.IsGstExempt = isGstExempt;
                }
                if (offeringsHashPrices[bp.Patient.ACPatOffering.OfferingID] != null)
                {
                    bool isGstExempt = bp.Patient.ACPatOffering.IsGstExempt;
                    bp.Patient.ACPatOffering = (Offering)offeringsHashPrices[bp.Patient.ACPatOffering.OfferingID];
                    bp.Patient.ACPatOffering.IsGstExempt = isGstExempt;
                }

                // use the field of the provider for what epcremaining field to count down in medicare    [[ do this AFTER changing to org specific price ]]
                bp.Patient.ACInvOffering.Field.ID = booking.Provider.Field.ID;
                bp.Patient.ACPatOffering.Field.ID = booking.Provider.Field.ID;

                if (bp.Patient.ACInvOffering.AgedCarePatientType.ID == 8) // Medicare
                {
                    HealthCard               hc            = GetHealthCardFromCache(patientHealthCardCache, bp.Patient.PatientID);
                    HealthCardEPCRemaining[] epcsRemaining = hc == null ? new HealthCardEPCRemaining[] { } : GetEPCRemainingFromCache(epcRemainingCache, hc, booking.Provider.Field.ID);
                    Booking.InvoiceType      invType       = booking.GetInvoiceType(hc, bp.Patient.ACInvOffering, bp.Patient, patientsMedicareCountThisYearCache, epcRemainingCache, MedicareMaxNbrServicesPerYear);

                    if (invType == Booking.InvoiceType.Medicare)
                    {
                        MC_Invoices.Add(new Invoice(MC_Invoice_NextID, -1, 363, booking.BookingID, -1, -1, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, bp.Patient.ACInvOffering.MedicareCharge, 0, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                        MC_InvoiceLines[MC_Invoice_NextID] = new ArrayList();
                        ((ArrayList)MC_InvoiceLines[MC_Invoice_NextID]).Add(new InvoiceLine(-1, MC_Invoice_NextID, bp.Patient.PatientID, bp.Patient.ACInvOffering.OfferingID, 1, bp.Patient.ACInvOffering.MedicareCharge, 0, "", "", -1));  // HERE

                        MC_Invoice_NextID++;

                        int newEpcRemainingCount = -1;
                        for (int j = 0; j < epcsRemaining.Length; j++)
                            if (epcsRemaining[j].Field.ID == booking.Provider.Field.ID)
                                if (epcsRemaining[j].NumServicesRemaining > 0)
                                {
                                    EPCRemaining_Changes.Add( new Tuple<int,int,int>(epcsRemaining[j].HealthCardEpcRemainingID, epcsRemaining[j].NumServicesRemaining, epcsRemaining[j].NumServicesRemaining - 1) );
                                    newEpcRemainingCount = epcsRemaining[j].NumServicesRemaining - 1;
                                }

                        RegisterReferrer[] regRefs = (RegisterReferrer[])patientReferrerCache[bp.Patient.PatientID];
                        if (regRefs != null && regRefs.Length > 0)
                            EPCRefLetterInfo.Add(new Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int>(bp, booking.Provider.Field.ID, regRefs[regRefs.Length - 1], invType, hc, newEpcRemainingCount));

                        //
                        // now add extras to seperate private invoice for the patient
                        //

                        if (bpos.Length > 0)
                        {
                            decimal total = 0;
                            decimal gst   = 0;
                            for (int j = 0; j < bpos.Length; j++)
                            {
                                total += bpos[j].Quantity * bpos[j].Offering.DefaultPrice;
                                gst   += bpos[j].Quantity * bpos[j].Offering.DefaultPrice * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                            }

                            MC_Invoices.Add(new Invoice(MC_Invoice_NextID, -1, 363, booking.BookingID, 0, bp.Patient.PatientID, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                            MC_InvoiceLines[MC_Invoice_NextID] = new ArrayList();
                            for (int j = 0; j < bpos.Length; j++)
                            {
                                decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                                decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);

                                InvoiceLine invoiceLine = new InvoiceLine(-1, MC_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, "", "", -1);  // HERE
                                ((ArrayList)MC_InvoiceLines[MC_Invoice_NextID]).Add(invoiceLine);
                                invoiceLinesExtras.Add(invoiceLine);
                            }

                            MC_Invoice_NextID++;
                        }
                    }
                    else
                    {
                        bp.Patient.ACInvOffering = bp.Patient.ACPatOffering; // this will get run in the below code..
                    }
                }
                else if (bp.Patient.ACInvOffering.AgedCarePatientType.ID == 9) // DVA
                {
                    HealthCard               hc            = GetHealthCardFromCache(patientHealthCardCache, bp.Patient.PatientID);
                    HealthCardEPCRemaining[] epcsRemaining = hc == null ? new HealthCardEPCRemaining[] { } : HealthCardEPCRemainingDB.GetByHealthCardID(hc.HealthCardID, booking.Provider.Field.ID);
                    Booking.InvoiceType      invType       = booking.GetInvoiceType(hc, bp.Patient.ACInvOffering, bp.Patient, patientsMedicareCountThisYearCache, epcRemainingCache, MedicareMaxNbrServicesPerYear);

                    /*
                     * anyone can have medicare
                     * but only LC/LCF can use DVA referral -- if not LC/LCF then cant pay by dva
                     */
                    if ((bp.Patient.ACPatOffering.AgedCarePatientType.ID == 2 || bp.Patient.ACPatOffering.AgedCarePatientType.ID == 4) && invType == Booking.InvoiceType.DVA)
                    {
                        decimal total = bp.Patient.ACInvOffering.DvaCharge;
                        decimal gst   = total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                        for (int j = 0; j < bpos.Length; j++)
                        {
                            total += bpos[j].Quantity * bpos[j].Offering.DvaCharge;
                            gst   += bpos[j].Quantity * bpos[j].Offering.DvaCharge * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                        }

                        DVA_Invoices.Add(new Invoice(DVA_Invoice_NextID, -1, 363, booking.BookingID, -2, -1, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                        DVA_InvoiceLines[DVA_Invoice_NextID] = new ArrayList();
                        decimal line_total = bp.Patient.ACInvOffering.DvaCharge;
                        decimal line_gst   = line_total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                        ((ArrayList)DVA_InvoiceLines[DVA_Invoice_NextID]).Add(new InvoiceLine(-1, DVA_Invoice_NextID, bp.Patient.PatientID, bp.Patient.ACInvOffering.OfferingID, 1, line_total + line_gst, line_gst, bp.AreaTreated, "", -1));  // HERE
                        for (int j = 0; j < bpos.Length; j++)
                        {
                            decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * (bpos[j].Offering.DvaCompanyCode.Length > 0 ? bpos[j].Offering.DvaCharge : bpos[j].Offering.DefaultPrice);
                            decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);

                            InvoiceLine invoiceLine = new InvoiceLine(-1, DVA_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, bpos[j].AreaTreated, "", -1);  // HERE
                            ((ArrayList)DVA_InvoiceLines[DVA_Invoice_NextID]).Add(invoiceLine);
                            invoiceLinesExtras.Add(invoiceLine);
                        }

                        DVA_Invoice_NextID++;

                        RegisterReferrer[] regRefs = (RegisterReferrer[])patientReferrerCache[bp.Patient.PatientID];
                        if (regRefs != null && regRefs.Length > 0)
                            EPCRefLetterInfo.Add(new Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int>(bp, booking.Provider.Field.ID, regRefs[regRefs.Length - 1], invType, hc, -1));
                    }
                    else
                    {
                        bp.Patient.ACInvOffering = bp.Patient.ACPatOffering; // this will get run in the below code..
                    }
                }

                if (bp.Patient.ACInvOffering.AgedCarePatientType.ID == 2) // LC
                {
                    decimal total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal gst   = total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        total += bpos[j].Quantity * bpos[j].Offering.DefaultPrice;
                        gst   += bpos[j].Quantity * bpos[j].Offering.DefaultPrice * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                    }

                    LC_Invoices.Add(new Invoice(LC_Invoice_NextID, -1, 363, booking.BookingID, 0, bp.Patient.PatientID, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                    LC_InvoiceLines[LC_Invoice_NextID] = new ArrayList();
                    decimal line_total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal line_gst   = line_total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    ((ArrayList)LC_InvoiceLines[LC_Invoice_NextID]).Add(new InvoiceLine(-1, LC_Invoice_NextID, bp.Patient.PatientID, bp.Patient.ACInvOffering.OfferingID, 1, line_total + line_gst, line_gst, "", "", -1));  // HERE
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);

                        InvoiceLine invoiceLine = new InvoiceLine(-1, LC_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, "", "", -1);  // HERE
                        ((ArrayList)LC_InvoiceLines[LC_Invoice_NextID]).Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }

                    LC_Invoice_NextID++;
                }
                else if (bp.Patient.ACInvOffering.AgedCarePatientType.ID == 4) // LCF
                {
                    decimal total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal gst   = total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    LCF_InvoiceLines.Add(new InvoiceLine(-1, -1, bp.Patient.PatientID, bp.Patient.ACInvOffering.OfferingID, 1, total + gst, gst, "", "", -1));  // HERE

                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);

                        InvoiceLine invoiceLine = new InvoiceLine(-1, -1, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, "", "", -1);  // HERE
                        LCF_InvoiceLines.Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }
                }
                else if (bp.Patient.ACInvOffering.AgedCarePatientType.ID == 3 || bp.Patient.ACInvOffering.AgedCarePatientType.ID == 5) // HC/HCU
                {
                    decimal total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal gst   = total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    HC_InvoiceLines.Add(new InvoiceLine(-1, -1, bp.Patient.PatientID, bp.Patient.ACInvOffering.OfferingID, 1, total + gst, gst, "", "", -1));  // HERE

                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);

                        InvoiceLine invoiceLine = new InvoiceLine(-1, -1, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, "", "", -1);  // HERE
                        HC_InvoiceLines.Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }
                }
                else if (bp.Patient.ACInvOffering.AgedCarePatientType.ID == 6) // LCE
                {
                    decimal total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal gst   = total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    for(int j=0; j<bpos.Length; j++)
                    {
                        total += bpos[j].Quantity * bpos[j].Offering.DefaultPrice;
                        gst   += bpos[j].Quantity * bpos[j].Offering.DefaultPrice * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                    }

                    LCE_InvoiceLines[LCE_Invoice_NextID] = new ArrayList();
                    LCE_Invoices.Add(new Invoice(LCE_Invoice_NextID, -1, 363, booking.BookingID, 0, bp.Patient.PatientID, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));
                    decimal line_total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal line_gst   = line_total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    ((ArrayList)LCE_InvoiceLines[LCE_Invoice_NextID]).Add(new InvoiceLine(-1, LCE_Invoice_NextID, bp.Patient.PatientID, bp.Patient.ACInvOffering.OfferingID, 1, line_total + line_gst, line_gst, "", "", -1));  // HERE
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);

                        InvoiceLine invoiceLine = new InvoiceLine(-1, LCE_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, "", "", -1);  // HERE
                        ((ArrayList)LCE_InvoiceLines[LCE_Invoice_NextID]).Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }

                    LCE_Invoice_NextID++;
                }
                else if (bp.Patient.ACInvOffering.AgedCarePatientType.ID == 7) // HCE
                {
                    decimal total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal gst   = total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        total += bpos[j].Quantity * bpos[j].Offering.DefaultPrice;
                        gst   += bpos[j].Quantity * bpos[j].Offering.DefaultPrice * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                    }

                    HCE_InvoiceLines[HCE_Invoice_NextID] = new ArrayList();
                    HCE_Invoices.Add(new Invoice(HCE_Invoice_NextID, -1, 363, booking.BookingID, booking.Organisation.OrganisationID, -1, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));
                    decimal line_total = bp.Patient.ACInvOffering.DefaultPrice;
                    decimal line_gst   = line_total * (bp.Patient.ACInvOffering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    ((ArrayList)HCE_InvoiceLines[HCE_Invoice_NextID]).Add(new InvoiceLine(-1, HCE_Invoice_NextID, bp.Patient.PatientID, bp.Patient.ACInvOffering.OfferingID, 1, line_total + line_gst, line_gst, "", "", -1));  // HERE
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);

                        InvoiceLine invoiceLine = new InvoiceLine(-1, HCE_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, "", "", -1);  // HERE
                        ((ArrayList)HCE_InvoiceLines[HCE_Invoice_NextID]).Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }

                    HCE_Invoice_NextID++;
                }
            }

            try
            {

                CreateInvoices(booking.BookingID, MC_Invoice_NextID,  MC_Invoices,  MC_InvoiceLines,  true,  ref invIDs, ref invLineIDs);  // Medicare
                foreach (Tuple<int,int,int> epcRemaining in EPCRemaining_Changes)
                    HealthCardEPCRemainingDB.UpdateNumServicesRemaining(epcRemaining.Item1, epcRemaining.Item3);

                CreateInvoices(booking.BookingID, DVA_Invoice_NextID, DVA_Invoices, DVA_InvoiceLines, true, ref invIDs, ref invLineIDs);   // DVA
                CreateInvoices(booking.BookingID, LC_Invoice_NextID,  LC_Invoices,  LC_InvoiceLines,  false, ref invIDs, ref invLineIDs);  // LC
                CreateInvoice (booking.BookingID, booking.Organisation.OrganisationID, -1, LCF_InvoiceLines, ref invIDs, ref invLineIDs);  // LCF
                CreateInvoice (booking.BookingID, booking.Organisation.OrganisationID, -1, HC_InvoiceLines,  ref invIDs, ref invLineIDs);  // HC
                CreateInvoices(booking.BookingID, LCE_Invoice_NextID, LCE_Invoices, LCE_InvoiceLines, false, ref invIDs, ref invLineIDs);  // LCE
                CreateInvoices(booking.BookingID, HCE_Invoice_NextID, HCE_Invoices, HCE_InvoiceLines, false, ref invIDs, ref invLineIDs);  // HCE

                // set booking as completed
                BookingDB.UpdateSetBookingStatusID(booking.BookingID, 187);

                // =============================================================================================================================================

                // Create Referrer Letters

                //
                // check that reversing invoice for clinics ... these are reset(?)
                //

                ArrayList allFileContents = new ArrayList();

                foreach (Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int> ptInfo in EPCRefLetterInfo)
                {
                    BookingPatient      bookingPatient    = ptInfo.Item1;
                    int                 fieldID           = ptInfo.Item2;
                    RegisterReferrer    registerReferrer  = ptInfo.Item3;
                    Booking.InvoiceType invType           = ptInfo.Item4;
                    HealthCard          hc                = ptInfo.Item5;
                    int                 epcCountRemaining = ptInfo.Item6;

                    // send referrer letters
                    //
                    // NB: FIRST/LAST letters ONLY FOR MEDICARE - DVA doesn't need letters
                    // Treatment letters for anyone with epc though -- even for private invoices
                    if (registerReferrer != null)
                    {
                        bool needToGenerateFirstLetter = false;
                        bool needToGenerateLastLetter  = false;
                        bool needToGenerateTreatmentLetter = registerReferrer.ReportEveryVisitToReferrer; // send treatment letter whether privately paid or not

                        if (invType == Booking.InvoiceType.Medicare)  // create first/last letters only if medicare
                        {
                            int nPodTreatmentsThisEPC = (int)InvoiceDB.GetMedicareCountByPatientAndDateRange(bookingPatient.Patient.PatientID, hc.DateReferralSigned.Date, DateTime.Now, -1, fieldID);
                            needToGenerateFirstLetter = (nPodTreatmentsThisEPC == 1);
                            needToGenerateLastLetter  = (epcCountRemaining == 0);
                        }

                        // if already generating first or last letter, don't generate treatement letter also
                        if (needToGenerateFirstLetter || needToGenerateLastLetter)
                            needToGenerateTreatmentLetter = false;

                        // TODO: Send Letter By Email

                        // ordereed by shippping/billing addr desc, so if any set, that will be the first one

                        string[] emails = ContactDB.GetEmailsByEntityID(registerReferrer.Organisation.EntityID);

                        bool generateSystemLetters = !registerReferrer.BatchSendAllPatientsTreatmentNotes && (emails.Length > 0 || chkGenerateSystemLetters.Checked);
                        int letterPrintHistorySendMethodID = emails.Length == 0 ? 1 : 2;

                        if (generateSystemLetters)
                        {
                            Letter.FileContents[] fileContentsList = booking.GetSystemLettersList(emails.Length > 0 ? Letter.FileFormat.PDF : Letter.FileFormat.Word, bookingPatient.Patient, hc, fieldID, registerReferrer.Referrer, true, needToGenerateFirstLetter, needToGenerateLastLetter, needToGenerateTreatmentLetter, false, Convert.ToInt32(Session["SiteID"]), Convert.ToInt32(Session["StaffID"]), letterPrintHistorySendMethodID);
                            if (fileContentsList != null && fileContentsList.Length > 0)
                            {
                                if (emails.Length > 0)
                                {
                                    Letter.EmailSystemLetter((string)Session["SiteName"], string.Join(",", emails), fileContentsList);
                                }
                                else
                                {
                                    allFileContents.AddRange(fileContentsList);
                                }
                            }
                        }

                        //BookingDB.UpdateSetGeneratedSystemLetters(booking.BookingID, needToGenerateFirstLetter, needToGenerateLastLetter, generateSystemLetters);
                        BookingPatientDB.UpdateSetGeneratedSystemLetters(bookingPatient.BookingPatientID, needToGenerateFirstLetter, needToGenerateLastLetter, generateSystemLetters);
                    }

                }

                if (allFileContents.Count > 0)
                {
                    Letter.FileContents[] fileContentsList = (Letter.FileContents[])allFileContents.ToArray(typeof(Letter.FileContents));
                    Letter.FileContents   fileContents     = Letter.FileContents.Merge(fileContentsList, "Treatment Letters.pdf"); // change here to create as pdf
                    Session["downloadFile_Contents"] = fileContents.Contents;
                    Session["downloadFile_DocName"]  = fileContents.DocName;
                    //showDownloadPopup = true;

                }

                // ==============================================================================================================================================

                // successfully completed, so update and check warning level for stocks
                foreach (InvoiceLine invoiceLine in invoiceLinesExtras)
                    if (invoiceLine.OfferingOrder == null) // stkip counting down if item is on order
                        StockDB.UpdateAndCheckWarning(booking.Organisation.OrganisationID, invoiceLine.Offering.OfferingID, (int)invoiceLine.Quantity);

            }
            catch (Exception ex)
            {
                if (ex is CustomMessageException == false)
                    Logger.LogException(ex);

                // roll back...
                BookingDB.UpdateSetBookingStatusID(booking.BookingID, 0);
                //BookingDB.UpdateSetGeneratedSystemLetters(booking.BookingID, booking.NeedToGenerateFirstLetter, booking.NeedToGenerateLastLetter, booking.HasGeneratedSystemLetters);
                foreach (int invLineID in invLineIDs)
                    InvoiceLineDB.Delete(invLineID);
                foreach (int invID in invIDs)
                    InvoiceDB.Delete(invID);
                foreach (Tuple<int,int,int> epcRemaining in EPCRemaining_Changes)
                    HealthCardEPCRemainingDB.UpdateNumServicesRemaining(epcRemaining.Item1, epcRemaining.Item2);

                throw;
            }

            SetErrorMessage("Done!");

            // close this window
            bool showDownloadPopup = false;
            Page.ClientScript.RegisterStartupScript(this.GetType(), "close", "<script language=javascript>window.returnValue=" + (showDownloadPopup ? "true" : "false") + ";self.close();</script>");
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
            return;
        }
        catch (System.Data.SqlClient.SqlException sqlEx)
        {
            if (sqlEx.Message.StartsWith("No claim numbers left") || sqlEx.Message.StartsWith("Error: Claim number already in use"))
                SetErrorMessage(sqlEx.Message);
            else
                SetErrorMessage("", sqlEx.ToString());
            return;
        }
        catch (Exception ex)
        {
            SetErrorMessage("", ex.ToString());
            return;
        }
    }
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        UpdateAreaTreated();

        try
        {
            ///////////////
            // validation
            ///////////////

            Booking booking = BookingDB.GetByID(GetFormBookingID());
            if (booking == null)
                throw new CustomMessageException("Invalid booking");
            if (booking.BookingStatus.ID != 0)
                throw new CustomMessageException("Booking already set as : " + BookingDB.GetStatusByID(booking.BookingStatus.ID).Descr);
            if (InvoiceDB.GetCountByBookingID(booking.BookingID) > 0) // shouldnt get here since should have been set as completed and thrown in error above
                throw new CustomMessageException("Booking already has an invoice");

            ///////////////////
            // create invoice
            ///////////////////

            decimal GST_Percent = Convert.ToDecimal(((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["GST_Percent"].Value);

            // keep id's to delete if exception and need to roll back

            ArrayList invIDs     = new ArrayList();
            ArrayList invLineIDs = new ArrayList();

            // get list of patients and associated info

            BookingPatient[] bookingPatients = BookingPatientDB.GetByBookingID(booking.BookingID);
            if (bookingPatients.Length == 0)
                throw new CustomMessageException("No patients added");
            Hashtable offeringsHash = OfferingDB.GetHashtable(true, -1, null, true);
            PatientDB.AddACOfferings(ref offeringsHash, ref bookingPatients);

            int[] patientIDs        = bookingPatients.Select(o => o.Patient.PatientID).ToArray();
            int[] bookingPatientIDs = bookingPatients.Select(o => o.BookingPatientID).ToArray();

            // caches for less db lookups to handle many patients
            Hashtable bpoHash                       = BookingPatientOfferingDB.GetHashtable(bookingPatientIDs);
            Hashtable patientHealthCardCache        = PatientsHealthCardsCacheDB.GetBullkActive(patientIDs);
            Hashtable epcRemainingCache             = GetEPCRemainingCache(patientHealthCardCache);
            Hashtable patientsMedicareCountCache    = PatientsMedicareCardCountThisYearCacheDB.GetBullk(patientIDs, DateTime.Today.Year);
            Hashtable patientsEPCRemainingCache     = PatientsEPCRemainingCacheDB.GetBullk(patientIDs, DateTime.Today.AddYears(-1));
            Hashtable patientReferrerCache          = PatientReferrerDB.GetEPCReferrersOf(patientIDs, true);
            int       MedicareMaxNbrServicesPerYear = Convert.ToInt32(SystemVariableDB.GetByDescr("MedicareMaxNbrServicesPerYear").Value);

            Hashtable offeringsHashPrices = GetOfferingHashtable(booking);

            int       MC_Invoice_NextID    = 1;
            ArrayList MC_Invoices          = new ArrayList();
            Hashtable MC_InvoiceLines      = new Hashtable();

            ArrayList EPCRemaining_Changes = new ArrayList(); // Tuple<int,int,int> (epcRemaining.ID, curNum, newNum)
            ArrayList EPCRefLetterInfo     = new ArrayList(); // Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, Healthcard, int> (bookingPatient, fieldID, ptReferrer, invType, hc, epcremainingAfter)

            int       DVA_Invoice_NextID   = 1;
            ArrayList DVA_Invoices         = new ArrayList();
            Hashtable DVA_InvoiceLines     = new Hashtable();

            int       TAC_Invoice_NextID   = 1;
            ArrayList TAC_Invoices         = new ArrayList();
            Hashtable TAC_InvoiceLines     = new Hashtable();

            int       Prv_Invoice_NextID   = 1;
            ArrayList Prv_Invoices         = new ArrayList();
            Hashtable Prv_InvoiceLines     = new Hashtable();

            // used to check update stock and check warning level emails sent
            ArrayList invoiceLinesExtras = new ArrayList();

            for (int i = 0; i < bookingPatients.Length; i++)
            {
                Patient                  patient = bookingPatients[i].Patient;
                BookingPatient           bp      = bookingPatients[i];
                BookingPatientOffering[] bpos    = bpoHash[bp.BookingPatientID] == null ? new BookingPatientOffering[] { } : (BookingPatientOffering[])((ArrayList)bpoHash[bp.BookingPatientID]).ToArray(typeof(BookingPatientOffering));

                HealthCard               hc                       = GetHealthCardFromCache(patientHealthCardCache, patient.PatientID);
                bool                     hasEPC                   = hc != null && hc.DateReferralSigned != DateTime.MinValue;
                HealthCardEPCRemaining[] epcsRemaining            = !hasEPC ? new HealthCardEPCRemaining[] { } : GetEPCRemainingFromCache(epcRemainingCache, hc, booking.Provider.Field.ID);
                int                      totalServicesAllowedLeft = !hasEPC ? 0 : (MedicareMaxNbrServicesPerYear - (int)patientsMedicareCountCache[patient.PatientID]);
                int                      totalEpcsRemaining       = epcsRemaining.Sum(o => o.NumServicesRemaining);
                DateTime                 referralSignedDate       = !hasEPC ? DateTime.MinValue : hc.DateReferralSigned.Date;
                DateTime                 hcExpiredDate            = !hasEPC ? DateTime.MinValue : referralSignedDate.AddYears(1);
                bool                     isExpired                = !hasEPC ? true              : hcExpiredDate <= DateTime.Today;

                Booking.InvoiceType invType = booking.GetInvoiceType(hc, bp.Offering, bp.Patient, patientsMedicareCountCache, epcRemainingCache, MedicareMaxNbrServicesPerYear);

                // change to use org specific price
                for (int j = 0; j < bpos.Length; j++)
                    if (offeringsHashPrices[bpos[j].Offering.OfferingID] != null)
                        bpos[j].Offering = (Offering)offeringsHashPrices[bpos[j].Offering.OfferingID];
                if (offeringsHashPrices[bp.Offering.OfferingID] != null)
                    bp.Offering = (Offering)offeringsHashPrices[bp.Offering.OfferingID];

        // RUN IT AND TRY IT!!!
        // Area Treated needed for main service -- in both AC and Group Classes...

                if (invType == Booking.InvoiceType.Medicare)
                {
                    MC_Invoices.Add(new Invoice(MC_Invoice_NextID, -1, 363, booking.BookingID, -1, -1, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, bp.Offering.MedicareCharge, 0, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                    MC_InvoiceLines[MC_Invoice_NextID] = new ArrayList();
                    ((ArrayList)MC_InvoiceLines[MC_Invoice_NextID]).Add(new InvoiceLine(-1, MC_Invoice_NextID, bp.Patient.PatientID, bp.Offering.OfferingID, 1, bp.Offering.MedicareCharge, 0, "", "", -1));  // HERE

                    MC_Invoice_NextID++;

                    int newEpcRemainingCount = -1;
                    for (int j = 0; j < epcsRemaining.Length; j++)
                        if (epcsRemaining[j].Field.ID == booking.Provider.Field.ID)
                            if (epcsRemaining[j].NumServicesRemaining > 0)
                            {
                                EPCRemaining_Changes.Add( new Tuple<int,int,int>(epcsRemaining[j].HealthCardEpcRemainingID, epcsRemaining[j].NumServicesRemaining, epcsRemaining[j].NumServicesRemaining - 1) );
                                newEpcRemainingCount = epcsRemaining[j].NumServicesRemaining - 1;
                            }

                    RegisterReferrer[] regRefs = (RegisterReferrer[])patientReferrerCache[bp.Patient.PatientID];
                    if (regRefs != null && regRefs.Length > 0)
                        EPCRefLetterInfo.Add(new Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int>(bp, booking.Provider.Field.ID, regRefs[regRefs.Length - 1], invType, hc, newEpcRemainingCount));

                    //
                    // now add extras to seperate private invoice for the patient
                    //

                    if (bpos.Length > 0)
                    {
                        decimal total = 0;
                        decimal gst   = 0;
                        for (int j = 0; j < bpos.Length; j++)
                        {
                            total += bpos[j].Quantity * bpos[j].Offering.DefaultPrice;
                            gst   += bpos[j].Quantity * bpos[j].Offering.DefaultPrice * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                        }

                        MC_Invoices.Add(new Invoice(MC_Invoice_NextID, -1, 363, booking.BookingID, 0, bp.Patient.PatientID, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                        MC_InvoiceLines[MC_Invoice_NextID] = new ArrayList();
                        for (int j = 0; j < bpos.Length; j++)
                        {
                            decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                            decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                            InvoiceLine invoiceLine = new InvoiceLine(-1, MC_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst , "", "", -1);  // HERE
                            ((ArrayList)MC_InvoiceLines[MC_Invoice_NextID]).Add(invoiceLine);
                            invoiceLinesExtras.Add(invoiceLine);
                        }

                        MC_Invoice_NextID++;
                    }
                }
                else if (invType == Booking.InvoiceType.DVA)
                {
                    decimal total = bp.Offering.DvaCharge;
                    decimal gst   = total * (bp.Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        total += bpos[j].Quantity * (bpos[j].Offering.DvaCompanyCode.Length > 0 ? bpos[j].Offering.DvaCharge : bpos[j].Offering.DefaultPrice);
                        gst   += bpos[j].Quantity * (bpos[j].Offering.DvaCompanyCode.Length > 0 ? bpos[j].Offering.DvaCharge : bpos[j].Offering.DefaultPrice) * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                    }

                    DVA_Invoices.Add(new Invoice(DVA_Invoice_NextID, -1, 363, booking.BookingID, -2, -1, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                    DVA_InvoiceLines[DVA_Invoice_NextID] = new ArrayList();
                    decimal line_total = bp.Offering.DvaCharge;
                    decimal line_gst   = line_total * (bp.Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    ((ArrayList)DVA_InvoiceLines[DVA_Invoice_NextID]).Add(new InvoiceLine(-1, DVA_Invoice_NextID, bp.Patient.PatientID, bp.Offering.OfferingID, 1, line_total + line_gst, line_gst, bp.AreaTreated, "", -1));  // HERE
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * (bpos[j].Offering.DvaCompanyCode.Length > 0 ? bpos[j].Offering.DvaCharge : bpos[j].Offering.DefaultPrice);
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                        InvoiceLine invoiceLine = new InvoiceLine(-1, DVA_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, bpos[j].AreaTreated, "", -1);  // HERE
                        ((ArrayList)DVA_InvoiceLines[DVA_Invoice_NextID]).Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }

                    DVA_Invoice_NextID++;

                    RegisterReferrer[] regRefs = (RegisterReferrer[])patientReferrerCache[bp.Patient.PatientID];
                    if (regRefs != null && regRefs.Length > 0)
                        EPCRefLetterInfo.Add(new Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int>(bp, booking.Provider.Field.ID, regRefs[regRefs.Length - 1], invType, hc, -1));
                }
                else if (invType == Booking.InvoiceType.Insurance)
                {
                    decimal total = bp.Offering.TacCharge;
                    decimal gst   = total * (bp.Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        total += bpos[j].Quantity * (bpos[j].Offering.TacCompanyCode.Length > 0 ? bpos[j].Offering.TacCharge : bpos[j].Offering.DefaultPrice);
                        gst   += bpos[j].Quantity * (bpos[j].Offering.TacCompanyCode.Length > 0 ? bpos[j].Offering.TacCharge : bpos[j].Offering.DefaultPrice) * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                    }

                    TAC_Invoices.Add(new Invoice(TAC_Invoice_NextID, -1, 363, booking.BookingID, hc.Organisation.OrganisationID, -1, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                    TAC_InvoiceLines[TAC_Invoice_NextID] = new ArrayList();
                    decimal line_total = bp.Offering.TacCharge;
                    decimal line_gst = line_total * (bp.Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    ((ArrayList)TAC_InvoiceLines[TAC_Invoice_NextID]).Add(new InvoiceLine(-1, TAC_Invoice_NextID, bp.Patient.PatientID, bp.Offering.OfferingID, 1, line_total + line_gst, line_gst, bp.AreaTreated, "", -1));  // HERE
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * (bpos[j].Offering.TacCompanyCode.Length > 0 ? bpos[j].Offering.TacCharge : bpos[j].Offering.DefaultPrice);
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                        InvoiceLine invoiceLine = new InvoiceLine(-1, TAC_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, bpos[j].AreaTreated, "", -1);  // HERE
                        ((ArrayList)TAC_InvoiceLines[TAC_Invoice_NextID]).Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }

                    TAC_Invoice_NextID++;

                    RegisterReferrer[] regRefs = (RegisterReferrer[])patientReferrerCache[bp.Patient.PatientID];
                    if (regRefs != null && regRefs.Length > 0)
                        EPCRefLetterInfo.Add(new Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int>(bp, booking.Provider.Field.ID, regRefs[regRefs.Length - 1], invType, hc, -1));
                }
                else // private invoice
                {
                    decimal total = bp.Offering.DefaultPrice;
                    decimal gst   = total * (bp.Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        total += bpos[j].Quantity * bpos[j].Offering.DefaultPrice;
                        gst   += bpos[j].Quantity * bpos[j].Offering.DefaultPrice * (bpos[j].Offering.IsGstExempt ? (decimal)0 : (GST_Percent) / (decimal)100);
                    }

                    Prv_Invoices.Add(new Invoice(Prv_Invoice_NextID, -1, 363, booking.BookingID, 0, bp.Patient.PatientID, 0, "", -1, "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), DateTime.Now, total + gst, gst, 0, 0, 0, 0, false, false, false, -1, DateTime.MinValue, DateTime.MinValue));

                    Prv_InvoiceLines[Prv_Invoice_NextID] = new ArrayList();
                    decimal line_total = bp.Offering.DefaultPrice;
                    decimal line_gst   = line_total * (bp.Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                    ((ArrayList)Prv_InvoiceLines[Prv_Invoice_NextID]).Add(new InvoiceLine(-1, Prv_Invoice_NextID, bp.Patient.PatientID, bp.Offering.OfferingID, 1, line_total + line_gst, line_gst, "", "", -1));  // HERE
                    for (int j = 0; j < bpos.Length; j++)
                    {
                        decimal bpos_total = Convert.ToDecimal(bpos[j].Quantity) * bpos[j].Offering.DefaultPrice;
                        decimal bpos_gst   = bpos_total * (bpos[j].Offering.IsGstExempt ? (decimal)0 : GST_Percent / (decimal)100);
                        InvoiceLine invoiceLine = new InvoiceLine(-1, Prv_Invoice_NextID, bp.Patient.PatientID, bpos[j].Offering.OfferingID, Convert.ToDecimal(bpos[j].Quantity), bpos_total + bpos_gst, bpos_gst, bpos[j].AreaTreated, "", -1);  // HERE
                        ((ArrayList)Prv_InvoiceLines[Prv_Invoice_NextID]).Add(invoiceLine);
                        invoiceLinesExtras.Add(invoiceLine);
                    }

                    Prv_Invoice_NextID++;

                    RegisterReferrer[] regRefs = (RegisterReferrer[])patientReferrerCache[bp.Patient.PatientID];
                    if (regRefs != null && regRefs.Length > 0)
                        EPCRefLetterInfo.Add(new Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int>(bp, booking.Provider.Field.ID, regRefs[regRefs.Length - 1], invType, hc, -1));
                }
            }

            try
            {
                CreateInvoices(booking.BookingID, MC_Invoice_NextID,  MC_Invoices,  MC_InvoiceLines,  true,  ref invIDs, ref invLineIDs);  // Medicare
                foreach (Tuple<int,int,int> epcRemaining in EPCRemaining_Changes)
                    HealthCardEPCRemainingDB.UpdateNumServicesRemaining(epcRemaining.Item1, epcRemaining.Item3);

                CreateInvoices(booking.BookingID, DVA_Invoice_NextID, DVA_Invoices, DVA_InvoiceLines, true,  ref invIDs, ref invLineIDs);   // DVA
                CreateInvoices(booking.BookingID, TAC_Invoice_NextID, TAC_Invoices, TAC_InvoiceLines, false, ref invIDs, ref invLineIDs);   // TAC
                CreateInvoices(booking.BookingID, Prv_Invoice_NextID, Prv_Invoices, Prv_InvoiceLines, false, ref invIDs, ref invLineIDs);   // Prv

                // set booking as completed
                BookingDB.UpdateSetBookingStatusID(booking.BookingID, 187);

                // =============================================================================================================================================

                // Create Referrer Letters

                //
                // check that reversing invoice for clinics ... these are reset(?)
                //

                ArrayList allFileContents = new ArrayList();

                foreach (Tuple<BookingPatient, int, RegisterReferrer, Booking.InvoiceType, HealthCard, int> ptInfo in EPCRefLetterInfo)
                {
                    BookingPatient      bookingPatient    = ptInfo.Item1;
                    int                 fieldID           = ptInfo.Item2;
                    RegisterReferrer    registerReferrer  = ptInfo.Item3;
                    Booking.InvoiceType invType           = ptInfo.Item4;
                    HealthCard          hc                = ptInfo.Item5;
                    int                 epcCountRemaining = ptInfo.Item6;

                    // send referrer letters
                    //
                    // NB: FIRST/LAST letters ONLY FOR MEDICARE - DVA doesn't need letters
                    // Treatment letters for anyone with epc though -- even for private invoices
                    if (registerReferrer != null)
                    {
                        bool needToGenerateFirstLetter = false;
                        bool needToGenerateLastLetter  = false;
                        bool needToGenerateTreatmentLetter = registerReferrer.ReportEveryVisitToReferrer; // send treatment letter whether privately paid or not

                        if (invType == Booking.InvoiceType.Medicare)  // create first/last letters only if medicare
                        {
                            int nPodTreatmentsThisEPC = (int)InvoiceDB.GetMedicareCountByPatientAndDateRange(bookingPatient.Patient.PatientID, hc.DateReferralSigned.Date, DateTime.Now, -1, fieldID);
                            needToGenerateFirstLetter = (nPodTreatmentsThisEPC == 1);
                            needToGenerateLastLetter  = (epcCountRemaining == 0);
                        }

                        // if already generating first or last letter, don't generate treatement letter also
                        if (needToGenerateFirstLetter || needToGenerateLastLetter)
                            needToGenerateTreatmentLetter = false;

                        // TODO: Send Letter By Email

                        // ordereed by shippping/billing addr desc, so if any set, that will be the first one

                        string[] emails = ContactDB.GetEmailsByEntityID(registerReferrer.Organisation.EntityID);

                        bool generateSystemLetters = !registerReferrer.BatchSendAllPatientsTreatmentNotes && (emails.Length > 0 || chkGenerateSystemLetters.Checked);
                        int letterPrintHistorySendMethodID = emails.Length == 0 ? 1 : 2;

                        if (generateSystemLetters)
                        {
                            Letter.FileContents[] fileContentsList = booking.GetSystemLettersList(emails.Length > 0 ? Letter.FileFormat.PDF : Letter.FileFormat.Word, bookingPatient.Patient, hc, fieldID, registerReferrer.Referrer, true, needToGenerateFirstLetter, needToGenerateLastLetter, needToGenerateTreatmentLetter, false, Convert.ToInt32(Session["SiteID"]), Convert.ToInt32(Session["StaffID"]), letterPrintHistorySendMethodID);
                            if (fileContentsList != null && fileContentsList.Length > 0)
                            {
                                if (emails.Length > 0)
                                {
                                    Letter.EmailSystemLetter((string)Session["SiteName"], string.Join(",", emails), fileContentsList);
                                }
                                else
                                {
                                    allFileContents.AddRange(fileContentsList);
                                }
                            }
                        }

                        //BookingDB.UpdateSetGeneratedSystemLetters(booking.BookingID, needToGenerateFirstLetter, needToGenerateLastLetter, generateSystemLetters);
                        BookingPatientDB.UpdateSetGeneratedSystemLetters(bookingPatient.BookingPatientID, needToGenerateFirstLetter, needToGenerateLastLetter, generateSystemLetters);
                    }

                }

                if (allFileContents.Count > 0)
                {
                    Letter.FileContents[] fileContentsList = (Letter.FileContents[])allFileContents.ToArray(typeof(Letter.FileContents));
                    Letter.FileContents   fileContents     = Letter.FileContents.Merge(fileContentsList, "Treatment Letters.pdf"); // change here to create as pdf
                    Session["downloadFile_Contents"] = fileContents.Contents;
                    Session["downloadFile_DocName"]  = fileContents.DocName;
                    //showDownloadPopup = true;

                }

                // ==============================================================================================================================================

                // successfully completed, so update and check warning level for stocks
                foreach (InvoiceLine invoiceLine in invoiceLinesExtras)
                    if (invoiceLine.OfferingOrder == null) // stkip counting down if item is on order
                        StockDB.UpdateAndCheckWarning(booking.Organisation.OrganisationID, invoiceLine.Offering.OfferingID, (int)invoiceLine.Quantity);

            }
            catch (Exception ex)
            {
                if (ex is CustomMessageException == false)
                    Logger.LogException(ex);

                // roll back...
                BookingDB.UpdateSetBookingStatusID(booking.BookingID, 0);
                //BookingDB.UpdateSetGeneratedSystemLetters(booking.BookingID, booking.NeedToGenerateFirstLetter, booking.NeedToGenerateLastLetter, booking.HasGeneratedSystemLetters);
                foreach (int invLineID in invLineIDs)
                    InvoiceLineDB.Delete(invLineID);
                foreach (int invID in invIDs)
                    InvoiceDB.Delete(invID);
                foreach (Tuple<int,int,int> epcRemaining in EPCRemaining_Changes)
                    HealthCardEPCRemainingDB.UpdateNumServicesRemaining(epcRemaining.Item1, epcRemaining.Item2);

                throw;
            }

            SetErrorMessage("Done!");

            // close this window
            bool showDownloadPopup = false;
            Page.ClientScript.RegisterStartupScript(this.GetType(), "close", "<script language=javascript>window.returnValue=" + (showDownloadPopup ? "true" : "false") + ";self.close();</script>");
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
            return;
        }
        catch (System.Data.SqlClient.SqlException sqlEx)
        {
            if (sqlEx.Message.StartsWith("No claim numbers left") || sqlEx.Message.StartsWith("Error: Claim number already in use"))
                SetErrorMessage(sqlEx.Message);
            else
                SetErrorMessage("", sqlEx.ToString());
            return;
        }
        catch (Exception ex)
        {
            SetErrorMessage("", ex.ToString());
            return;
        }
    }
Пример #33
0
    public static InvoiceLine[] GetByInvoiceID(int invoice_id)
    {
        string sql = JoinedSql + " WHERE invoice_id = " + invoice_id.ToString();
        DataTable tbl = DBBase.ExecuteQuery(sql).Tables[0];

        InvoiceLine[] ret = new InvoiceLine[tbl.Rows.Count];
        for (int i = 0; i < tbl.Rows.Count; i++)
            ret[i] = LoadAll(tbl.Rows[i]);

        return ret;
    }
Пример #34
0
    public static InvoiceLine[] GetByInvoiceIDs(int[] invoice_ids)
    {
        string sql = JoinedSql + (invoice_ids != null && invoice_ids.Length > 0 ? " WHERE invoice_id IN (" + string.Join(",", invoice_ids) + ")" : " WHERE 1<>1");
        DataTable tbl = DBBase.ExecuteQuery(sql).Tables[0];

        InvoiceLine[] ret = new InvoiceLine[tbl.Rows.Count];
        for (int i = 0; i < tbl.Rows.Count; i++)
            ret[i] = LoadAll(tbl.Rows[i]);

        return ret;
    }
Пример #35
0
        public ActionResult SaveInvoiceLine(int? InvoiceLineId, int? InvoiceID, int? ProductId, string ProductReference,
                                            string ProductName, double? InvoiceProductValue, double? InvoiceLineQuantity,
                                            double? InvoiceLineDiscount, int? SupplierId, int? BrandProductId, int? TypeProductId)
        {
            var invoiceLine = new InvoiceLine();

            if (InvoiceLineId > 0)
            {
                invoiceLine = this.DataService.InvoiceLineRepository.CreateQuery(Proyection.Basic)
                    .Where(InvoiceLineFields.InvoiceLineId, InvoiceLineId).ToList().FirstOrDefault();
            }

            var product = new Product();
            if (ProductId.HasValue) product = this.DataService.ProductRepository.CreateQuery(Proyection.Basic).Where(ProductFields.ProductId, ProductId).ToList().FirstOrDefault();
            if (InvoiceID.HasValue) invoiceLine.InvoiceId = InvoiceID;
            if (!string.IsNullOrEmpty(ProductReference)) product.ProductReference = ProductReference;

            product.ProductName = ProductName;
            product.ProductCost = (decimal)InvoiceProductValue;

            if (SupplierId.HasValue) product.SupplierId = SupplierId;
            if (BrandProductId.HasValue) product.BrandProductId = BrandProductId;
            if (TypeProductId.HasValue) product.TypeProductId = TypeProductId;

            if (ProductId.HasValue) this.DataService.Update(product);
            else this.DataService.Insert(product);

            invoiceLine.ProductId = product.ProductId;
            invoiceLine.InvoiceLineQuantity = InvoiceLineQuantity;
            invoiceLine.InvoiceProductValue = (decimal)InvoiceProductValue;
            if (InvoiceLineDiscount.HasValue)
                invoiceLine.InvoiceLineDiscount = InvoiceLineDiscount/100;
            var total = (decimal)InvoiceProductValue * (decimal)invoiceLine.InvoiceLineQuantity;
            if (InvoiceLineDiscount.HasValue)
            {
                invoiceLine.InvoiceLineTotal = total - (total * (decimal)invoiceLine.InvoiceLineDiscount);
                invoiceLine.InvoideLineTotalDiscount = total * (decimal)invoiceLine.InvoiceLineDiscount;
            }
            else
            {
                invoiceLine.InvoiceLineDiscount = 0;
                invoiceLine.InvoiceLineTotal = total;
            }

            this.DataService.BeginTransaction();
            if (InvoiceLineId > 0)
            {
                this.DataService.Update(invoiceLine);
            }
            else
            {
                this.DataService.Insert(invoiceLine);
            }
            TotalsInvoice(InvoiceID);

            this.DataService.Commit();

            return this.Json(new { result = "success" });
        }