} // ValidateFreightHeaders

        /// <summary>
        /// Validate the data in all freight update spreadsheet rows
        /// </summary>
        /// <param name="csv"></param>
        /// <returns></returns>
        private bool ValidateFreightRows(ref FreightCSV csv)
        {
            bool result = csv.ValidateRows();

            if (!result)
            {
                // TODO:  Fix this to display the bad data
                log.Error("Failed to validate row data for one or more rows");
                using (new CenterDialog(this))
                {
                    MessageBox.Show($"Error in csv. Failed to validate data in one or more rows.  See log file and documentation for more information.", "Error in Freight Update CSV Data", MessageBoxButtons.OK);
                }
            }
            else
            {
                log.Debug("All row data is valid for all required columns");
            }
            return(result);
        } // ValidateFreightRows
        } // ValidateShipToRows

        /// <summary>
        /// Validate the required columns exist in the freight update spreadsheet
        /// </summary>
        /// <param name="freight"></param>
        /// <returns></returns>
        private bool ValidateFreightHeaders(ref FreightCSV csv)
        {
            bool result = csv.ValidateHeader();

            if (!result)
            {
                // TODO: Fix this to display the missing information
                log.Error("Failed to validate required headers");
                using (new CenterDialog(this))
                {
                    MessageBoxButtons buttons = MessageBoxButtons.OK;
                    MessageBox.Show($"Error in csv.  There are missing required header rows.  See Log file and documentation for more information.", "Error in Freight CSV Headers", buttons);
                }
            }
            else
            {
                log.Debug("All required columns exist");
            }
            return(result);
        } // ValidateFreightHeaders
        } // CustomerMasterFlow

        /// <summary>
        /// Control flow for Freight Data update
        /// </summary>
        public void FreightUpdateFlow()
        {
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.GetDirectoryName(Assembly.GetAssembly(typeof(FileIO)).Location) + @"\" + "log4net.config"));
            this.dgv_DataDisplay.DataSource = null;
            using (LoadingForm frm = new LoadingForm())
            {
                frm.Visible = true;
                freightCSV  = null;
                // 1.) Get the file to load
                string FileToLoad = FileIO.GetFileName(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), FileFilter);
                if (String.Empty != FileToLoad)
                {
                    try
                    {
                        // 2.) Load the file
                        log.Debug($"Attempting to load file {FileToLoad} using <tab> as a delimiter");
                        frm.AddText($"Attempting to load file {FileToLoad} using <tab> as a delimiter.");
                        freightCSV = new FreightCSV(FileToLoad, "\t");
                        freightCSV.ReadFreight();
                        frm.AddText($"Successfully read file {FileToLoad}.");
                        // 3.) Validate the required columns exist in the spreadsheet
                        log.Debug($"Attempting to validate all required columns exist in the file.");
                        frm.AddText("Validating required columns exist in the file.");
                        if (!ValidateFreightHeaders(ref freightCSV))
                        {
                            return;
                        }
                        // 4.) Validate the data in the rows match the column requirements
                        frm.AddText("Validate data is in the correct format for each row and column.");
                        log.Debug("Validating all row data in all required columns");
                        if (!ValidateFreightRows(ref freightCSV))
                        {
                            return;
                        }
                        // 5.) Either populate the data table for viewing or load the data into JDE
                        using (new CenterDialog(this))
                        {
                            DialogResult result = MessageBox.Show($"All {freightCSV.DT.Rows.Count} rows of data appear to be valid -- Further checks required.\r\nTry to Load the Data into JDE?\r\nSelect No to preview the detail data before load.",
                                                                  "Load Data?",
                                                                  MessageBoxButtons.YesNoCancel,
                                                                  MessageBoxIcon.Information);
                            if (DialogResult.Cancel == result)
                            {
                                return;
                            }

                            // 6.) Save the data into a Freight structure & save that to JDE
                            log.Debug($"Tranform the FreightCSV into a Freight object");
                            frm.AddText($"Converting CSV file to a JDE loadable object.");
                            Freight freight = XfrmFreight.CSVToFreight(freightCSV);
                            // 7.) Validate all shipments exist
                            log.Debug($"Validating that there aren't any 0 shipment numbers");
                            frm.AddText($"Validating that all shipments exist");
                            if (freight.freight_lines.Any(n => 0 == n.shipment))
                            {
                                log.Error($"There are {freight.freight_lines.Count(n => 0 == n.shipment)} freight lines with a 0 shipment");
                                return;
                            }
                            log.Info($"All {freight.freight_lines.Count} lines have shipments");


                            if (DialogResult.Yes == result)
                            {
                                log.Debug($"Update Shipment Reference Numbers in F4217");
                                frm.AddText($"Updating Shipment Tracking Numbers in JDE");
                                JDE.PopulateF4217(freight);
                                log.Debug($"Update Package Information in F4943");
                                frm.AddText($"Updating package information in JDE");
                                JDE.PopulateF4943(freight);
                                log.Debug($"Updating freight prices in F4211");
                                frm.AddText($"Updating freight prices on sales orders");
                                JDE.UpdateFreightF4211(freight);
                                using (new CenterDialog(this))
                                {
                                    MessageBox.Show($"The Freight information was successfully loaded into JDE.\r\n",
                                                    "Success!",
                                                    MessageBoxButtons.OK,
                                                    MessageBoxIcon.Information);
                                }
                            }
                            else if (DialogResult.No == result)
                            {
                                log.Info($"Loading data grid view for the freight lines");
                                this.dgv_DataDisplay.DataSource = freight.freight_lines;
                            }
                        } // using
                    }     // try
                    catch (Exception er)
                    {
                        log.Error($"{er.Message} + {er.InnerException} + {er.StackTrace}");
                        using (new CenterDialog(this))
                        {
                            MessageBox.Show($"{er.Message} + {er.InnerException} + {er.StackTrace}",
                                            "Error in Freight Update",
                                            MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                        }
                    } // catch
                }
            }
            return;
        } // FreightUpdateFlow