private void butRefreshConns_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            if (gridMain.SelectedIndices.Length == 0)
            {
                gridMain.SetSelected(true);
            }
            for (int i = 0; i < gridMain.SelectedIndices.Length; i++)
            {
                CentralConnection conn = (CentralConnection)gridMain.Rows[gridMain.SelectedIndices[i]].Tag;
                if (conn.DatabaseName == "" && conn.ServerName == "" && conn.ServiceURI == "")
                {
                    continue;
                }
                ODThread odThread = new ODThread(ConnectAndVerify, new object[] { conn, _progVersion });
                odThread.Name      = "VerifyThread" + i;
                odThread.GroupName = "Verify";
                odThread.Start(false);
            }
            ODThread.JoinThreadsByGroupName(Timeout.Infinite, "Verify");
            List <ODThread> listComplThreads = ODThread.GetThreadsByGroupName("Verify");

            for (int i = 0; i < listComplThreads.Count; i++)
            {
                object[]          obj        = (object[])listComplThreads[i].Tag;
                CentralConnection conn       = ((CentralConnection)obj[0]);
                string            status     = ((string)obj[1]);
                CentralConnection connection = _listConns.Find(x => x.CentralConnectionNum == conn.CentralConnectionNum);
                connection.ConnectionStatus = status;
            }
            ODThread.QuitSyncThreadsByGroupName(100, "Verify");
            Cursor = Cursors.Default;
            FillGrid();
        }
        private void butRefresh_Click(object sender, EventArgs e)
        {
            if (textProviderSearch.Text == "" && textClinicSearch.Text == "")
            {
                FillGrid();
                return;
            }
            for (int i = 0; i < gridMain.Rows.Count; i++)
            {
                CentralConnection conn = (CentralConnection)gridMain.Rows[i].Tag;
                if (conn.ConnectionStatus != "OK")
                {
                    continue;
                }
                ODThread odThread = new ODThread(ConnectAndSearch, new object[] { conn });
                odThread.Name      = "SearchThread" + i;
                odThread.GroupName = "Search";
                odThread.Start(false);
            }
            ODThread.JoinThreadsByGroupName(Timeout.Infinite, "Search");
            List <ODThread> listComplThreads = ODThread.GetThreadsByGroupName("Search");
            List <long>     connNums         = new List <long>();

            for (int i = 0; i < listComplThreads.Count; i++)
            {
                object[]          obj  = (object[])listComplThreads[i].Tag;
                CentralConnection conn = ((CentralConnection)obj[0]);
                bool result            = ((bool)obj[1]);
                if (result)
                {
                    connNums.Add(conn.CentralConnectionNum);
                }
                listComplThreads[i].QuitAsync();
            }
            FillGrid(connNums);
        }
        private void RunProvider()
        {
            ReportComplex report = new ReportComplex(true, true);

            _dateFrom = PIn.Date(textDateFrom.Text);
            _dateTo   = PIn.Date(textDateTo.Text);
            List <DataSet>  listProdData    = new List <DataSet>();
            List <Provider> listProvs       = new List <Provider>();
            List <string>   listServerNames = new List <string>();
            string          strFailedConn   = "";

            for (int i = 0; i < ConnList.Count; i++)
            {
                ODThread odThread = new ODThread(ConnectAndRunProviderReport, new object[] { ConnList[i] });
                odThread.GroupName = "ConnectAndReportProvider";
                odThread.Start(false);
            }
            ODThread.JoinThreadsByGroupName(Timeout.Infinite, "ConnectAndReportProvider");
            List <ODThread> listThreads = ODThread.GetThreadsByGroupName("ConnectAndReportProvider");

            for (int i = 0; i < listThreads.Count; i++)
            {
                object[]        obj           = (object[])listThreads[i].Tag;
                DataSet         data          = (DataSet)obj[0];
                string          connString    = CentralConnections.GetConnectionString((CentralConnection)obj[1]);
                List <Provider> listConnProvs = (List <Provider>)obj[2];
                if (data == null)
                {
                    strFailedConn += connString + "\r\n";
                }
                else
                {
                    listServerNames.Add(connString);
                    listProdData.Add(data);
                    listProvs.AddRange(listConnProvs);
                }
                listThreads[i].QuitSync(Timeout.Infinite);
            }
            report.ReportName = "Provider P&I";
            report.AddTitle("Title", Lan.g(this, "Provider Production and Income"));
            report.AddSubTitle("PracName", PrefC.GetString(PrefName.PracticeTitle));
            report.AddSubTitle("Date", _dateFrom.ToShortDateString() + " - " + _dateTo.ToShortDateString());
            report.AddSubTitle("Providers", Lan.g(this, "All Providers"));
            report.AddSubTitle("Clinics", Lan.g(this, "All Clinics"));
            //setup query
            QueryObject query;
            DataSet     dsTotal = new DataSet();

            for (int i = 0; i < listProdData.Count; i++)
            {
                DataTable dt    = listProdData[i].Tables["Clinic"];
                DataTable dtTot = listProdData[i].Tables["Total"].Copy();
                dtTot.TableName = dtTot.TableName + "_" + i;
                dsTotal.Tables.Add(dtTot);
                query = report.AddQuery(dt, listServerNames[i], "Clinic", SplitByKind.Value, 1, true);
                // add columns to report
                query.AddColumn("Provider", 75, FieldValueType.String);
                query.AddColumn("Production", 120, FieldValueType.Number);
                query.AddColumn("Adjustments", 120, FieldValueType.Number);
                query.AddColumn("Writeoff", 120, FieldValueType.Number);
                query.AddColumn("Tot Prod", 120, FieldValueType.Number);
                query.AddColumn("Pt Income", 120, FieldValueType.Number);
                query.AddColumn("Ins Income", 120, FieldValueType.Number);
                query.AddColumn("Total Income", 120, FieldValueType.Number);
            }
            if (dsTotal.Tables.Count == 0)
            {
                MsgBox.Show(this, "This report returned no values");
                return;
            }
            DataTable dtTotal;
            decimal   production;
            decimal   adjust;
            decimal   inswriteoff;
            decimal   totalproduction;
            decimal   ptincome;
            decimal   insincome;
            decimal   totalincome;

            dtTotal = dsTotal.Tables[0].Clone();
            for (int i = 0; i < listProvs.Count; i++)
            {
                Provider provCur = listProvs[i];
                DataRow  row     = dtTotal.NewRow();
                row[0]          = provCur.Abbr;
                production      = 0;
                adjust          = 0;
                inswriteoff     = 0;
                totalproduction = 0;
                ptincome        = 0;
                insincome       = 0;
                totalincome     = 0;
                bool hasAnyAmount = false;
                for (int j = 0; j < dsTotal.Tables.Count; j++)
                {
                    for (int k = 0; k < dsTotal.Tables[j].Rows.Count; k++)
                    {
                        if (dsTotal.Tables[j].Rows[k][0].ToString() == provCur.Abbr &&
                            (PIn.Decimal(dsTotal.Tables[j].Rows[k]["Production"].ToString()) != 0 ||
                             PIn.Decimal(dsTotal.Tables[j].Rows[k]["Adjustments"].ToString()) != 0 ||
                             PIn.Decimal(dsTotal.Tables[j].Rows[k]["WriteOff"].ToString()) != 0 ||
                             PIn.Decimal(dsTotal.Tables[j].Rows[k]["Pt Income"].ToString()) != 0 ||
                             PIn.Decimal(dsTotal.Tables[j].Rows[k]["Ins Income"].ToString()) != 0))
                        {
                            production  += PIn.Decimal(dsTotal.Tables[j].Rows[k]["Production"].ToString());
                            adjust      += PIn.Decimal(dsTotal.Tables[j].Rows[k]["Adjustments"].ToString());
                            inswriteoff += PIn.Decimal(dsTotal.Tables[j].Rows[k]["WriteOff"].ToString());                          //Writeoffs stored as negative number
                            ptincome    += PIn.Decimal(dsTotal.Tables[j].Rows[k]["Pt Income"].ToString());
                            insincome   += PIn.Decimal(dsTotal.Tables[j].Rows[k]["Ins Income"].ToString());
                            hasAnyAmount = true;
                        }
                    }
                }
                totalproduction = production + adjust + inswriteoff;
                totalincome     = ptincome + insincome;
                row[1]          = production.ToString("n");
                row[2]          = adjust.ToString("n");
                row[3]          = inswriteoff.ToString("n");
                row[4]          = totalproduction.ToString("n");
                row[5]          = ptincome.ToString("n");
                row[6]          = insincome.ToString("n");
                row[7]          = totalincome.ToString("n");
                if (hasAnyAmount)
                {
                    dtTotal.Rows.Add(row);
                }
            }
            query = report.AddQuery(dtTotal, "Totals", "", SplitByKind.None, 2, true);
            query.AddColumn("Provider", 75, FieldValueType.String);
            query.AddColumn("Production", 120, FieldValueType.Number);
            query.AddColumn("Adjustments", 120, FieldValueType.Number);
            query.AddColumn("Writeoff", 120, FieldValueType.Number);
            query.AddColumn("Tot Prod", 120, FieldValueType.Number);
            query.AddColumn("Pt Income", 120, FieldValueType.Number);
            query.AddColumn("Ins Income", 120, FieldValueType.Number);
            query.AddColumn("Total Income", 120, FieldValueType.Number);
            report.AddPageNum();
            // execute query
            if (!report.SubmitQueries())             //Does not actually submit queries because we use datatables in the central management tool.
            {
                return;
            }
            if (strFailedConn != "")
            {
                MsgBoxCopyPaste msgBoxCP = new MsgBoxCopyPaste(strFailedConn);
                msgBoxCP.ShowDialog();
            }
            // display the report
            FormReportComplex FormR = new FormReportComplex(report);

            FormR.ShowDialog();
            DialogResult = DialogResult.OK;
        }
        private void RunMonthly()
        {
            ReportComplex report = new ReportComplex(true, false);

            _dateFrom = PIn.Date(textDateFrom.Text);
            _dateTo   = PIn.Date(textDateTo.Text);
            List <DataSet> listProdData      = new List <DataSet>();   //A list of all data sets for each connection.
            List <string>  listServerNames   = new List <string>();
            string         stringFailedConns = "";

            for (int i = 0; i < ConnList.Count; i++)
            {
                ODThread odThread = new ODThread(ConnectAndRunMonthlyReport, new object[] { ConnList[i] });
                odThread.GroupName = "ConnectAndReportMonthly";
                odThread.Start(false);
            }
            ODThread.JoinThreadsByGroupName(Timeout.Infinite, "ConnectAndReportMonthly");
            List <ODThread> listThreads = ODThread.GetThreadsByGroupName("ConnectAndReportMonthly");

            for (int i = 0; i < listThreads.Count; i++)
            {
                object[] obj        = (object[])listThreads[i].Tag;
                DataSet  data       = (DataSet)obj[0];
                string   connString = CentralConnections.GetConnectionString((CentralConnection)obj[1]);
                if (data == null)
                {
                    stringFailedConns += connString + "\r\n";
                }
                else
                {
                    listServerNames.Add(connString);
                    listProdData.Add(data);
                }
                listThreads[i].QuitSync(Timeout.Infinite);
            }
            report.ReportName = "MonthlyP&I";
            report.AddTitle("Title", Lan.g(this, "Monthly Production and Income"));
            report.AddSubTitle("Date", _dateFrom.ToShortDateString() + " - " + _dateTo.ToShortDateString());
            report.AddSubTitle("Clinics", Lan.g(this, "All Clinics"));
            QueryObject query;
            DataSet     dsTotal        = new DataSet();//Totals dataset for all connections, it contains a totals table per connection.  We use this later for a summary section.
            int         queryObjectNum = 0;

            for (int i = 0; i < listProdData.Count; i++)
            {
                DataTable dt    = listProdData[i].Tables["Clinic"];
                DataTable dtTot = listProdData[i].Tables["Total"].Copy();
                if (dt.Rows.Count > 0 && dtTot.Rows.Count > 0)
                {
                    queryObjectNum++;
                    dtTot.TableName = dtTot.TableName + "_" + i;
                    dsTotal.Tables.Add(dtTot);
                    query = report.AddQuery(dt, listServerNames[i], "Clinic", SplitByKind.Value, 1, true);
                    // add columns to report
                    Font font = new Font("Tahoma", 8, FontStyle.Regular);
                    query.AddColumn("Date", 70, FieldValueType.String, font);
                    query.AddColumn("Weekday", 70, FieldValueType.String, font);
                    query.AddColumn("Production", 80, FieldValueType.Number, font);
                    query.AddColumn("Sched", 80, FieldValueType.Number, font);
                    query.AddColumn("Adj", 80, FieldValueType.Number, font);
                    query.AddColumn("Writeoff", 80, FieldValueType.Number, font);
                    query.AddColumn("Tot Prod", 80, FieldValueType.Number, font);
                    query.AddColumn("Pt Income", 80, FieldValueType.Number, font);
                    query.AddColumn("Ins Income", 80, FieldValueType.Number, font);
                    query.AddColumn("Tot Income", 80, FieldValueType.Number, font);
                }
                else
                {
                    MsgBox.Show(this, "Connection " + listServerNames[i] + " has no results to show.");
                }
            }
            if (dsTotal.Tables.Count == 0)
            {
                MsgBox.Show(this, "This report returned no values");
                return;
            }
            //setup query
            DataTable dtTotal;
            double    production;
            double    sched;
            double    adjust;
            double    writeoff;
            double    totprod;
            double    ptincome;
            double    insincome;
            double    totalincome;

            DateTime[] dates = new DateTime[(_dateTo - _dateFrom).Days];
            dtTotal = dsTotal.Tables[0].Clone();
            dtTotal.Rows.Clear();
            for (int i = 0; i < dates.Length; i++)       //Per day
            {
                production  = 0;
                sched       = 0;
                adjust      = 0;
                writeoff    = 0;
                totprod     = 0;
                ptincome    = 0;
                insincome   = 0;
                totalincome = 0;
                dates[i]    = _dateFrom.AddDays(i);
                DataRow row = dtTotal.NewRow();
                row[0] = dates[i].ToShortDateString();
                row[1] = dates[i].DayOfWeek;                               //Weekday
                for (int j = 0; j < dsTotal.Tables.Count; j++)             //Per totals table
                {
                    for (int k = 0; k < dsTotal.Tables[j].Rows.Count; k++) //Per row
                    //If it's the correct day, add to the totals.
                    {
                        if (PIn.Date(dsTotal.Tables[j].Rows[k]["Month"].ToString()).ToShortDateString() == dates[i].ToShortDateString())
                        {
                            DataRow dataRow = dsTotal.Tables[j].Rows[k];
                            production  += PIn.Double(dataRow["Production"].ToString());
                            sched       += PIn.Double(dataRow["Sched"].ToString());
                            adjust      += PIn.Double(dataRow["Adjustments"].ToString());
                            writeoff    += PIn.Double(dataRow["Writeoff"].ToString());                       //Writeoffs stored as negative number
                            totprod     += PIn.Double(dataRow["Tot Prod"].ToString());
                            ptincome    += PIn.Double(dataRow["Pt Income"].ToString());
                            insincome   += PIn.Double(dataRow["Ins Income"].ToString());
                            totalincome += PIn.Double(dataRow["Total Income"].ToString());
                            break;
                        }
                    }
                }
                if (production == 0 && sched == 0 && adjust == 0 && writeoff == 0 && totprod == 0 && ptincome == 0 && insincome == 0 && totalincome == 0)
                {
                    continue;                    //Don't display this row if there's nothing to show. (Wasn't like this in 14.3 but is now in 15.3)
                }
                row[2] = production.ToString("n");
                row[3] = sched.ToString("n");
                row[4] = adjust.ToString("n");
                row[5] = writeoff.ToString("n");
                row[6] = totprod.ToString("n");
                row[7] = ptincome.ToString("n");
                row[8] = insincome.ToString("n");
                row[9] = totalincome.ToString("n");
                dtTotal.Rows.Add(row);
            }
            query = report.AddQuery(dtTotal, "Totals", "", SplitByKind.None, 2, true);
            Font font2 = new Font("Tahoma", 8, FontStyle.Regular);

            query.AddColumn("Date", 70, FieldValueType.String, font2);
            query.AddColumn("Weekday", 70, FieldValueType.String, font2);
            query.AddColumn("Production", 80, FieldValueType.Number, font2);
            query.AddColumn("Sched", 80, FieldValueType.Number, font2);
            query.AddColumn("Adj", 80, FieldValueType.Number, font2);
            query.AddColumn("Writeoff", 80, FieldValueType.Number, font2);
            query.AddColumn("Tot Prod", 80, FieldValueType.Number, font2);
            query.AddColumn("Pt Income", 80, FieldValueType.Number, font2);
            query.AddColumn("Ins Income", 80, FieldValueType.Number, font2);
            query.AddColumn("Tot Income", 80, FieldValueType.Number, font2);
            query.AddGroupSummaryField("Total Production (Production + Adjustments - Writeoffs): ", "Writeoff", "Tot Prod", SummaryOperation.Sum, new List <int>()
            {
                queryObjectNum
            }, Color.Black, new Font("Tahoma", 9, FontStyle.Bold), 104, 20);
            query.AddGroupSummaryField("Total Income (Pt Income + Ins Income): ", "Writeoff", "Total Income", SummaryOperation.Sum, new List <int>()
            {
                queryObjectNum
            }, Color.Black, new Font("Tahoma", 9, FontStyle.Bold), 0, 25);
            report.AddPageNum();
            // execute query
            if (!report.SubmitQueries())             //Does not actually submit queries because we use datatables in the central management tool.
            {
                return;
            }
            if (stringFailedConns != "")
            {
                stringFailedConns = "Failed Connections:\r\n" + stringFailedConns;
                MsgBoxCopyPaste msgBoxCP = new MsgBoxCopyPaste(stringFailedConns);
                msgBoxCP.ShowDialog();
            }
            // display the report
            FormReportComplex FormR = new FormReportComplex(report);

            FormR.ShowDialog();
            DialogResult = DialogResult.OK;
        }
        private void RunDaily()
        {
            ReportComplex report = new ReportComplex(true, true);

            _dateFrom = PIn.Date(textDateFrom.Text);
            _dateTo   = PIn.Date(textDateTo.Text);
            List <DataSet> listProdData      = new List <DataSet>();   //A list of all data sets for each connection.
            List <string>  listServerNames   = new List <string>();
            string         stringFailedConns = "";

            for (int i = 0; i < ConnList.Count; i++)
            {
                ODThread odThread = new ODThread(ConnectAndRunDailyReport, ConnList[i]);
                odThread.GroupName = "ConnectAndReportDaily";
                odThread.Start(false);
            }
            ODThread.JoinThreadsByGroupName(Timeout.Infinite, "ConnectAndReportDaily");
            List <ODThread> listThreads = ODThread.GetThreadsByGroupName("ConnectAndReportDaily");

            for (int i = 0; i < listThreads.Count; i++)
            {
                object[] obj        = (object[])listThreads[i].Tag;
                DataSet  data       = (DataSet)obj[0];
                string   connString = CentralConnections.GetConnectionString((CentralConnection)obj[1]);
                if (data == null)
                {
                    stringFailedConns += connString + "\r\n";
                }
                else
                {
                    listServerNames.Add(connString);
                    listProdData.Add(data);
                }
                listThreads[i].QuitSync(Timeout.Infinite);
            }
            report.ReportName = "DailyP&I";
            report.AddTitle("Title", Lan.g(this, "Daily Production and Income"));
            report.AddSubTitle("PracName", PrefC.GetString(PrefName.PracticeTitle));
            string dateRangeStr = _dateFrom.ToShortDateString() + " - " + _dateTo.ToShortDateString();

            if (_dateFrom.Date == _dateTo.Date)
            {
                dateRangeStr = _dateFrom.ToShortDateString();              //Do not show a date range for the same day...
            }
            report.AddSubTitle("Date", dateRangeStr);
            report.AddSubTitle("Providers", Lan.g(this, "All Providers"));
            report.AddSubTitle("Clinics", Lan.g(this, "All Clinics"));
            QueryObject query = null;
            //Per connection, add each table and split on clinic.  We also need to make a totals table that will be total per clinic per connection.
            DataTable connectionTotals = new DataTable("Totals");

            connectionTotals.Columns.Add(new DataColumn("Connection"));
            connectionTotals.Columns.Add(new DataColumn("Clinic"));
            connectionTotals.Columns.Add(new DataColumn("Production"));
            connectionTotals.Columns.Add(new DataColumn("Adjust"));
            connectionTotals.Columns.Add(new DataColumn("Writeoff"));
            connectionTotals.Columns.Add(new DataColumn("Pt Income"));
            connectionTotals.Columns.Add(new DataColumn("Ins Income"));
            for (int i = 0; i < listProdData.Count; i++)                               //Per connection
            {
                DataTable tableDailyProdForConn = listProdData[i].Tables["DailyProd"]; //Includes multiple clinics.
                for (int j = 0; j < tableDailyProdForConn.Rows.Count; j++)             //Go through the rows
                {
                    DataRow connRow = tableDailyProdForConn.Rows[j];
                    bool    isFound = false;
                    for (int k = 0; k < connectionTotals.Rows.Count; k++)               //Attempt to find an existing totals row that matches.
                    {
                        DataRow connTotalsRow = connectionTotals.Rows[k];
                        if (connRow["Clinic"] == connTotalsRow["Clinic"] && listServerNames[i] == connTotalsRow["Connection"].ToString()) //Totals row already exists. Add to it.
                        {
                            DataRow totalRow = connectionTotals.NewRow();                                                                 //Need to make a new row, can't just modify old table values.  Sadly.
                            double  prod     = PIn.Double(connTotalsRow["Production"].ToString());
                            double  adjust   = PIn.Double(connTotalsRow["Adjust"].ToString());
                            double  writeoff = PIn.Double(connTotalsRow["Writeoff"].ToString());
                            double  ptInc    = PIn.Double(connTotalsRow["Pt Income"].ToString());
                            double  insInc   = PIn.Double(connTotalsRow["Ins Income"].ToString());
                            totalRow[0] = connTotalsRow["Connection"];
                            totalRow[1] = connTotalsRow["Clinic"];
                            totalRow[2] = (prod + PIn.Double(connRow["Production"].ToString()));
                            totalRow[3] = (adjust + PIn.Double(connRow["Adjust"].ToString()));
                            totalRow[4] = (writeoff + PIn.Double(connRow["Writeoff"].ToString()));
                            totalRow[5] = (ptInc + PIn.Double(connRow["Pt Income"].ToString()));
                            totalRow[6] = (insInc + PIn.Double(connRow["Ins Income"].ToString()));
                            connectionTotals.Rows.RemoveAt(k);
                            connectionTotals.Rows.Add(totalRow);
                            isFound = true;
                            break;
                        }
                    }
                    if (!isFound)                    //Totals row for this connection and clinic combination doesn't exist yet.
                    {
                        DataRow totalRow = connectionTotals.NewRow();
                        totalRow[0] = listServerNames[i];
                        totalRow[1] = connRow["Clinic"];
                        totalRow[2] = connRow["Production"];
                        totalRow[3] = connRow["Adjust"];
                        totalRow[4] = connRow["Writeoff"];
                        totalRow[5] = connRow["Pt Income"];
                        totalRow[6] = connRow["Ins Income"];
                        connectionTotals.Rows.Add(totalRow);
                    }
                }
                query = report.AddQuery(tableDailyProdForConn, listServerNames[i], "Clinic", SplitByKind.Value, 1, true);
                // add columns to report
                query.AddColumn("Date", 75, FieldValueType.String, new Font("Tahoma", 8));
                query.AddColumn("Patient Name", 130, FieldValueType.String, new Font("Tahoma", 8));
                query.AddColumn("Description", 220, FieldValueType.String, new Font("Tahoma", 8));
                query.AddColumn("Prov", 65, FieldValueType.String, new Font("Tahoma", 8));
                query.AddColumn("Clinic", 130, FieldValueType.String, new Font("Tahoma", 8));
                query.AddColumn("Production", 75, FieldValueType.Number, new Font("Tahoma", 8));
                query.AddColumn("Adjust", 75, FieldValueType.Number, new Font("Tahoma", 8));
                query.AddColumn("Writeoff", 75, FieldValueType.Number, new Font("Tahoma", 8));
                query.AddColumn("Pt Income", 75, FieldValueType.Number, new Font("Tahoma", 8));
                query.AddColumn("Ins Income", 75, FieldValueType.Number, new Font("Tahoma", 8));
            }
            if (connectionTotals.Rows.Count == 0)
            {
                //MsgBox.Show(this,"This report returned no values.");//We don't want to do this, it hides behind the progress bar!
                return;
            }
            connectionTotals = connectionTotals.AsEnumerable().OrderBy(r => r.Field <string>("Connection"))
                               .ThenBy(r => r.Field <string>("Clinic")).CopyToDataTable();
            query = report.AddQuery(connectionTotals, "Totals", "", SplitByKind.None, 2, true);
            query.AddColumn("Connection", 250, FieldValueType.String, new Font("Tahoma", 8));
            query.AddColumn("Clinic", 250, FieldValueType.String, new Font("Tahoma", 8));
            query.AddColumn("Production", 75, FieldValueType.Number, new Font("Tahoma", 8));
            query.AddColumn("Adjust", 75, FieldValueType.Number, new Font("Tahoma", 8));
            query.AddColumn("Writeoff", 75, FieldValueType.Number, new Font("Tahoma", 8));
            query.AddColumn("Pt Income", 75, FieldValueType.Number, new Font("Tahoma", 8));
            query.AddColumn("Ins Income", 75, FieldValueType.Number, new Font("Tahoma", 8));
            //Calculate the total production and total income and add them to the bottom of the report:
            double totalProduction = 0;
            double totalIncome     = 0;

            for (int i = 0; i < connectionTotals.Rows.Count; i++)
            {
                //Total production is (Production + Adjustments - Writeoffs)
                totalProduction += PIn.Double(connectionTotals.Rows[i]["Production"].ToString());
                totalProduction += PIn.Double(connectionTotals.Rows[i]["Adjust"].ToString());
                totalProduction += PIn.Double(connectionTotals.Rows[i]["Writeoff"].ToString());              //Writeoffs stored as negative number
                //Total income is (Pt Income + Ins Income)
                totalIncome += PIn.Double(connectionTotals.Rows[i]["Pt Income"].ToString());
                totalIncome += PIn.Double(connectionTotals.Rows[i]["Ins Income"].ToString());
            }
            //Add the Total Production and Total Income to the bottom of the report if there were any rows present.
            if (connectionTotals.Rows.Count > 0)
            {
                //Use a custom table and add it like it is a "query" to the report because using a group summary would be more complicated due
                //to the need to add and subtract from multiple columns at the same time.
                DataTable tableTotals = new DataTable("TotalProdAndInc");
                tableTotals.Columns.Add("Summary");
                tableTotals.Rows.Add(Lan.g(this, "Total Production (Production + Adjustments - Writeoffs):") + " " + totalProduction.ToString("c"));
                tableTotals.Rows.Add(Lan.g(this, "Total Income (Pt Income + Ins Income):") + " " + totalIncome.ToString("c"));
                //Add tableTotals to the report.
                //No column name and no header because we want to display this table to NOT look like a table.
                query = report.AddQuery(tableTotals, "", "", SplitByKind.None, 2, false);
                query.AddColumn("", 785, FieldValueType.String, new Font("Tahoma", 8, FontStyle.Bold));
            }
            report.AddPageNum();
            // execute query
            if (!report.SubmitQueries())
            {
                return;
            }
            // display report
            FormReportComplex FormR = new FormReportComplex(report);

            FormR.ShowDialog();
            DialogResult = DialogResult.OK;
        }
