Exemplo n.º 1
0
        ///<summary>Throws exceptions if the PaySimple program or program properties are not valid.
        ///If this method doesn't throw an exception, everything is assumed to be valid.</summary>
        private static void ValidateProgram(long clinicNum = -1)
        {
            if (clinicNum == -1)
            {
                clinicNum = Clinics.ClinicNum;
            }
            Program progPaySimple = Programs.GetCur(ProgramName.PaySimple);

            if (progPaySimple == null)
            {
                throw new ODException(Lans.g("PaySimple", "PaySimple program does not exist in the database.  Please call support."));
            }
            if (!progPaySimple.Enabled)
            {
                throw new ODException(Lans.g("PaySimple", "PaySimple is not enabled."));
            }
            string apiUserName = ProgramProperties.GetPropValForClinicOrDefault(progPaySimple.ProgramNum, PropertyDescs.PaySimpleApiUserName, clinicNum);
            string apiKey      = ProgramProperties.GetPropValForClinicOrDefault(progPaySimple.ProgramNum, PropertyDescs.PaySimpleApiKey, clinicNum);
            string payType     = ProgramProperties.GetPropValForClinicOrDefault(progPaySimple.ProgramNum, PropertyDescs.PaySimplePayType, clinicNum);

            if (string.IsNullOrWhiteSpace(apiUserName) || string.IsNullOrWhiteSpace(apiKey) || string.IsNullOrWhiteSpace(payType))
            {
                throw new ODException(Lans.g("PaySimple", "PaySimple Username, Key, or PayType is empty."));
            }
        }
Exemplo n.º 2
0
        /// <summary>Inserts a TsiTransLog for the adjustment if necessary.</summary>
        public static void CheckAndInsertLogsIfAdjTypeExcluded(Adjustment adj, bool isFromTsi = false)
        {
            Program progCur = Programs.GetCur(ProgramName.Transworld);

            if (progCur == null || !progCur.Enabled)
            {
                return;
            }
            Patient guar = Patients.GetGuarForPat(adj.PatNum);

            if (guar == null || !IsTransworldEnabled(guar.ClinicNum) || !Patients.IsGuarCollections(guar.PatNum))
            {
                return;
            }
            string       msgText = "This was not a message sent to Transworld.  This adjustment was entered due to a payment received from Transworld.";
            TsiTransType typeCur = TsiTransType.None;

            if (!isFromTsi)             //if not an adj due to a payment from TSI, see if it is an excluded adj type
            {
                Dictionary <long, List <ProgramProperty> > dictClinicProps = ProgramProperties
                                                                             .GetWhere(x => x.ProgramNum == progCur.ProgramNum && x.PropertyDesc.In(ExcludeAdjustTypes) && x.ClinicNum.In(0, guar.ClinicNum))
                                                                             .GroupBy(x => x.ClinicNum)
                                                                             .ToDictionary(x => x.Key, x => x.ToList());
                //use guar's clinic if clinics are enabled and props for that clinic exist, otherwise use ClinicNum 0
                long clinicNum = (PrefC.HasClinicsEnabled && dictClinicProps.ContainsKey(guar.ClinicNum))?guar.ClinicNum:0;
                if (!dictClinicProps.TryGetValue(clinicNum, out List <ProgramProperty> listPropsCur) ||          //should always be props for ClinicNum 0
                    listPropsCur.All(x => PIn.Long(x.PropertyValue, false) != adj.AdjType))
                {
                    return;                    //if this adjustment is not an excluded type, return
                }
                msgText = "Adjustment type is set to excluded type from transworld program properties.";
                typeCur = TsiTransType.Excluded;
            }
            InsertTsiLogsForAdjustment(guar.PatNum, adj, msgText, typeCur);
        }
Exemplo n.º 3
0
        public static bool IsTransworldEnabled(long clinicNum)
        {
            //No need to check RemotingRole;no call to db.
            Program progCur = Programs.GetCur(ProgramName.Transworld);

            if (progCur == null || !progCur.Enabled)
            {
                return(false);
            }
            Dictionary <long, List <ProgramProperty> > dictAllProps = ProgramProperties.GetForProgram(progCur.ProgramNum)
                                                                      .GroupBy(x => x.ClinicNum)
                                                                      .ToDictionary(x => x.Key, x => x.ToList());

            if (dictAllProps.Count == 0)
            {
                return(false);
            }
            List <long> listDisabledClinicNums = new List <long>();

            if (!PrefC.HasClinicsEnabled)
            {
                return(TsiTransLogs.ValidateClinicSftpDetails(dictAllProps[0], false));
            }
            List <Clinic> listAllClinics = Clinics.GetDeepCopy();

            listDisabledClinicNums.AddRange(dictAllProps.Where(x => !TsiTransLogs.ValidateClinicSftpDetails(x.Value, false)).Select(x => x.Key));
            listDisabledClinicNums.AddRange(listAllClinics
                                            .FindAll(x => x.IsHidden || (listDisabledClinicNums.Contains(0) && !dictAllProps.ContainsKey(x.ClinicNum)))//if no props for HQ, skip other clinics without props
                                            .Select(x => x.ClinicNum)
                                            );
            return(!listDisabledClinicNums.Contains(clinicNum));
        }
