Exemplo n.º 1
0
        ///<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);
        }
Exemplo n.º 2
0
        ///<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);
        }
Exemplo n.º 3
0
        ///<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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        ///<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);
        }
Exemplo n.º 6
0
        ///<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);
        }
Exemplo n.º 7
0
 ///<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);
 }
Exemplo n.º 8
0
        ///<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);
        }
Exemplo n.º 9
0
        ///<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("");
        }
Exemplo n.º 10
0
 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("");
 }
Exemplo n.º 11
0
        ///<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);
        }
Exemplo n.º 12
0
        ///<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);
        }
Exemplo n.º 13
0
 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);
 }
Exemplo n.º 14
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);
        }