///<summary>Insert Payment and PaySplit. Returns newly inserted Payment.PayNum. Throws exceptions if XWeb Program Properties are invalid.</summary> public static long InsertFromXWeb(long patNum, long provNum, long clinicNum, double amount, string payNote, string receipt, CreditCardSource ccSource) { //No need to check RemotingRole;no call to db. OpenDentBusiness.WebTypes.Shared.XWeb.WebPaymentProperties xwebProperties; OpenDentBusiness.ProgramProperties.GetXWebCreds(clinicNum, out xwebProperties); long ret = Payments.Insert(new Payment() { ClinicNum = clinicNum, IsRecurringCC = false, IsSplit = false, PatNum = patNum, PayAmt = amount, PayDate = DateTime.Now, PaymentSource = ccSource, PayType = xwebProperties.PaymentTypeDefNum, ProcessStatus = ProcessStat.OnlinePending, Receipt = receipt, PayNote = payNote, }); PaySplits.Insert(new PaySplit() { ClinicNum = clinicNum, DatePay = DateTime.Now, PatNum = patNum, PayNum = ret, ProvNum = provNum, SplitAmt = amount, }); SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, patNum, Lans.g("Payments.InsertFromXWeb", "XWeb payment by") + " " + OpenDentBusiness.Patients.GetLim(patNum).GetNameLF() + ", " + amount.ToString("c"), LogSources.PatientPortal); return(ret); }
///<summary>Insert Payment and PaySplit. Returns newly inserted Payment.PayNum. Throws exceptions if PayConnect Program Properties are invalid.</summary> public static long InsertFromPayConnect(long patNum, long provNum, long clinicNum, double amount, string payNote, string receipt, CreditCardSource ccSource) { //No need to check RemotingRole;no call to db. long ret = Payments.Insert(new Payment() { ClinicNum = clinicNum, IsRecurringCC = false, IsSplit = false, PatNum = patNum, PayAmt = amount, PayDate = DateTime.Now, PaymentSource = ccSource, PayType = PIn.Long(ProgramProperties.GetPropVal(Programs.GetCur(ProgramName.PayConnect).ProgramNum, "PaymentType", clinicNum)), ProcessStatus = ProcessStat.OnlinePending, Receipt = receipt, PayNote = payNote, }); PaySplits.Insert(new PaySplit() { ClinicNum = clinicNum, DatePay = DateTime.Now, PatNum = patNum, PayNum = ret, ProvNum = provNum, SplitAmt = amount, }); SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, patNum, Lans.g("Payments.InsertFromPayConnect", "PayConnect payment by") + " " + OpenDentBusiness.Patients.GetLim(patNum).GetNameLF() + ", " + amount.ToString("c"), LogSources.PatientPortal); return(ret); }
///<summary>Creates a transfer originating from the prepayment containing the procOriginal, back to the procOriginal. ///Used to transfer money from TP unearned back onto the procedure as an allocated non pre-pay split. ///Optionally pass in procNumAttaching when wanting to attach to a procedure other than the procOriginal. ///Optionally pass in transferAmountOverride when transferring an amount that is not the split amount, as in the case for broken procs.</summary> public static void CreateTransferForTpProcs(Procedure procOriginal, List <PaySplit> listSplitsForProc, Procedure procAttaching = null, double transferAmountOverride = 0) { if (listSplitsForProc.IsNullOrEmpty() || listSplitsForProc.Sum(x => x.SplitAmt) == 0) { return; } //procAttaching will be null when transferring from unearned to same procedure. procAttaching = procAttaching ?? procOriginal; Payment transferPayment = new Payment(); transferPayment.PayDate = DateTime.Today; transferPayment.ClinicNum = procOriginal.ClinicNum; transferPayment.PayNote = "Automatic transfer from treatment planned procedure prepayment."; transferPayment.PatNum = procAttaching.PatNum; //ultimately where the payment ends up. transferPayment.PayType = 0; Insert(transferPayment); foreach (PaySplit prepaySplit in listSplitsForProc) { //make negative split to remove the 'tp prepayment' PaySplit negSplitForTxfr = new PaySplit { ClinicNum = procOriginal.ClinicNum, DatePay = DateTime.Today, FSplitNum = prepaySplit.SplitNum, ProcNum = 0, //either the procedure is being set complete, or pref for Non-Refundable TP prepay is set and transferring to procAttaching. //If non-refundable the procedure needs to be disassociated as well as we will not have a way to determine when procOriginal eventually //gets set complete and unearned cannot exist with a completed procedure attached. PatNum = procOriginal.PatNum, PayNum = transferPayment.PayNum, SplitAmt = (transferAmountOverride == 0?prepaySplit.SplitAmt:transferAmountOverride) * -1, UnearnedType = prepaySplit.UnearnedType, ProcDate = procOriginal.ProcDate, ProvNum = prepaySplit.ProvNum, }; PaySplits.Insert(negSplitForTxfr); //Update original pre-payment split to disassociate the procedure now that the procedure is complete (Splits cannot have unaerned and C proc) prepaySplit.ProcNum = 0; PaySplits.Update(prepaySplit); PaySplit positiveSplit = new PaySplit { ClinicNum = procAttaching.ClinicNum, DatePay = DateTime.Today, FSplitNum = negSplitForTxfr.SplitNum, //if meant for unearned, FSplitNum must be 0 to show up correctly. ProcNum = procAttaching.ProcNum, PatNum = procAttaching.PatNum, PayNum = transferPayment.PayNum, SplitAmt = transferAmountOverride == 0?prepaySplit.SplitAmt:transferAmountOverride, ProcDate = procAttaching.ProcDate, ProvNum = procAttaching.ProvNum, UnearnedType = 0 //necessary for when broken appointments do not get a procedure created for them to transfer to. }; PaySplits.Insert(positiveSplit); } SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, transferPayment.PatNum, "Automatic transfer of funds for treatment plan procedure pre-payments."); }
private static Procedure AddRepeatingChargeHelper(RepeatCharge repeatCharge, DateTime billingDate, DateTime dateNow) { //No remoting role check; no call to db Procedure procedure = new Procedure(); ProcedureCode procCode = ProcedureCodes.GetProcCode(repeatCharge.ProcCode); Patient pat = Patients.GetPat(repeatCharge.PatNum); procedure.CodeNum = procCode.CodeNum; procedure.ClinicNum = pat.ClinicNum; procedure.DateEntryC = dateNow; procedure.PatNum = repeatCharge.PatNum; procedure.ProcDate = billingDate; procedure.DateTP = billingDate; procedure.ProcFee = repeatCharge.ChargeAmt; procedure.ProcStatus = ProcStat.C; if (procCode.ProvNumDefault == 0) { procedure.ProvNum = pat.PriProv; } else { procedure.ProvNum = procCode.ProvNumDefault; } procedure.MedicalCode = ProcedureCodes.GetProcCode(procedure.CodeNum).MedicalCode; procedure.BaseUnits = ProcedureCodes.GetProcCode(procedure.CodeNum).BaseUnits; procedure.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs); procedure.RepeatChargeNum = repeatCharge.RepeatChargeNum; procedure.PlaceService = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService); //Default Proc Place of Service for the Practice is used. //Check if the repeating charge has been flagged to copy it's note into the billing note of the procedure. if (repeatCharge.CopyNoteToProc) { procedure.BillingNote = repeatCharge.Note; if (repeatCharge.ErxAccountId != "") { procedure.BillingNote = "NPI=" + repeatCharge.Npi + " " + "ErxAccountId=" + repeatCharge.ErxAccountId; if (!string.IsNullOrEmpty(repeatCharge.ProviderName)) //Provider name would be empty if older and no longer updated from eRx. { procedure.BillingNote += "\r\nProviderName=" + repeatCharge.ProviderName; } if (!string.IsNullOrEmpty(repeatCharge.Note)) { procedure.BillingNote += "\r\n" + repeatCharge.Note; } } } if (!PrefC.GetBool(PrefName.EasyHidePublicHealth)) { procedure.SiteNum = pat.SiteNum; } Procedures.Insert(procedure); //no recall synch needed because dental offices don't use this feature //Using Prepayments for this Procedure if (repeatCharge.UsePrepay) { //NOTE: ProvNum=0 on these splits, so I'm pretty sure they aren't allocated to anything. List <PaySplit> prePaySplits = PaySplits.GetPrepayForFam(Patients.GetFamily(repeatCharge.PatNum)); List <PaySplit> paySplitsForPrePaySplits = PaySplits.GetSplitsForPrepay(prePaySplits); Payment payCur = new Payment(); payCur.ClinicNum = procedure.ClinicNum; payCur.DateEntry = billingDate; payCur.IsSplit = true; payCur.PatNum = repeatCharge.PatNum; payCur.PayDate = billingDate; payCur.PayType = 0; //Income transfer (will always be income transfer) payCur.PayAmt = 0; //Income transfer payment payCur.PayNum = Payments.Insert(payCur); decimal payAmt = 0; string noteText = ""; foreach (PaySplit prePaySplit in prePaySplits) { prePaySplit.SplitAmt += paySplitsForPrePaySplits.Where(x => x.FSplitNum == prePaySplit.SplitNum).Sum(y => y.SplitAmt); //Reduce prepay split amount. PaySplit split = new PaySplit(); PaySplit split2 = new PaySplit(); if (prePaySplit.SplitAmt > procedure.ProcFee - (double)payAmt) { //Split amount is more than the remainder of the procfee requires, use partial from split split.SplitAmt = procedure.ProcFee - (double)payAmt; split2.SplitAmt = 0 - (procedure.ProcFee - (double)payAmt); payAmt = (decimal)procedure.ProcFee; } else { //Split amount is less than or equal to the remainder of the procfee split.SplitAmt = prePaySplit.SplitAmt; split2.SplitAmt = 0 - prePaySplit.SplitAmt; payAmt += (decimal)prePaySplit.SplitAmt; } if (split.SplitAmt == 0) { continue; //Don't make splits for 0 amount. } //Positive split, attached to proc and for proc's prov and clinic split.DateEntry = billingDate; split.DatePay = billingDate; split.PatNum = procedure.PatNum; split.PayNum = payCur.PayNum; split.ProcNum = procedure.ProcNum; split.ProvNum = procedure.ProvNum; split.ClinicNum = procedure.ClinicNum; if (noteText != "") { noteText += ", "; } noteText += split.SplitAmt.ToString("c"); PaySplits.Insert(split); //Negative split, attached to prepay's prov and clinic, but not proc split2.DateEntry = billingDate; split2.DatePay = billingDate; split2.PatNum = procedure.PatNum; split2.PayNum = payCur.PayNum; split2.FSplitNum = prePaySplit.SplitNum; split2.ProvNum = prePaySplit.ProvNum; split2.ClinicNum = prePaySplit.ClinicNum; PaySplits.Insert(split2); if (payAmt >= (decimal)procedure.ProcFee) { //Break out of loop break; } } payCur.PayNote = "Allocated " + noteText + " prepayments to repeating charge."; Payments.Update(payCur, false); } return(procedure); }