Example #1
0
        protected static void FeeTestSetup()
        {
            //Some unit tests cannot handle duplicate procedure codes being present within the database.
            //This is acceptable because that scenario should be impossible (we block the user via the UI layer).
            //Delete all duplicate procedure codes.
            Dictionary <string, ProcedureCode> dictProcCodes = ProcedureCodes.GetAllCodes().GroupBy(x => x.ProcCode).ToDictionary(x => x.Key, x => x.First());

            ProcedureCodeT.ClearProcedureCodeTable();
            foreach (ProcedureCode procedureCode in dictProcCodes.Values)
            {
                ProcedureCodes.Insert(procedureCode);
            }
            ProcedureCodes.RefreshCache();
            _listProcCodes    = ProcedureCodes.GetAllCodes();       //Just in case the PKs matter to some tests.
            _listProcCodesOld = _listProcCodes.Select(x => x.Copy()).ToList();
            if (Fees.GetCountByFeeSchedNum(_standardFeeSchedNum) <= 0)
            {
                List <Fee> listFees = new List <Fee>();
                foreach (ProcedureCode procCode in _listProcCodes)
                {
                    listFees.Add(new Fee()
                    {
                        FeeSched  = _standardFeeSchedNum,
                        CodeNum   = procCode.CodeNum,
                        Amount    = _defaultFeeAmt * _rand.NextDouble(),
                        ClinicNum = 0,
                        ProvNum   = 0
                    });                     //create the default fee schedule fee
                }
                Fees.InsertMany(listFees);
            }
        }
Example #2
0
        public static void SetUp(TestContext context)
        {
            _listProcCodes = ProcedureCodes.GetAllCodes();
            List <Fee> listFees = new List <Fee>();

            foreach (ProcedureCode procCode in _listProcCodes)
            {
                listFees.Add(new Fee()
                {
                    FeeSched  = _standardFeeSchedNum,
                    CodeNum   = procCode.CodeNum,
                    Amount    = _defaultFeeAmt * _rand.NextDouble(),
                    ClinicNum = 0,
                    ProvNum   = 0
                });                 //create the default fee schedule fee
            }
            Fees.InsertMany(listFees);
        }
