private void butCopy_Click(object sender, EventArgs e)
 {
     try {
         ODClipboard.SetClipboard(textSchedulingURL.Text);
     }
     catch (Exception ex) {
         FriendlyException.Show(Lan.g(this, "Unable to copy to clipboard."), ex);
     }
 }
Example #2
0
 ///<summary>Sends data for pat to the Dexis Integrator program using a DDE Execute command.  Shows a message box if pat is null instructing user
 ///to first select a pat.  Sends SET command with the following format: SET 17 LN="LName" FN="FName" MI="MiddleI" BD=19760205.  The first
 ///parameter of the command is the patient ID defined by the program property as either PatNum or ChartNumber.  The BD portion will only be added
 ///if the pat has a valid bday and adding it to the commmand won't increase the length of the command to >255 characters.</summary>
 public static void SendData(Program progCur, Patient pat)
 {
     if (pat == null)
     {
         MsgBox.Show("DexisIntegrator", "Please select a patient first.");
         return;
     }
     try {
         if (_client == null || _client.Context == null)
         {
             DdeContext context = new DdeContext(Application.OpenForms.OfType <FormOpenDental>().FirstOrDefault() ?? Application.OpenForms[0]);
             _client = new DdeClient("Dexis", "Patient", context);
         }
         if (!_client.IsConnected)
         {
             _client.Connect();
         }
         string patId = pat.PatNum.ToString();
         if (ProgramProperties.GetPropVal(progCur.ProgramNum, "Enter 0 to use PatientNum, or 1 to use ChartNum") == "1")
         {
             patId = pat.ChartNumber;
         }
         string ddeCommand = "SET " + patId + " LN=\"" + pat.LName + "\" FN=\"" + pat.FName + "\" MI=\"" + pat.MiddleI + "\"";
         if (pat.Birthdate.Year > 1880 && ddeCommand.Length < 244)             //add optional bday only if valid and it won't increase the length to >255 characters
         {
             ddeCommand += " BD=" + pat.Birthdate.ToString("yyyyMMdd");
         }
         _client.Execute(ddeCommand, 30000);               //timeout 30 seconds
         //if execute was successfully sent, subscribe the PatientChangedEvent_Fired handler to the PatientChangedEvent.Fired event
         PatientChangedEvent.Fired -= PatientChangedEvent_Fired;
         PatientChangedEvent.Fired += PatientChangedEvent_Fired;
         UserodChangedEvent.Fired  -= UserodChangedEvent_Fired;
         UserodChangedEvent.Fired  += UserodChangedEvent_Fired;
     }
     catch (ObjectDisposedException ode) {
         if (_isRetry)
         {
             FriendlyException.Show(Lans.g("DexisIntegrator", "There was an error trying to launch Dexis with the selected patient."), ode);
             return;
         }
         _isRetry = true;
         if (_client != null && _client.IsConnected)
         {
             ODException.SwallowAnyException(new Action(() => _client.Disconnect()));                    //disconnect if necessary
         }
         ODException.SwallowAnyException(new Action(() => _client.Dispose()));
         _client = null;              //will cause a new _client to be made with a new context
         SendData(progCur, pat);
     }
     catch (Exception ex) {
         FriendlyException.Show(Lans.g("DexisIntegrator", "There was an error trying to launch Dexis with the selected patient."), ex);
         return;
     }
     finally {
         _isRetry = false;
     }
 }