Exemplo n.º 4
0
        public static PayConnectService.signatureResponse ProcessSignature(PayConnectService.signatureRequest sigRequest, long clinicNum,
                                                                           Action <string> showError)
        {
            try {
                Program prog = Programs.GetCur(ProgramName.PayConnect);
                PayConnectService.Credentials     cred = GetCredentials(prog, clinicNum);
                PayConnectService.MerchantService ms   = new PayConnectService.MerchantService();
#if DEBUG
                ms.Url = "https://prelive.dentalxchange.com/merchant/MerchantService?wsdl";
#else
                ms.Url = "https://webservices.dentalxchange.com/merchant/MerchantService?wsdl";
#endif
                PayConnectService.signatureResponse response = ms.processSignature(cred, sigRequest);
                ms.Dispose();
                if (response.Status.code != 0)               //Error
                {
                    showError(Lans.g("PayConnect", "Signature capture failed") + ". \r\n" + Lans.g("PayConnect", "Error message from") + " Pay Connect: \"" + response.Status.description + "\"");
                }
                return(response);
            }
            catch (Exception ex) {
                showError(Lans.g("PayConnect", "Signature capture failed") + ". \r\n" + Lans.g("PayConnect", "Error message from") + " Open Dental: \"" + ex.Message + "\"");
            }
            return(null);
        }
Exemplo n.º 5
0
        ///<summary>Insert Payment and PaySplit. Returns newly inserted Payment.PayNum.  Throws exceptions if PayConnect Program Properties are invalid.</summary>
        public static long InsertFromPayConnect(long patNum, long provNum, long clinicNum, double amount, string payNote, string receipt, CreditCardSource ccSource)
        {
            //No need to check RemotingRole;no call to db.
            long ret = Payments.Insert(new Payment()
            {
                ClinicNum     = clinicNum,
                IsRecurringCC = false,
                IsSplit       = false,
                PatNum        = patNum,
                PayAmt        = amount,
                PayDate       = DateTime.Now,
                PaymentSource = ccSource,
                PayType       = PIn.Long(ProgramProperties.GetPropVal(Programs.GetCur(ProgramName.PayConnect).ProgramNum, "PaymentType", clinicNum)),
                ProcessStatus = ProcessStat.OnlinePending,
                Receipt       = receipt,
                PayNote       = payNote,
            });

            PaySplits.Insert(new PaySplit()
            {
                ClinicNum = clinicNum,
                DatePay   = DateTime.Now,
                PatNum    = patNum,
                PayNum    = ret,
                ProvNum   = provNum,
                SplitAmt  = amount,
            });
            SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, patNum, Lans.g("Payments.InsertFromPayConnect", "PayConnect payment by") + " "
                                      + OpenDentBusiness.Patients.GetLim(patNum).GetNameLF() + ", " + amount.ToString("c"), LogSources.PatientPortal);
            return(ret);
        }