Example #6
0
        ///<summary>Refreshes the data and changes the UI accordingly. Called from FillGrid when dataRefresh is true.</summary>
        private void RefreshData()
        {
            List <ODThread> listThreadsRunning = ODThread.GetThreadsByGroupName("FormBackport_Refresh");

            //Quit all threads that are still running. The user may have changed the path. This way the grid will not be filled with false information.
            listThreadsRunning.ForEach(x => x.QuitAsync());
            //Store path
            _pathOnRefresh           = comboPath.Text.TrimEnd('\\');
            _ignoreListNameOnRefresh = textIgnoreList.Text;
            _currentProject          = BackportProjects.Unknown;
            _listFileChanges         = new List <ODFileChanges>();
            //Clear Rows
            gridMain.BeginUpdate();
            gridMain.ListGridRows.Clear();
            gridMain.EndUpdate();
            if (!Directory.Exists(comboPath.Text))
            {
                MessageBox.Show("The directory does not exist.");
                return;
            }
            else
            {
                if (_pathOnRefresh.Contains("OPEN DENTAL SUBVERSION"))                 //look for open dental first as its naming scheme does not match the rest.
                {
                    _currentProject = BackportProjects.OpenDental;
                }
                else
                {
                    for (int i = 0; i < Enum.GetNames(typeof(ProjectName)).Length; i++)
                    {
                        if (_pathOnRefresh.Contains(Enum.GetNames(typeof(ProjectName))[i]))
                        {
                            _currentProject = BackportProjects.ListProjects.Find(x => x.Name == ((ProjectName)i));
                            break;
                        }
                    }
                }
            }
            if (_currentProject == BackportProjects.Unknown)
            {
                MessageBox.Show("Could not find the correct project.");
                return;
            }
            //Get available versions based on folder structure.
            UpdateListVersions();
            Cursor = Cursors.AppStarting;
            //Refresh Data
            string          pathOnRefresh           = _pathOnRefresh;
            string          ignoreListNameOnRefresh = _ignoreListNameOnRefresh;
            BackportProject currentProject          = _currentProject.Copy();
            ODThread        odThread = new ODThread((o) => {
                List <ODFileChanges> listFileChanges = GetListOfFiles(pathOnRefresh, _listAvailableVersions, ignoreListNameOnRefresh, currentProject);
                this.InvokeIfNotDisposed(() => {       //If window quit, this action will not run and the thread will die.
                    if (o.HasQuit)                     //If the user refreshed the path and this was marked to quit.
                    {
                        return;
                    }
                    Cursor            = Cursors.Default;
                    _listFileChanges  = listFileChanges;
                    labelCurProj.Text = "Current Project: " + Enum.GetName(_currentProject.Name.GetType(), _currentProject.Name);
                    FillGrid();
                    _progressBarAction?.Invoke();
                    _progressBarAction = null;
                });
            });

            odThread.AddExceptionHandler(ex => {
                _progressBarAction?.Invoke();
                _progressBarAction = null;
                this.InvokeIfNotDisposed(() => {                //If there's an exception after the form is closed, swallow and do not do anything.
                    FriendlyException.Show("Error refreshing data.", ex);
                });
            });
            odThread.GroupName = "FormBackport_Refresh";
            odThread.Name      = "FormBackport_Refresh" + DateTime.Now.Millisecond;
            odThread.Start();
            if (_progressBarAction == null)
            {
                _progressBarAction = ODProgress.Show();
            }
        }