Example #3
0
        ///<summary></summary>
        public static void SendData(Program ProgramCur)
        {
            string path = ProgramCur.Path;

            try {
                Process.Start(path);
            }
            catch (Exception ex) {
                FriendlyException.Show(Lans.g("Benco", "Unable to launch") + " " + ProgramCur.ProgDesc + ".", ex);
            }
        }
 ///<summary>Returns true if Topaz is initialized. If it is not initialized, it will attempt to do so.</summary>
 private bool CheckTopaz()
 {
     if (sigBoxTopaz == null)
     {
         try {
             InitializeTopaz();
         }
         catch (Exception ex) {
             FriendlyException.Show(Lans.g(this, "Unable to initialize Topaz."), ex);
             return(false);
         }
     }
     return(true);
 }
        private void butImport_Click(object sender, EventArgs e)
        {
            if (gridMain.SelectedGridRows.Count == 0)
            {
                MsgBox.Show(this, "Please select a fee schedule to import fees into.");
                return;
            }
            if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "If you want a clean slate, the current fee schedule should be cleared first.  "
                             + "When imported, any fees found in the text file will overwrite values of the selected fee schedule.  Are you sure you want to continue?"))
            {
                return;
            }
            // Set up general base fee schedules with no provider or clinic
            long provNum   = 0;
            long clinicNum = 0;

            Cursor = Cursors.WaitCursor;
            OpenFileDialog Dlg = new OpenFileDialog();

            if (Directory.Exists(PrefC.GetString(PrefName.ExportPath)))
            {
                Dlg.InitialDirectory = PrefC.GetString(PrefName.ExportPath);
            }
            else if (Directory.Exists("C:\\"))
            {
                Dlg.InitialDirectory = "C:\\";
            }
            if (Dlg.ShowDialog() != DialogResult.OK)
            {
                Cursor = Cursors.Default;
                return;
            }
            if (!File.Exists(Dlg.FileName))
            {
                MsgBox.Show(this, "File not found");
                Cursor = Cursors.Default;
                return;
            }
            FeeSched feeSched = ((FeeSched)gridMain.SelectedGridRows[0].Tag);          //get selected fee sched from grid.

            try {
                FeeL.ImportFees(Dlg.FileName, feeSched.FeeSchedNum, clinicNum, provNum);
                _isChanged = true;
            }
            catch (Exception ex) {
                FriendlyException.Show("Error importing fees.", ex);
            }
            Cursor = Cursors.Default;
        }
Example #6
0
 private void butTransfer_Click(object sender, EventArgs e)
 {
     if (gridPatients.ListGridRows.Count == 0)
     {
         MsgBox.Show(this, "At least one patient must be selected to transfer.");
         return;
     }
     if (gridDatabasesTo.ListGridRows.Count == 0)
     {
         MsgBox.Show(this, "At least one database must be selected to transfer.");
         return;
     }
     if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "The transfer process may take a long time. Continue?"))
     {
         return;
     }
     ODProgress.ShowAction(() => RunTransfer(), startingMessage: Lans.g(this, "Transferring patient(s)..."),
                           actionException: err => this.Invoke(() => FriendlyException.Show(Lan.g(this, "Error transferring patient(s)."), err)));
 }
Example #7
0
        public void FriendlyException_Show_ThrowsInUnitTest()
        {
            string strMessageExpected = "Exception thrown.";
            string strMessageCaught   = "FormFriendlyException is not throwing.";
            //Call FriendlyException in a thread so we don't hang in this test if it fails.
            ODThread odThread = new ODThread((o) => {
                try {
                    FriendlyException.Show("FriendlyException", new Exception(strMessageExpected));
                }
                catch (Exception ex) {
                    strMessageCaught = ex.InnerException.Message;
                }
            });

            odThread.Start();
            int millis = 0;

            while (strMessageExpected != strMessageCaught && millis < 1000)
            {
                System.Threading.Thread.Sleep(1);                //sleep 1 milliseconds.
                millis++;
            }
            Assert.AreEqual(strMessageExpected, strMessageCaught);
        }