Example #3
0
        ///<summary>Sets the MissingData and Warnings fields on the queueItem as appropriate.</summary>
        public static void GetMissingData(Clearinghouse clearinghouseClin, ClaimSendQueueItem queueItem)
        {
            StringBuilder sbErrors       = new StringBuilder();
            StringBuilder sbWarnings     = new StringBuilder();
            Claim         claim          = Claims.GetClaim(queueItem.ClaimNum);
            Provider      provClaimTreat = Providers.GetProv(claim.ProvTreat);
            InsSub        insSub         = InsSubs.GetOne(claim.InsSubNum);

            #region Header
            //TRNSM
            if (!Regex.IsMatch(clearinghouseClin.SenderTIN, @"^[0-9]+$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Tax ID Number (RAMQ TRNSM) is invalid");
            }
            else
            {
                int trnsm = PIn.Int(clearinghouseClin.SenderTIN);
                if (clearinghouseClin.ISA15 != "T" && trnsm >= 18000 && trnsm <= 18999)
                {
                    if (sbErrors.Length != 0)
                    {
                        sbErrors.Append(",");
                    }
                    sbErrors.Append("Tax ID Number (RAMQ TRNSM) is a test value on this production claim");
                }
                else if (clearinghouseClin.ISA15 == "T" && (trnsm < 18000 || trnsm > 18999))
                {
                    if (sbErrors.Length != 0)
                    {
                        sbErrors.Append(",");
                    }
                    sbErrors.Append("Tax ID Number (RAMQ TRNSM) must be between 18000 and 18999 for this test claim");
                }
            }
            //DISP
            if (!Regex.IsMatch(provClaimTreat.NationalProvID, @"^[27][0-9]{5}$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Claim treating provider CDA Number for RAMQ is invalid");
            }
            //DISP_REFNT
            if (claim.CanadianReferralProviderNum.Trim().Length > 0 &&
                !Regex.IsMatch(claim.CanadianReferralProviderNum.Trim(), @"^[0-9]{6}$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Referral provider CDA Number for RAMQ is invalid");
            }
            //ETAB
            if (!Regex.IsMatch(provClaimTreat.CanadianOfficeNum, @"^[0-9]{5}$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Claim treating provider Office Number for RAMQ is invalid");
            }
            //SERV
            if (claim.DateService.Year < 1880)
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Claim date of service is invalid or missing");
            }
            #endregion Header
            #region Insurance
            //Most fields in the insuranace section are optional and thus do not require validation.
            //NAM
            if (!Regex.IsMatch(insSub.SubscriberID, @"^[a-zA-Z]{4}[0-9]{6}[a-zA-Z0-9][0-9]$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Subscriber ID for RAMQ is invalid");
            }
            #endregion Insurance
            #region Procedures
            List <ProcedureCode> listProcCodes          = ProcedureCodes.GetAllCodes();
            List <ClaimProc>     listClaimProcsForPat   = ClaimProcs.Refresh(claim.PatNum);
            List <ClaimProc>     listClaimProcsForClaim = ClaimProcs.GetForSendClaim(listClaimProcsForPat, claim.ClaimNum);     //Excludes labs.
            List <Procedure>     listProcsForPat        = Procedures.Refresh(claim.PatNum);
            foreach (ClaimProc claimProc in listClaimProcsForClaim)
            {
                Procedure proc = Procedures.GetProcFromList(listProcsForPat, claimProc.ProcNum);
                if (proc.ProcFee == 0)
                {
                    continue;
                }
                ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum, listProcCodes);
                if (procCode.NoBillIns)
                {
                    continue;
                }
                //ACTE
                if (procCode.ProcCode.Length < 5 || !Regex.IsMatch(procCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$"))
                {
                    if (sbErrors.Length != 0)
                    {
                        sbErrors.Append(",");
                    }
                    sbErrors.Append("Procedure code invalid '" + procCode.ProcCode + "'");
                }
                List <Procedure> listLabProcs = Procedures.GetCanadianLabFees(proc.ProcNum, listProcsForPat);
                foreach (Procedure labProc in listLabProcs)
                {
                    if (labProc.ProcFee == 0)
                    {
                        continue;
                    }
                    ProcedureCode labProcCode = ProcedureCodes.GetProcCode(labProc.CodeNum, listProcCodes);
                    if (labProcCode.ProcCode.Length < 5 || !Regex.IsMatch(labProcCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$"))
                    {
                        if (sbErrors.Length != 0)
                        {
                            sbErrors.Append(",");
                        }
                        sbErrors.Append("Lab code invalid '" + labProcCode.ProcCode + "'");
                    }
                }
            }
            #endregion Procedures
            queueItem.MissingData = sbErrors.ToString();
            queueItem.Warnings    = sbWarnings.ToString();
        }
Example #4
0
        ///<summary>Called from Eclaims and includes multiple claims.</summary>
        public static string SendBatch(Clearinghouse clearinghouseClin, List <ClaimSendQueueItem> queueItems, int batchNum)
        {
            //STEP 1 - Build XML output.
            List <DP_RACINDP>    listDps       = new List <DP_RACINDP>();
            List <ProcedureCode> listProcCodes = ProcedureCodes.GetAllCodes();
            List <Etrans>        listEtrans    = new List <Etrans>();

            foreach (ClaimSendQueueItem queueItem in queueItems)
            {
                Etrans etrans = Etranss.SetClaimSentOrPrinted(queueItem.ClaimNum, queueItem.PatNum, clearinghouseClin.HqClearinghouseNum, EtransType.Claim_Ramq, batchNum, Security.CurUser.UserNum);
                listEtrans.Add(etrans);
                //Now we need to update our cache of claims to reflect the change that took place in the database above in Etranss.SetClaimSentOrPrinted()
                queueItem.ClaimStatus = "S";
                Claim      claim          = Claims.GetClaim(queueItem.ClaimNum);
                Provider   provClaimTreat = Providers.GetProv(claim.ProvTreat);
                DP_RACINDP dp             = new DP_RACINDP();
                #region Header
                dp.CHN           = DP_RACINDPCHN.Item06;
                dp.CHNSpecified  = true;
                dp.ENRG          = DP_RACINDPENRG.Item1;
                dp.ENRGSpecified = true;
                //We hijack the TaxID number for the TRNSM field.  The TRNSM is a office identifying number.  Test range for developers is 18000 to 18999.
                dp.TRNSM = clearinghouseClin.SenderTIN;
                dp.DISP  = provClaimTreat.NationalProvID;
                //dp.CPTE_ADMN=;//Administrative account number.  Not currently used.
                JulianCalendar calendar = new JulianCalendar();
                dp.ATTES = (DateTime.Now.Year % 10).ToString()                               //One digit for year
                           + calendar.GetDayOfYear(DateTime.Now).ToString().PadLeft(3, '0')  //3 digits for Julian day of year.
                           + (etrans.CarrierTransCounter % 1000).ToString().PadLeft(3, '0'); //3 digits for sequence number.
                dp.NCE        = (etrans.CarrierTransCounter % 10000).ToString().PadLeft(4, '0');
                dp.DISP_REFNT = claim.CanadianReferralProviderNum.Trim();
                //dp.DIAGN=;//Diagnostic code.  Not currently used.
                dp.ETAB = provClaimTreat.CanadianOfficeNum;              //Usually empty.
                //dp.ADMIS=;//Date of patient admission.  Not currently used.  This would be the same as the date of service for dental claims anyway.
                //dp.SORTI=;//Date patient discharged.  Not currently used.  This would be the same as the date of service for dental claims anyway.
                dp.TOT_DEM = claim.ClaimFee.ToString().Replace(".", "").PadLeft(6, '0');
                dp.COMPL   = TidyStr(claim.ClaimNote, 200);
                //dp.CS=;//Not sure what this is.  Not currently used.
                //dp.AUTOR=claim.PreAuthString;//Authorization number when invoicing acrylic prostheses. Required if DAT_AUTOR is present. Not currently used.
                //dp.DAT_AUTOR=claim.CanadianDateInitialLower;//Date of authorization when invoicing acrylic prostheses. Format YYMMDD. Not currently used.
                dp.SERV = claim.DateService.ToString("yyMMdd");
                #endregion Header
                #region Insurance
                //Most fields in the insuranace section are optional.
                InsSub insSub = InsSubs.GetOne(claim.InsSubNum);
                dp.PERS_ASSU     = new DP_RACINDPPERS_ASSU();
                dp.PERS_ASSU.NAM = insSub.SubscriberID;
                Patient pat = Patients.GetPat(claim.PatNum);
                dp.PERS_ASSU.PRE = TidyStr(pat.FName, 20);
                dp.PERS_ASSU.NOM = TidyStr(pat.LName, 30);
                if (pat.Birthdate.Year > 1880)
                {
                    dp.PERS_ASSU.NAISS = pat.Birthdate.ToString("yyyyMMdd");
                }
                if (pat.Gender == PatientGender.Male)
                {
                    dp.PERS_ASSU.SEXE = DP_RACINDPPERS_ASSUSEXE.M;
                }
                else if (pat.Gender == PatientGender.Female)
                {
                    dp.PERS_ASSU.SEXE = DP_RACINDPPERS_ASSUSEXE.F;
                }
                else
                {
                    //There is no value for UNKNOWN.  This field is optional if the subscriber ID is present anyway.
                }
                List <PatPlan> listPatPlans = PatPlans.Refresh(claim.PatNum);
                PatPlan        patPlan      = PatPlans.GetByInsSubNum(listPatPlans, insSub.InsSubNum);
                dp.PERS_ASSU.CAM = patPlan.PatID;
                if (insSub.DateTerm.Year > 1880)
                {
                    dp.PERS_ASSU.EXPIR_CAM = insSub.DateTerm.ToString("yyMM");
                }
                InsPlan insPlan  = InsPlans.RefreshOne(claim.PlanNum);
                InsPlan insPlan2 = InsPlans.RefreshOne(claim.PlanNum2);
                Carrier carrier  = null;
                if (claim.ClaimType == "S")
                {
                    carrier = Carriers.GetCarrier(insPlan2.CarrierNum);
                }
                else
                {
                    carrier = Carriers.GetCarrier(insPlan.CarrierNum);
                }
                if (carrier.Address.Trim() != "")
                {
                    dp.PERS_ASSU.ADR_1 = carrier.Address;
                    dp.PERS_ASSU.ADR_2 = carrier.Address2;
                    dp.PERS_ASSU.CP    = carrier.Zip;
                }
                #endregion Insurance
                #region Procedures
                List <ClaimProc>      listClaimProcsForPat   = ClaimProcs.Refresh(claim.PatNum);
                List <ClaimProc>      listClaimProcsForClaim = ClaimProcs.GetForSendClaim(listClaimProcsForPat, claim.ClaimNum);        //Excludes labs.
                List <Procedure>      listProcsForPat        = Procedures.Refresh(claim.PatNum);
                List <DP_RACINDPACTE> listProcs = new List <DP_RACINDPACTE>();
                foreach (ClaimProc claimProc in listClaimProcsForClaim)
                {
                    Procedure proc = Procedures.GetProcFromList(listProcsForPat, claimProc.ProcNum);
                    if (proc.ProcFee == 0)
                    {
                        continue;
                    }
                    ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum, listProcCodes);
                    if (procCode.NoBillIns)
                    {
                        continue;
                    }
                    DP_RACINDPACTE acteProc = new DP_RACINDPACTE();
                    acteProc.ACTE = procCode.ProcCode;
                    if (procCode.ProcCode.Length > 5)
                    {
                        acteProc.ACTE = procCode.ProcCode.Substring(0, 5);
                    }
                    acteProc.ROLE = "1";                  //1 for principal role and 2 for assistant role.
                    //acte.MODIF=;//Optional.  Not sure what to put here, so leaving blank for now.
                    acteProc.UNIT = proc.UnitQty.ToString().PadLeft(3, '0');
                    acteProc.MNT  = proc.ProcFee.ToString("F").Replace(".", "").PadLeft(6, '0');
                    acteProc.DENT = proc.ToothNum.ToString().PadLeft(2, '0');
                    acteProc.SURF = proc.Surf.ToString().PadLeft(2, '0');
                    listProcs.Add(acteProc);
                    List <Procedure> listLabProcs = Procedures.GetCanadianLabFees(proc.ProcNum, listProcsForPat);
                    foreach (Procedure labProc in listLabProcs)
                    {
                        if (labProc.ProcFee == 0)
                        {
                            continue;
                        }
                        ProcedureCode  labProcCode = ProcedureCodes.GetProcCode(labProc.CodeNum, listProcCodes);
                        DP_RACINDPACTE acteLab     = new DP_RACINDPACTE();
                        acteLab.ACTE = labProcCode.ProcCode;
                        if (labProcCode.ProcCode.Length > 5)
                        {
                            acteLab.ACTE = labProcCode.ProcCode.Substring(0, 5);
                        }
                        acteLab.ROLE = "1";                      //1 for principal role and 2 for assistant role.
                        acteLab.MNT  = labProc.ProcFee.ToString("F").Replace(".", "").PadLeft(6, '0');
                        listProcs.Add(acteLab);
                    }
                }
                dp.ACTE = listProcs.ToArray();
                #endregion Procedures
                listDps.Add(dp);
            }
            DP_RACIN batch = new DP_RACIN();
            batch.DP = listDps.ToArray();
            StringWriter  sw         = new StringWriter();
            XmlSerializer serializer = new XmlSerializer(typeof(DP_RACIN));
            serializer.Serialize(sw, batch);
            string xml = sw.ToString();
            //Save a copy of the batch xml to each etrans entry (one per claim).
            EtransMessageText etransMsgText = new EtransMessageText();
            etransMsgText.MessageText = xml;
            EtransMessageTexts.Insert(etransMsgText);
            foreach (Etrans etrans in listEtrans)
            {
                etrans.EtransMessageTextNum = etransMsgText.EtransMessageTextNum;
                Etranss.Update(etrans);
            }
            //Step 2 - ZIP XML and save to report path.  The zip file name and file name within the zip file do not matter.
            string  zipFilePath = CodeBase.ODFileUtils.CreateRandomFile(clearinghouseClin.ExportPath, ".zip", "claims");
            ZipFile zip         = null;
            try {
                zip = new ZipFile();
                zip.UseZip64WhenSaving = Zip64Option.Always;
                zip.AddEntry("claims" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xml", xml);
                zip.Save(zipFilePath);
                zip.Dispose();
            }
            catch (Exception ex) {
                ex.ToString();
                if (zip != null)
                {
                    zip.Dispose();
                }
                if (File.Exists(zipFilePath))
                {
                    try {
                        File.Delete(zipFilePath);
                    }
                    catch (Exception ex2) {
                        ex2.ToString();
                    }
                }
            }
            return(xml);
        }
Example #5
0
 public static void SetUp(TestContext context)
 {
     _listProcCodes     = ProcedureCodes.GetAllCodes();
     _listProcCodesOrig = _listProcCodes.Select(x => x.Copy()).ToList();
 }
Example #6
0
        public void Procedures_GlobalUpdateFees()
        {
            string name = MethodBase.GetCurrentMethod().Name;
            Random rand = new Random();
            //set up fees
            List <Clinic> listClinics = new List <Clinic>();

            for (int i = 0; i < 3; i++)
            {
                listClinics.Add(ClinicT.CreateClinic(name + "_" + i));
            }
            List <long> listFeeSchedNums = new List <long>();

            for (int i = 0; i < 2; i++)
            {
                listFeeSchedNums.Add(FeeSchedT.CreateFeeSched(FeeScheduleType.Normal, name + "_" + i, false));
            }
            List <long> listProvNums = new List <long>();

            for (int i = 0; i < 2; i++)
            {
                long feeSched = listFeeSchedNums[rand.Next(listFeeSchedNums.Count - 1)];
                listProvNums.Add(ProviderT.CreateProvider(name + "_" + i, feeSchedNum: feeSched));
            }
            List <ProcedureCode> listProcCodes = ProcedureCodes.GetAllCodes();
            List <Fee>           listFees      = new List <Fee>();

            foreach (ProcedureCode procCode in listProcCodes)
            {
                foreach (long feeSched in listFeeSchedNums)
                {
                    foreach (Clinic clinic in listClinics)
                    {
                        foreach (long provNum in listProvNums)
                        {
                            listFees.Add(FeeT.GetNewFee(feeSched, procCode.CodeNum, 50 * rand.NextDouble(), clinic.ClinicNum, provNum));
                        }
                    }
                }
            }
            //set up patients
            List <Patient> listPatients = new List <Patient>();

            for (int i = 0; i < 3; i++)
            {
                listPatients.Add(PatientT.CreatePatient(name + "_" + i,
                                                        listProvNums[rand.Next(listProvNums.Count - 1)],
                                                        listClinics[rand.Next(listClinics.Count - 1)].ClinicNum));
            }
            //TP some procedures
            List <Fee> listTPFees = new List <Fee>();

            for (int i = 0; i < 100; i++)
            {
                ProcedureCode procCode = listProcCodes[rand.Next(listProcCodes.Count - 1)];
                Patient       patient  = listPatients[rand.Next(listPatients.Count - 1)];
                Fee           fee      = Fees.GetFee(procCode.CodeNum, Providers.GetProv(patient.PriProv).FeeSched, patient.ClinicNum, patient.PriProv);
                Procedure     proc     = ProcedureT.CreateProcedure(patient, procCode.ProcCode, ProcStat.TP, "", fee.Amount);
                listTPFees.Add(fee);
            }
            //change some of the fees
            List <Fee> listTPFeesChanged    = listTPFees.OrderBy(x => rand.Next()).Take(50).ToList();
            List <Fee> listNonTPFeesChanged = (listFees.Except(listTPFees)).OrderBy(x => rand.Next()).Take(50).ToList();
            FeeCache   cache = new FeeCache(listTPFeesChanged.Union(listNonTPFeesChanged).ToList());

            cache.BeginTransaction();
            foreach (Fee fee in listTPFeesChanged)
            {
                fee.Amount = 50 * rand.NextDouble();
                cache.Update(fee);
            }
            foreach (Fee fee in listNonTPFeesChanged)
            {
                fee.Amount = 50 * rand.NextDouble();
                cache.Update(fee);
            }
            cache.SaveToDb();
            //Run the global update
            long updatedCount = 0;

            cache = new FeeCache();
            for (int i = 0; i < listClinics.Count; i++)
            {
                updatedCount += Procedures.GlobalUpdateFees(cache.GetFeesForClinics(listClinics.Select(x => x.ClinicNum)), listClinics[i].ClinicNum, listClinics[i].Abbr);
            }
            //check the counts are the same
            List <Fee> listToCount = listTPFees.Where(x => listTPFeesChanged.Select(y => y.FeeNum).Contains(x.FeeNum)).ToList();

            Assert.AreEqual(listToCount.Count, updatedCount);
        }
Example #7
0
 public static void SetUp(TestContext context)
 {
     _listProcCodes = ProcedureCodes.GetAllCodes();
 }
Example #8
0
        ///<summary>Sets the MissingData and Warnings fields on the queueItem as appropriate.</summary>
        public static void GetMissingData(ClaimSendQueueItem queueItem)
        {
            StringBuilder sbErrors       = new StringBuilder();
            StringBuilder sbWarnings     = new StringBuilder();
            Claim         claim          = Claims.GetClaim(queueItem.ClaimNum);
            Provider      provClaimTreat = Providers.GetProv(claim.ProvTreat);
            InsSub        insSub         = InsSubs.GetOne(claim.InsSubNum);
            Patient       pat            = Patients.GetPat(claim.PatNum);

            #region Header
            //DISP
            if (!Regex.IsMatch(provClaimTreat.NationalProvID, @"^[27][0-9]{5}$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Claim treating provider ID for RAMQ is invalid");
            }
            //DISP_REFNT
            if (claim.CanadianReferralProviderNum.Trim().Length > 0 &&
                !Regex.IsMatch(claim.CanadianReferralProviderNum.Trim(), @"^[0-9]{6}$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Referral provider ID for RAMQ is invalid");
            }
            //ETAB
            if (!Regex.IsMatch(provClaimTreat.CanadianOfficeNum, @"^[0-9]{5}$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Claim treating provider office number is invalid");
            }
            //SERV
            if (claim.DateService.Year < 1880)
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Claim date of service is invalid or missing");
            }
            #endregion Header
            #region Insurance
            //Most fields in the insuranace section are optional and thus do not require validation.
            //NAM
            if (!Regex.IsMatch(insSub.SubscriberID, @"^[a-zA-Z]{4}[0-9]{6}[a-zA-Z0-9][0-9]$"))
            {
                if (sbErrors.Length != 0)
                {
                    sbErrors.Append(",");
                }
                sbErrors.Append("Subscriber ID invalid");
            }
            #endregion Insurance
            #region Procedures
            List <ProcedureCode> listProcCodes          = ProcedureCodes.GetAllCodes();
            List <ClaimProc>     listClaimProcsForPat   = ClaimProcs.Refresh(claim.PatNum);
            List <ClaimProc>     listClaimProcsForClaim = ClaimProcs.GetForSendClaim(listClaimProcsForPat, claim.ClaimNum);     //Excludes labs.
            List <Procedure>     listProcsForPat        = Procedures.Refresh(claim.PatNum);
            foreach (ClaimProc claimProc in listClaimProcsForClaim)
            {
                Procedure proc = Procedures.GetProcFromList(listProcsForPat, claimProc.ProcNum);
                if (proc.ProcFee == 0)
                {
                    continue;
                }
                ProcedureCode procCode = ProcedureCodes.GetProcCode(proc.CodeNum, listProcCodes);
                if (procCode.NoBillIns)
                {
                    continue;
                }
                //ACTE
                if (procCode.ProcCode.Length < 5 || !Regex.IsMatch(procCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$"))
                {
                    if (sbErrors.Length != 0)
                    {
                        sbErrors.Append(",");
                    }
                    sbErrors.Append("Procedure code invalid '" + procCode.ProcCode + "'");
                }
                List <Procedure> listLabProcs = Procedures.GetCanadianLabFees(proc.ProcNum, listProcsForPat);
                foreach (Procedure labProc in listLabProcs)
                {
                    if (labProc.ProcFee == 0)
                    {
                        continue;
                    }
                    ProcedureCode labProcCode = ProcedureCodes.GetProcCode(labProc.CodeNum, listProcCodes);
                    if (labProcCode.ProcCode.Length < 5 || !Regex.IsMatch(labProcCode.ProcCode.Substring(0, 5), @"^[0-9]{5}$"))
                    {
                        if (sbErrors.Length != 0)
                        {
                            sbErrors.Append(",");
                        }
                        sbErrors.Append("Lab code invalid '" + labProcCode.ProcCode + "'");
                    }
                }
            }
            #endregion Procedures
            queueItem.MissingData = sbErrors.ToString();
            queueItem.Warnings    = sbWarnings.ToString();
        }