///<summary>Attempts to retrieve an End of Day report from EDS. ///No need to pass in a date as this web call, when clearinghouseClin.IsEraDownloadAllowed is enabled, ///will retrieve an 835 containing all data since last called.</summary> public static bool Retrieve835s(Clearinghouse clearinghouseClin, IODProgressExtended progress) { if (clearinghouseClin.IsEraDownloadAllowed == EraBehaviors.None) { return(true); } progress = progress ?? new ODProgressExtendedNull(); progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server and downloading reports"), "reports", "40%", 40); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading ERAs"), "reports", "50%", 50); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } bool retVal = Retrieve835s(clearinghouseClin); if (retVal) { progress.UpdateProgress(Lans.g(progress.LanThis, "Retrieved 835s successfully.")); } else { progress.UpdateProgress(Lans.g(progress.LanThis, "Retrieving 835s was unsuccessful.")); } return(retVal); }
///<summary>Attempts to retrieve an End of Day report from EDS. ///No need to pass in a date as this web call will retrieve a 277 containing all data since last called. ///When clearinghouseClin.IsEraDownloadAllowed is enabled, we also attempt to retrieve a 835 since last called.</summary> public static bool Retrieve(Clearinghouse clearinghouseClin, IODProgressExtended progress = null) { progress = progress ?? new ODProgressExtendedNull(); 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); } progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading 277s"), "reports", "33%", 33); bool retVal = Retrieve277s(clearinghouseClin); if (retVal) { progress.UpdateProgress(Lans.g(progress.LanThis, "Retrieved 277s successfully.")); } else { progress.UpdateProgress(Lans.g(progress.LanThis, "Retrieving 277s was unsuccessful.")); } if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } if (clearinghouseClin.IsEraDownloadAllowed != EraBehaviors.None) { progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading ERAs"), "reports", "50%", 50); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } if (retVal) //We successfully retrieved 277s { retVal = Retrieve835s(clearinghouseClin); progress.UpdateProgress(Lans.g(progress.LanThis, "Retrieved 835s successfully.")); } } return(retVal); }
///<summary>Attempts to retrieve an End of Day report from EDS. ///No need to pass in a date as this web call will retrieve a 277 containing all data since last called.</summary> public static bool Retrieve277s(Clearinghouse clearinghouseClin, IODProgressExtended progress) { progress = progress ?? new ODProgressExtendedNull(); progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server and downloading reports"), "reports", "17%", 17); bool retVal = false; if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading 277s"), "reports", "33%", 33); retVal = Retrieve277s(clearinghouseClin); if (retVal) { progress.UpdateProgress(Lans.g(progress.LanThis, "Retrieved 277s successfully.")); } else { progress.UpdateProgress(Lans.g(progress.LanThis, "Retrieving 277s was unsuccessful.")); } return(retVal); }
public static bool Retrieve(Clearinghouse clearinghouse, IODProgressExtended progress = null) { progress = progress ?? new ODProgressExtendedNull(); 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); } Dentalxchange2016.Credentials cred = new Dentalxchange2016.Credentials(); if (PrefC.GetBool(PrefName.CustomizedForPracticeWeb)) //even though they currently use code from a different part of the program. { cred.Client = "Practice-Web"; cred.ServiceID = "DCI Web Service ID: 001513"; } else { cred.Client = "OpenDental"; cred.ServiceID = "DCI Web Service ID: 002778"; } cred.Username = clearinghouse.LoginID; cred.Password = clearinghouse.Password; Dentalxchange2016.unProcessedEraRequest request = new Dentalxchange2016.unProcessedEraRequest(); Dentalxchange2016.DwsService service = new Dentalxchange2016.DwsService(); #if DEBUG service.Url = "https://prelive2.dentalxchange.com/dws/DwsService?wsdl"; #else service.Url = "https://webservices.dentalxchange.com/dws/DwsService?wsdl"; #endif ErrorMessage = ""; List <string> listEraStrings = new List <string>(); try { Dentalxchange2016.UnProcessedEraResponse response; do { response = service.getUnProcessedEra(cred, request); if (response.Status.code == 0 && response.ClaimPaymentAdvice.EdiContent != null) { listEraStrings.Add(response.ClaimPaymentAdvice.EdiContent); //X12 835 ERA raw content } } while(response.Status.code == 0 && response.ClaimPaymentAdvice != null && response.ClaimPaymentAdvice.AdditionalEraExists); if (response.Status.code != 0) //!=Approved //If the following error message changes, then also see if FormClaimReports.RetrieveReports() needs to change as well. { ErrorMessage = "Era request unsuccessful." + "\r\nError message received directly from Claim Connect: " + response.Status.code + "\r\n\r\n" + response.Status.description; return(false); } /* * Code Description * 0 Approved * 1 Operation Failed * 90 Invalid Group * 100 Invalid User * 110 Invalid Client * 120 Service Not Allowed * 130 User Not Allowed * 140 Invalid PMS * 150 Service Not Contracted by User * 1000 Internal server error has occurred. The problem is being investigated. * 2000 Generic Host Error * 2001 Malformed document sent. Please insure that the format is correct and all required data is present. * 2002 Deficient request - required data is missing. * 2003 No insurers found for this selection. * 2004 Unable to contact the payer at this time. Please try again later. * 2005 Only the relationship self is supported at this time. * 2007 Original request patient info reflected back * 2008 Claim submission failed. */ } catch (Exception ex) { ErrorMessage = Lans.g(progress.LanThis, "If this is a new customer, this error might be due to an invalid Username or Password. " + "Servers may need a few hours before ready to accept new user information.") + "\r\n" + Lans.g(progress.LanThis, "Error message received directly from Claim Connect:") + " " + ex.ToString(); return(false); } progress.UpdateProgress(Lans.g(progress.LanThis, "Web server contact successful.")); string path = clearinghouse.ResponsePath; progress.UpdateProgress(Lans.g(progress.LanThis, "Writing files"), "reports", "40%", 40); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } //write each message to a distinct file in the export path. listEraStrings.ForEach(x => File.WriteAllText(ODFileUtils.CreateRandomFile(path, ".txt"), x)); progress.UpdateProgress(Lans.g(progress.LanThis, "Files written successfully.")); progress.UpdateProgress(Lans.g(progress.LanThis, "Finalizing"), "reports", "50%", 50); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } return(true); }
///<summary>Returns true if the communications were successful, and false if they failed. Both sends and retrieves.</summary> public static bool Launch(Clearinghouse clearinghouseClin, int batchNum, IODProgressExtended progress = null) //called from Eclaims and FormClaimReports.cs. Clinic-level clearinghouse passed in. { progress = progress ?? new ODProgressExtendedNull(); _clearinghouseClin = clearinghouseClin; //Before this function is called, the X12 file for the current batch has already been generated in //the clearinghouse export folder. The export folder will also contain batch files which have failed //to upload from previous attempts and we must attempt to upload these older batch files again if //there are any. //Step 1: Retrieve reports regarding the existing pending claim statuses. //Step 2: Send new claims in a new batch. bool success = true; //Connect to the MDE SFTP server. Session session = null; Channel channel = null; ChannelSftp ch = null; JSch jsch = new JSch(); progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server"), "reports", "17%", 17); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } try{ session = jsch.getSession(_clearinghouseClin.LoginID, remoteHost, 22); session.setPassword(_clearinghouseClin.Password); Hashtable config = new Hashtable(); config.Add("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); channel = session.openChannel("sftp"); channel.connect(); ch = (ChannelSftp)channel; } catch (Exception ex) { progress.UpdateProgress(Lans.g(progress.LanThis, "Connection Failed")); ErrorMessage = Lans.g("MercuryDE", "Connection Failed") + ": " + ex.Message; return(false); } progress.UpdateProgress(Lans.g(progress.LanThis, "Web server contact successful.")); try{ //At this point we are connected to the MDE SFTP server. if (batchNum == 0) { if (!Directory.Exists(clearinghouseClin.ResponsePath)) { throw new Exception(Lans.g(progress.LanThis, "Clearinghouse response path is invalid.")); } progress.UpdateProgress(Lans.g(progress.LanThis, "Getting files"), "reports", "33%", 33); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } //Only retrieving reports so do not send new claims. string retrievePath = "/" + rootFolderName + "/Out/997/"; Tamir.SharpSsh.java.util.Vector fileList = ch.ls(retrievePath); for (int i = 0; i < fileList.Count; i++) { int percent = (i / fileList.Count) * 100; //We re-use the bar again for importing later, hence the tag. progress.UpdateProgress(Lans.g(progress.LanThis, "Getting file:") + i + " / " + fileList.Count, "import", percent + "%", percent); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } string listItem = fileList[i].ToString().Trim(); if (listItem[0] == 'd') { continue; //Skip directories and focus on files. } Match fileNameMatch = Regex.Match(listItem, ".*\\s+(.*)$"); string getFileName = fileNameMatch.Result("$1"); string getFilePath = retrievePath + getFileName; string exportFilePath = CodeBase.ODFileUtils.CombinePaths(clearinghouseClin.ResponsePath, getFileName); Tamir.SharpSsh.java.io.InputStream fileStream = null; FileStream exportFileStream = null; try{ fileStream = ch.get(getFilePath); exportFileStream = File.Open(exportFilePath, FileMode.Create, FileAccess.Write); //Creates or overwrites. byte[] dataBytes = new byte[4096]; int numBytes = fileStream.Read(dataBytes, 0, dataBytes.Length); while (numBytes > 0) { exportFileStream.Write(dataBytes, 0, numBytes); numBytes = fileStream.Read(dataBytes, 0, dataBytes.Length); } float overallpercent = 33 + (i / fileList.Count) * 17; //33 is starting point. 17 is the amount of bar space we have before our next major spot (50%) progress.UpdateProgress(Lans.g(progress.LanThis, "Getting files"), "reports", overallpercent + "%", (int)overallpercent); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } } catch (Exception ex) { ErrorMessage = ex.Message; success = false; } finally { if (exportFileStream != null) { exportFileStream.Dispose(); } if (fileStream != null) { fileStream.Dispose(); } } string archiveFilePath = retrievePath + "Archive/" + getFileName; try{ ch.rm(archiveFilePath); } catch { //Remove any destination files by the same exact name. The file will most likely not be present. } ch.rename(getFilePath, archiveFilePath); } } else { if (!Directory.Exists(clearinghouseClin.ExportPath)) { throw new Exception(Lans.g(progress.LanThis, "Clearinghouse export path is invalid.")); } //First upload the batch to the temporary directory. progress.UpdateProgress(Lans.g(progress.LanThis, "Uploading files to temp directory"), "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++) { int percent = (i / files.Length) * 100; //We re-use the bar again for importing later, hence the tag. progress.UpdateProgress(Lans.g(progress.LanThis, "Uploading file:") + i + " / " + files.Length, "import", percent + "%", percent); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } string accountNumber = _clearinghouseClin.ISA08; string dateTimeStr = DateTime.Now.ToString("yyyyMMddhhmmss"); string remoteFileName = accountNumber + dateTimeStr + i.ToString().PadLeft(3, '0') + ".837D.txt"; string remoteTempFilePath = "/" + rootFolderName + "/In/837D/Temp/" + remoteFileName; ch.put(files[i], remoteTempFilePath); //Read, Write and Execute permissions for everyone. This appears to cause no effect. ch.chmod((((7 << 3) | 7) << 3) | 7, remoteTempFilePath); string remoteFilePath = "/" + rootFolderName + "/In/837D/" + remoteFileName; ch.rename(remoteTempFilePath, remoteFilePath); File.Delete(files[i]); //Remove the processed file. float overallpercent = 33 + (i / files.Length) * 17; //33 is starting point. 17 is the amount of bar space we have before our next major spot (50%) progress.UpdateProgress(Lans.g(progress.LanThis, "Uploading files"), "reports", overallpercent + "%", (int)overallpercent); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } } } } catch (Exception ex) { if (ErrorMessage != "") { ErrorMessage += "\r\n"; } ErrorMessage = ex.Message; success = false; } finally { //Disconnect from the MDE SFTP server. progress.UpdateProgress("", "import", ""); //Clear import bar for now. channel.disconnect(); ch.disconnect(); session.disconnect(); } return(success); }
///<summary>Retrieves any waiting reports from this clearinghouse. Returns true if the communications were successful, and false if they failed.</summary> public static bool Retrieve(Clearinghouse clearinghouseClin, bool isAutomatic, ITerminalConnector terminalConnector, IODProgressExtended progress = null) { progress = progress ?? new ODProgressExtendedNull(); bool retVal = true; try { 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); } terminalConnector.ShowForm(); terminalConnector.OpenConnection(clearinghouseClin.ModemPort); terminalConnector.Dial("17065713158"); //2. Wait for connect, then pause 3 seconds terminalConnector.WaitFor("CONNECT 9600", 50000); terminalConnector.Pause(3000); terminalConnector.ClearRxBuff(); //1. Send submitter login record string submitterLogin = "******" //1,6 /SLRON=Submitter login + terminalConnector.Sout(clearinghouseClin.LoginID, 12, 12) //7,12 Submitter ID + terminalConnector.Sout(clearinghouseClin.Password, 8, 8) //19,8 submitter password + " " //27,3 use 3 spaces //Possible issue with Trans ID + "12345678" //30,8. they did not explain this field very well in documentation + "* " //38,15 " * "=All available. spacing ok? + "X" //53,1 X=Xmodem, or Y for transmission protocol + "MDD " //54,4 use 'MDD ' + "VND" //58,3 Vendor ID is yet to be assigned by BCBS + "00"; //61,2 Software version not important byte response = (byte)'Y'; string retrieveFile = ""; progress.UpdateProgress(Lans.g(progress.LanThis, "Web server contact successful.")); progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading files"), "reports", "33%", 33); if (progress.IsPauseOrCancel()) { return(false); } while (response == (byte)'Y') { terminalConnector.ClearRxBuff(); terminalConnector.Send(submitterLogin); response = 0; while (response != (byte)'N' && response != (byte)'Y' && response != (byte)'Z') { response = terminalConnector.GetOneByte(20000); terminalConnector.ClearRxBuff(); Application.DoEvents(); } //2. If not accepted, N is returned //3. and must receive transmission acknowledgement if (response == (byte)'N') { progress.UpdateProgress(terminalConnector.Receive(10000)); break; } //4. If login accepted, but no records, Z is returned. Hang up. if (response == (byte)'Z') { progress.UpdateProgress(Lans.g(progress.LanThis, "No reports to retrieve.")); break; } //5. If record(s) available, Y is returned, followed by dos filename and 32 char subj. //less than one second since all text is supposed to immediately follow the Y retrieveFile = terminalConnector.Receive(800).Substring(0, 12); //12 char in dos filename terminalConnector.ClearRxBuff(); //6. Pause for 200 ms. (already mostly handled); terminalConnector.Pause(200); //7. Receive file using Xmodem //path must include trailing slash for now. terminalConnector.DownloadXmodem(clearinghouseClin.ResponsePath + retrieveFile); //8. Pause for 5 seconds. terminalConnector.Pause(5000); //9. Repeat all steps including login until a Z is returned. } progress.UpdateProgress(Lans.g(progress.LanThis, "Closing connection to web server"), "reports", "50%", 50); if (progress.IsPauseOrCancel()) { return(false); } } catch (Exception ex) { ErrorMessage = ex.Message; retVal = false; } finally { terminalConnector.CloseConnection(); } return(retVal); }
///<summary>Throws exceptions.</summary> public static bool Retrieve(Clearinghouse clearinghouseClin, IODProgressExtended progress = null) //called from FormClaimReports. clinic-level clearinghouse passed in. { progress = progress ?? new ODProgressExtendedNull(); try { if (!Directory.Exists(clearinghouseClin.ResponsePath)) { throw new ODException(Lans.g(progress.LanThis, "Clearinghouse response path is invalid.")); } progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server"), "reports", "17%", 17); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } bool reportsDownloaded = false; bool isTest = (clearinghouseClin.ISA15 == "T"); //See guide pages 21 through 25 for "batch download message types" List <EmdeonMedicalReportType> listReportTypes = new List <EmdeonMedicalReportType>(); //Also known and Institutional Claims. Might not need this report type, but leaving here for backwards compatibility. listReportTypes.Add(new EmdeonMedicalReportType("Hospital Claims", "HCTG", "HCDG", "HCTD", "HCDD")); //Might not need this report type, but leaving here for backwards compatibility. listReportTypes.Add(new EmdeonMedicalReportType("Medical Claims", "MCTG", "MCDG", "MCTD", "MCDD")); listReportTypes.Add(new EmdeonMedicalReportType("Automated Verification (270,276,278)", "AETG", "AEVG", "AETD", "AEVD")); if (clearinghouseClin.IsEraDownloadAllowed != EraBehaviors.None) //ERA download is enabled. { listReportTypes.Add(new EmdeonMedicalReportType("Electronic Remittance Acceptance (ERA) 835", "EDT", "EDP", "EAT", "EAP")); } progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading files"), "reports", "33%", 33); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } for (int i = 0; i < listReportTypes.Count; i++) { float overallpercent = 33 + (i / listReportTypes.Count) * 17; //33 is starting point. 17 is the amount of bar space we have before our next major spot (50%) progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading files"), "reports", overallpercent + "%", (int)overallpercent); EmdeonITS.ITSWS itsws = new EmdeonITS.ITSWS(); itsws.Url = (isTest?emdeonITSUrlTest:emdeonITSUrl); EmdeonMedicalReportType reportType = listReportTypes[i]; //Download the most up to date reports, but do not delete them from the server yet. EmdeonITS.ItsReturn response = itsws.GetFile(clearinghouseClin.LoginID, clearinghouseClin.Password, reportType.GetCodeForGetReport(isTest)); //Change Health Care ITS User Guide 3.0.6B_20160107.pdf, page 20 for GetFile() states: //"If ErrorCode is zero, Response will contain a Base64 encoded string of the binary download content or a text based message, depending on //the type of download requested (see discussions below regarding Message Types and Client File Acknowledgement). If the Response is a //Base64 encoded string, the client application must perform Base64 decoding on the Response. The result will be the binary content of a //PK-Zip compatible file which can then be written to disk. If ErrorCode is greater than zero, //Response will contain a text based error message" if (response.ErrorCode == 0) //Report retrieval successful. { string reportFileDataBase64 = response.Response; byte[] reportFileDataBytes = Convert.FromBase64String(reportFileDataBase64); string reportFilePath = CodeBase.ODFileUtils.CreateRandomFile(clearinghouseClin.ResponsePath, ".zip"); File.WriteAllBytes(reportFilePath, reportFileDataBytes); string errorMsg = ""; ZipFile zipFile = null; try { zipFile = new ZipFile(reportFilePath); //Open zip file. zipFile.ExtractAll(clearinghouseClin.ResponsePath); } catch (Exception ex) { errorMsg = Lans.g(progress.LanThis, "Report zip file downloaded but could not be extracted.") + "\r\n" + "File: " + reportFilePath + "\r\n" + ex.Message; } try { if (zipFile != null) { zipFile.Dispose(); //This releases the file handle created when opening the file above. } File.Delete(reportFilePath); } catch (Exception ex) { ex.DoNothing(); //Could not be deleted. Not a big deal, because at least we were able to extract it, making it available for import. } if (errorMsg != "") { throw new ODException(errorMsg); } reportsDownloaded = true; //Now that the file has been saved, remove the report file from the Emdeon production server. //If deleting the report fails, we don't care because that will simply mean that we download it again next time. //Thus we don't need to check the status after this next call. progress.UpdateProgress(Lans.g(progress.LanThis, "Removing report file from server")); itsws.GetFile(clearinghouseClin.LoginID, clearinghouseClin.Password, reportType.GetCodeForDeleteReport(isTest)); } else if (response.ErrorCode != 209) //Error 209 means mailbox is empty for requested report type. { throw new ODException(Lans.g(progress.LanThis, "Failed to get reports. Error number from Emdeon:") + " " + response.ErrorCode + ". " + Lans.g(progress.LanThis, "Error message from Emdeon: ") + response.Response); } } progress.UpdateProgress(Lans.g(progress.LanThis, "Download successful.")); progress.UpdateProgress(Lans.g(progress.LanThis, "Finalizing"), "reports", "50%", 50); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } if (!reportsDownloaded) { ErrorMessage = Lans.g(progress.LanThis, "Report mailbox is empty."); } } catch (Exception ex) { ErrorMessage = ex.Message; return(false); } return(true); }
///<summary></summary> public static string RetrieveAndImport(Clearinghouse clearinghouseClin, bool isAutomaticMode, IODProgressExtended progress = null , bool isTimeToRetrieve = false) { progress = progress ?? new ODProgressExtendedNull(); string errorMessage = ""; bool doRetrieveReports = isTimeToRetrieve || (!isAutomaticMode && IsTimeToRetrieveReports(isAutomaticMode, out errorMessage, progress)); if (doRetrieveReports) //Timer interval OK. Now we can retrieve the reports from web services. { if (!isAutomaticMode) { Prefs.UpdateDateT(PrefName.ClaimReportReceiveLastDateTime, DateTime.Now); } errorMessage = RetrieveReports(clearinghouseClin, isAutomaticMode, progress); if (errorMessage != "") { progress.UpdateProgress(Lans.g(progress.LanThis, "Error getting reports, attempting to import manually downloaded reports.")); } progress.UpdateProgress(Lans.g(progress.LanThis, "Report retrieval successful. Attempting to import.")); //Don't return yet even if there was an error. This is so that Open Dental will automatically import reports that have been manually //downloaded to the Reports folder. } if (isAutomaticMode && clearinghouseClin.ResponsePath.Trim() == "") { return(""); //The user opened FormClaimsSend, or FormOpenDental called this function automatically. } if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(errorMessage); } string importErrors = ImportReportFiles(clearinghouseClin, progress); if (!string.IsNullOrWhiteSpace(importErrors)) { if (string.IsNullOrWhiteSpace(errorMessage)) { errorMessage = importErrors; progress.UpdateProgress(Lans.g(progress.LanThis, "Error importing.")); } else { errorMessage += "\r\n" + importErrors; } } if (string.IsNullOrWhiteSpace(errorMessage) && string.IsNullOrWhiteSpace(importErrors)) { progress.UpdateProgress(Lans.g(progress.LanThis, "Import successful.")); } return(errorMessage); }
///<summary>Takes any files found in the reports folder for the clearinghouse, and imports them into the database. ///Moves the original file into an Archive sub folder. ///Returns a string with any errors that occured.</summary> private static string ImportReportFiles(Clearinghouse clearinghouseClin, IODProgressExtended progress = null) //uses clinic-level clearinghouse where necessary. { progress = progress ?? new ODProgressExtendedNull(); if (!Directory.Exists(clearinghouseClin.ResponsePath)) { return(Lans.g("FormClaimReports", "Report directory does not exist") + ": " + clearinghouseClin.ResponsePath); } if (clearinghouseClin.Eformat == ElectronicClaimFormat.Canadian || clearinghouseClin.Eformat == ElectronicClaimFormat.Ramq) { //the report path is shared with many other important files. Do not process anything. Comm is synchronous only. return(""); } progress.UpdateProgress(Lans.g(progress.LanThis, "Reading download files"), "reports", "55%", 55); if (progress.IsPauseOrCancel()) { return(Lans.g(progress.LanThis, "Import canceled by user.")); } string[] files = null; string archiveDir; try { files = Directory.GetFiles(clearinghouseClin.ResponsePath); archiveDir = ODFileUtils.CombinePaths(clearinghouseClin.ResponsePath, "Archive" + "_" + DateTime.Now.Year.ToString()); if (!Directory.Exists(archiveDir)) { Directory.CreateDirectory(archiveDir); } } catch (UnauthorizedAccessException ex) { ex.DoNothing(); return(Lans.g("FormClaimReports", "Access to the Report Path is denied. Try running as administrator or contact your network administrator.")); } List <string> listFailedFiles = new List <string>(); progress.UpdateProgress(Lans.g(progress.LanThis, "Files read.")); progress.UpdateProgress(Lans.g(progress.LanThis, "Importing files"), "reports", "83%", 83); if (files.Length > 0) { progress.UpdateProgressDetailed(Lans.g(progress.LanThis, "Importing"), tagString: "import"); //add a new progress bar for imports if there are any to import } else { progress.UpdateProgress(Lans.g(progress.LanThis, "No files to import.")); } for (int i = 0; i < files.Length; i++) { int percent = (i / files.Length) * 100; progress.UpdateProgress(Lans.g(progress.LanThis, "Importing") + " " + i + " / " + files.Length, "import", percent + "%", percent); if (progress.IsPauseOrCancel()) { return(Lans.g(progress.LanThis, "Import canceled by user.")); } string fileSource = files[i]; string fileDestination = ODFileUtils.CombinePaths(archiveDir, Path.GetFileName(files[i])); try { File.Move(fileSource, fileDestination); } catch (Exception ex) { ex.DoNothing(); //OK to continue, since ProcessIncomingReport() above saved the raw report into the etrans table. listFailedFiles.Add(fileSource); continue; //Skip current report file and leave in folder to processing later. } try { Etranss.ProcessIncomingReport( File.GetCreationTime(fileDestination), clearinghouseClin.HqClearinghouseNum, File.ReadAllText(fileDestination), Security.CurUser.UserNum); } catch (Exception ex) { ex.DoNothing(); listFailedFiles.Add(fileSource); File.Move(fileDestination, fileSource); //Move file back so that the archived folder only contains succesfully processed reports. } } if (listFailedFiles.Count > 0) { return(Lans.g("FormClaimReports", "Failed to process the following files due to permission issues or malformed data") + ":\r\n" + string.Join(",\r\n", listFailedFiles)); } return(""); }
private static string RetrieveReports(Clearinghouse clearinghouseClin, bool isAutomaticMode, IODProgressExtended progress = null) { progress = progress ?? new ODProgressExtendedNull(); progress.UpdateProgress(Lans.g(progress.LanThis, "Beginning report retrieval..."), "reports", "0%"); if (progress.IsPauseOrCancel()) { return(Lans.g(progress.LanThis, "Process canceled by user.")); } if (clearinghouseClin.ISA08 == "113504607") //TesiaLink //But the import will still happen { return(""); } if (clearinghouseClin.CommBridge == EclaimsCommBridge.None || clearinghouseClin.CommBridge == EclaimsCommBridge.Renaissance || clearinghouseClin.CommBridge == EclaimsCommBridge.RECS) { return(""); } if (clearinghouseClin.CommBridge == EclaimsCommBridge.WebMD) { if (!WebMD.Launch(clearinghouseClin, 0, isAutomaticMode, progress)) { return(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + WebMD.ErrorMessage); } } else if (clearinghouseClin.CommBridge == EclaimsCommBridge.BCBSGA) { if (!BCBSGA.Retrieve(clearinghouseClin, true, new TerminalConnector(), progress)) { return(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + BCBSGA.ErrorMessage); } } else if (clearinghouseClin.CommBridge == EclaimsCommBridge.ClaimConnect) { if (!Directory.Exists(clearinghouseClin.ResponsePath)) { //The clearinghouse report path is not setup. Therefore, the customer does not use ClaimConnect reports via web services. if (isAutomaticMode) //The user opened FormClaimsSend, or FormOpenDental called this function automatically. { return(""); //Suppress error message. } else //The user pressed the Get Reports button manually. //This cannot happen, because the user is blocked by the UI before they get to this point. { } } else if (!ClaimConnect.Retrieve(clearinghouseClin, progress)) { if (ClaimConnect.ErrorMessage.Contains(": 150\r\n")) //Error message 150 "Service Not Contracted" { if (isAutomaticMode) //The user opened FormClaimsSend, or FormOpenDental called this function automatically. { return(""); //Pretend that there is no error when loading FormClaimsSend for those customers who do not pay for ERA service. } else //The user pressed the Get Reports button manually. //The old way. Some customers still prefer to go to the dentalxchange web portal to view reports because the ERA service costs money. { try { Process.Start(@"http://www.dentalxchange.com"); } catch (Exception ex) { ex.DoNothing(); return(Lans.g("FormClaimReports", "Could not locate the site.")); } return(""); } } return(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + ClaimConnect.ErrorMessage); } } else if (clearinghouseClin.CommBridge == EclaimsCommBridge.AOS) { try { //This path would never exist on Unix, so no need to handle back slashes. Process.Start(@"C:\Program files\AOS\AOSCommunicator\AOSCommunicator.exe"); } catch { return(Lans.g("FormClaimReports", "Could not locate the file.")); } } else if (clearinghouseClin.CommBridge == EclaimsCommBridge.MercuryDE) { if (!MercuryDE.Launch(clearinghouseClin, 0, progress)) { return(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + MercuryDE.ErrorMessage); } } else if (clearinghouseClin.CommBridge == EclaimsCommBridge.EmdeonMedical) { if (!EmdeonMedical.Retrieve(clearinghouseClin, progress)) { return(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + EmdeonMedical.ErrorMessage); } } else if (clearinghouseClin.CommBridge == EclaimsCommBridge.DentiCal) { if (!DentiCal.Launch(clearinghouseClin, 0, progress)) { return(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + DentiCal.ErrorMessage); } } else if (clearinghouseClin.CommBridge == EclaimsCommBridge.EDS) { List <string> listEdsErrors = new List <string>(); if (!EDS.Retrieve277s(clearinghouseClin, progress)) { listEdsErrors.Add(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + EDS.ErrorMessage); } if (!EDS.Retrieve835s(clearinghouseClin, progress)) { listEdsErrors.Add(Lans.g("FormClaimReports", "Error retrieving.") + "\r\n" + EDS.ErrorMessage); } if (listEdsErrors.Count > 0) { return(string.Join("\r\n", listEdsErrors)); } } return(""); }
///<summary>Returns true if it is time to retrieve reports.</summary> private static bool IsTimeToRetrieveReports(bool isAutomaticMode, out string errorMessage, IODProgressExtended progress = null) { progress = progress ?? new ODProgressExtendedNull(); DateTime timeLastReport = PIn.DateT(PrefC.GetStringNoCache(PrefName.ClaimReportReceiveLastDateTime)); double timeReceiveInternal = PIn.Double(PrefC.GetStringNoCache(PrefName.ClaimReportReceiveInterval)); //Interval in minutes. DateTime timeToRecieve = DateTime.Now.Date + PrefC.GetDateT(PrefName.ClaimReportReceiveTime).TimeOfDay; double timeDiff = DateTime.Now.Subtract(timeLastReport).TotalMinutes; errorMessage = ""; if (isAutomaticMode) { if (timeReceiveInternal != 0) //preference is set instead of pref for specific time. { if (timeDiff < timeReceiveInternal) { //Automatically retrieving reports from this computer and the report interval has not passed yet. return(false); } } else //pref is set for specific time, not interval { if (DateTime.Now.TimeOfDay < timeToRecieve.TimeOfDay || //We haven't reach to the time to retrieve timeLastReport.Date == DateTime.Today) //Or we have already retrieved today { //Automatically retrieving reports and the time has not come to pass yet return(false); } } } else if (timeDiff < 1) { //When the user presses the Get Reports button manually we allow them to get reports up to once per minute errorMessage = Lans.g(progress.LanThis, "Reports can only be retrieved once per minute."); progress.UpdateProgress(Lans.g(progress.LanThis, "Reports can only be retrieved once per minute. Attempting to import manually downloaded reports.")); return(false); } return(true); }
///<summary>Returns true if the communications were successful, and false if they failed. Both sends and retrieves.</summary> public static bool Launch(Clearinghouse clearinghouseClin, int batchNum, IODProgressExtended progress = null) //called from FormClaimReports and Eclaims.cs. clinic-level clearinghouse passed in. //Before this function is called, the X12 file for the current batch has already been generated in //the clearinghouse export folder. The export folder will also contain batch files which have failed //to upload from previous attempts and we must attempt to upload these older batch files again if //there are any. //Step 1: Retrieve reports regarding the existing pending claim statuses. //Step 2: Send new claims in a new batch. { progress = progress ?? new ODProgressExtendedNull(); bool success = true; //Connect to the Denti-Cal SFTP server. Session session = null; Channel channel = null; ChannelSftp ch = null; JSch jsch = new JSch(); progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server"), "reports", "17%", 17); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } try { string remoteHost = "mft.oxi.arcaas.com"; session = jsch.getSession(clearinghouseClin.LoginID, remoteHost); session.setPassword(clearinghouseClin.Password); Hashtable config = new Hashtable(); config.Add("StrictHostKeyChecking", "no"); session.setConfig(config); int port = 2222; //new production port session.setPort(port); session.connect(); channel = session.openChannel("sftp"); channel.connect(); ch = (ChannelSftp)channel; } catch (Exception ex) { ErrorMessage = Lans.g("DentiCal", "Connection Failed") + ": " + ex.Message; return(false); } progress.UpdateProgress(Lans.g(progress.LanThis, "Web server contact successful.")); try { string homeDir = "/"; //new production home root dir //At this point we are connected to the Denti-Cal SFTP server. if (batchNum == 0) //Retrieve reports. { progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading reports"), "reports", "33%", 33); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } if (!Directory.Exists(clearinghouseClin.ResponsePath)) { progress.UpdateProgress(Lans.g(progress.LanThis, "Clearinghouse response path is invalid.")); return(false); throw new Exception("Clearinghouse response path is invalid."); } //Only retrieving reports so do not send new claims. //Although the documentation we received from Denti-Cal says that the folder name should start "OXi", that was not the case for a customer //that we connected to and Barbara Castelli from Denti-Cal informed us that the folder name should start with "dcaprod". string retrievePath = homeDir + "dcaprod_" + clearinghouseClin.LoginID + "_out/"; Tamir.SharpSsh.java.util.Vector fileList; try { fileList = ch.ls(retrievePath); } catch (Exception ex) { ex.DoNothing(); //Try again with the path as described in the documentation. retrievePath = homeDir + "OXi_" + clearinghouseClin.LoginID + "_out/"; fileList = ch.ls(retrievePath); } for (int i = 0; i < fileList.Count; i++) { int percent = (i / fileList.Count) * 100; //We re-use the bar again for importing later, hence the tag. progress.UpdateProgress(Lans.g(progress.LanThis, "Getting file:") + i + " / " + fileList.Count, "import", percent + "%", percent); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } string listItem = fileList[i].ToString().Trim(); if (listItem[0] == 'd') { continue; //Skip directories and focus on files. } Match fileNameMatch = Regex.Match(listItem, ".*\\s+(.*)$"); string getFileName = fileNameMatch.Result("$1"); string getFilePath = retrievePath + getFileName; string exportFilePath = CodeBase.ODFileUtils.CombinePaths(clearinghouseClin.ResponsePath, getFileName); Tamir.SharpSsh.java.io.InputStream fileStream = null; FileStream exportFileStream = null; try { fileStream = ch.get(getFilePath); exportFileStream = File.Open(exportFilePath, FileMode.Create, FileAccess.Write); //Creates or overwrites. byte[] dataBytes = new byte[4096]; int numBytes = fileStream.Read(dataBytes, 0, dataBytes.Length); while (numBytes > 0) { exportFileStream.Write(dataBytes, 0, numBytes); numBytes = fileStream.Read(dataBytes, 0, dataBytes.Length); } float overallpercent = 33 + (i / fileList.Count) * 17; //33 is starting point. 17 is the amount of bar space we have before our next major spot (50%) progress.UpdateProgress(Lans.g(progress.LanThis, "Getting files"), "reports", overallpercent + "%", (int)overallpercent); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } } catch { success = false; } finally { if (exportFileStream != null) { exportFileStream.Dispose(); } if (fileStream != null) { fileStream.Dispose(); } progress.UpdateProgress("", "import", ""); //Clear import bar for now } if (success) { //Removed the processed report from the Denti-Cal SFTP so it does not get processed again in the future. try { ch.rm(getFilePath); progress.UpdateProgress(Lans.g(progress.LanThis, "Reports downloaded successfully.")); } catch { } } } } else //Send batch of claims. { progress.UpdateProgress(Lans.g(progress.LanThis, "Sending batch of claims"), "reports", "33%", 33); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } if (!Directory.Exists(clearinghouseClin.ExportPath)) { throw new Exception(Lans.g(progress.LanThis, "Clearinghouse export path is invalid.")); } string[] files = Directory.GetFiles(clearinghouseClin.ExportPath); //Try to find a folder that starts with "dcaprod" or "OXi". string uploadPath = homeDir + "dcaprod_" + clearinghouseClin.LoginID + "_in/"; Tamir.SharpSsh.java.util.Vector fileList; try { fileList = ch.ls(uploadPath); } catch (Exception ex) { ex.DoNothing(); //Try again with the path as described in the documentation. uploadPath = homeDir + "OXi_" + clearinghouseClin.LoginID + "_in/"; fileList = ch.ls(uploadPath); } //We have successfully found the folder where we need to put the files. for (int i = 0; i < files.Length; i++) { float overallpercent = 33 + (i / files.Length) * 17; //33 is starting point. 17 is the amount of bar space we have before our next major spot (50%) progress.UpdateProgress(Lans.g(progress.LanThis, "Sending claims"), "reports", overallpercent + "%", (int)overallpercent); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } //First upload the batch file to a temporary file name. Denti-Cal does not process file names unless they start with the Login ID. //Uploading to a temporary file and then renaming the file allows us to avoid partial file uploads if there is connection loss. string tempRemoteFilePath = uploadPath + "temp_" + Path.GetFileName(files[i]); ch.put(files[i], tempRemoteFilePath); //Denti-Cal requires the file name to start with the Login ID followed by a period and end with a .txt extension. //The middle part of the file name can be anything. string remoteFilePath = uploadPath + Path.GetFileName(files[i]); ch.rename(tempRemoteFilePath, remoteFilePath); File.Delete(files[i]); //Remove the processed file. } progress.UpdateProgress(Lans.g(progress.LanThis, "Claims sent successfully.")); } } catch (Exception ex) { success = false; ErrorMessage += ex.Message; } finally { progress.UpdateProgress(Lans.g(progress.LanThis, "Closing connection"), "reports", "50%", 50); //Disconnect from the Denti-Cal SFTP server. channel.disconnect(); ch.disconnect(); session.disconnect(); } return(success); }
public static bool Retrieve(Clearinghouse clearinghouseClin, IODProgressExtended progress = null) //called from FormClaimReports. clinic-level clearinghouse passed in. { progress = progress ?? new ODProgressExtendedNull(); try { if (!Directory.Exists(clearinghouseClin.ResponsePath)) { throw new Exception(Lans.g(progress.LanThis, "Clearinghouse response path is invalid.")); } progress.UpdateProgress(Lans.g(progress.LanThis, "Contacting web server"), "reports", "17%", 17); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } bool reportsDownloaded = false; bool isTest = (clearinghouseClin.ISA15 == "T"); string[] arrayMessageTypes = new string[] { (isTest?"MCT":"MCD"), //Medical (isTest?"HCT":"HCD"), //Institutional //(isTest?"DCT":"DCD") //Dental. Planned for future. }; progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading files"), "reports", "33%", 33); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } for (int i = 0; i < arrayMessageTypes.Length; i++) { float overallpercent = 33 + (i / arrayMessageTypes.Length) * 17; //33 is starting point. 17 is the amount of bar space we have before our next major spot (50%) progress.UpdateProgress(Lans.g(progress.LanThis, "Downloading files"), "reports", overallpercent + "%", (int)overallpercent); EmdeonITS.ITSWS itsws = new EmdeonITS.ITSWS(); itsws.Url = (isTest?emdeonITSUrlTest:emdeonITSUrl); //Download the most up to date reports, but do not delete them from the server yet. EmdeonITS.ITSReturn response = itsws.GetFile(clearinghouseClin.LoginID, clearinghouseClin.Password, arrayMessageTypes[i] + "G"); if (response.ErrorCode == 0) //Report retrieval successful. { string reportFileDataBase64 = response.Response; byte[] reportFileDataBytes = Convert.FromBase64String(reportFileDataBase64); string reportFilePath = CodeBase.ODFileUtils.CreateRandomFile(clearinghouseClin.ResponsePath, ".zip"); File.WriteAllBytes(reportFilePath, reportFileDataBytes); reportsDownloaded = true; //Now that the file has been saved, remove the report file from the Emdeon production server. //If deleting the report fails, we don't care because that will simply mean that we download it again next time. //Thus we don't need to check the status after this next call. progress.UpdateProgress(Lans.g(progress.LanThis, "Removing report file from server")); itsws.GetFile(clearinghouseClin.LoginID, clearinghouseClin.Password, arrayMessageTypes[i] + "D"); } else if (response.ErrorCode != 209) //Report retrieval failure, excluding the error that can be returned when the mailbox is empty. { throw new Exception(Lans.g(progress.LanThis, "Failed to get reports. Error number from Emdeon:") + " " + response.ErrorCode + ". " + Lans.g(progress.LanThis, "Error message from Emdeon: ") + response.Response); } } progress.UpdateProgress(Lans.g(progress.LanThis, "Download successful.")); progress.UpdateProgress(Lans.g(progress.LanThis, "Finalizing"), "reports", "50%", 50); if (progress.IsPauseOrCancel()) { progress.UpdateProgress(Lans.g(progress.LanThis, "Canceled by user.")); return(false); } if (!reportsDownloaded) { ErrorMessage = Lans.g(progress.LanThis, "Report mailbox is empty."); } } catch (Exception ex) { ErrorMessage = ex.Message; return(false); } return(true); }
///<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); }