/// <summary>
        /// Reorganizes the data view for STV print_ program.
        /// </summary>
        /// <param name="dv">The dv.</param>
        /// <param name="refNo">The ref no.</param>
        /// <param name="pickListId">The pick list id.</param>
        /// <param name="userID">The user ID.</param>
        /// <param name="stvLogID">The STV log ID.</param>
        /// <param name="convertDNtoSTV">if set to <c>true</c> [convert D nto STV].</param>
        /// <param name="generateNewPrintID">if set to <c>true</c> [generate new print ID].</param>
        /// <param name="hasInsurance">if set to <c>true</c> [has insurance].</param>
        /// <returns></returns>
        public static DataTable ReorganizeDataViewForSTVPrint_Program(DataView dv, int orderID, int pickListId, int userID, int? stvLogID, bool convertDNtoSTV, bool generateNewPrintID, bool hasInsurance)
        {
            BLL.Order order = new Order();
            order.LoadByPrimaryKey(orderID);
            int? paymentTypeID = null;

            if (order.PaymentTypeID == PaymentType.Constants.CASH || order.PaymentTypeID == PaymentType.Constants.CREDIT || order.PaymentTypeID == PaymentType.Constants.STV)
            {
                paymentTypeID = order.PaymentTypeID;
            }

            // This is just to make the delivery notes print a separate series of numbers.
            // This section completely asks for a re-write.
            if (dv.Count > 0 && (dv[0]["Cost"] == DBNull.Value || Convert.ToDecimal(dv[0]["Cost"]) == 0M))
            {
                paymentTypeID = PaymentType.Constants.DELIVERY_NOTE;
            }
            else if (stvLogID != null)
            {
                Issue issue = new Issue();
                issue.LoadByPrimaryKey(stvLogID.Value);

                if (!issue.IsColumnNull("IsDeliveryNote") && issue.IsDeliveryNote && !convertDNtoSTV)
                {
                    paymentTypeID = PaymentType.Constants.DELIVERY_NOTE;
                }
            }

            // prepare the pick list for printing.
            // this method only merges the items that come in different rows but ...
            // that have same price same item.
            DataTable dtbl = dv.Table.Clone();

            if (!dtbl.Columns.Contains("Supplier"))
            {
                dtbl.Columns.Add("Supplier");
            }
            if (!dtbl.Columns.Contains("SupplierID"))
            {
                dtbl.Columns.Add("SupplierID");
            }
            dtbl.Columns.Add("STVNumber");
            dtbl.Columns.Add("StoreName");
            dtbl.Columns.Add("ContactPerson");
            dtbl.Columns.Add("PhysicalStoreType"); //The virtual store (The grouping for the stores) for the display on the stv

            dtbl.Clear();
            foreach (DataRowView drv in dv)
            {
                if (dtbl.Rows.Count == 0)
                {
                    dtbl.ImportRow(drv.Row);
                }

                else
                {

                    //check if items with same expiry exists in the table
                    //TOFIX: Add the supplier in this mix

                    string qItemID = "", qbatchNumberID = "", qUnitPriceID = "", qPhysicalStoreName = "", qStoreID = "";

                    qItemID = string.Format("ItemID={0} and UnitID={1}", drv["ItemID"].ToString(), drv["UnitID"]);

                    if (drv["BatchNumber"] != DBNull.Value)
                        qbatchNumberID = string.Format(" and BatchNumber='{0}'", drv["BatchNumber"].ToString());
                    if (drv["UnitPrice"] != DBNull.Value)
                        qUnitPriceID = string.Format(" and UnitPrice = {0} ", drv["UnitPrice"].ToString());
                    if (drv["PhysicalStoreName"] != DBNull.Value)
                        qPhysicalStoreName = string.Format(" and PhysicalStoreName= '{0}'",
                                                           drv["PhysicalStoreName"].ToString());
                    if (drv["StoreID"] != DBNull.Value)
                        qStoreID = string.Format(" and StoreID= '{0}'", drv["StoreID"].ToString());

                    string query = string.Format("{0}{1}{2}{3}{4}", qItemID, qbatchNumberID, qUnitPriceID,
                                                 qPhysicalStoreName, qStoreID);
                    DataRow[] ar = dtbl.Select(query);
                    if (ar.Length > 0)
                    {
                        //
                        foreach (var dataRow in ar)
                        {
                            dataRow["SKUPICKED"] = Convert.ToInt32(dataRow["SKUPICKED"]) +
                                                   Convert.ToInt32(drv["SKUPICKED"]);
                            dataRow["Cost"] = (dataRow["Cost"] != DBNull.Value ? Convert.ToDouble(dataRow["Cost"]) : 0) +
                                              (drv["Cost"] != DBNull.Value ? Convert.ToDouble(drv["Cost"]) : 0);
                            dataRow["IssueDocID"] = dataRow["IssueDocID"].ToString() + ',' +
                                                    drv["IssueDocID"].ToString();
                            dataRow.EndEdit();
                            // If we have been here before, no need to do it again.
                            // this means the same amount is printed duplicated.
                            break;
                        }
                    }
                    else
                    {
                        dtbl.ImportRow(drv.Row);
                    }
                }

            }

            Supplier supplier = new Supplier();
            ReceiveDoc rd = new ReceiveDoc();

            // First sort the Data Table by Supplier
            // then create STV Number for each supplier

            foreach (DataRowView drw in dtbl.DefaultView)
            {
                rd.LoadByPrimaryKey(Convert.ToInt32(drw["ReceiveDocID"]));
                if (rd.RowCount > 0)
                {
                    supplier.LoadByPrimaryKey(rd.SupplierID);
                    // Add the supplier to the table
                    drw["SupplierID"] = supplier.ID;
                    drw["Supplier"] = supplier.CompanyName;
                    drw.EndEdit();
                }
            }

            int supplierId = 0;
            int storeID = 0;
            int phyStoreTypeID = 0;
            bool isManufacturerLocal = false;
            int storeGroupID = 0;
            string storeName = "";

            int lineNumber = 1;
            int rowsOnPaper = 1;
            int maxLinesOnPage = 15;

            string stvNo = "";
            string stvNoForPrint = "";
            int stvID = -1;

            dtbl.DefaultView.Sort = "PhysicalStoreTypeName, StoreGroupID,StoreID,IsManufacturerLocal, CommodityType, FullItemName";

            string commodityType = "";
            foreach (DataRowView drw in dtbl.DefaultView)
            {
                //if ((BLL.Settings.IsRdfMode && (palletLocationID != Convert.ToInt32(drw["PalletLocationID"]) || storeID != Convert.ToInt32(drw["StoreID"]))) || (Convert.ToInt32(drw["SupplierID"]) != supplierId) || lineNumber > 13)

                if (commodityType == "")
                    commodityType = drw["CommodityType"].ToString();

                if ((drw["PhysicalStoreTypeID"] != DBNull.Value) && phyStoreTypeID != Convert.ToInt32(drw["PhysicalStoreTypeID"]) || (commodityType != drw["CommodityType"].ToString() && !BLL.Settings.PrintMultipleCommodityTypesPerPage) || (isManufacturerLocal != bool.Parse(drw["IsManufacturerLocal"].ToString()) || storeGroupID != Convert.ToInt32(drw["StoreGroupID"]) || storeID != Convert.ToInt32(drw["StoreID"]) || (rowsOnPaper + (Convert.ToInt32(drw["FullItemName"].ToString().Length / 32))) > maxLinesOnPage))// lineNumber > 10)
                {

                    lineNumber = 1;
                    rowsOnPaper = 1;

                    supplierId = Convert.ToInt32(drw["SupplierID"]);
                    storeGroupID = Convert.ToInt32(drw["StoreGroupID"]);
                    storeID = Convert.ToInt32(drw["StoreID"]);
                    var activity = new Activity();
                    activity.LoadByPrimaryKey(storeID);
                    storeName = activity.FullActivityName;

                    isManufacturerLocal = Convert.ToBoolean(drw["IsManufacturerLocal"]);

                    if (drw["PhysicalStoreTypeID"] != DBNull.Value)
                    {
                        phyStoreTypeID = Convert.ToInt32(drw["PhysicalStoreTypeID"]);
                    }

                    // Pseudo:
                    // Get hub details from the general info table
                    // prepare the printable data
                    // bind the printable data and GO

                    Issue stvLog = new Issue();
                    if (BLL.Settings.UseHeadedSTV && generateNewPrintID)
                    {
                        stvLog.AddNew();
                        stvLog.PrintedDate = DateTimeHelper.ServerDateTime;
                        stvLog.RefNo = order.RefNo;
                        stvLog.PickListID = pickListId;
                        stvLog.SupplierID = supplierId;
                        stvLog.UserID = userID;
                        stvLog.StoreID = storeID;
                         stvLog.IsDeliveryNote = (paymentTypeID == PaymentType.Constants.DELIVERY_NOTE);
                        stvLog.HasInsurance = hasInsurance;
                        stvLog.FiscalYearID = FiscalYear.Current.ID;
                        stvLog.AccountID = activity.AccountID;
                        if (paymentTypeID == PaymentType.Constants.DELIVERY_NOTE)
                        {
                            stvLog.DocumentTypeID = DocumentType.documentTypes.DeliveryNote.DocumentTypeID;
                        }
                        else if (paymentTypeID == PaymentType.Constants.CASH)
                        {
                            stvLog.DocumentTypeID = DocumentType.documentTypes.Cash.DocumentTypeID;
                        }
                        else if (paymentTypeID == PaymentType.Constants.CREDIT)
                        {
                            stvLog.DocumentTypeID = DocumentType.documentTypes.Credit.DocumentTypeID;
                        }
                        else if(paymentTypeID == PaymentType.Constants.STV)
                        {
                            stvLog.DocumentTypeID = DocumentType.documentTypes.STV.DocumentTypeID;
                        }
                        stvLog.IDPrinted = DocumentType.GetNextSequenceNo(stvLog.DocumentTypeID,stvLog.AccountID,stvLog.FiscalYearID);
                        stvLog.PaymentTypeID = order.PaymentTypeID;

                        if (!order.IsColumnNull("RequestedBy"))
                            stvLog.ReceivingUnitID = order.RequestedBy;
                        if (stvLogID.HasValue)
                        {
                            stvLog.IsReprintOf = stvLogID.Value;
                            //this means the STV is from replaced
                            Issue s = new Issue();
                            s.LoadByPrimaryKey(stvLogID.Value);
                            stvLog.IsDeliveryNote=(!s.IsColumnNull("IsDeliveryNote") && s.IsDeliveryNote && !convertDNtoSTV);
                        }

                        stvLog.Save();

                        stvNo = stvLog.ID.ToString("00000"); //If we wanted  to show just the ID of the sql table on the printout. We Use this
                        stvNoForPrint = FiscalYear.Current.GetCode(stvLog.IDPrinted);
                        stvID = stvLog.ID;
                    }
                    else if (!generateNewPrintID && stvLogID.HasValue)
                    {
                        // this assumes that we don't have to export
                        stvLog.LoadByPrimaryKey(stvLogID.Value);

                        stvNo = stvLog.ID.ToString("00000");//If we wanted  to show just the ID of the sql table on the printout. Use this
                       FiscalYear fiscalYear = new FiscalYear();
                        fiscalYear.LoadByPrimaryKey(stvLog.FiscalYearID);
                        stvNoForPrint = fiscalYear.GetCode(stvLog.IDPrinted);
                    }
                }

                if (commodityType != drw["CommodityType"].ToString()) //Check if the commodity type has changed.  Meaning that there will be a new group on the same paper (Pharmaceuticals, Chemicals, etc.) therefore we have to make the number of items that come to that page lower (Because we have headings for each group)
                {
                    commodityType = drw["CommodityType"].ToString();
                    rowsOnPaper = rowsOnPaper + 5;
                }
                else
                {
                    if (drw["FullItemName"].ToString().Length > 30) //The reason behind this code.  If the item name is a long one, it wraps and goes into the next line, making the number of row numbers more than just 1, so we don't just add one
                        rowsOnPaper += Convert.ToInt32(drw["FullItemName"].ToString().Length / 30) + 1;
                    else
                        rowsOnPaper++;
                }

                drw["STVNumber"] = stvNo;
                drw["LineNum"] = lineNumber++;
                drw["StoreName"] = storeName;
                drw["PrintedSTVNumber"] = stvNoForPrint;

                //Save the STVID into the IssueDoc Table.

                BLL.IssueDoc issDoc = new IssueDoc();

                int itemID = Convert.ToInt32(drw["ItemID"]);
                int receiveDocID = Convert.ToInt32(drw["ReceiveDocID"]);
                int picklistID = Convert.ToInt32(drw["PicklistID"]);
                drw["ContactPerson"] = BLL.Order.GetContactPerson(picklistID);
                BLL.Order orderInfo = new Order();

                // the only time the STVLog ID should be an entry in the Issue Doc should be when this is a fresh printout.
                if (stvID != -1 && stvLogID == null)
                {
                    SaveSTVIDbyPickListDetails(drw["IssueDocID"].ToString(), stvID);
                    //SaveSTVIDIntoIssueData(supplierId, itemID, stvID, issDoc, orderInfo.LoadByPickListID(picklistID), receiveDocID, storeID);
                }

                if (stvID == -1 && stvLogID == null)
                {
                    throw new Exception("An error occurred during save.  Please contact your administrator if this happens again.");
                }
                //SaveSTVIDIntoIssueData(supplierId, itemID, stvID, issDoc, order.LoadByPickListID(picklistID), receiveDocID);
            }
            return dtbl;
        }