///<summary>Returns true if the communications were successful, and false if they failed. If they failed, a rollback will happen automatically by deleting the previously created X12 file. The batchnum is supplied for the possible rollback. Also used for mail retrieval.</summary> public static bool Launch(Clearinghouse clearhouse, int batchNum) { string arguments = ""; try{ if (!Directory.Exists(clearhouse.ExportPath)) { throw new Exception("Clearinghouse export path is invalid."); } if (!Directory.Exists(clearhouse.ResponsePath)) { throw new Exception("Clearinghouse response path is invalid."); } if (!File.Exists(clearhouse.ClientProgram)) { throw new Exception("Client program not installed properly."); } arguments = ODFileUtils.RemoveTrailingSeparators(clearhouse.ExportPath) + "\\" + "*.* " //upload claims path + ODFileUtils.RemoveTrailingSeparators(clearhouse.ResponsePath) + " " //Mail path + "316 " //vendor number. + clearhouse.LoginID + " " //Client number. Assigned by us, and we have to coordinate for all other 'vendors' of Open Dental, because there is only one vendor number for OD for now. + clearhouse.Password; //call the WebMD client program Process process = Process.Start(clearhouse.ClientProgram, arguments); process.EnableRaisingEvents = true; process.WaitForExit(); //delete the uploaded claims string[] files = Directory.GetFiles(clearhouse.ExportPath); for (int i = 0; i < files.Length; i++) { //string t=files[i]; File.Delete(files[i]); } //rename the downloaded mail files to end with txt files = Directory.GetFiles(clearhouse.ResponsePath); for (int i = 0; i < files.Length; i++) { //string t=files[i]; if (Path.GetExtension(files[i]) != ".txt") { File.Move(files[i], files[i] + ".txt"); } } } catch (Exception e) { MessageBox.Show(e.Message); //+"\r\n"+clearhouse.ClientProgram+" "+arguments); if (batchNum != 0) { x837Controller.Rollback(clearhouse, batchNum); } return(false); } return(true); }
///<summary>This is the function that the worker thread uses to perform the backup.</summary> private void InstanceMethodBackup() { curVal = 0; Invoke(new PassProgressDelegate(PassProgressToDialog), new object [] { curVal, Lan.g(this, "Preparing to copy database"), //this happens very fast and probably won't be noticed. 100, "" }); //max of 100 keeps dlg from closing string dbName = MiscData.GetCurrentDatabase(); ulong driveFreeSpace = 0; double dbSize = GetFileSizes(textBackupFromPath.Text + dbName) / 1024; //Attempt to get the free disk space on the drive or share of the destination folder. //If the free space cannot be determined the backup will be attempted anyway (old behavior). if (ODFileUtils.GetDiskFreeSpace(textBackupToPath.Text, out driveFreeSpace)) { if ((ulong)dbSize * 1024 * 1024 >= driveFreeSpace) //dbSize is in megabytes, cast to ulong to compare. It will never be negative so this is safe. { Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Not enough free disk space available on the destination drive to backup the database.") }); //We now want to automatically close FormProgress. This is done by clearing out the variables. Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" }); return; } } try{ string dbtopath = ODFileUtils.CombinePaths(textBackupToPath.Text, dbName); if (Directory.Exists(dbtopath)) // D:\opendental { int loopCount = 1; while (Directory.Exists(dbtopath + "backup_" + loopCount)) { loopCount++; } Directory.Move(dbtopath, dbtopath + "backup_" + loopCount); } string fromPath = ODFileUtils.CombinePaths(textBackupFromPath.Text, dbName); string toPath = textBackupToPath.Text; DirectoryInfo dirInfo = new DirectoryInfo(fromPath); //does not check to see if dir exists Directory.CreateDirectory(ODFileUtils.CombinePaths(toPath, dirInfo.Name)); FileInfo[] files = dirInfo.GetFiles(); curVal = 0; //curVal gets increased for (int i = 0; i < files.Length; i++) { string fromFile = files[i].FullName; string toFile = ODFileUtils.CombinePaths(new string[] { toPath, dirInfo.Name, files[i].Name }); if (File.Exists(toFile)) { if (files[i].LastWriteTime != File.GetLastWriteTime(toFile)) //if modification dates don't match { FileAttributes fa = File.GetAttributes(toFile); bool isReadOnly = ((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly); if (isReadOnly) { //If the destination file exists and is marked as read only, then we must mark it as a //normal read/write file before it may be overwritten. File.SetAttributes(toFile, FileAttributes.Normal); //Remove read only from the destination file. } File.Copy(fromFile, toFile, true); } } else //file doesn't exist, so just copy { File.Copy(fromFile, toFile); } curVal += (double)files[i].Length / (double)1024 / (double)1024; if (curVal < dbSize) //this avoids setting progress bar to max, which would close the dialog. { Invoke(new PassProgressDelegate(PassProgressToDialog), new object [] { curVal, Lan.g(this, "Database: ?currentVal MB of ?maxVal MB copied"), dbSize, "" }); } } } catch { //for instance, if abort. //If the user aborted, FormP will return DialogResult.Cancel which will not cause this error text to be displayed to the user. See butBackup_Click for more info. Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Backup failed.") }); //We now want to automatically close FormProgress. This is done by clearing out the variables. Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" }); return; } //A to Z folder------------------------------------------------------------------------------------ try { if (ShouldUseAtoZFolder()) { string atozFull = ODFileUtils.RemoveTrailingSeparators(ImageStore.GetPreferredAtoZpath()); string atozDir = atozFull.Substring(atozFull.LastIndexOf(Path.DirectorySeparatorChar) + 1); //OpenDentalData Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, Lan.g(this, "Calculating size of files in A to Z folder."), 100, "" });//max of 100 keeps dlg from closing long atozSize = GetFileSizes(ODFileUtils.CombinePaths(atozFull, ""), ODFileUtils.CombinePaths(new string[] { textBackupToPath.Text, atozDir, "" })) / 1024; driveFreeSpace = 0; //Attempt to get the free disk space on the drive or share of the destination folder. //If the free space cannot be determined the backup will be attempted anyway (old behavior). if (ODFileUtils.GetDiskFreeSpace(textBackupToPath.Text, out driveFreeSpace)) { if ((ulong)(atozSize * 1024 * 1024) >= driveFreeSpace) //atozSize is in megabytes, cast to ulong in order to compare. It will never be negative so it's safe. //Not enough free space to perform the backup. { throw new ApplicationException(Lan.g(this, "Backing up A to Z images folder failed. Not enough free disk space available on the destination drive.") + "\r\n" + Lan.g(this, "AtoZ folder size:") + " " + atozSize * 1024 * 1024 + "B\r\n" + Lan.g(this, "Destination available space:") + " " + driveFreeSpace + "B"); } } if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupToPath.Text, atozDir))) // D:\OpenDentalData { Directory.CreateDirectory(ODFileUtils.CombinePaths(textBackupToPath.Text, atozDir)); // D:\OpenDentalData } curVal = 0; CopyDirectoryIncremental(ODFileUtils.CombinePaths(atozFull, ""), // C:\OpenDentalData\ ODFileUtils.CombinePaths(new string[] { textBackupToPath.Text, atozDir, "" }), // D:\OpenDentalData\ atozSize); } } catch (ApplicationException ex) { Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { ex.Message }); } catch { Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Backing up A to Z images folder failed. User might not have enough permissions or a file might be in use.") }); } //force dialog to close even if no files copied or calculation was slightly off. Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" }); }
///<summary>Used for both sending claims and receiving reports. Set isSilent to true to hide the cmd window popup. ///Returns true if the communications were successful, and false if they failed. If they failed, a rollback will happen automatically by ///deleting the previously created X12 file. The batchnum is supplied for the possible rollback. Also used for mail retrieval.</summary> public static bool Launch(Clearinghouse clearinghouseClin, int batchNum, bool isSilent = false, IODProgressExtended progress = null) { //called from Eclaims and FormClaimReports.cs. Clinic-level clearinghouse passed in. progress = progress ?? new ODProgressExtendedNull(); string arguments = ""; try { if (!Directory.Exists(clearinghouseClin.ExportPath)) { throw new Exception(Lans.g(progress.LanThis, "Clearinghouse export path is invalid.")); } if (!Directory.Exists(clearinghouseClin.ResponsePath)) { throw new Exception(Lans.g(progress.LanThis, "Clearinghouse response path is invalid.")); } if (!File.Exists(clearinghouseClin.ClientProgram)) { throw new Exception(Lans.g(progress.LanThis, "Client program not installed properly.")); } arguments = "\"" + ODFileUtils.RemoveTrailingSeparators(clearinghouseClin.ExportPath) + "\\" + "*.*\" " //upload claims path + "\"" + ODFileUtils.RemoveTrailingSeparators(clearinghouseClin.ResponsePath) + "\" " //Mail path + "316 " //vendor number. //LoginID is client number. Assigned by us, and we have to coordinate for all other 'vendors' of Open Dental, //because there is only one vendor number for OD for now. + clearinghouseClin.LoginID + " " + clearinghouseClin.Password; //call the WebMD client program Process process = new Process(); process.EnableRaisingEvents = true; if (isSilent) { process.StartInfo.UseShellExecute = false; //Required to redirect standard input on the next line. process.StartInfo.RedirectStandardInput = true; //Required to send a newline character into the input stream below. process.StartInfo.CreateNoWindow = true; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; } process.StartInfo.FileName = clearinghouseClin.ClientProgram; process.StartInfo.Arguments = arguments; progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server and downloading reports"), "reports", "17%", 17); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } process.Start(); if (isSilent) { //If the LoginID or password are incorrect, then the WebMD client program will show an error message and wait for the user to click enter. //Above we redirected standard input so that we could send a newline into the input. //This way if the LoginID or password are incorrect, then the WebMD client will still exit. //Write an excessive amount of newlines in case the WebMD client asks multiple questions. //If we send the input before the WebMD client is ready, then the input is queued until it is needed. //If no input is needed, then the input will be ignored. for (int i = 0; i < 10; i++) { process.StandardInput.WriteLine(); } } process.WaitForExit(); //delete the uploaded claims progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server sucessful.")); progress.UpdateProgress(Lans.g(progress.LanThis, "Deleting uploaded claims"), "reports", "33%", 33); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } string[] files = Directory.GetFiles(clearinghouseClin.ExportPath); for (int i = 0; i < files.Length; i++) { float overallpercent = 33 + (i / files.Length) * 11; //33 is starting point. 11 is the amount of bar space we have before our next major spot (44%) progress.UpdateProgress(Lans.g(progress.LanThis, "Getting files"), "reports", overallpercent + "%", (int)overallpercent); //string t=files[i]; File.Delete(files[i]); } //rename the downloaded mail files to end with txt progress.UpdateProgress(Lans.g(progress.LanThis, "Deleteing uploaded claims successful.")); progress.UpdateProgress("Renaming downloaded files", "reports", "44%", 44); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } files = Directory.GetFiles(clearinghouseClin.ResponsePath); for (int i = 0; i < files.Length; i++) { float overallpercent = 44 + (i / files.Length) * 11; //44 is starting point. 11 is the amount of bar space we have before our next major spot (55%) progress.UpdateProgress(Lans.g(progress.LanThis, "Getting files"), "reports", overallpercent + "%", (int)overallpercent); //string t=files[i]; if (Path.GetExtension(files[i]) != ".txt") { File.Move(files[i], files[i] + ".txt"); } } progress.UpdateProgress(Lans.g(progress.LanThis, "File rename successful.")); } catch (Exception e) { ErrorMessage = e.Message; progress.UpdateProgress(Lans.g(progress.LanThis, "Error encountered:") + "\r\n" + ErrorMessage); if (batchNum != 0) { progress.UpdateProgress(Lans.g(progress.LanThis, "Rolling back batch.")); progress.UpdateProgressDetailed(Lans.g(progress.LanThis, "Rolling back batch"), tagString: "reports", marqSpeed: 20, progStyle: ProgBarStyle.Marquee); x837Controller.Rollback(clearinghouseClin, batchNum); progress.UpdateProgressDetailed(Lans.g(progress.LanThis, "Done rolling back"), tagString: "reports", marqSpeed: 20, progStyle: ProgBarStyle.Marquee); progress.UpdateProgress(Lans.g(progress.LanThis, "Rolling back batch complete.")); } return(false); } return(true); }