Esempio n. 1
0
        /// <summary>Only used from FormInsPlan. Throws ApplicationException if any dependencies. This is quite complex, because it also must update all claimprocs for all patients affected by the deletion.  Also deletes patplans, benefits, and claimprocs.</summary>
        public static void Delete(InsPlan plan)
        {
            //first, check claims
            string command = "SELECT PatNum FROM claim "
                             + "WHERE plannum = '" + plan.PlanNum.ToString() + "' ";

            if (FormChooseDatabase.DBtype == DatabaseType.Oracle)
            {
                command += "AND ROWNUM<=1";
            }
            else              //Assume MySQL
            {
                command += "LIMIT 1";
            }
            DataTable table = General.GetTable(command);

            if (table.Rows.Count != 0)
            {
                throw new ApplicationException(Lan.g("FormInsPlan", "Not allowed to delete a plan with existing claims."));
            }
            //then, check claimprocs
            command = "SELECT PatNum FROM claimproc "
                      + "WHERE PlanNum = " + POut.PInt(plan.PlanNum)
                      + " AND Status != 6 ";         //ignore estimates
            if (FormChooseDatabase.DBtype == DatabaseType.Oracle)
            {
                command += "AND ROWNUM<=1";
            }
            else              //Assume MySQL
            {
                command += "LIMIT 1";
            }
            table = General.GetTable(command);
            if (table.Rows.Count != 0)
            {
                throw new ApplicationException(Lan.g("FormInsPlan", "Not allowed to delete a plan attached to procedures."));
            }
            //get a list of all patplans with this planNum
            command = "SELECT PatPlanNum FROM patplan "
                      + "WHERE PlanNum = " + plan.PlanNum.ToString();
            table = General.GetTable(command);
            for (int i = 0; i < table.Rows.Count; i++)
            {
                //benefits with this PatPlanNum are also deleted here
                PatPlans.Delete(PIn.PInt(table.Rows[i][0].ToString()));
            }
            command = "DELETE FROM benefit WHERE PlanNum=" + POut.PInt(plan.PlanNum);
            General.NonQ(command);
            command = "DELETE FROM claimproc WHERE PlanNum=" + POut.PInt(plan.PlanNum);        //just estimates
            General.NonQ(command);
            command = "DELETE FROM insplan "
                      + "WHERE PlanNum = '" + plan.PlanNum.ToString() + "'";
            General.NonQ(command);
        }