Example #7
0
        ///<summary>Generic function that launches different thread methods depending on how isSyncUsers and isSyncLocks are set.  Set only one or the other to true.</summary>
        private static string SyncAll(List <CentralConnection> listConns, bool isSyncUsers, bool isSyncLocks)
        {
            //Get CEMT users, groups, and associated permissions
            ListSyncErrors       = new List <string>();
            _listCEMTUsers       = Userods.GetUsersForCEMT();
            _securityLockDate    = PrefC.GetDate(PrefName.SecurityLockDate).ToShortDateString();
            _securityLockDays    = PrefC.GetInt(PrefName.SecurityLockDays);
            _securityLockAdmin   = PrefC.GetBool(PrefName.SecurityLockIncludesAdmin);
            _securityCentralLock = PrefC.GetBool(PrefName.CentralManagerSecurityLock);
            _syncCode            = PrefC.GetString(PrefName.CentralManagerSyncCode);
            _listAlertSubs       = AlertSubs.GetAll();
            List <CentralUserData> listCentralUserData = new List <CentralUserData>();
            List <UserGroup>       listUserGroups      = UserGroups.GetCEMTGroups();

            foreach (UserGroup userGroup in listUserGroups)             //for each CEMT user group
            //get all usergroupattaches, userods, and grouppermissions.
            {
                List <UserGroupAttach> listUserGroupAttaches = UserGroupAttaches.GetForUserGroup(userGroup.UserGroupNum);
                List <Userod>          listUserOds           = Userods.GetForGroup(userGroup.UserGroupNum);
                List <GroupPermission> listGroupPermissions  = GroupPermissions.GetPerms(userGroup.UserGroupNum);
                //then create a new CentralUserData and add it to the list.
                listCentralUserData.Add(new CentralUserData(userGroup, listUserOds, listGroupPermissions, listUserGroupAttaches));
            }
            string failedConns     = "";
            string nameConflicts   = "";
            string failedSyncCodes = "";

            for (int i = 0; i < listConns.Count; i++)
            {
                List <CentralUserData> listCentralDataForThreads = new List <CentralUserData>();
                for (int j = 0; j < listCentralUserData.Count; j++)
                {
                    listCentralDataForThreads.Add(listCentralUserData[j].Copy());
                }
                ODThread odThread = null;
                if (isSyncUsers)
                {
                    odThread = new ODThread(ConnectAndSyncUsers, new object[] { listConns[i], listCentralDataForThreads });
                    odThread.AddExceptionHandler(new ODThread.ExceptionDelegate(SyncExceptionHelper));
                }
                else if (isSyncLocks)
                {
                    odThread = new ODThread(ConnectAndSyncLocks, new object[] { listConns[i] });
                    odThread.AddExceptionHandler(new ODThread.ExceptionDelegate(SyncExceptionHelper));
                }
                else
                {
                    odThread = new ODThread(ConnectAndSyncAll, new object[] { listConns[i], listCentralDataForThreads });
                    odThread.AddExceptionHandler(new ODThread.ExceptionDelegate(SyncExceptionHelper));
                }
                odThread.GroupName = "Sync";
                odThread.Start(false);
            }
            ODThread.JoinThreadsByGroupName(Timeout.Infinite, "Sync");
            List <ODThread> listComplThreads = ODThread.GetThreadsByGroupName("Sync");

            for (int i = 0; i < listComplThreads.Count; i++)
            {
                if (listComplThreads[i].Tag == null)
                {
                    continue;                    //Failed due to lacking credentials
                }
                failedConns     += ((List <string>)listComplThreads[i].Tag)[0];
                nameConflicts   += ((List <string>)listComplThreads[i].Tag)[1];
                failedSyncCodes += ((List <string>)listComplThreads[i].Tag)[2];
                listComplThreads[i].QuitAsync();
            }
            string errorText = "";

            if (failedConns == "" && nameConflicts == "" && failedSyncCodes == "")
            {
                errorText += "Done";
            }
            if (failedConns != "")
            {
                errorText = "Failed Connections:\r\n" + failedConns + "Please try these connections again.\r\n";
            }
            if (nameConflicts != "")
            {
                errorText += "Name Conflicts:\r\n" + nameConflicts + "Please rename users and try again.\r\n";
            }
            if (failedSyncCodes != "")
            {
                errorText += "Incorrect Sync Codes:\r\n" + failedSyncCodes + "\r\n";
            }
            return(errorText);
        }