Example #8
0
        /// <summary></summary>
        public static void SendData(Program ProgramCur, Patient pat)
        {
            if (pat == null)
            {
                MsgBox.Show("Guru", "Please select a patient first.");
                return;
            }
            try {
                int errorNum = MVStart();
                if (errorNum != 0)
                {
                    /* Error codes:
                     * MV_SUCCESS if successful
                     * MV_WRONG_PARAM if hPMS is not null and pContextString is null
                     * MV_WRONG_PARAM if pContextString is length 0 or is not null terminated within strSize characters
                     * MV_ERROR if an unknown error occurred
                     *
                     * Enumeration Name - E_MV_ERROR
                     * This enumeration defines the different return values of exported functions.  When successful, functions return MV_SUCCESS, an other value otherwise:  see the full list below.
                     * MV_SUCCESS - The function has succeeded
                     * MV_NOT_RUNNING - MV is not running
                     * MV_NOT_CREATED - MedVisor has not been created
                     * MV_NO_PATIENT - No patient has been set in MedVisor
                     * MV_REQUIRED_DATA - Required data has not been sent
                     * MV_WRONG_VALUE - Send data are not valid
                     * MV_FILE_NOT_FOUND - Sent file cannot be found
                     * MV_ERROR - General Error
                     */
                    throw new ODException(Lan.g("Guru", "MedVisorInterface.MVStart() returned with an error code of:") + $" {errorNum}");
                }
            }
            catch (DllNotFoundException e) {
                e.DoNothing();
                MessageBox.Show(Lans.g("Guru", "Could not find MedVisorInterface.dll. Verify that Guru is installed."));
                return;
            }
            catch (Exception ex) {
                FriendlyException.Show(Lans.g("Guru", "An error occurred when launching Guru."), ex);
                return;
            }
            MVPatient mvPatient = new MVPatient();

            mvPatient.LastName  = Tidy(pat.LName, 64);
            mvPatient.FirstName = Tidy(pat.FName, 64);
            if (pat.Gender == PatientGender.Male)
            {
                mvPatient.Sex = Tidy("M", 1);
            }
            else if (pat.Gender == PatientGender.Female)
            {
                mvPatient.Sex = Tidy("F", 1);
            }
            else if (pat.Gender == PatientGender.Unknown)
            {
                mvPatient.Sex = Tidy("0", 1);
            }
            mvPatient.BirthDate = Tidy(pat.Birthdate.ToString("MMddyyyy"), 8);
            if (ProgramProperties.GetPropVal(ProgramCur.ProgramNum, "Enter 0 to use PatientNum, or 1 to use ChartNum") == "0")
            {
                mvPatient.ID = Tidy(pat.PatNum.ToString(), 64);
            }
            else
            {
                mvPatient.ID = Tidy(pat.ChartNumber.ToString(), 64);
            }
            if (pat.ImageFolder == "")           //Could happen if the images module has not been visited for a new patient.
            {
                Patient patOld = pat.Copy();
                pat.ImageFolder = ImageStore.GetImageFolderName(pat);
                Patients.Update(pat, patOld);
            }
            string imagePath = CodeBase.ODFileUtils.CombinePaths(ProgramProperties.GetPropVal(ProgramCur.ProgramNum, "Guru image path"), pat.ImageFolder);

            mvPatient.Directory = Tidy(imagePath, 259);
            if (MVSendPatient(mvPatient) != 0)
            {
                MsgBox.Show("Guru", "An error has occurred.");
            }
        }