Esempio n. 2
0
        private void Import834_Unsafe()
        {
            if (!MsgBox.Show(this, true, "Importing insurance plans is a database intensive operation and can take 10 minutes or more to run.  "
                             + "It is best to import insurance plans after hours or during another time period when database usage is otherwise low.\r\n"
                             + "Click OK to import insurance plans now, or click Cancel."))
            {
                return;
            }
            checkIsPatientCreate.Enabled = false;
            gridInsPlans.Enabled         = false;
            butOK.Enabled     = false;
            butCancel.Enabled = false;
            Cursor            = Cursors.WaitCursor;
            Prefs.UpdateBool(PrefName.Ins834IsPatientCreate, checkIsPatientCreate.Checked);
            int           rowIndex             = 1;
            int           createdPatsCount     = 0;
            int           updatedPatsCount     = 0;
            int           skippedPatsCount     = 0;
            int           createdCarrierCount  = 0;
            int           createdPlanCount     = 0;
            int           droppedPlanCount     = 0;
            int           updatedPlanCount     = 0;
            StringBuilder sbErrorMessages      = new StringBuilder();
            List <int>    listImportedSegments = new List <int> ();      //Used to reconstruct the 834 with imported patients removed.

            for (int i = 0; i < _x834.ListTransactions.Count; i++)
            {
                Hx834_Tran tran = _x834.ListTransactions[i];
                for (int j = 0; j < tran.ListMembers.Count; j++)
                {
                    Hx834_Member member = tran.ListMembers[j];
                    ShowStatus("Progress " + (rowIndex).ToString().PadLeft(6) + "/" + gridInsPlans.Rows.Count.ToString().PadLeft(6)
                               + "  Importing plans for patient " + member.Pat.GetNameLF());
                    //The patient's status is not affected by the maintenance code.  After reviewing all of the possible maintenance codes in
                    //member.MemberLevelDetail.MaintenanceTypeCode, we believe that all statuses suggest either insert or update, except for "Cancel".
                    //Nathan and Derek feel that archiving the patinet in response to a Cancel request is a bit drastic.
                    //Thus we ignore the patient maintenance code and always assume insert/update.
                    //Even if the status was "Cancel", then updating the patient does not hurt.
                    bool isMemberImported = false;
                    bool isMultiMatch     = false;
                    if (member.Pat.PatNum == 0)
                    {
                        //The patient may need to be created below.  However, the patient may have already been inserted in a pervious iteration of this loop
                        //in following scenario: Two different 834s include updates for the same patient and both documents are being imported at the same time.
                        //If the patient was already inserted, then they would show up in _listPatients and also in the database.  Attempt to locate the patient
                        //in _listPatients again before inserting.
                        List <Patient> listPatientMatches = Patients.GetPatientsByNameAndBirthday(member.Pat, _listPatients);
                        if (listPatientMatches.Count == 1)
                        {
                            member.Pat.PatNum = listPatientMatches[0].PatNum;
                        }
                        else if (listPatientMatches.Count > 1)
                        {
                            isMultiMatch = true;
                        }
                    }
                    if (isMultiMatch)
                    {
                        skippedPatsCount++;
                    }
                    else if (member.Pat.PatNum == 0 && checkIsPatientCreate.Checked)
                    {
                        //The code here mimcs the behavior of FormPatientSelect.butAddPt_Click().
                        Patients.Insert(member.Pat, false);
                        Patient memberPatOld = member.Pat.Copy();
                        member.Pat.PatStatus   = PatientStatus.Patient;
                        member.Pat.BillingType = PrefC.GetLong(PrefName.PracticeDefaultBillType);
                        if (!PrefC.GetBool(PrefName.PriProvDefaultToSelectProv))
                        {
                            //Set the patients primary provider to the practice default provider.
                            member.Pat.PriProv = Providers.GetDefaultProvider().ProvNum;
                        }
                        member.Pat.ClinicNum = Clinics.ClinicNum;
                        member.Pat.Guarantor = member.Pat.PatNum;
                        Patients.Update(member.Pat, memberPatOld);
                        int patIdx    = _listPatients.BinarySearch(member.Pat); //Preserve sort order by locating the index in which to insert the newly added patient.
                        int insertIdx = ~patIdx;                                //According to MSDN, the index returned by BinarySearch() is a "bitwise compliment", since not currently in list.
                        _listPatients.Insert(insertIdx, member.Pat);
                        SecurityLogs.MakeLogEntry(Permissions.PatientCreate, member.Pat.PatNum, "Created from Import Ins Plans 834.", LogSources.InsPlanImport834);
                        isMemberImported = true;
                        createdPatsCount++;
                    }
                    else if (member.Pat.PatNum == 0 && !checkIsPatientCreate.Checked)
                    {
                        skippedPatsCount++;
                    }
                    else                                                                                  //member.Pat.PatNum!=0
                    {
                        Patient patDb = _listPatients.FirstOrDefault(x => x.PatNum == member.Pat.PatNum); //Locate by PatNum, in case user selected manually.
                        member.MergePatientIntoDbPatient(patDb);                                          //Also updates the patient to the database and makes log entry.
                        _listPatients.Remove(patDb);                                                      //Remove patient from list so we can add it back in the correct location (in case name or bday changed).
                        int patIdx = _listPatients.BinarySearch(patDb);                                   //Preserve sort order by locating the index in which to insert the newly added patient.
                        //patIdx could be positive if the user manually selected a patient when there were multiple matches found.
                        //If patIdx is negative, then according to MSDN, the index returned by BinarySearch() is a "bitwise compliment".
                        //If there were mult instances of patDb BinarySearch() would return 0, which should not be complimented (OutOfRangeException)
                        int insertIdx = (patIdx >= 0)?patIdx:~patIdx;
                        _listPatients.Insert(insertIdx, patDb);
                        isMemberImported = true;
                        updatedPatsCount++;
                    }
                    if (isMemberImported)
                    {
                        //Import insurance changes for patient.
                        for (int k = 0; k < member.ListHealthCoverage.Count; k++)
                        {
                            Hx834_HealthCoverage healthCoverage = member.ListHealthCoverage[k];
                            if (k > 0)
                            {
                                rowIndex++;
                            }
                            List <Carrier> listCarriers = Carriers.GetByNameAndTin(tran.Payer.Name, tran.Payer.IdentificationCode);
                            if (listCarriers.Count == 0)
                            {
                                Carrier carrier = new Carrier();
                                carrier.CarrierName = tran.Payer.Name;
                                carrier.TIN         = tran.Payer.IdentificationCode;
                                Carriers.Insert(carrier);
                                DataValid.SetInvalid(InvalidType.Carriers);
                                listCarriers.Add(carrier);
                                SecurityLogs.MakeLogEntry(Permissions.CarrierCreate, 0, "Carrier '" + carrier.CarrierName
                                                          + "' created from Import Ins Plans 834.", LogSources.InsPlanImport834);
                                createdCarrierCount++;
                            }
                            //Update insurance plans.  Match based on carrier and SubscriberId.
                            bool isDropping = false;
                            if (healthCoverage.HealthCoverage.MaintenanceTypeCode == "002")
                            {
                                isDropping = true;
                            }
                            //The insPlanNew will only be inserted if necessary.  Created temporarily in order to determine if insert is needed.
                            InsPlan insPlanNew = InsertOrUpdateInsPlan(null, member, listCarriers[0], false);
                            //Since the insurance plans in the 834 do not include very much information, it is likely that many patients will share the same exact plan.
                            //We look for an existing plan being used by any other patinents which match the fields we typically import.
                            List <InsPlan> listInsPlans = InsPlans.GetAllByCarrierNum(listCarriers[0].CarrierNum);
                            InsPlan        insPlanMatch = null;
                            for (int p = 0; p < listInsPlans.Count; p++)
                            {
                                //Set the PlanNums equal so that AreEqualValue() will ignore this field.  We must ignore PlanNum, since we do not know the PlanNum.
                                insPlanNew.PlanNum = listInsPlans[p].PlanNum;
                                if (InsPlans.AreEqualValue(listInsPlans[p], insPlanNew))
                                {
                                    insPlanMatch = listInsPlans[p];
                                    break;
                                }
                            }
                            Family         fam          = Patients.GetFamily(member.Pat.PatNum);
                            List <InsSub>  listInsSubs  = InsSubs.RefreshForFam(fam);
                            List <PatPlan> listPatPlans = PatPlans.Refresh(member.Pat.PatNum);
                            InsSub         insSubMatch  = null;
                            PatPlan        patPlanMatch = null;
                            for (int p = 0; p < listInsSubs.Count; p++)
                            {
                                InsSub insSub = listInsSubs[p];
                                //According to section 1.4.3 of the standard, the preferred method of matching a dependent to a subscriber is to use the subscriberId.
                                if (insSub.SubscriberID.Trim() != member.SubscriberId.Trim())
                                {
                                    continue;
                                }
                                insSubMatch  = insSub;
                                patPlanMatch = PatPlans.GetFromList(listPatPlans, insSub.InsSubNum);
                                break;
                            }
                            if (patPlanMatch == null && isDropping)                           //No plan match and dropping plan.
                            //Nothing to do.  The plan either never existed or is already dropped.
                            {
                            }
                            else if (patPlanMatch == null && !isDropping)                           //No plan match and not dropping plan.  Create the plan.
                            {
                                insPlanMatch = InsertOrUpdateInsPlan(insPlanMatch, member, listCarriers[0]);
                                insSubMatch  = InsertOrUpdateInsSub(insSubMatch, insPlanMatch, member, healthCoverage, listCarriers[0]);
                                patPlanMatch = InsertOrUpdatePatPlan(patPlanMatch, insSubMatch, insPlanMatch, member, listCarriers[0], listPatPlans);
                                createdPlanCount++;
                            }
                            else if (patPlanMatch != null && isDropping)                           //Plan matched and dropping plan.  Drop the plan.
                            //This code mimics the behavior of FormInsPlan.butDrop_Click(), except here we do not care if there are claims for this plan today.
                            //We need this feature to be as streamlined as possible so that it might become an automated process later.
                            //Testing for claims on today's date does not seem that useful anyway, or at least not as useful as checking for any claims
                            //associated to the plan, instead of just today's date.
                            {
                                PatPlans.Delete(patPlanMatch.PatPlanNum);                                //Estimates recomputed within Delete()
                                SecurityLogs.MakeLogEntry(Permissions.InsPlanDropPat, patPlanMatch.PatNum,
                                                          "Insurance plan dropped from patient for carrier '" + listCarriers[0].CarrierName + "' and groupnum "
                                                          + "'" + insPlanMatch.GroupNum + "' and subscriber ID '" + insSubMatch.SubscriberID + "' "
                                                          + "from Import Ins Plans 834.", insPlanMatch.PlanNum, LogSources.InsPlanImport834, insPlanMatch.SecDateTEdit);
                                droppedPlanCount++;
                            }
                            else if (patPlanMatch != null && !isDropping)                            //Plan matched and not dropping plan.  Update the plan.
                            {
                                insPlanMatch = InsertOrUpdateInsPlan(insPlanMatch, member, listCarriers[0]);
                                insSubMatch  = InsertOrUpdateInsSub(insSubMatch, insPlanMatch, member, healthCoverage, listCarriers[0]);
                                patPlanMatch = InsertOrUpdatePatPlan(patPlanMatch, insSubMatch, insPlanMatch, member, listCarriers[0], listPatPlans);
                                updatedPlanCount++;
                            }
                        }                        //end loop k
                        //Remove the member from the X834.
                        int endSegIndex = 0;
                        if (j < tran.ListMembers.Count - 1)
                        {
                            endSegIndex = tran.ListMembers[j + 1].MemberLevelDetail.SegmentIndex - 1;
                        }
                        else
                        {
                            X12Segment segSe = _x834.GetNextSegmentById(member.MemberLevelDetail.SegmentIndex + 1, "SE");                       //SE segment is required.
                            endSegIndex = segSe.SegmentIndex - 1;
                        }
                        for (int s = member.MemberLevelDetail.SegmentIndex; s <= endSegIndex; s++)
                        {
                            listImportedSegments.Add(s);
                        }
                    }
                    rowIndex++;
                }                                                       //end loop j
            }                                                           //end loop i
            if (listImportedSegments.Count > 0 && skippedPatsCount > 0) //Some patients imported, while others did not.
            {
                if (MoveFileToArchiveFolder())
                {
                    //Save the unprocessed members back to the import directory, so the user can try to import them again.
                    File.WriteAllText(_x834.FilePath, _x834.ReconstructRaw(listImportedSegments));
                }
            }
            else if (listImportedSegments.Count > 0)             //All patinets imported.
            {
                MoveFileToArchiveFolder();
            }
            else if (skippedPatsCount > 0)             //No patients imported.  All patients were skipped.
            //Leave the raw file unaltered and where it is, so it can be processed again.
            {
            }
            Cursor = Cursors.Default;
            string msg = Lan.g(this, "Done.");

            if (createdPatsCount > 0)
            {
                msg += "\r\n" + Lan.g(this, "Number of patients created:") + " " + createdPatsCount;
            }
            if (updatedPatsCount > 0)
            {
                msg += "\r\n" + Lan.g(this, "Number of patients updated:") + " " + updatedPatsCount;
            }
            if (skippedPatsCount > 0)
            {
                msg += "\r\n" + Lan.g(this, "Number of patients skipped:") + " " + skippedPatsCount;
                msg += sbErrorMessages.ToString();
            }
            if (createdCarrierCount > 0)
            {
                msg += "\r\n" + Lan.g(this, "Number of carriers created:") + " " + createdCarrierCount;
                msg += sbErrorMessages.ToString();
            }
            if (createdPlanCount > 0)
            {
                msg += "\r\n" + Lan.g(this, "Number of plans created:") + " " + createdPlanCount;
                msg += sbErrorMessages.ToString();
            }
            if (droppedPlanCount > 0)
            {
                msg += "\r\n" + Lan.g(this, "Number of plans dropped:") + " " + droppedPlanCount;
                msg += sbErrorMessages.ToString();
            }
            if (updatedPlanCount > 0)
            {
                msg += "\r\n" + Lan.g(this, "Number of plans updated:") + " " + updatedPlanCount;
                msg += sbErrorMessages.ToString();
            }
            MsgBoxCopyPaste msgBox = new MsgBoxCopyPaste(msg);

            msgBox.ShowDialog();
        }