示例#1
0
        /// <summary>Getting the balance from the messages from the patAging object using logs.</summary>
        public static double GetBalFromMsgs(PatAging patAging)
        {
            TsiTransLog placeLog = patAging.ListTsiLogs.FirstOrDefault(x => x.TransType == TsiTransType.PL);

            if (placeLog == null)
            {
                return(0);               //should never happen, this is a collection guarantor so there must be a placement log
            }
            return(placeLog.AccountBalance +
                   patAging.ListTsiLogs
                   .Where(x => x.TransDateTime > placeLog.TransDateTime &&
                          !x.TransType.In(TsiTransType.PL, TsiTransType.RI, TsiTransType.SS, TsiTransType.CN, TsiTransType.Agg, TsiTransType.Excluded))
                   .Sum(x => x.TransAmt));
        }
示例#2
0
        ///<summary>Returns a message string used to place a patient or guarantor account with TSI for collection.</summary>
        public static string GeneratePlacement(PatAging patAge, string clientID, DateTime dateBalBegan, TsiDemandType demandType)
        {
            Family  fam  = Patients.GetFamily(patAge.PatNum);
            Patient pat  = fam.ListPats.FirstOrDefault(x => x.PatNum == patAge.PatNum);
            Patient guar = fam.ListPats[0];

            if (pat == null || guar == null)
            {
                throw new ApplicationException("Invalid PatNum.  Please contact support.");
            }
            string[] fieldVals = new string[33] {
                clientID,
                "",                //since PatNums can be larger than 10 digits, we will send in field 3 which can hold up to 20 digits
                POut.Long(patAge.Guarantor),
                guar.GetNameLFnoPref(),
                guar.Address,
                guar.Address2,
                guar.City,
                guar.State,
                guar.Zip,
                guar.HmPhone,
                guar.WirelessPhone,
                guar.SSN,
                guar.Birthdate.ToString("MMddyyyy"),
                gGetPatType(guar, pat),
                pat.FName,
                pat.LName,
                pat.HmPhone,
                pat.WirelessPhone,
                pat.Birthdate.ToString("MMddyyyy"),
                pat.SSN,
                pat.Address,
                pat.Address2,
                pat.City,
                pat.State,
                pat.Zip,
                pat.Country,                                     //country will be blank unless HQ
                gGetLanguageString(pat.Language),                //will be blank if not set
                dateBalBegan.ToString("MMddyyyy"),
                POut.Double(patAge.AmountDue),                   //POut.Double so it will be in the format XXX.XX with 2 decimal places,
                patAge.DateLastPay.ToString("MMddyyyy"),
                Math.Max((int)demandType, 1).ToString(),         //(enum 0 based, send 1 for Accelerator - 0 and ProfitRecovery - 1) 1 - AcceleratorPr, 2 - Collection
                ((int)TsiServiceCode.Diplomatic + 1).ToString(), //(enum 0 based, plus 1 to send to TSI) 1 - Diplomatic, 2 - Intensive or 3 - Bad Check.
                "Transferred to TSI"
            };
            return(fieldVals.Aggregate((a, b) => (a ?? "") + "|" + (b ?? "")));
        }
示例#3
0
        private static void InsertTsiLogsForAdjustment(long patGuar, Adjustment adj, string msgText, TsiTransType transType)
        {
            //insert tsitranslog for this transaction so the ODService won't send it to Transworld.  _isTsiAdj means Transworld received a payment on
            //behalf of this guar and took a percentage and send the rest to the office for the account.  This will result in a payment being entered
            //into the account, having been received from Transworld, and an adjustment to account for Transorld's cut.
            PatAging patAgingCur = Patients.GetAgingListFromGuarNums(new List <long>()
            {
                patGuar
            }).FirstOrDefault();                                                                                              //should only ever be 1

            if (patAgingCur == null)
            {
                return;
            }
            double offsetAmt = adj.AdjAmt - patAgingCur.ListTsiLogs.FindAll(x => x.FKeyType == TsiFKeyType.Adjustment && x.FKey == adj.AdjNum).Sum(x => x.TransAmt);

            if (offsetAmt.IsZero())
            {
                return;
            }
            double balFromMsgs = GetBalFromMsgs(patAgingCur);

            if (balFromMsgs.IsZero())
            {
                return;
            }
            Insert(new TsiTransLog()
            {
                PatNum    = patAgingCur.PatNum,
                UserNum   = Security.CurUser.UserNum,
                TransType = transType,
                //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       = patAgingCur.ListTsiLogs.FirstOrDefault()?.ClientId ?? "",      //can be blank, not used since this isn't really sent to Transworld
                TransAmt       = offsetAmt,
                AccountBalance = balFromMsgs + (transType == TsiTransType.Excluded?0:offsetAmt),
                FKeyType       = TsiFKeyType.Adjustment,
                FKey           = adj.AdjNum,
                RawMsgText     = msgText,
                //TransJson=""//only valid for placement msgs
                ClinicNum = (PrefC.HasClinicsEnabled?patAgingCur.ClinicNum:0)
            });
        }
示例#4
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("");
        }