Example #9
0
        ///<summary>Sends data for Patient to a mailbox file and launches the program.</summary>
        public static void SendData(Program ProgramCur, Patient pat)
        {
            string path = Programs.GetProgramPath(ProgramCur);
            List <ProgramProperty> listProgramProperties = ProgramProperties.GetForProgram(ProgramCur.ProgramNum);

            if (pat != null)
            {
                try {
                    #region Read / Write .ini
                    //read file C:\sidexis\sifiledb.ini
                    string iniFile = Path.GetDirectoryName(path) + "\\sifiledb.ini";
                    if (!File.Exists(iniFile))
                    {
                        throw new ApplicationException(iniFile + " " + Lan.g("Sirona", "could not be found. Is Sidexis installed properly?"));
                    }
                    //read FromStation0 | File to determine location of comm file (sendBox) (siomin.sdx)
                    //example:
                    //[FromStation0]
                    //File=F:\PDATA\siomin.sdx  //only one sendBox on entire network.
                    StringBuilder retVal = new StringBuilder(255);
                    GetPrivateProfileString("FromStation0", "File", "", retVal, 255, iniFile);
                    string sendBox = retVal.ToString();
                    //read Multistations | GetRequest (=1) to determine if station can take xrays.
                    //but we don't care at this point, so ignore
                    //set OfficeManagement | OffManConnected = 1 to make sidexis ready to accept a message.
                    WritePrivateProfileString("OfficeManagement", "OffManConnected", "1", iniFile);
                    #endregion
                    #region Write to SendBox File (siomin.sdx)
                    using (FileStream fs = new FileStream(sendBox, FileMode.Append))
                        using (BinaryWriter bw = new BinaryWriter(fs)) {
                            //line formats: first two bytes are the length of line including first two bytes and \r\n
                            //each field is terminated by null (byte 0).
                            //Append U token to siomin.sdx file
                            StringBuilder line  = new StringBuilder();
                            char          nTerm = (char)0;       //Convert.ToChar(0);
                            line.Append("U");                    //U signifies Update patient in sidexis. Gets ignored if new patient.
                            line.Append(nTerm);
                            line.Append(pat.LName);
                            line.Append(nTerm);
                            line.Append(pat.FName);
                            line.Append(nTerm);
                            line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                            line.Append(nTerm);
                            //leave initial patient id blank. This updates sidexis to patNums used in Open Dental
                            line.Append(nTerm);
                            line.Append(pat.LName);
                            line.Append(nTerm);
                            line.Append(pat.FName);
                            line.Append(nTerm);
                            line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                            line.Append(nTerm);
                            //Patient id:
                            ProgramProperty PPCur = ProgramProperties.GetCur(listProgramProperties, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
                            if (PPCur.PropertyValue == "0")
                            {
                                line.Append(pat.PatNum.ToString());
                            }
                            else
                            {
                                line.Append(pat.ChartNumber);
                            }
                            line.Append(nTerm);
                            if (pat.Gender == PatientGender.Female)
                            {
                                line.Append("F");
                            }
                            else
                            {
                                line.Append("M");
                            }
                            line.Append(nTerm);
                            line.Append(Providers.GetAbbr(Patients.GetProvNum(pat)));
                            line.Append(nTerm);
                            line.Append("OpenDental");
                            line.Append(nTerm);
                            line.Append("Sidexis");
                            line.Append(nTerm);
                            line.Append("\r\n");
                            bw.Write(IntToByteArray(line.Length + 2));                  //the 2 accounts for these two chars.
                            bw.Write(StrBuildToBytes(line));
                            //Append N token to siomin.sdx file
                            //N signifies create New patient in sidexis. If patient already exists,
                            //then it simply updates any old data.
                            line = new StringBuilder();
                            line.Append("N");
                            line.Append(nTerm);
                            line.Append(pat.LName);
                            line.Append(nTerm);
                            line.Append(pat.FName);
                            line.Append(nTerm);
                            line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                            line.Append(nTerm);
                            //Patient id:
                            if (PPCur.PropertyValue == "0")
                            {
                                line.Append(pat.PatNum.ToString());
                            }
                            else
                            {
                                line.Append(pat.ChartNumber);
                            }
                            line.Append(nTerm);
                            if (pat.Gender == PatientGender.Female)
                            {
                                line.Append("F");
                            }
                            else
                            {
                                line.Append("M");
                            }
                            line.Append(nTerm);
                            line.Append(Providers.GetAbbr(Patients.GetProvNum(pat)));
                            line.Append(nTerm);
                            line.Append("OpenDental");
                            line.Append(nTerm);
                            line.Append("Sidexis");
                            line.Append(nTerm);
                            line.Append("\r\n");
                            bw.Write(IntToByteArray(line.Length + 2));
                            bw.Write(StrBuildToBytes(line));
                            //Append A token to siomin.sdx file
                            //A signifies Autoselect patient.
                            line = new StringBuilder();
                            line.Append("A");
                            line.Append(nTerm);
                            line.Append(pat.LName);
                            line.Append(nTerm);
                            line.Append(pat.FName);
                            line.Append(nTerm);
                            line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                            line.Append(nTerm);
                            if (PPCur.PropertyValue == "0")
                            {
                                line.Append(pat.PatNum.ToString());
                            }
                            else
                            {
                                line.Append(pat.ChartNumber);
                            }
                            line.Append(nTerm);
                            line.Append(SystemInformation.ComputerName);
                            line.Append(nTerm);
                            line.Append(DateTime.Now.ToString("dd.MM.yyyy"));
                            line.Append(nTerm);
                            line.Append(DateTime.Now.ToString("HH.mm.ss"));
                            line.Append(nTerm);
                            line.Append("OpenDental");
                            line.Append(nTerm);
                            line.Append("Sidexis");
                            line.Append(nTerm);
                            line.Append("0");                    //0=no image selection
                            line.Append(nTerm);
                            line.Append("\r\n");
                            bw.Write(IntToByteArray(line.Length + 2));
                            bw.Write(StrBuildToBytes(line));
                        }
                    #endregion
                }
                catch (Exception ex) {
                    FriendlyException.Show(Lan.g("Sirona", "Error preparing Sidexis for patient message."), ex);
                    return;
                }
            }            //if patient is loaded
            //Start Sidexis.exe whether patient loaded or not.
            try {
                Process.Start(path);
            }
            catch {
                MessageBox.Show(path + " is not available.");
            }
        }
Example #10
0
        ///<summary>Sends data for Patient to a mailbox file and launches the program.</summary>
        public static void SendData(Program ProgramCur, Patient pat)
        {
            OpenDentBusiness.Shared.Sirona.Lans_g = Lans.g;
            string path = Programs.GetProgramPath(ProgramCur);
            List <ProgramProperty> listProgramProperties = ProgramProperties.GetForProgram(ProgramCur.ProgramNum);
            List <string>          listIniLines          = new List <string>();

            if (pat != null)
            {
                try {
                    #region Construct ini info
                    //line formats: first two bytes are the length of line including first two bytes and \r\n
                    //each field is terminated by null (byte 0).
                    //Append U token to siomin.sdx file
                    StringBuilder line  = new StringBuilder();
                    char          nTerm = (char)0;       //Convert.ToChar(0);
                    line.Append("U");                    //U signifies Update patient in sidexis. Gets ignored if new patient.
                    line.Append(nTerm);
                    line.Append(pat.LName);
                    line.Append(nTerm);
                    line.Append(pat.FName);
                    line.Append(nTerm);
                    line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                    line.Append(nTerm);
                    //leave initial patient id blank. This updates sidexis to patNums used in Open Dental
                    line.Append(nTerm);
                    line.Append(pat.LName);
                    line.Append(nTerm);
                    line.Append(pat.FName);
                    line.Append(nTerm);
                    line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                    line.Append(nTerm);
                    //Patient id:
                    ProgramProperty PPCur = ProgramProperties.GetCur(listProgramProperties, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
                    if (PPCur.PropertyValue == "0")
                    {
                        line.Append(pat.PatNum.ToString());
                    }
                    else
                    {
                        line.Append(pat.ChartNumber);
                    }
                    line.Append(nTerm);
                    if (pat.Gender == PatientGender.Female)
                    {
                        line.Append("F");
                    }
                    else
                    {
                        line.Append("M");
                    }
                    line.Append(nTerm);
                    line.Append(Providers.GetAbbr(Patients.GetProvNum(pat)));
                    line.Append(nTerm);
                    line.Append("OpenDental");
                    line.Append(nTerm);
                    line.Append("Sidexis");
                    line.Append(nTerm);
                    line.Append("\r\n");
                    listIniLines.Add(line.ToString());
                    //Append N token to siomin.sdx file
                    //N signifies create New patient in sidexis. If patient already exists,
                    //then it simply updates any old data.
                    line = new StringBuilder();
                    line.Append("N");
                    line.Append(nTerm);
                    line.Append(pat.LName);
                    line.Append(nTerm);
                    line.Append(pat.FName);
                    line.Append(nTerm);
                    line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                    line.Append(nTerm);
                    //Patient id:
                    if (PPCur.PropertyValue == "0")
                    {
                        line.Append(pat.PatNum.ToString());
                    }
                    else
                    {
                        line.Append(pat.ChartNumber);
                    }
                    line.Append(nTerm);
                    if (pat.Gender == PatientGender.Female)
                    {
                        line.Append("F");
                    }
                    else
                    {
                        line.Append("M");
                    }
                    line.Append(nTerm);
                    line.Append(Providers.GetAbbr(Patients.GetProvNum(pat)));
                    line.Append(nTerm);
                    line.Append("OpenDental");
                    line.Append(nTerm);
                    line.Append("Sidexis");
                    line.Append(nTerm);
                    line.Append("\r\n");
                    listIniLines.Add(line.ToString());
                    //Append A token to siomin.sdx file
                    //A signifies Autoselect patient.
                    line = new StringBuilder();
                    line.Append("A");
                    line.Append(nTerm);
                    line.Append(pat.LName);
                    line.Append(nTerm);
                    line.Append(pat.FName);
                    line.Append(nTerm);
                    line.Append(pat.Birthdate.ToString("dd.MM.yyyy"));
                    line.Append(nTerm);
                    if (PPCur.PropertyValue == "0")
                    {
                        line.Append(pat.PatNum.ToString());
                    }
                    else
                    {
                        line.Append(pat.ChartNumber);
                    }
                    line.Append(nTerm);
                    if (ODBuild.IsWeb())
                    {
                        line.Append("{{SystemInformation.ComputerName}}");                        //Will be replaced on the client side
                    }
                    else
                    {
                        line.Append(SystemInformation.ComputerName);
                    }
                    line.Append(nTerm);
                    line.Append(DateTime.Now.ToString("dd.MM.yyyy"));
                    line.Append(nTerm);
                    line.Append(DateTime.Now.ToString("HH.mm.ss"));
                    line.Append(nTerm);
                    line.Append("OpenDental");
                    line.Append(nTerm);
                    line.Append("Sidexis");
                    line.Append(nTerm);
                    line.Append("0");                    //0=no image selection
                    line.Append(nTerm);
                    line.Append("\r\n");
                    listIniLines.Add(line.ToString());
                    #endregion
                    if (!ODBuild.IsWeb())
                    {
                        OpenDentBusiness.Shared.Sirona.WriteToSendBoxFile(path, listIniLines);
                    }
                }
                catch (Exception ex) {
                    FriendlyException.Show(Lan.g("Sirona", "Error preparing Sidexis for patient message."), ex);
                    return;
                }
            }            //if patient is loaded
            //Start Sidexis.exe whether patient loaded or not.
            try {
                if (ODBuild.IsWeb())
                {
                    ODCloudClient.SendToSirona(path, listIniLines);
                }
                else
                {
                    ODFileUtils.ProcessStart(path);
                }
            }
            catch (Exception ex) {
                FriendlyException.Show(path + " is not available.", ex);
            }
        }
Example #11
0
        ///<summary>Makes an API call to get an Oryx URL to launch that is specific to the current user and patient.</summary>
        public static void SendData(Program progOryx, Patient pat)
        {
            string clientUrl = "";

            try {
                clientUrl = OpenDentBusiness.ProgramProperties.GetPropVal(progOryx.ProgramNum, ProgramProperties.ClientUrl);
                if (clientUrl == "")               //Office has not signed up with Oryx yet, launch a promotional page.
                {
                    string promoUrl = "http://www.opendental.com/resources/redirects/redirectoryx.html";
#if DEBUG
                    promoUrl = "http://www.opendental.com/resources/redirects/redirectoryxdebug.html";
#endif
                    ODFileUtils.ProcessStart(promoUrl);
                    return;
                }
                if (!progOryx.Enabled)
                {
                    MsgBox.Show("Oryx", "Oryx must be enabled in Program Links.");
                    return;
                }
                if (!clientUrl.ToLower().StartsWith("http"))
                {
                    clientUrl = "https://" + clientUrl;
                }
                UserOdPref userNamePref = UserOdPrefs.GetByUserFkeyAndFkeyType(Security.CurUser.UserNum, progOryx.ProgramNum, UserOdFkeyType.ProgramUserName)
                                          .FirstOrDefault();
                UserOdPref passwordPref = UserOdPrefs.GetByUserFkeyAndFkeyType(Security.CurUser.UserNum, progOryx.ProgramNum, UserOdFkeyType.ProgramPassword)
                                          .FirstOrDefault();
                if ((userNamePref == null || userNamePref.ValueString == "") && (passwordPref == null || passwordPref.ValueString == ""))
                {
                    //User hasn't entered credentials yet. Launch the office's Oryx page where the user can then log in.
                    ODFileUtils.ProcessStart(clientUrl);
                    return;
                }
                string apiUrl = clientUrl.TrimEnd('/') + "/api/auth/opendental/v1/login";
                string passwordPlain;
                if (!CDT.Class1.Decrypt(passwordPref.ValueString, out passwordPlain))
                {
                    MsgBox.Show("Oryx", "Unable to decrypt password");
                    return;
                }
                var content = new {
                    username  = userNamePref.ValueString,
                    password  = passwordPlain,
                    patientId = (pat != null ? pat.PatNum.ToString() : ""),
                };
                string contentJson = JsonConvert.SerializeObject(content);
                string responseStr;
                using (WebClient client = new WebClient()) {
                    client.Headers[HttpRequestHeader.ContentType] = "application/json";
                    responseStr = client.UploadString(apiUrl, "POST", contentJson);
                }
                var response = new {
                    success      = false,
                    redirectUrl  = "",
                    errorMessage = "",
                };
                response = JsonConvert.DeserializeAnonymousType(responseStr, response);
                if (!response.success)
                {
                    MessageBox.Show(Lans.g("Orxy", "Error message from Oryx:") + " " + response.errorMessage);
                    return;
                }
                ODFileUtils.ProcessStart(response.redirectUrl);
            }
            catch (Exception ex) {
                string errorMessage = "Unable to launch Oryx.";
                if (ex is NotSupportedException && ex.Message == "The given path's format is not supported.")
                {
                    //Oryx has asked us to give a more helpful error message when this happens.
                    errorMessage += " This is likely because the Client URL is invalid.\r\nClient URL: " + clientUrl;
                }
                FriendlyException.Show(Lans.g("Oryx", errorMessage), ex);
            }
        }