Exemplo n.º 6
0
        ///<summary>Returns true if either the XCharge program or PayConnect program is enabled and at least one clinic has online payments enabled.
        ///progEnabledForPayments will return the program that is enabled for online payments if it is allowed.  Both programs cannot be enabled at the same time</summary>
        public static bool HasOnlinePaymentEnabled(out ProgramName progEnabledForPayments)
        {
            progEnabledForPayments = ProgramName.None;
            Program progXCharge    = Programs.GetCur(ProgramName.Xcharge);
            Program progPayConnect = Programs.GetCur(ProgramName.PayConnect);

            if (!progXCharge.Enabled && !progPayConnect.Enabled)
            {
                return(false);
            }
            if (progXCharge.Enabled)
            {
                List <ProgramProperty> listXChargeProps = ProgramProperties.GetForProgram(progXCharge.ProgramNum);
                if (listXChargeProps.Any(x => x.PropertyDesc == "IsOnlinePaymentsEnabled" && x.PropertyValue == "1"))
                {
                    progEnabledForPayments = ProgramName.Xcharge;
                    return(true);
                }
            }
            if (progPayConnect.Enabled)
            {
                List <ProgramProperty> listPayConnectProps = ProgramProperties.GetForProgram(progPayConnect.ProgramNum);
                if (listPayConnectProps.Any(x => x.PropertyDesc == PayConnect.ProgramProperties.PatientPortalPaymentsEnabled && x.PropertyValue == "1"))
                {
                    progEnabledForPayments = ProgramName.PayConnect;
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 7
0
        ///<summary>If isRemovable is false, then the file referenced in the program property will be cleared.
        ///If isRemovable is true, then the file referenced in the program property will be deleted.</summary>
        private static void ScrubFileForProperty(ProgramName programName, string strFileProperty, string strFilePropertySuffix, bool isRemovable)
        {
            Program program = Programs.GetCur(programName);

            if (!program.Enabled)
            {
                return;
            }
            string strFileToScrub = CodeBase.ODFileUtils.CombinePaths(ProgramProperties.GetPropVal(program.ProgramNum, strFileProperty), strFilePropertySuffix);

            if (!File.Exists(strFileToScrub))
            {
                return;
            }
            try {
                File.WriteAllText(strFileToScrub, "");               //Always clear the file contents, in case deleting fails below.
            }
            catch {
                //Another instance of OD might be closing at the same time, in which case the delete will fail. Could also be a permission issue or a concurrency issue. Ignore.
            }
            if (!isRemovable)
            {
                return;
            }
            try {
                File.Delete(strFileToScrub);
            }
            catch {
                //Another instance of OD might be closing at the same time, in which case the delete will fail. Could also be a permission issue or a concurrency issue. Ignore.
            }
        }
Exemplo n.º 8
0
        ///<summary>Safe to call on any program. Only returns true if the program is not enabled
        ///AND the program has a property of "Disable Advertising" = 1 OR "Disable Advertising HQ" = 1.
        ///This means that either the office has disabled the ad or HQ has disabled the ad.</summary>
        public static bool IsAdvertisingDisabled(ProgramName progName)
        {
            Program program = Programs.GetCur(progName);

            if (program == null || program.Enabled)
            {
                return(false);               //do not block advertising
            }
            return(GetForProgram(program.ProgramNum).Any(x => (x.PropertyDesc == "Disable Advertising" && x.PropertyValue == "1") ||      //Office has decided to hide the advertising
                                                         (x.PropertyDesc == "Disable Advertising HQ" && x.PropertyValue == "1")));//HQ has decided to hide the advertising
        }
Exemplo n.º 9
0
        ///<summary>Returns true if the XCharge program is enabled and at least one clinic has online payments enabled.</summary>
        public static bool HasOnlinePaymentEnabled()
        {
            Program prog = Programs.GetCur(ProgramName.Xcharge);

            if (!prog.Enabled)
            {
                return(false);
            }
            List <ProgramProperty> listXChargeProps = ProgramProperties.GetForProgram(prog.ProgramNum);

            return(listXChargeProps.Any(x => x.PropertyDesc == "IsOnlinePaymentsEnabled" && x.PropertyValue == "1"));
        }
Exemplo n.º 10
0
        public static ErxOption GetErxOption()
        {
            Program progCur = Programs.GetCur(ProgramName.eRx);

            if (progCur == null)
            {
                throw new ODException(Lans.g("eRx", "The eRx bridge is missing from the database."));
            }
            List <ProgramProperty> listProgramProperties = ProgramProperties.GetForProgram(progCur.ProgramNum);
            ProgramProperty        propCur = listProgramProperties.FirstOrDefault(x => x.PropertyDesc == PropertyDescs.ErxOption);

            if (propCur == null)
            {
                throw new ODException(Lans.g("eRx", "The eRx Option program property is missing from the database."));
            }
            return(PIn.Enum <ErxOption>(propCur.PropertyValue));
        }
Exemplo n.º 11
0
        ///<summary>Returns the Authorization header for the api call, using the passed in clinicNum if provided, otherwise uses the currently selected clinic.</summary>
        private static string GetAuthHeader(long clinicNum = -1)
        {
            if (clinicNum == -1)
            {
                clinicNum = Clinics.ClinicNum;
            }
            string apiUserName = ProgramProperties.GetPropValForClinicOrDefault(Programs.GetCur(ProgramName.PaySimple).ProgramNum
                                                                                , PropertyDescs.PaySimpleApiUserName
                                                                                , clinicNum);
            string apiKey = ProgramProperties.GetPropValForClinicOrDefault(Programs.GetCur(ProgramName.PaySimple).ProgramNum
                                                                           , PropertyDescs.PaySimpleApiKey
                                                                           , clinicNum);

#if DEBUG
            //string apiUserName="******";
            //string apiKey="QkQRj8i0QDPOtUBhbTWx7irBrqospeY8RDC4HxW2LD3IDIfo1bcumTMomp7IJbYONjIna84QPwMwfFLMTtZcMJ2Bm4meQIfojgsDrZr5HxAnQkylHJgF7t2XUDoVy6I0";
#endif
            return(PaySimpleApi.GetAuthHeader(apiUserName, apiKey));
        }
Exemplo n.º 12
0
        ///<summary>Shows a message box on error.</summary>
        public static PayConnectService.transResponse ProcessCreditCard(PayConnectService.creditCardRequest request, long clinicNum,
                                                                        Action <string> showError)
        {
            try {
                Program prog = Programs.GetCur(ProgramName.PayConnect);
                PayConnectService.Credentials     cred = GetCredentials(prog, clinicNum);
                PayConnectService.MerchantService ms   = new PayConnectService.MerchantService();
                ms.Url = Introspection.GetOverride(Introspection.IntrospectionEntity.PayConnectRestURL, "https://webservices.dentalxchange.com/merchant/MerchantService?wsdl");
#if DEBUG
                ms.Url = "https://prelive.dentalxchange.com/merchant/MerchantService?wsdl";
#endif
                PayConnectService.transResponse response = ms.processCreditCard(cred, request);
                ms.Dispose();
                if (response.Status.code != 0 && response.Status.description.ToLower().Contains("duplicate"))
                {
                    showError(Lans.g("PayConnect", "Payment failed") + ". \r\n" + Lans.g("PayConnect", "Error message from") + " Pay Connect: \""
                              + response.Status.description + "\"\r\n"
                              + Lans.g("PayConnect", "Try using the Force Duplicate checkbox if a duplicate is intended."));
                }
                if (response.Status.code != 0 && response.Status.description.ToLower().Contains("invalid user"))
                {
                    showError(Lans.g("PayConnect", "Payment failed") + ".\r\n"
                              + Lans.g("PayConnect", "PayConnect username and password combination invalid.") + "\r\n"
                              + Lans.g("PayConnect", "Verify account settings by going to") + "\r\n"
                              + Lans.g("PayConnect", "Setup | Program Links | PayConnect. The PayConnect username and password are probably the same as the DentalXChange login ID and password."));
                }
                else if (response.Status.code != 0)               //Error
                {
                    showError(Lans.g("PayConnect", "Payment failed") + ". \r\n" + Lans.g("PayConnect", "Error message from") + " Pay Connect: \""
                              + response.Status.description + "\"");
                }
                return(response);
            }
            catch (Exception ex) {
                showError(Lans.g("PayConnect", "Payment failed") + ". \r\n" + Lans.g("PayConnect", "Error message") + ": \"" + ex.Message + "\"");
            }
            return(null);
        }
Exemplo n.º 13
0
        ///<summary>Sends an SFTP message to TSI to suspend the account for the guarantor passed in.  Returns empty string if successful.
        ///Returns a translated error message that should be displayed to the user if anything goes wrong.</summary>
        public static string SuspendGuar(Patient guar)
        {
            PatAging patAging = Patients.GetAgingListFromGuarNums(new List <long>()
            {
                guar.PatNum
            }).FirstOrDefault();

            if (patAging == null)           //this would only happen if the patient was not in the db??, just in case
            {
                return(Lans.g("TsiTransLogs", "An error occurred when trying to send a suspend message to TSI."));
            }
            long    clinicNum = (PrefC.HasClinicsEnabled?guar.ClinicNum:0);
            Program prog      = Programs.GetCur(ProgramName.Transworld);

            if (prog == null)           //shouldn't be possible, the program link should always exist, just in case
            {
                return(Lans.g("TsiTransLogs", "The Transworld program link does not exist.  Contact support."));
            }
            Dictionary <long, List <ProgramProperty> > dictAllProps = ProgramProperties.GetForProgram(prog.ProgramNum)
                                                                      .GroupBy(x => x.ClinicNum)
                                                                      .ToDictionary(x => x.Key, x => x.ToList());

            if (dictAllProps.Count == 0)           //shouldn't be possible, there should always be a set of props for ClinicNum 0 even if disabled, just in case
            {
                return(Lans.g("TsiTransLogs", "The Transworld program link is not setup properly."));
            }
            if (PrefC.HasClinicsEnabled && !dictAllProps.ContainsKey(clinicNum) && dictAllProps.ContainsKey(0))
            {
                clinicNum = 0;
            }
            string clinicDesc = clinicNum == 0?"Headquarters":Clinics.GetDesc(clinicNum);

            if (!dictAllProps.ContainsKey(clinicNum) ||
                !ValidateClinicSftpDetails(dictAllProps[clinicNum], true))                    //the props should be valid, but this will test the connection using the props
            {
                return(Lans.g("TsiTransLogs", "The Transworld program link is not enabled") + " "
                       + (PrefC.HasClinicsEnabled?(Lans.g("TsiTransLogs", "for the guarantor's clinic") + ", " + clinicDesc + ", "):"")
                       + Lans.g("TsiTransLogs", "or is not setup properly."));
            }
            List <ProgramProperty> listProps = dictAllProps[clinicNum];
            long newBillType = PrefC.GetLong(PrefName.TransworldPaidInFullBillingType);

            if (newBillType == 0 || Defs.GetDef(DefCat.BillingTypes, newBillType) == null)
            {
                return(Lans.g("TsiTransLogs", "The default paid in full billing type is not set.  An automated suspend message cannot be sent until the "
                              + "default paid in full billing type is set in the Transworld program link")
                       + (PrefC.HasClinicsEnabled?(" " + Lans.g("TsiTransLogs", "for the guarantor's clinic") + ", " + clinicDesc):"") + ".");
            }
            string clientId = "";

            if (patAging.ListTsiLogs.Count > 0)
            {
                clientId = patAging.ListTsiLogs[0].ClientId;
            }
            if (string.IsNullOrEmpty(clientId))
            {
                clientId = listProps.Find(x => x.PropertyDesc == "ClientIdAccelerator")?.PropertyValue;
            }
            if (string.IsNullOrEmpty(clientId))
            {
                clientId = listProps.Find(x => x.PropertyDesc == "ClientIdCollection")?.PropertyValue;
            }
            if (string.IsNullOrEmpty(clientId))
            {
                return(Lans.g("TsiTransLogs", "There is no client ID in the Transworld program link")
                       + (PrefC.HasClinicsEnabled?(" " + Lans.g("TsiTransLogs", "for the guarantor's clinic") + ", " + clinicDesc):"") + ".");
            }
            string sftpAddress = listProps.Find(x => x.PropertyDesc == "SftpServerAddress")?.PropertyValue ?? "";
            int    sftpPort;

            if (!int.TryParse(listProps.Find(x => x.PropertyDesc == "SftpServerPort")?.PropertyValue ?? "", out sftpPort))
            {
                sftpPort = 22;              //default to port 22
            }
            string userName     = listProps.Find(x => x.PropertyDesc == "SftpUsername")?.PropertyValue ?? "";
            string userPassword = listProps.Find(x => x.PropertyDesc == "SftpPassword")?.PropertyValue ?? "";

            if (new[] { sftpAddress, userName, userPassword }.Any(x => string.IsNullOrEmpty(x)))
            {
                return(Lans.g("TsiTransLogs", "The SFTP address, username, or password for the Transworld program link") + " "
                       + (PrefC.HasClinicsEnabled?(Lans.g("TsiTransLogs", "for the guarantor's clinic") + ", " + clinicDesc + ", "):"") + Lans.g("TsiTransLogs", "is blank."));
            }
            string msg = TsiMsgConstructor.GenerateUpdate(patAging.PatNum, clientId, TsiTransType.SS, 0.00, patAging.AmountDue);

            try {
                byte[]          fileContents = Encoding.ASCII.GetBytes(TsiMsgConstructor.GetUpdateFileHeader() + "\r\n" + msg);
                TaskStateUpload state        = new Sftp.Upload(sftpAddress, userName, userPassword, sftpPort)
                {
                    Folder        = "/xfer/incoming",
                    FileName      = "TsiUpdates_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".txt",
                    FileContent   = fileContents,
                    HasExceptions = true
                };
                state.Execute(false);
            }
            catch (Exception ex) {
                return(Lans.g("TsiTransLogs", "There was an error sending the update message to Transworld")
                       + (PrefC.HasClinicsEnabled?(" " + Lans.g("TsiTransLogs", "using the program properties for the guarantor's clinic") + ", " + clinicDesc):"") + ".\r\n"
                       + ex.Message);
            }
            //Upload was successful
            TsiTransLog log = new TsiTransLog()
            {
                PatNum    = patAging.PatNum,
                UserNum   = Security.CurUser.UserNum,
                TransType = TsiTransType.SS,
                //TransDateTime=DateTime.Now,//set on insert, not editable by user
                //DemandType=TsiDemandType.Accelerator,//only valid for placement msgs
                //ServiceCode=TsiServiceCode.Diplomatic,//only valid for placement msgs
                ClientId       = clientId,
                TransAmt       = 0.00,
                AccountBalance = patAging.AmountDue,
                FKeyType       = TsiFKeyType.None, //only used for account trans updates
                FKey           = 0,                //only used for account trans updates
                RawMsgText     = msg,
                ClinicNum      = clinicNum
                                 //,TransJson=""//only valid for placement msgs
            };

            TsiTransLogs.Insert(log);
            //update family billing type to the paid in full billing type pref
            Patients.UpdateFamilyBillingType(newBillType, patAging.PatNum);
            return("");
        }
Exemplo n.º 14
0
        ///<summary>Safe to call on any program. Only returns true if the program is not enabled
        ///AND the program has a property of "Disable Advertising" = 1 OR "Disable Advertising HQ" = 1.
        ///This means that either the office has disabled the ad or HQ has disabled the ad.</summary>
        public static bool IsAdvertisingDisabled(ProgramName progName)
        {
            Program program = Programs.GetCur(progName);

            return(IsAdvertisingDisabled(program));
        }
Exemplo n.º 15
0
        ///<summary>Called by local practice db to query HQ for EService setup info. Must remain very lite and versionless. Will be used by signup portal.
        ///If HasClinics==true then any SignupOut.EServices entries where ClinicNum==0 are invalid and should be ignored.
        ///If HasClinics==false then SignupOut.EServices should only pay attention items where ClinicNum==0.
        ///This list is kept completely unfiltered by ClinicNum for forward compatibility reasons.
        ///The ClinicNum 0 items are always used by the Signup portal to determine default signup preferences.
        ///However, these items are only used for validation and billing in the case where HasClinics==true.</summary>
        public static EServiceSetup.SignupOut GetEServiceSetupFull(SignupPortalPermission permission, bool isSwitchClinicPref = false)
        {
            //Clinics will be stored in this order at HQ to allow signup portal to display them in proper order.
            List <Clinic> clinics = Clinics.GetDeepCopy().OrderBy(x => x.ItemOrder).ToList();

            if (PrefC.GetBool(PrefName.ClinicListIsAlphabetical))
            {
                clinics = clinics.OrderBy(x => x.Abbr).ToList();
            }
#if DEBUG
            bool isMockChanged = false;
            if (WebServiceMainHQProxy.MockWebServiceMainHQ == null)
            {
                WebServiceMainHQProxy.MockWebServiceMainHQ = new WebServiceMainHQMockDemo();
                isMockChanged = true;
            }
#endif
            EServiceSetup.SignupOut signupOut = ReadXml <EServiceSetup.SignupOut>
                                                (
                WebSerializer.DeserializePrimitiveOrThrow <string>
                (
                    GetWebServiceMainHQInstance().EServiceSetup
                    (
                        CreateWebServiceHQPayload
                        (
                            WriteXml(new EServiceSetup.SignupIn()
            {
                MethodNameInt = (int)EServiceSetup.SetupMethod.GetSignupOutFull,
                HasClinics    = PrefC.HasClinicsEnabled,
                //ClinicNum is not currently used as input.
                ClinicNum                 = 0,
                ProgramVersionStr         = PrefC.GetString(PrefName.ProgramVersion),
                SignupPortalPermissionInt = (int)permission,
                Clinics = clinics
                          .Select(x => new EServiceSetup.SignupIn.ClinicLiteIn()
                {
                    ClinicNum   = x.ClinicNum,
                    ClinicTitle = x.Abbr,
                    IsHidden    = x.IsHidden,
                }).ToList(),
                IsSwitchClinicPref = isSwitchClinicPref,
            }), eServiceCode.Undefined
                        )
                    )
                )
                                                );
#if DEBUG
            if (isMockChanged)
            {
                WebServiceMainHQProxy.MockWebServiceMainHQ = null;
            }
#endif
            //We just got the latest sync info from HQ so update the local db to reflect what HQ says is true.
            #region Reconcile Phones
            List <SmsPhone> listPhonesHQ = signupOut.Phones.Select(x => new SmsPhone()
            {
                ClinicNum        = x.ClinicNum,
                CountryCode      = x.CountryCode,
                DateTimeActive   = x.DateTimeActive,
                DateTimeInactive = x.DateTimeInactive,
                InactiveCode     = x.InactiveCode,
                PhoneNumber      = x.PhoneNumber,
            }).ToList();
            SmsPhones.UpdateOrInsertFromList(listPhonesHQ);
            #endregion
            #region Reconcile practice and clinics
            List <EServiceSetup.SignupOut.SignupOutSms> smsSignups = GetSignups <EServiceSetup.SignupOut.SignupOutSms>(signupOut, eServiceCode.IntegratedTexting);
            bool isCacheInvalid = false;
            bool isSmsEnabled   = false;
            if (PrefC.HasClinicsEnabled)              //Clinics are ON so loop through all clinics and reconcile with HQ.
            {
                List <Clinic> listClinicsAll = Clinics.GetDeepCopy();
                foreach (Clinic clinicDb in listClinicsAll)
                {
                    WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms clinicSignup =
                        smsSignups.FirstOrDefault(x => x.ClinicNum == clinicDb.ClinicNum) ?? new WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms()
                    {
                        //Not found so turn it off.
                        SmsContractDate = DateTime.MinValue,
                        MonthlySmsLimit = 0,
                        IsEnabled       = false,
                    };
                    Clinic clinicNew = clinicDb.Copy();
                    clinicNew.SmsContractDate = clinicSignup.SmsContractDate;
                    clinicNew.SmsMonthlyLimit = clinicSignup.MonthlySmsLimit;
                    isCacheInvalid           |= Clinics.Update(clinicNew, clinicDb);
                    isSmsEnabled |= clinicSignup.IsEnabled;
                }
            }
            else               //Clinics are off so ClinicNum 0 is the practice clinic.
            {
                WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms practiceSignup =
                    smsSignups.FirstOrDefault(x => x.ClinicNum == 0) ?? new WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms()
                {
                    //Not found so turn it off.
                    SmsContractDate = DateTime.MinValue,
                    MonthlySmsLimit = 0,
                    IsEnabled       = false,
                };
                isCacheInvalid
                    |= Prefs.UpdateDateT(PrefName.SmsContractDate, practiceSignup.SmsContractDate)
                       | Prefs.UpdateLong(PrefName.TextingDefaultClinicNum, 0)
                       | Prefs.UpdateDouble(PrefName.SmsMonthlyLimit, practiceSignup.MonthlySmsLimit);
                isSmsEnabled |= practiceSignup.IsEnabled;
            }
            #endregion
            #region Reconcile CallFire
            //Turn off CallFire if SMS has been activated.
            //This only happens the first time SMS is turned on and CallFire is still activated.
            if (isSmsEnabled && Programs.IsEnabled(ProgramName.CallFire))
            {
                Program callfire = Programs.GetCur(ProgramName.CallFire);
                if (callfire != null)
                {
                    callfire.Enabled = false;
                    Programs.Update(callfire);
                    Signalods.Insert(new Signalod()
                    {
                        IType = InvalidType.Providers
                    });
                    signupOut.Prompts.Add("Call Fire has been disabled. Cancel Integrated Texting and access program properties to retain Call Fire.");
                }
            }
            #endregion
            #region eConfirmations
            if (Prefs.UpdateBool(PrefName.ApptConfirmAutoSignedUp, IsEServiceActive(signupOut, eServiceCode.ConfirmationRequest)))
            {
                //HQ does not match the local pref. Make it match with HQ.
                isCacheInvalid = true;
                SecurityLogs.MakeLogEntry(Permissions.Setup, 0, "Automated appointment eConfirmations automatically changed by HQ.  Local pref set to "
                                          + IsEServiceActive(signupOut, eServiceCode.ConfirmationRequest).ToString() + ".");
            }
            #endregion
            if (isCacheInvalid)              //Something changed in the db. Alert other workstations and change this workstation immediately.
            {
                Signalods.Insert(new Signalod()
                {
                    IType = InvalidType.Prefs
                });
                Prefs.RefreshCache();
                Signalods.Insert(new Signalod()
                {
                    IType = InvalidType.Providers
                });
                Providers.RefreshCache();
                Clinics.RefreshCache();
            }
            return(signupOut);
        }
Exemplo n.º 16
0
        ///<summary>For each enabled bridge, if the bridge uses a file to transmit patient data to the other software, then we need to remove the files or clear the files when OD is exiting.
        ///Required for EHR 2014 module d.7 (as stated by proctor).</summary>
        public static void ScrubExportedPatientData()
        {
            //List all program links here. If there is nothing to do for that link, then create a comment stating so.
            string path = "";

            //Apixia:
            ScrubFileForProperty(ProgramName.Apixia, "System path to Apixia Digital Imaging ini file", "", true);         //C:\Program Files\Digirex\Switch.ini
            //Apteryx: Has no file paths containing outgoing patient data from Open Dental.
            //BioPAK: Has no file paths containing outgoing patient data from Open Dental.
            //CallFire: Has no file paths containing outgoing patient data from Open Dental.
            //Camsight: Has no file paths containing outgoing patient data from Open Dental.
            //CaptureLink: Has no file paths containing outgoing patient data from Open Dental.
            //Cerec: Has no file paths containing outgoing patient data from Open Dental.
            //CliniView: Has no file paths containing outgoing patient data from Open Dental.
            //ClioSoft: Has no file paths containing outgoing patient data from Open Dental.
            //DBSWin:
            ScrubFileForProperty(ProgramName.DBSWin, "Text file path", "", true);         //C:\patdata.txt
            //DentalEye: Has no file paths containing outgoing patient data from Open Dental.
            //DentalStudio: Has no file paths containing outgoing patient data from Open Dental.
            //DentForms: Has no file paths containing outgoing patient data from Open Dental.
            //DentX: Has no file paths containing outgoing patient data from Open Dental.
            //Dexis:
            ScrubFileForProperty(ProgramName.Dexis, "InfoFile path", "", true);         //InfoFile.txt
            //Digora: Has no file paths containing outgoing patient data from Open Dental.
            //Divvy: Has no file paths containing outgoing patient data from Open Dental.
            //Dolphin:
            ScrubFileForProperty(ProgramName.Dolphin, "Filename", "", true);         //C:\Dolphin\Import\Import.txt
            //DrCeph: Has no file paths containing outgoing patient data from Open Dental.
            //Dxis: Has no file paths containing outgoing patient data from Open Dental.
            //EasyNotesPro: Has no file paths containing outgoing patient data from Open Dental.
            //eClinicalWorks: HL7 files are created, but eCW is supposed to consume and delete them.
            //EvaSoft: Has no file paths containing outgoing patient data from Open Dental.
            //EwooEZDent:
            Program program = Programs.GetCur(ProgramName.EwooEZDent);

            if (program.Enabled)
            {
                path = Programs.GetProgramPath(program);
                if (File.Exists(path))
                {
                    string dir     = Path.GetDirectoryName(path);
                    string linkage = CodeBase.ODFileUtils.CombinePaths(dir, "linkage.xml");
                    if (File.Exists(linkage))
                    {
                        try {
                            File.Delete(linkage);
                        }
                        catch {
                            //Another instance of OD might be closing at the same time, in which case the delete will fail. Could also be a permission issue or a concurrency issue. Ignore.
                        }
                    }
                }
            }
            //FloridaProbe: Has no file paths containing outgoing patient data from Open Dental.
            //Guru: Has no file paths containing outgoing patient data from Open Dental.
            //HouseCalls:
            ScrubFileForProperty(ProgramName.HouseCalls, "Export Path", "Appt.txt", true);         //C:\HouseCalls\Appt.txt
            //IAP: Has no file paths containing outgoing patient data from Open Dental.
            //iCat:
            ScrubFileForProperty(ProgramName.iCat, "XML output file path", "", true);         //C:\iCat\Out\pm.xml
            //ImageFX: Has no file paths containing outgoing patient data from Open Dental.
            //Lightyear: Has no file paths containing outgoing patient data from Open Dental.
            //MediaDent:
            ScrubFileForProperty(ProgramName.MediaDent, "Text file path", "", true);         //C:\MediadentInfo.txt
            //MiPACS: Has no file paths containing outgoing patient data from Open Dental.
            //Mountainside: Has no file paths containing outgoing patient data from Open Dental.
            //NewCrop: Has no file paths containing outgoing patient data from Open Dental.
            //Orion: Has no file paths containing outgoing patient data from Open Dental.
            //OrthoPlex: Has no file paths containing outgoing patient data from Open Dental.
            //Owandy: Has no file paths containing outgoing patient data from Open Dental.
            //PayConnect: Has no file paths containing outgoing patient data from Open Dental.
            //Patterson:
            ScrubFileForProperty(ProgramName.Patterson, "System path to Patterson Imaging ini", "", true);         //C:\Program Files\PDI\Shared files\Imaging.ini
            //PerioPal: Has no file paths containing outgoing patient data from Open Dental.
            //Planmeca: Has no file paths containing outgoing patient data from Open Dental.
            //PracticeWebReports: Has no file paths containing outgoing patient data from Open Dental.
            //Progeny: Has no file paths containing outgoing patient data from Open Dental.
            //PT: Per our website "The files involved get deleted immediately after they are consumed."
            //PTupdate: Per our website "The files involved get deleted immediately after they are consumed."
            //RayMage: Has no file paths containing outgoing patient data from Open Dental.
            //Schick: Has no file paths containing outgoing patient data from Open Dental.
            //Sirona:
            program = Programs.GetCur(ProgramName.Sirona);
            if (program.Enabled)
            {
                path = Programs.GetProgramPath(program);
                //read file C:\sidexis\sifiledb.ini
                string iniFile = Path.GetDirectoryName(path) + "\\sifiledb.ini";
                if (File.Exists(iniFile))
                {
                    string sendBox = ReadValueFromIni("FromStation0", "File", iniFile);
                    if (File.Exists(sendBox))
                    {
                        File.WriteAllText(sendBox, "");                       //Clear the sendbox instead of deleting.
                    }
                }
            }
            //Sopro: Has no file paths containing outgoing patient data from Open Dental.
            //TigerView:
            ScrubFileForProperty(ProgramName.TigerView, "Tiger1.ini path", "", false);         //C:\Program Files\PDI\Shared files\Imaging.ini.  TigerView complains if the file is not present.
            //Trojan: Has no file paths containing outgoing patient data from Open Dental.
            //Trophy: Has no file paths containing outgoing patient data from Open Dental.
            //TrophyEnhanced: Has no file paths containing outgoing patient data from Open Dental.
            //Tscan: Has no file paths containing outgoing patient data from Open Dental.
            //UAppoint: Has no file paths containing outgoing patient data from Open Dental.
            //Vipersoft: Has no file paths containing outgoing patient data from Open Dental.
            //VixWin: Has no file paths containing outgoing patient data from Open Dental.
            //VixWinBase41: Has no file paths containing outgoing patient data from Open Dental.
            //VixWinOld: Has no file paths containing outgoing patient data from Open Dental.
            //Xcharge: Has no file paths containing outgoing patient data from Open Dental.
            ScrubFileForProperty(ProgramName.XDR, "InfoFile path", "", true);         //C:\XDRClient\Bin\infofile.txt
        }