private void butOK_Click(object sender, EventArgs e) { if (!CheckBeginDateTime()) { return; } //If the AvaTax API is not available at HQ show popup and return. if (AvaTax.IsEnabled() && !AvaTax.PingAvaTax()) { MsgBox.Show(this, "Unable to connect to AvaTax API."); return; } Cursor = Cursors.WaitCursor; RepeatChargeResult result = RepeatCharges.RunRepeatingCharges(MiscData.GetNowDateTime(), checkRunAging.Checked); string metrics = result.ProceduresAddedCount + " " + Lan.g(this, "procedures added.") + "\r\n" + result.ClaimsAddedCount + " " + Lan.g(this, "claims added."); SecurityLogs.MakeLogEntry(Permissions.RepeatChargeTool, 0, "Repeat Charge Tool ran.\r\n" + metrics); Cursor = Cursors.Default; MessageBox.Show(metrics); if (!string.IsNullOrEmpty(result.ErrorMsg)) { SecurityLogs.MakeLogEntry(Permissions.RepeatChargeTool, 0, "Repeat Charge Tool Error: " + result.ErrorMsg); MessageBox.Show(result.ErrorMsg); } DialogResult = DialogResult.OK; }
private void butOK_Click(object sender, System.EventArgs e) { RepeatCharge[] chargeList = RepeatCharges.Refresh(0); int countAdded = 0; DateTime possibleDate; Procedure proc; for (int i = 0; i < chargeList.Length; i++) { if (chargeList[i].DateStart > DateTime.Today) //not started yet { continue; } //if(chargeList[i].DateStop.Year>1880//not blank // && chargeList[i].DateStop<DateTime.Today)//but already ended //{ // continue; //} //get a list dates of all completed procedures with this Code and patNum ArrayList ALdates = RepeatCharges.GetDates(ProcedureCodes.GetCodeNum(chargeList[i].ProcCode), chargeList[i].PatNum); possibleDate = chargeList[i].DateStart; //start looping through possible dates, beginning with the start date of the repeating charge while (possibleDate <= DateTime.Today) { if (possibleDate < DateTime.Today.AddMonths(-3)) { possibleDate = possibleDate.AddMonths(1); continue; //don't go back more than three months } //check to see if the possible date is present in the list if (ALdates.Contains(possibleDate)) { possibleDate = possibleDate.AddMonths(1); continue; } if (chargeList[i].DateStop.Year > 1880 && //not blank chargeList[i].DateStop < possibleDate) //but already ended { break; } //otherwise, insert a procedure to db proc = new Procedure(); proc.CodeNum = ProcedureCodes.GetCodeNum(chargeList[i].ProcCode); proc.DateEntryC = DateTime.Today; proc.PatNum = chargeList[i].PatNum; proc.ProcDate = possibleDate; proc.DateTP = possibleDate; proc.ProcFee = chargeList[i].ChargeAmt; proc.ProcStatus = ProcStat.C; proc.ProvNum = PrefC.GetLong(PrefName.PracticeDefaultProv); proc.MedicalCode = ProcedureCodes.GetProcCode(proc.CodeNum).MedicalCode; proc.BaseUnits = ProcedureCodes.GetProcCode(proc.CodeNum).BaseUnits; Procedures.Insert(proc); //no recall synch needed because dental offices don't use this feature countAdded++; possibleDate = possibleDate.AddMonths(1); } } MessageBox.Show(countAdded.ToString() + " " + Lan.g(this, "procedures added.")); DialogResult = DialogResult.OK; }
private void butOK_Click(object sender, System.EventArgs e) { if (textChargeAmt.errorProvider1.GetError(textChargeAmt) != "" || textDateStart.errorProvider1.GetError(textDateStart) != "" || textDateStop.errorProvider1.GetError(textDateStop) != "" ) { MsgBox.Show(this, "Please fix data entry errors first."); return; } if (textDateStart.Text == "") { MsgBox.Show(this, "Start date cannot be left blank."); return; } if (PIn.PDate(textDateStart.Text) < DateTime.Today.AddMonths(-1)) { MsgBox.Show(this, "Start date cannot be more than a month in the past. But you can still enter previous charges manually in the account."); return; } RepeatCur.ADACode = textADACode.Text; RepeatCur.ChargeAmt = PIn.PDouble(textChargeAmt.Text); RepeatCur.DateStart = PIn.PDate(textDateStart.Text); RepeatCur.DateStop = PIn.PDate(textDateStop.Text); RepeatCur.Note = textNote.Text; if (IsNew) { RepeatCharges.Insert(RepeatCur); } else { RepeatCharges.Update(RepeatCur); } DialogResult = DialogResult.OK; }
private void CreateChargeList() { #region Parse CSV _listNewCropCharges = new List <NewCropCharge>(); string csvData = File.ReadAllText(textBillingFilePath.Text); string[] arrayCsvLines = csvData.Split(new string[] { "\r\n" }, StringSplitOptions.None); for (int i = 2; i < arrayCsvLines.Length; i++) //Skip the first row (the column names), skip the second row (the totals). { string[] arrayLineValues = arrayCsvLines[i].Split('\t'); if (arrayLineValues.Length < 25) { continue; //This often happens on the last line of the file, due to a trailing newline. Skip this line or any other malformed line. } for (int j = 0; j < arrayLineValues.Length; j++) { arrayLineValues[j] = arrayLineValues[j].Trim('\"'); //Remove leading and trailing double quotes from each cell of the csv table. } NewCropCharge charge = new NewCropCharge(); charge.ParentAccount = arrayLineValues[0]; charge.AccountName = arrayLineValues[1]; charge.AccountId = arrayLineValues[2]; charge.SiteId = arrayLineValues[3]; charge.LastName = arrayLineValues[4]; charge.FirstName = arrayLineValues[5]; charge.Dea = arrayLineValues[6]; charge.NPI = arrayLineValues[7]; charge.DateAdded = arrayLineValues[8]; charge.DoctorID = arrayLineValues[9]; charge.DoctorType = arrayLineValues[10]; charge.FTEPercent = arrayLineValues[11]; charge.CompFTEPercent = arrayLineValues[12]; charge.BasicFTEPercent = arrayLineValues[13]; charge.DrugChecks = arrayLineValues[14]; charge.ForumaryChecks = arrayLineValues[15]; charge.EPCS = arrayLineValues[16]; charge.IDP = arrayLineValues[17]; charge.Interop = arrayLineValues[18]; charge.PatientPortal = arrayLineValues[19]; charge.Registries = arrayLineValues[20]; charge.Labs = arrayLineValues[21]; charge.Genomics = arrayLineValues[22]; charge.Direct = arrayLineValues[23]; charge.DoctorDirect = arrayLineValues[24]; int patNumLength = charge.AccountId.IndexOf("-"); string patNumStr = PIn.String(charge.AccountId.Substring(0, patNumLength)); charge.PatNumForRegKey = PIn.Long(patNumStr); //PatNum of registration key used to create the account id. if (charge.PatNumForRegKey == 6566) { //Account 6566 corresponds to our software key in the training database. These accounts are test accounts. continue; //Do not show OD test accounts. } _listNewCropCharges.Add(charge); } #endregion Parse CSV _listErxRepeatCharges = RepeatCharges.GetForErx(); foreach (NewCropCharge charge in _listNewCropCharges) { charge.repeatCharge = _listErxRepeatCharges.FirstOrDefault(x => x.ErxAccountId == charge.AccountId && x.Npi == charge.NPI); } }
private void FillGrid() { try { string xmlData = File.ReadAllText(textBillingXmlPath.Text); xmlData = xmlData.Replace(" ", ""); XmlDocument xml = new XmlDocument(); xml.LoadXml(xmlData); XmlNode divNode = xml.FirstChild; XmlNode tableNode = divNode.FirstChild; RefreshGridColumns(); gridBillingList.BeginUpdate(); gridBillingList.Rows.Clear(); for (int i = 1; i < tableNode.ChildNodes.Count; i++) //Skip the first row, because it contains the column names. { ODGridRow gr = new ODGridRow(); XmlNode trNode = tableNode.ChildNodes[i]; //0 PatNum string shortName = trNode.ChildNodes[1].InnerText; int accountIdStartIndex = shortName.IndexOf("-") + 1; int accountIdLength = shortName.Substring(accountIdStartIndex).LastIndexOf("-"); string accountId = shortName.Substring(accountIdStartIndex, accountIdLength); int patNumLength = accountId.IndexOf("-"); string patNumStr = PIn.String(accountId.Substring(0, patNumLength)); if (patNumStr == "6566") //Account 6566 corresponds to our software key in the training database. These accounts are test accounts. { continue; //Do not show OD test accounts. } long patNum = PIn.Long(patNumStr); gr.Cells.Add(new ODGridCell(patNumStr)); //1 NPI string npi = PIn.String(trNode.ChildNodes[8].InnerText); gr.Cells.Add(new ODGridCell(npi)); //2 YearMonthAdded gr.Cells.Add(new ODGridCell(trNode.ChildNodes[9].InnerText)); //3 Type gr.Cells.Add(new ODGridCell(trNode.ChildNodes[10].InnerText)); //4 IsNew List <RepeatCharge> RepeatChargesCur = RepeatCharges.GetForNewCrop(patNum); RepeatCharge repeatChargeForNpi = GetRepeatChargeForNPI(RepeatChargesCur, npi); gr.Cells.Add(new ODGridCell((repeatChargeForNpi == null)?"X":"")); //5 PracticeTitle gr.Cells.Add(new ODGridCell(trNode.ChildNodes[0].InnerText)); //6 FirstLastName gr.Cells.Add(new ODGridCell(trNode.ChildNodes[2].InnerText)); gridBillingList.Rows.Add(gr); } gridBillingList.EndUpdate(); } catch (Exception ex) { MessageBox.Show("There is something wrong with the input file. Try again. If issue persists, then contact a programmer: " + ex.Message); } }
private void FormPrepaymentTool_Load(object sender, EventArgs e) { _listRcForPat = RepeatCharges.Refresh(_patCur.PatNum).ToList(); _listProcedureCharge = new List <ProcedureCharge>(); _listCompletedProcs = new List <Procedure>(); _listPreviouslyCompProcedureCharges = new List <ProcedureCharge>(); _prevPaymentRowCount = 0; _listPrepaymentCodes = new List <ProcedureCode>(); //Load procedurecode list. HQ internal codes. _listPrePaySupportCodes = AvaTax.ListPrePayProcCodes; DatePrepaidThrough = DateTime.MinValue; FillGridCodes(); FillGridPrepayment(); }
private void butOK_Click(object sender, EventArgs e) { Prefs.RefreshCache(); //Just to be sure we don't miss someone who has just started running repeating charges. if (PrefC.GetString(PrefName.RepeatingChargesBeginDateTime) != "") { MsgBox.Show(this, "Repeating charges already running on another workstation, you must wait for them to finish before continuing."); return; } RepeatChargeResult result = RepeatCharges.RunRepeatingCharges(MiscData.GetNowDateTime()); SecurityLogs.MakeLogEntry(Permissions.RepeatChargeTool, 0, "Repeat Charge Tool ran."); MessageBox.Show(result.ProceduresAddedCount + " " + Lan.g(this, "procedures added.") + "\r\n" + result.ClaimsAddedCount + " " + Lan.g(this, "claims added.")); DialogResult = DialogResult.OK; }
private void butOK_Click(object sender, System.EventArgs e) { if (textChargeAmt.errorProvider1.GetError(textChargeAmt) != "" || textDateStart.errorProvider1.GetError(textDateStart) != "" || textDateStop.errorProvider1.GetError(textDateStop) != "" ) { MsgBox.Show(this, "Please fix data entry errors first."); return; } if (textDateStart.Text == "") { MsgBox.Show(this, "Start date cannot be left blank."); return; } if (PIn.Date(textDateStart.Text) != RepeatCur.DateStart) //if the user changed the date { if (PIn.Date(textDateStart.Text) < DateTime.Today.AddDays(-3)) //and if the date the user entered is more than three days in the past { MsgBox.Show(this, "Start date cannot be more than three days in the past. You should enter previous charges manually in the account."); return; } } RepeatCur.ProcCode = textCode.Text; RepeatCur.ChargeAmt = PIn.Double(textChargeAmt.Text); RepeatCur.DateStart = PIn.Date(textDateStart.Text); RepeatCur.DateStop = PIn.Date(textDateStop.Text); RepeatCur.Note = textNote.Text; RepeatCur.CopyNoteToProc = checkCopyNoteToProc.Checked; RepeatCur.IsEnabled = checkIsEnabled.Checked; RepeatCur.CreatesClaim = checkCreatesClaim.Checked; if (IsNew) { RepeatCharges.Insert(RepeatCur); } else { RepeatCharges.Update(RepeatCur); } DialogResult = DialogResult.OK; }
private int GetChargeDayOfMonth(long patNum) { //Match the day of the month for the NewCrop repeating charge to their existing monthly support charge (even if the monthly support is disabled). int day = 15; //Day 15 will be used if they do not have any existing repeating charges. RepeatCharge[] chargesForPat = RepeatCharges.Refresh(patNum); bool hasMaintCharge = false; for (int j = 0; j < chargesForPat.Length; j++) { if (chargesForPat[j].ProcCode == "001") //Monthly maintenance repeating charge { hasMaintCharge = true; day = chargesForPat[j].DateStart.Day; break; } } //The customer is not on monthly support, so use any other existing repeating charge day (example EHR Monthly and Mobile). if (!hasMaintCharge && chargesForPat.Length > 0) { day = chargesForPat[0].DateStart.Day; } return(day); }
///<summary>Go through the transaction dictionary created in CreateProcedureLogs() to edit repeat charges as needed. ///Returns the note for the newly generated repeat charge.</summary> private void ZeroOutRepeatingCharge(ProcedureCode procCur, List <AvaTax.TransQtyAmt> listCurTrans) { Commlog prepaymentCommlog = new Commlog(); prepaymentCommlog.PatNum = _patCur.PatNum; prepaymentCommlog.SentOrReceived = CommSentOrReceived.Received; prepaymentCommlog.CommDateTime = DateTime.Now; prepaymentCommlog.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.FIN); prepaymentCommlog.Mode_ = CommItemMode.None; prepaymentCommlog.Note = "";//Appended to below. prepaymentCommlog.UserNum = Security.CurUser.UserNum; string note = "From PrepaymentTool: \r\n"; bool hasBeenBilledThisMonth = (DateTimeOD.Today.Day >= _patCur.BillingCycleDay); //Get all applicable repeat charges. List <RepeatCharge> listRcForProc = _listRcForPat.FindAll(x => x.ProcCode == procCur.ProcCode && x.IsEnabled); //Get number of months new repeat charge will be for. int numMonths = listCurTrans.Sum(x => x.qty); //Create repeat charge, taken from ContrAccount.cs RepeatCharge rcNew = new RepeatCharge(); rcNew.PatNum = _patCur.PatNum; rcNew.ProcCode = procCur.ProcCode; rcNew.ChargeAmt = 0; rcNew.IsEnabled = true; rcNew.CopyNoteToProc = true; //Build dates using billing day so the patient doesn't have gaps in their repeat charges. DateTime dateBillThisMonth = DateTimeOD.GetMostRecentValidDate(DateTime.Today.Year, DateTime.Today.Month, _patCur.BillingCycleDay); if (hasBeenBilledThisMonth) { //Current month has been billed, push new repeat charge out a month. rcNew.DateStart = dateBillThisMonth.AddMonths(1); rcNew.DateStop = dateBillThisMonth.AddMonths(numMonths); } else { //Current month has not been billed yet, include on this repeat charge. rcNew.DateStart = dateBillThisMonth; rcNew.DateStop = dateBillThisMonth.AddMonths(numMonths - 1); } //Use the stop date to update the Note as requested by Accounting. DatePrepaidThrough = rcNew.DateStop.AddMonths(1).AddDays(-1); rcNew.Note = _prepaidThroughNote; //Edit exisiting repeat charge start/stop dates. foreach (RepeatCharge rcExisting in listRcForProc) { if (rcExisting.DateStop.Year > 1880 && rcExisting.DateStop < DateTimeOD.Today) { continue; //The charge has a stop date in the past (has been disabled). } if (rcExisting.DateStop.Year > 1880 && rcExisting.DateStop <= DateTimeOD.Today.AddMonths(numMonths)) { rcExisting.DateStop = DateTimeOD.Today; rcExisting.IsEnabled = false; //This repeat charge will never be used again due to the prepayment we are creating right now. Disable and add note to commlog for history. note += "Disabled repeat charge with Rate: " + POut.Double(rcExisting.ChargeAmt) + " for Code: " + POut.String(rcExisting.ProcCode) + " Start Date: " + POut.Date(rcExisting.DateStart) + " Stop Date: " + POut.Date(rcExisting.DateStop) + "\r\n"; RepeatCharges.Update(rcExisting); continue; } //Need to push start date of existing repeat charge forward one month past the new repeat charge (if charge months overlap). DateTime dateNext = rcNew.DateStop.AddMonths(1); if (dateNext > rcExisting.DateStart) //Only change if needed. { note += "Edited Start Date for repeat charge from: " + POut.Date(rcExisting.DateStart) + " to: " + POut.Date(dateNext) + " Code: " + POut.String(rcExisting.ProcCode) + " Rate: " + POut.Double(rcExisting.ChargeAmt) + "\r\n"; //Change to billing day to make sure it matches other repeat charges. rcExisting.DateStart = dateNext; RepeatCharges.Update(rcExisting); } } //Insert the new repeat charge. prepaymentCommlog.Note = note; Commlogs.Insert(prepaymentCommlog); RepeatCharges.Insert(rcNew); }
///<summary>Do not use this method in release code. This is only to be used for Unit Tests 53-56.</summary> public void RunRepeatingChargesForUnitTests(DateTime dateRun) { RepeatCharges.RunRepeatingCharges(dateRun); }
private void butOK_Click(object sender, System.EventArgs e) { RepeatCharge[] chargeList = RepeatCharges.Refresh(0); //Gets all repeating charges for all patients, they may be disabled int countAdded = 0; int claimsAdded = 0; DateTime startDate; Procedure proc; for (int i = 0; i < chargeList.Length; i++) { if (!chargeList[i].IsEnabled) //first make sure it is not disabled { continue; } if (chargeList[i].DateStart > DateTime.Today) //not started yet { continue; } //if(chargeList[i].DateStop.Year>1880//not blank // && chargeList[i].DateStop<DateTime.Today)//but already ended //{ // continue; //} //get a list dates of all completed procedures with this Code and patNum ArrayList ALdates = RepeatCharges.GetDates(ProcedureCodes.GetCodeNum(chargeList[i].ProcCode), chargeList[i].PatNum); startDate = chargeList[i].DateStart; //This is the repeating date using the old methodology. It is necessary for checking if the repeating procedure was already added using the old methodology. DateTime possibleDateOld = startDate; //This is a more accurate repeating date which will allow procedures to be added on the 28th and later. DateTime possibleDateNew = startDate; int countMonths = 0; //start looping through possible dates, beginning with the start date of the repeating charge while (possibleDateNew <= DateTime.Today) { //Only allow back dating up to one month and 20 days. if (possibleDateNew < DateTime.Today.AddDays(-50)) { possibleDateOld = possibleDateOld.AddMonths(1); countMonths++; possibleDateNew = startDate.AddMonths(countMonths); continue; //don't go back more than one month and 20 days } //check to see if the possible date is present in the list if (ALdates.Contains(possibleDateNew) || ALdates.Contains(possibleDateOld)) { possibleDateOld = possibleDateOld.AddMonths(1); countMonths++; possibleDateNew = startDate.AddMonths(countMonths); continue; } if (chargeList[i].DateStop.Year > 1880 && //not blank chargeList[i].DateStop < possibleDateNew) //but already ended { break; } //otherwise, insert a procedure to db proc = new Procedure(); proc.CodeNum = ProcedureCodes.GetCodeNum(chargeList[i].ProcCode); proc.DateEntryC = DateTimeOD.Today; proc.PatNum = chargeList[i].PatNum; proc.ProcDate = possibleDateNew; proc.DateTP = possibleDateNew; proc.ProcFee = chargeList[i].ChargeAmt; proc.ProcStatus = ProcStat.C; proc.ProvNum = PrefC.GetLong(PrefName.PracticeDefaultProv); proc.MedicalCode = ProcedureCodes.GetProcCode(proc.CodeNum).MedicalCode; proc.BaseUnits = ProcedureCodes.GetProcCode(proc.CodeNum).BaseUnits; proc.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs); //Check if the repeating charge has been flagged to copy it's note into the billing note of the procedure. if (chargeList[i].CopyNoteToProc) { proc.BillingNote = chargeList[i].Note; } Procedures.Insert(proc); //no recall synch needed because dental offices don't use this feature countAdded++; possibleDateOld = possibleDateOld.AddMonths(1); countMonths++; possibleDateNew = startDate.AddMonths(countMonths); if (chargeList[i].CreatesClaim && !ProcedureCodes.GetProcCode(chargeList[i].ProcCode).NoBillIns) { List <PatPlan> patPlanList = PatPlans.Refresh(chargeList[i].PatNum); List <InsSub> subList = InsSubs.RefreshForFam(Patients.GetFamily(chargeList[i].PatNum)); List <InsPlan> insPlanList = InsPlans.RefreshForSubList(subList);; List <Benefit> benefitList = Benefits.Refresh(patPlanList, subList); Claim claimCur; List <Procedure> procCurList = new List <Procedure>(); procCurList.Add(proc); if (patPlanList.Count == 0) //no current insurance, do not create a claim { continue; } //create the claimprocs Procedures.ComputeEstimates(proc, proc.PatNum, new List <ClaimProc>(), true, insPlanList, patPlanList, benefitList, Patients.GetPat(proc.PatNum).Age, subList); //get claimprocs for this proc, may be more than one List <ClaimProc> claimProcList = ClaimProcs.GetForProc(ClaimProcs.Refresh(proc.PatNum), proc.ProcNum); string claimType = "P"; if (patPlanList.Count == 1 && PatPlans.GetOrdinal(PriSecMed.Medical, patPlanList, insPlanList, subList) > 0) //if there's exactly one medical plan { claimType = "Med"; } claimCur = CreateClaim(claimType, patPlanList, insPlanList, claimProcList, proc, subList); claimProcList = ClaimProcs.Refresh(proc.PatNum); if (claimCur.ClaimNum == 0) { continue; } claimsAdded++; ClaimL.CalculateAndUpdate(procCurList, insPlanList, claimCur, patPlanList, benefitList, Patients.GetPat(proc.PatNum).Age, subList); if (PatPlans.GetOrdinal(PriSecMed.Secondary, patPlanList, insPlanList, subList) > 0 && //if there exists a secondary plan !CultureInfo.CurrentCulture.Name.EndsWith("CA")) //and not canada (don't create secondary claim for canada) { claimCur = CreateClaim("S", patPlanList, insPlanList, claimProcList, proc, subList); if (claimCur.ClaimNum == 0) { continue; } claimsAdded++; claimProcList = ClaimProcs.Refresh(proc.PatNum); claimCur.ClaimStatus = "H"; ClaimL.CalculateAndUpdate(procCurList, insPlanList, claimCur, patPlanList, benefitList, Patients.GetPat(proc.PatNum).Age, subList); } } } } //MessageBox.Show(countAdded.ToString()+" "+Lan.g(this,"procedures added.")); MessageBox.Show(countAdded.ToString() + " " + Lan.g(this, "procedures added.") + "\r\n" + claimsAdded.ToString() + " " + Lan.g(this, "claims added.")); DialogResult = DialogResult.OK; }
private void butDelete_Click(object sender, System.EventArgs e) { RepeatCharges.Delete(RepeatCur); DialogResult = DialogResult.OK; }
private void FormRepeatChargeEdit_Load(object sender, EventArgs e) { SetPatient(); if (IsNew) { FormProcCodes FormP = new FormProcCodes(); FormP.IsSelectionMode = true; FormP.ShowDialog(); if (FormP.DialogResult != DialogResult.OK) { DialogResult = DialogResult.Cancel; return; } ProcedureCode procCode = ProcedureCodes.GetProcCode(FormP.SelectedCodeNum); if (procCode.TreatArea != TreatmentArea.Mouth && procCode.TreatArea != TreatmentArea.None) { MsgBox.Show(this, "Procedure codes that require tooth numbers are not allowed."); DialogResult = DialogResult.Cancel; return; } RepeatCur.ProcCode = ProcedureCodes.GetStringProcCode(FormP.SelectedCodeNum); RepeatCur.IsEnabled = true; RepeatCur.CreatesClaim = false; } textCode.Text = RepeatCur.ProcCode; textDesc.Text = ProcedureCodes.GetProcCode(RepeatCur.ProcCode).Descript; textChargeAmt.Text = RepeatCur.ChargeAmt.ToString("F"); if (RepeatCur.DateStart.Year > 1880) { textDateStart.Text = RepeatCur.DateStart.ToShortDateString(); } if (RepeatCur.DateStop.Year > 1880) { textDateStop.Text = RepeatCur.DateStop.ToShortDateString(); } textNote.Text = RepeatCur.Note; _isErx = false; if (PrefC.GetBool(PrefName.DistributorKey) && Regex.IsMatch(RepeatCur.ProcCode, "^Z[0-9]{3,}$")) //Is eRx if HQ and a using an eRx Z code. { _isErx = true; labelPatNum.Visible = true; textPatNum.Visible = true; butMoveTo.Visible = true; labelNpi.Visible = true; textNpi.Visible = true; labelProviderName.Visible = true; textProvName.Visible = true; labelErxAccountId.Visible = true; textErxAccountId.Visible = true; if (!IsNew) //Existing eRx repeating charge. { textNpi.Text = RepeatCur.Npi; textErxAccountId.Text = RepeatCur.ErxAccountId; textProvName.Text = RepeatCur.ProviderName; textNpi.ReadOnly = true; textErxAccountId.ReadOnly = true; textProvName.ReadOnly = true; } } checkCopyNoteToProc.Checked = RepeatCur.CopyNoteToProc; checkCreatesClaim.Checked = RepeatCur.CreatesClaim; checkIsEnabled.Checked = RepeatCur.IsEnabled; if (PrefC.GetBool(PrefName.DistributorKey)) //OD HQ disable the IsEnabled and CreatesClaim checkboxes { checkCreatesClaim.Enabled = false; checkIsEnabled.Enabled = false; } if (PrefC.IsODHQ && EServiceCodeLink.IsProcCodeAnEService(RepeatCur.ProcCode)) { if (IsNew) { MsgBox.Show(this, "You cannot manually create any eService repeating charges.\r\n" + "Use the Signup Portal instead.\r\n\r\n" + "The Charge Amount can be manually edited after the Signup Portal has created the desired eService repeating charge."); DialogResult = DialogResult.Abort; return; } //The only things that users should be able to do for eServices are: //1. Change the repeating charge amount. //2. Manipulate the Start Date. //3. Manipulate the Note. //4. Manipulate Billing Day because not all customers will have a non-eService repeating charge in order to manipulate. //This is because legacy users (versions prior to 17.1) need the ability to manually set their monthly charge amount, etc. SetFormReadOnly(this, butOK, butCancel , textChargeAmt, labelChargeAmount , textDateStart, labelDateStart , textNote, labelNote , textBillingDay, labelBillingCycleDay); } Patient pat = Patients.GetPat(RepeatCur.PatNum); //pat should never be null. If it is, this will fail. //If this is a new repeat charge and no other active repeat charges exist, set the billing cycle day to today if (IsNew && !RepeatCharges.ActiveRepeatChargeExists(RepeatCur.PatNum)) { textBillingDay.Text = DateTimeOD.Today.Day.ToString(); } else { textBillingDay.Text = pat.BillingCycleDay.ToString(); } if (PrefC.GetBool(PrefName.BillingUseBillingCycleDay)) { labelBillingCycleDay.Visible = true; textBillingDay.Visible = true; } checkUsePrepay.Checked = RepeatCur.UsePrepay; }
private void butProcess_Click(object sender, EventArgs e) { if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "This will add a new repeating charge for each provider in the list above" + " who is new (does not already have a repeating charge), based on PatNum and NPI. Continue?")) { return; } Cursor = Cursors.WaitCursor; int numChargesAdded = 0; int numSkipped = 0; for (int i = 0; i < gridBillingList.Rows.Count; i++) { long patNum = PIn.Long(gridBillingList.Rows[i].Cells[0].Text); string npi = PIn.String(gridBillingList.Rows[i].Cells[1].Text); string billingType = gridBillingList.Rows[i].Cells[3].Text; List <RepeatCharge> repeatChargesNewCrop = RepeatCharges.GetForNewCrop(patNum); RepeatCharge repeatCur = GetRepeatChargeForNPI(repeatChargesNewCrop, npi); if (repeatCur == null) //No such repeating charge exists yet for the given npi. //We consider the provider a new provider and create a new repeating charge. { string yearMonth = gridBillingList.Rows[i].Cells[2].Text; int yearBilling = PIn.Int(yearMonth.Substring(0, 4)); //The year chosen by the OD employee when running the NewCrop Billing report. int monthBilling = PIn.Int(yearMonth.Substring(4)); //The month chosen by the OD employee when running the NewCrop Billing report. int dayOtherCharges = GetChargeDayOfMonth(patNum); //The day of the month that the customer already has other repeating charges. Keeps their billing simple (one bill per month for all charges). DateTime dateNewCropCharge = new DateTime(yearBilling, monthBilling, dayOtherCharges); if (dateNewCropCharge < DateTime.Today.AddMonths(-3)) //Just in case the user runs an older report. { numSkipped++; continue; } repeatCur = new RepeatCharge(); repeatCur.IsNew = true; repeatCur.PatNum = patNum; repeatCur.ProcCode = GetProcCodeForNewCharge(repeatChargesNewCrop); repeatCur.ChargeAmt = 15; //15$/month repeatCur.DateStart = dateNewCropCharge; repeatCur.Note = "NPI=" + npi; repeatCur.IsEnabled = true; RepeatCharges.Insert(repeatCur); numChargesAdded++; } else //The repeating charge for NewCrop billing already exists for the given npi. { DateTime dateEndLastMonth = (new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1)).AddDays(-1); if (billingType == "B" || billingType == "N") //The provider sent eRx last month. { if (repeatCur.DateStop.Year > 2010) //NewCrop support for this provider was disabled at one point, but has been used since. { if (repeatCur.DateStop < dateEndLastMonth) //If the stop date is in the future or already at the end of the month, then we cannot presume that there will be a charge next month. { repeatCur.DateStop = dateEndLastMonth; //Make sure the recent use is reflected in the end date. RepeatCharges.Update(repeatCur); } } } else if (billingType == "U") //The provider did not send eRx last month, but did send eRx two months ago. //Customers must call in to disable repeating charges, they are not disabled automatically. { } else { throw new Exception("Unknown NewCrop Billing type " + billingType); } } } FillGrid(); Cursor = Cursors.Default; string msg = "Done. Number of provider charges added: " + numChargesAdded; if (numSkipped > 0) { msg += Environment.NewLine + "Number skipped due to old DateBilling (over 3 months ago): " + numSkipped; } MessageBox.Show(msg); }
private void butOK_Click(object sender, EventArgs e) { if (textChargeAmt.errorProvider1.GetError(textChargeAmt) != "" || textDateStart.errorProvider1.GetError(textDateStart) != "" || textDateStop.errorProvider1.GetError(textDateStop) != "" || textBillingDay.errorProvider1.GetError(textBillingDay) != "" ) { MsgBox.Show(this, "Please fix data entry errors first."); return; } if (textDateStart.Text == "") { MsgBox.Show(this, "Start date cannot be left blank."); return; } if (PIn.Date(textDateStart.Text) != RepeatCur.DateStart) //if the user changed the date { if (PIn.Date(textDateStart.Text) < DateTime.Today.AddDays(-3)) //and if the date the user entered is more than three days in the past { MsgBox.Show(this, "Start date cannot be more than three days in the past. You should enter previous charges manually in the account."); return; } } if (textDateStop.Text.Trim() != "" && PIn.Date(textDateStart.Text) > PIn.Date(textDateStop.Text)) { if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "The start date is after the stop date. Continue?")) { return; } } if (_isErx && !Regex.IsMatch(textNpi.Text, "^[0-9]{10}$")) { MsgBox.Show(this, "Invalid NPI. Must be 10 digits."); return; } if (_isErx && textErxAccountId.Text != "" && !Regex.IsMatch(textErxAccountId.Text, "^[0-9]+\\-[a-zA-Z0-9]{5}$")) { MsgBox.Show(this, "Invalid ErxAccountId."); return; } if (PrefC.GetBool(PrefName.BillingUseBillingCycleDay) && textBillingDay.Text != "") { Patient patOld = Patients.GetPat(RepeatCur.PatNum); Patient patNew = patOld.Copy(); patNew.BillingCycleDay = PIn.Int(textBillingDay.Text); Patients.Update(patNew, patOld); } RepeatCur.ProcCode = textCode.Text; RepeatCur.ChargeAmt = PIn.Double(textChargeAmt.Text); RepeatCur.DateStart = PIn.Date(textDateStart.Text); RepeatCur.DateStop = PIn.Date(textDateStop.Text); RepeatCur.Npi = textNpi.Text; RepeatCur.ErxAccountId = textErxAccountId.Text; RepeatCur.Note = textNote.Text; RepeatCur.ProviderName = textProvName.Text; RepeatCur.CopyNoteToProc = checkCopyNoteToProc.Checked; RepeatCur.IsEnabled = checkIsEnabled.Checked; RepeatCur.CreatesClaim = checkCreatesClaim.Checked; RepeatCur.UsePrepay = checkUsePrepay.Checked; if (IsNew) { if (!RepeatCharges.ActiveRepeatChargeExists(RepeatCur.PatNum) && (textBillingDay.Text == "" || textBillingDay.Text == "0")) { Patient patOld = Patients.GetPat(RepeatCur.PatNum); Patient patNew = patOld.Copy(); patNew.BillingCycleDay = PIn.Date(textDateStart.Text).Day; Patients.Update(patNew, patOld); } RepeatCharges.Insert(RepeatCur); if (PrefC.IsODHQ) { AddProcedureToCC(); } } else //not a new repeat charge { RepeatCharges.Update(RepeatCur); } DialogResult = DialogResult.OK; }
private void butProcess_Click(object sender, EventArgs e) { if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "This will add a new repeating charge for each provider in the list above" + " who is new (does not already have a repeating charge), based on PatNum and NPI. Continue?")) { return; } Cursor = Cursors.WaitCursor; List <NewCropCharge> listAddedCharges = new List <NewCropCharge>(); int numSkipped = 0; StringBuilder strBldArchivedPats = new StringBuilder(); foreach (NewCropCharge charge in _listNewCropCharges) { if (charge.repeatCharge == null) //No such repeating charge exists yet for the given npi. //We consider the provider a new provider and create a new repeating charge. { int dayOtherCharges = GetChargeDayOfMonth(charge.PatNumForRegKey); //The day of the month that the customer already has other repeating charges. Keeps their billing simple (one bill per month for all charges). int daysInMonth = DateTime.DaysInMonth(_dateBillingMonthYear.Year, _dateBillingMonthYear.Month); if (dayOtherCharges > daysInMonth) { //The day that the user used eRx (signed up) was in a month that does not have the day of the other monthly charges in it. //E.g. dayOtherCharges = 31 and the user started a new eRx account in a month without 31 days. //Therefore, we have to use the last day of the month that they started. //This can introduce multiple statements being sent out which can potentially delay us (HQ) from getting paid in a timely fashion. //A workaround for this would be to train our techs to never run billing after the 28th of every month that way incomplete statements are not sent. dayOtherCharges = daysInMonth; } DateTime dateErxCharge = new DateTime(_dateBillingMonthYear.Year, _dateBillingMonthYear.Month, dayOtherCharges); if (dateErxCharge < DateTime.Today.AddMonths(-3)) //Just in case the user runs an older report. { numSkipped++; continue; } charge.repeatCharge = new RepeatCharge(); charge.repeatCharge.IsNew = true; charge.repeatCharge.PatNum = charge.PatNumForRegKey; charge.repeatCharge.ProcCode = GetProcCodeForNewCharge(charge.PatNumForRegKey); charge.repeatCharge.ChargeAmt = 15; //15$/month charge.repeatCharge.DateStart = dateErxCharge; charge.repeatCharge.Npi = charge.NPI; charge.repeatCharge.ErxAccountId = charge.AccountId; charge.repeatCharge.ProviderName = charge.FirstName + " " + charge.LastName; charge.repeatCharge.IsEnabled = true; charge.repeatCharge.CopyNoteToProc = true; //Copy the billing note to the procedure note by default so that the customer can see the NPI the charge corresponds to. Can be unchecked by user if a private note is added later (rare). if (!RepeatCharges.ActiveRepeatChargeExists(charge.repeatCharge.PatNum)) { //Set the patient's billing day to the start day on the repeat charge Patient patOld = Patients.GetPat(charge.repeatCharge.PatNum); Patient patNew = patOld.Copy(); //Check the patients status and move them to Archived if they are currently deleted. if (patOld.PatStatus == PatientStatus.Deleted) { patNew.PatStatus = PatientStatus.Archived; } //Notify the user about any deleted or archived patients that were just given a new repeating charge. if (patOld.PatStatus == PatientStatus.Archived || patOld.PatStatus == PatientStatus.Deleted) { strBldArchivedPats.AppendLine("#" + patOld.PatNum + " - " + patOld.GetNameLF()); } patNew.BillingCycleDay = charge.repeatCharge.DateStart.Day; Patients.Update(patNew, patOld); } RepeatCharges.Insert(charge.repeatCharge); _listErxRepeatCharges.Add(charge.repeatCharge); listAddedCharges.Add(charge); } else //The repeating charge for eRx billing already exists for the given npi. { DateTime dateEndLastMonth = (new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1)).AddDays(-1); if (charge.repeatCharge.DateStop.Year > 2010) //eRx support for this provider was disabled at one point, but has been used since. { if (charge.repeatCharge.DateStop < dateEndLastMonth) //If the stop date is in the future or already at the end of the month, then we cannot presume that there will be a charge next month. { charge.repeatCharge.DateStop = dateEndLastMonth; //Make sure the recent use is reflected in the end date. RepeatCharges.Update(charge.repeatCharge); } } } } FillGrid(); Cursor = Cursors.Default; StringBuilder sbMsg = new StringBuilder(); sbMsg.AppendLine("Done."); if (numSkipped > 0) { sbMsg.AppendLine("Number skipped due to old DateBilling (over 3 months ago): " + numSkipped); } if (listAddedCharges.Count > 0) { const int colNameWidth = 62; const int colErxAccountIdWidth = 18; const int colNpiWidth = 10; sbMsg.AppendLine("Added the following new repeating charges (" + listAddedCharges.Count + " total):"); sbMsg.Append(" "); sbMsg.Append("NAME".PadRight(colNameWidth, ' ')); sbMsg.Append("ERXACCOUNTID".PadRight(colErxAccountIdWidth, ' ')); sbMsg.AppendLine("NPI".PadRight(colNpiWidth, ' ')); foreach (NewCropCharge charge in listAddedCharges) { string firstLastName = charge.FirstName + " " + charge.LastName; if (firstLastName.Length > colNameWidth) { firstLastName = firstLastName.Substring(0, colNameWidth); } sbMsg.Append(" "); sbMsg.Append(firstLastName.PadRight(colNameWidth, ' ')); sbMsg.Append(charge.AccountId.PadRight(colErxAccountIdWidth, ' ')); sbMsg.AppendLine(charge.NPI.PadRight(colNpiWidth, ' ')); } } if (strBldArchivedPats.Length > 0) { sbMsg.AppendLine("Archived patients that had a repeating charge created:"); sbMsg.AppendLine(strBldArchivedPats.ToString()); } MsgBoxCopyPaste msgBoxCP = new MsgBoxCopyPaste(sbMsg.ToString()); msgBoxCP.ShowDialog(); //Must be modal, because non-modal does not display here for some reason. }