コード例 #1
0
ファイル: PaySplits.cs プロジェクト: romeroyonatan/opendental
		///<summary></summary>
		public static long Insert(PaySplit split) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				split.SplitNum=Meth.GetLong(MethodBase.GetCurrentMethod(),split);
				return split.SplitNum;
			}
			return Crud.PaySplitCrud.Insert(split);
		}
コード例 #2
0
ファイル: PaySplits.cs プロジェクト: romeroyonatan/opendental
		///<summary></summary>
		public static void Update(PaySplit split){
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				Meth.GetVoid(MethodBase.GetCurrentMethod(),split);
				return;
			}
			Crud.PaySplitCrud.Update(split);
		}
コード例 #3
0
ファイル: PaySplits.cs プロジェクト: romeroyonatan/opendental
		///<summary>Deletes the paysplit.</summary>
		public static void Delete(PaySplit split){
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				Meth.GetVoid(MethodBase.GetCurrentMethod(),split);
				return;
			}
			string command= "DELETE from paysplit WHERE SplitNum = "+POut.Long(split.SplitNum);
 			Db.NonQ(command);
		}
コード例 #4
0
 ///<summary></summary>
 public static void Update(PaySplit paySplit, PaySplit oldPaySplit)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         Meth.GetVoid(MethodBase.GetCurrentMethod(), paySplit, oldPaySplit);
         return;
     }
     Crud.PaySplitCrud.Update(paySplit, oldPaySplit);
 }
コード例 #5
0
ファイル: PaySplits.cs プロジェクト: steev90/opendental
 ///<summary></summary>
 public static long Insert(PaySplit split)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         split.SplitNum = Meth.GetLong(MethodBase.GetCurrentMethod(), split);
         return(split.SplitNum);
     }
     return(Crud.PaySplitCrud.Insert(split));
 }
コード例 #6
0
ファイル: PaySplits.cs プロジェクト: romeroyonatan/opendental
		///<summary>Used from ContrAccount and ProcEdit to display and calculate payments attached to procs. Used once in FormProcEdit</summary>
		public static double GetTotForProc(long procNum,PaySplit[] List) {
			//No need to check RemotingRole; no call to db.
			double retVal=0;
			for(int i=0;i<List.Length;i++){
				if(List[i].ProcNum==procNum){
					retVal+=List[i].SplitAmt;
				}
			}
			return retVal;
		}
コード例 #7
0
ファイル: PaySplits.cs プロジェクト: romeroyonatan/opendental
		///<summary>Returns all paySplits for the given procNum. Must supply a list of all paysplits for the patient.</summary>
		public static ArrayList GetForProc(long procNum,PaySplit[] List) {
			//No need to check RemotingRole; no call to db.
			ArrayList retVal=new ArrayList();
			for(int i=0;i<List.Length;i++){
				if(List[i].ProcNum==procNum){
					retVal.Add(List[i]);
				}
			}
			return retVal;
		}
コード例 #8
0
ファイル: Payments.cs プロジェクト: ChemBrain/OpenDental
        ///<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.");
        }
コード例 #9
0
        ///<summary>Deletes the paysplit.</summary>
        public static void Delete(PaySplit split)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                Meth.GetVoid(MethodBase.GetCurrentMethod(), split);
                return;
            }
            string command = "DELETE from paysplit WHERE SplitNum = " + POut.Long(split.SplitNum);

            Db.NonQ(command);
        }
コード例 #10
0
 ///<summary>Determines if this is the same paysplit based on SplitNum or TagOD.</summary>
 public bool IsSame(PaySplit otherSplit)
 {
     if (this.SplitNum == otherSplit.SplitNum && this.SplitNum != 0)
     {
         return(true);
     }
     if (this.TagOD == otherSplit.TagOD)
     {
         return(true);
     }
     return(false);
 }
コード例 #11
0
ファイル: PaySplits.cs プロジェクト: nampn/ODental
 ///<summary>Used once in ContrAccount to just get the splits for a single patient.  The supplied list also contains splits that are not necessarily for this one patient.</summary>
 public static PaySplit[] GetForPatient(long patNum,PaySplit[] List)
 {
     //No need to check RemotingRole; no call to db.
     ArrayList retVal=new ArrayList();
     for(int i=0;i<List.Length;i++){
         if(List[i].PatNum==patNum){
             retVal.Add(List[i]);
         }
     }
     PaySplit[] retList=new PaySplit[retVal.Count];
     retVal.CopyTo(retList);
     return retList;
 }
コード例 #12
0
ファイル: AccountEntry.cs プロジェクト: ChemBrain/OpenDental
 public AccountEntry(PaySplit paySplit)
 {
     Tag            = paySplit;
     Date           = paySplit.DatePay;
     PriKey         = paySplit.SplitNum;
     AmountOriginal = 0 - (decimal)paySplit.SplitAmt;
     AmountStart    = AmountOriginal;
     AmountEnd      = AmountOriginal;
     ProvNum        = paySplit.ProvNum;
     SplitCollection.Add(paySplit);
     ClinicNum = paySplit.ClinicNum;
     PatNum    = paySplit.PatNum;
 }
コード例 #13
0
 ///<summary></summary>
 public static long Insert(PaySplit split)
 {
     if (RemotingClient.RemotingRole != RemotingRole.ServerWeb)
     {
         split.SecUserNumEntry = Security.CurUser.UserNum;              //must be before normal remoting role check to get user at workstation
     }
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         split.SplitNum = Meth.GetLong(MethodBase.GetCurrentMethod(), split);
         return(split.SplitNum);
     }
     return(Crud.PaySplitCrud.Insert(split));
 }
コード例 #14
0
        ///<summary>Used once in ContrAccount to just get the splits for a single patient.  The supplied list also contains splits that are not necessarily for this one patient.</summary>
        public static PaySplit[] GetForPatient(long patNum, PaySplit[] List)
        {
            //No need to check RemotingRole; no call to db.
            ArrayList retVal = new ArrayList();

            for (int i = 0; i < List.Length; i++)
            {
                if (List[i].PatNum == patNum)
                {
                    retVal.Add(List[i]);
                }
            }
            PaySplit[] retList = new PaySplit[retVal.Count];
            retVal.CopyTo(retList);
            return(retList);
        }
コード例 #15
0
        ///<summary>Returns the original prepayment.</summary>
        public static PaySplit GetOriginalPrepayment(PaySplit paySplit)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <PaySplit>(MethodBase.GetCurrentMethod(), paySplit));
            }
            long fSplitNum = paySplit.FSplitNum;

            if (paySplit.UnearnedType == 0)           //paySplit is pos allocation split, find negative income transfer split first
            {
                fSplitNum = Db.GetLong("SELECT FSplitNum FROM paysplit WHERE paysplit.SplitNum=" + POut.Long(paySplit.FSplitNum));
            }
            string command = "SELECT * FROM paysplit WHERE paysplit.SplitNum=" + POut.Long(fSplitNum);

            return(Crud.PaySplitCrud.SelectOne(command));
        }
コード例 #16
0
ファイル: PaySplit.cs プロジェクト: luisurbinanet/apolloniax
        ///<summary>Returns a copy of this PaySplit.</summary>
        public PaySplit Copy()
        {
            PaySplit p = new PaySplit();

            p.SplitNum   = SplitNum;
            p.SplitAmt   = SplitAmt;
            p.PatNum     = PatNum;
            p.ProcDate   = ProcDate;
            p.PayNum     = PayNum;
            p.ProvNum    = ProvNum;
            p.PayPlanNum = PayPlanNum;
            p.DatePay    = DatePay;
            p.ProcNum    = ProcNum;
            p.DateEntry  = DateEntry;
            return(p);
        }
コード例 #17
0
ファイル: PaySplits.cs プロジェクト: nampn/ODental
 ///<summary>Only those amounts that have the same paynum, procDate, and patNum as the payment, and are not attached to procedures.</summary>
 public static double GetAmountForPayment(long payNum,DateTime payDate,long patNum,PaySplit[] paySplitList)
 {
     //No need to check RemotingRole; no call to db.
     double retVal=0;
     for(int i=0;i<paySplitList.Length;i++){
         if(paySplitList[i].PayNum!=payNum) {
             continue;
         }
         if(paySplitList[i].PatNum!=patNum){
             continue;
         }
         if(paySplitList[i].ProcDate!=payDate){
             continue;
         }
         if(paySplitList[i].ProcNum!=0){
             continue;
         }
         retVal+=paySplitList[i].SplitAmt;
     }
     return retVal;
 }
コード例 #18
0
ファイル: FormPaySplitManage.cs プロジェクト: mnisl/OD
		///<summary>Creates a split similar to how CreateSplitsForPayment does it, but with selected rows of the grid.  If payAmt=0, pay charge in full.</summary>
		private void CreateSplit(AccountEntry charge,double payAmt) {
			PaySplit split=new PaySplit();
			split.DatePay=DateTime.Today;
			if(charge.GetType()==typeof(Procedure)) {//Row selected is a Procedure.
				Procedure proc=(Procedure)charge.Tag;
				split.ProcNum=charge.PriKey;
			}
			else if(charge.GetType()==typeof(PayPlanCharge)) {//Row selected is a PayPlanCharge.
				PayPlanCharge payPlanCharge=(PayPlanCharge)charge.Tag;
				split.PayPlanNum=payPlanCharge.PayPlanNum;
			}
			else if(charge.Tag.GetType()==typeof(Adjustment)) {//Row selected is an Adjustment.
				//Do nothing, nothing to link.
			}
			else {//PaySplits and overpayment refunds.
				//Do nothing, nothing to link.
			}
			double chargeAmt=charge.AmountEnd;
			if(Math.Abs(chargeAmt)<Math.Abs(payAmt) || payAmt==0) {//Full payment of charge
				split.SplitAmt=chargeAmt;
				charge.AmountEnd=0;//Reflect payment in underlying datastructure
			}
			else {//Partial payment of charge
				charge.AmountEnd-=payAmt;
				split.SplitAmt=payAmt;
			}
			if(!PrefC.GetBool(PrefName.EasyNoClinics)) {//Not no clinics
				split.ClinicNum=charge.ClinicNum;
			}
			split.ProvNum=charge.ProvNum;
			split.PatNum=charge.PatNum;
			split.ProcDate=charge.Date;
			split.PayNum=PaymentCur.PayNum;
			charge.ListPaySplits.Add(split);
			ListSplitsCur.Add(split);
		}
コード例 #19
0
ファイル: Payments.cs プロジェクト: mnisl/OD
		/// <summary>Only Called only from FormPayment.butOK click.  Only called if the user did not enter any splits.  Usually just adds one split for the current patient.  But if that would take the balance negative, then it loops through all other family members and creates splits for them.  It might still take the current patient negative once all other family members are zeroed out.</summary>
		public static List<PaySplit> Allocate(Payment pay){//double amtTot,int patNum,Payment payNum){
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				return Meth.GetObject<List<PaySplit>>(MethodBase.GetCurrentMethod(),pay);
			}
			string command= 
				"SELECT Guarantor FROM patient "
				+"WHERE PatNum = "+POut.Long(pay.PatNum);
 			DataTable table=Db.GetTable(command);
			if(table.Rows.Count==0){
				return new List<PaySplit>();
			}
			command= 
				"SELECT patient.PatNum,EstBalance,PriProv,SUM(InsPayEst)+SUM(Writeoff) insEst_ "
				+"FROM patient "
				+"LEFT JOIN claimproc ON patient.PatNum=claimproc.PatNum "
				+"AND Status=0 "//NotReceived
				+"WHERE Guarantor = "+table.Rows[0][0].ToString()+" "
				+"GROUP BY  patient.PatNum,EstBalance,PriProv";
				//+" ORDER BY PatNum!="+POut.PInt(pay.PatNum);//puts current patient in position 0 //Oracle does not allow
 			table=Db.GetTable(command);
			List<Patient> pats=new List<Patient>();
			Patient pat;
			//first, put the current patient at position 0.
			for(int i=0;i<table.Rows.Count;i++) {
				if(table.Rows[i]["PatNum"].ToString()==pay.PatNum.ToString()){
					pat=new Patient();
					pat.PatNum    = PIn.Long(table.Rows[i][0].ToString());
					pat.EstBalance= PIn.Double(table.Rows[i][1].ToString());
					if(!PrefC.GetBool(PrefName.BalancesDontSubtractIns)){
						pat.EstBalance-=PIn.Double(table.Rows[i]["insEst_"].ToString());
					}
					pat.PriProv   = PIn.Long(table.Rows[i][2].ToString());
					pats.Add(pat.Copy());
				}
			}
			//then, do all the rest of the patients.
			for(int i=0;i<table.Rows.Count;i++){
				if(table.Rows[i]["PatNum"].ToString()==pay.PatNum.ToString()){
					continue;
				}
				pat=new Patient();
				pat.PatNum    = PIn.Long   (table.Rows[i][0].ToString());
				pat.EstBalance= PIn.Double(table.Rows[i][1].ToString());
				if(!PrefC.GetBool(PrefName.BalancesDontSubtractIns)){
					pat.EstBalance-=PIn.Double(table.Rows[i]["insEst_"].ToString());
				}
				pat.PriProv   = PIn.Long   (table.Rows[i][2].ToString());
				pats.Add(pat.Copy());
			}
			//first calculate all the amounts
			double amtRemain=pay.PayAmt;//start off with the full amount
			double[] amtSplits=new double[pats.Count];
			//loop through each family member, starting with current
			for(int i=0;i<pats.Count;i++){
				if(pats[i].EstBalance==0 || pats[i].EstBalance<0){
					continue;//don't apply paysplits to anyone with a negative balance
				}
				if(amtRemain<pats[i].EstBalance){//entire remainder can be allocated to this patient
					amtSplits[i]=amtRemain;
					amtRemain=0;
					break;
				}
				else{//amount remaining is more than or equal to the estBal for this family member
					amtSplits[i]=pats[i].EstBalance;
					amtRemain-=pats[i].EstBalance;
				}
			}
			//add any remainder to the split for this patient
			amtSplits[0]+=amtRemain;
			//now create a split for each non-zero amount
			PaySplit PaySplitCur;
			List<PaySplit> retVal=new List<PaySplit>();
			for(int i=0;i<pats.Count;i++){
				if(amtSplits[i]==0){
					continue;
				}
				PaySplitCur=new PaySplit();
				PaySplitCur.PatNum=pats[i].PatNum;
				PaySplitCur.PayNum=pay.PayNum;
				PaySplitCur.ProcDate=pay.PayDate;
				PaySplitCur.DatePay=pay.PayDate;
				PaySplitCur.ClinicNum=pay.ClinicNum;
				PaySplitCur.ProvNum=Patients.GetProvNum(pats[i]);
				PaySplitCur.SplitAmt=Math.Round(amtSplits[i],CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits);
				//PaySplitCur.InsertOrUpdate(true);
				retVal.Add(PaySplitCur);
			}
			//finally, adjust each EstBalance, but no need to do current patient
			//This no longer works here.  Must do it when closing payment window somehow
			/*for(int i=1;i<pats.Length;i++){
				if(amtSplits[i]==0){
					continue;
				}
				command="UPDATE patient SET EstBalance=EstBalance-"+POut.PDouble(amtSplits[i])
					+" WHERE PatNum="+POut.PInt(pats[i].PatNum);
				Db.NonQ(command);
			}*/
			return retVal;
		}
コード例 #20
0
        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);
        }
コード例 #21
0
ファイル: FormPayment.cs プロジェクト: nampn/ODental
 private void butOK_Click(object sender,System.EventArgs e)
 {
     if(textDate.errorProvider1.GetError(textDate)!=""
         || textAmount.errorProvider1.GetError(textAmount)!="") {
         MessageBox.Show(Lan.g(this,"Please fix data entry errors first."));
         return;
     }
     if(checkPayTypeNone.Checked) {
         if(PIn.Double(textAmount.Text)!=0) {
             MsgBox.Show(this,"Amount must be zero for a transfer.");
             return;
         }
     }
     else {
         if(textAmount.Text=="") {
             MessageBox.Show(Lan.g(this,"Please enter an amount."));
             return;
         }
         if(PIn.Double(textAmount.Text)==0) {
             MessageBox.Show(Lan.g(this,"Amount must not be zero unless this is a transfer."));
             return;
         }
         if(listPayType.SelectedIndex==-1) {
             MsgBox.Show(this,"A payment type must be selected.");
         }
     }
     if(IsNew) {
         //prevents backdating of initial payment
         if(!Security.IsAuthorized(Permissions.PaymentCreate,PIn.Date(textDate.Text))) {
             return;
         }
     }
     else {
         //Editing an old entry will already be blocked if the date was too old, and user will not be able to click OK button
         //This catches it if user changed the date to be older.
         if(!Security.IsAuthorized(Permissions.PaymentEdit,PIn.Date(textDate.Text))) {
             return;
         }
     }
     bool accountingSynchRequired=false;
     double accountingOldAmt=PaymentCur.PayAmt;
     long accountingNewAcct=-1;//the old acctNum will be retrieved inside the validation code.
     if(textDepositAccount.Visible) {
         accountingNewAcct=-1;//indicates no change
     }
     else if(comboDepositAccount.Visible && comboDepositAccount.Items.Count>0 && comboDepositAccount.SelectedIndex!=-1) {
         accountingNewAcct=DepositAccounts[comboDepositAccount.SelectedIndex];
     }
     else {//neither textbox nor combo visible. Or something's wrong with combobox
         accountingNewAcct=0;
     }
     try {
         accountingSynchRequired=Payments.ValidateLinkedEntries(accountingOldAmt,PIn.Double(textAmount.Text),IsNew,
             PaymentCur.PayNum,accountingNewAcct);
     }
     catch(ApplicationException ex) {
         MessageBox.Show(ex.Message);//not able to alter, so must not allow user to continue.
         return;
     }
     PaymentCur.PayAmt=PIn.Double(textAmount.Text);//handles blank
     PaymentCur.PayDate=PIn.Date(textDate.Text);
     #region Recurring charge logic
     //User chose to have a recurring payment so we need to know if the card has recurring setup and which month to apply the payment to.
     if(IsNew && checkRecurring.Checked && comboCreditCards.SelectedIndex!=creditCards.Count) {
         //Check if a recurring charge is setup for the selected card.
         if(creditCards[comboCreditCards.SelectedIndex].ChargeAmt==0
             || creditCards[comboCreditCards.SelectedIndex].DateStart.Year < 1880)
         {
             MsgBox.Show(this,"The selected credit card has not been setup for recurring charges.");
             return;
         }
         //Check if a stop date was set and if that date falls in on today or in the past.
         if(creditCards[comboCreditCards.SelectedIndex].DateStop.Year > 1880
             && creditCards[comboCreditCards.SelectedIndex].DateStop<=DateTime.Now)
         {
             MsgBox.Show(this,"This card is no longer accepting recurring charges based on the stop date.");
             return;
         }
         //Have the user decide what month to apply the recurring charge towards.
         FormCreditRecurringDateChoose formDateChoose=new FormCreditRecurringDateChoose(creditCards[comboCreditCards.SelectedIndex]);
         formDateChoose.ShowDialog();
         if(formDateChoose.DialogResult!=DialogResult.OK) {
             MsgBox.Show(this,"Uncheck the \"Apply to Recurring Charge\" box.");
             return;
         }
         //This will change the PayDate to work better with the recurring charge automation.  User was notified in previous window.
         PaymentCur.PayDate=formDateChoose.PayDate;
     }
     else if(IsNew && checkRecurring.Checked && comboCreditCards.SelectedIndex==creditCards.Count) {
         MsgBox.Show(this,"Cannot apply a recurring charge to a new card.");
         return;
     }
     #endregion
     PaymentCur.CheckNum=textCheckNum.Text;
     PaymentCur.BankBranch=textBankBranch.Text;
     PaymentCur.PayNote=textNote.Text;
     PaymentCur.IsRecurringCC=checkRecurring.Checked;
     if(checkPayTypeNone.Checked) {
         PaymentCur.PayType=0;
     }
     else {
         PaymentCur.PayType=DefC.Short[(int)DefCat.PaymentTypes][listPayType.SelectedIndex].DefNum;
     }
     //PaymentCur.PatNum=PatCur.PatNum;//this is already done before opening this window.
     //PaymentCur.ClinicNum already handled
     if(SplitList.Count==0) {
         if(Payments.AllocationRequired(PaymentCur.PayAmt,PaymentCur.PatNum)
             && MsgBox.Show(this,true,"Apply part of payment to other family members?")) {
             SplitList=Payments.Allocate(PaymentCur);//PayAmt needs to be set first
         }
         else {//Either no allocation required, or user does not want to allocate.  Just add one split.
             PaySplit split=new PaySplit();
             split.PatNum=PaymentCur.PatNum;
             split.ClinicNum=PaymentCur.ClinicNum;
             split.PayNum=PaymentCur.PayNum;
             split.ProcDate=PaymentCur.PayDate;
             split.DatePay=PaymentCur.PayDate;
             split.ProvNum=Patients.GetProvNum(PatCur);
             split.SplitAmt=PaymentCur.PayAmt;
             SplitList.Add(split);
         }
     }
     else if(SplitList.Count==1//if one split
         && PIn.Double(textAmount.Text) != SplitList[0].SplitAmt)//and amount doesn't match payment
     {
         SplitList[0].SplitAmt=PIn.Double(textAmount.Text);//make amounts match
     }
     else if(SplitList.Count==1//if one split
         && PaymentCur.PayDate != SplitList[0].ProcDate
         && SplitList[0].ProcNum==0)//not attached to procedure
     {
         if(MsgBox.Show(this,MsgBoxButtons.YesNo,"Change split date to match payment date?")) {
             SplitList[0].ProcDate=PaymentCur.PayDate;
         }
     }
     else if(PaymentCur.PayAmt!=PIn.Double(textTotal.Text)) {
         MsgBox.Show(this,"Split totals must equal payment amount.");
         //work on reallocation schemes here later
         return;
     }
     if(SplitList.Count>1) {
         PaymentCur.IsSplit=true;
     }
     else {
         PaymentCur.IsSplit=false;
     }
     try {
         Payments.Update(PaymentCur,true);
     }
     catch(ApplicationException ex) {//this catches bad dates.
         MessageBox.Show(ex.Message);
         return;
     }
     //Set all DatePays the same.
     for(int i=0;i<SplitList.Count;i++) {
         SplitList[i].DatePay=PaymentCur.PayDate;
     }
     PaySplits.UpdateList(SplitListOld,SplitList);
     //Accounting synch is done here.  All validation was done further up
     //If user is trying to change the amount or linked account of an entry that was already copied and linked to accounting section
     if(accountingSynchRequired) {
         Payments.AlterLinkedEntries(accountingOldAmt,PIn.Double(textAmount.Text),IsNew,
             PaymentCur.PayNum,accountingNewAcct,PaymentCur.PayDate,FamCur.GetNameInFamFL(PaymentCur.PatNum));
     }
     if(IsNew) {
         SecurityLogs.MakeLogEntry(Permissions.PaymentCreate,PaymentCur.PatNum,
             Patients.GetLim(PaymentCur.PatNum).GetNameLF()+", "
             +PaymentCur.PayAmt.ToString("c"));
     }
     else {
         SecurityLogs.MakeLogEntry(Permissions.PaymentEdit,PaymentCur.PatNum,
             Patients.GetLim(PaymentCur.PatNum).GetNameLF()+", "
             +PaymentCur.PayAmt.ToString("c"));
     }
     DialogResult=DialogResult.OK;
 }
コード例 #22
0
ファイル: FormPaySplitManage.cs プロジェクト: mnisl/OD
		///<summary>Creates a manual paysplit.</summary>
		private void butAdd_Click(object sender,EventArgs e) {
			PaySplit paySplit=new PaySplit();
			paySplit.SplitAmt=0;
			paySplit.DateEntry=DateTime.Today;
			paySplit.DatePay=DateTime.Today;
			paySplit.PayNum=PaymentCur.PayNum;
			FormPaySplitEdit FormPSE=new FormPaySplitEdit(FamCur);
			FormPSE.PaySplitCur=paySplit;
			if(FormPSE.ShowDialog()==DialogResult.OK) {
				UpdateForManualSplit(paySplit);
			}
		}
コード例 #23
0
ファイル: FormPaySplitManage.cs プロジェクト: mnisl/OD
		///<summary>Updates the underlying data structures when a manual split is created or edited.</summary>
		private void UpdateForManualSplit(PaySplit paySplit) {
			//Find the charge row for this new split.
			ListSplitsCur.Add(paySplit);
			List<PayPlanCharge> listCharges=PayPlanCharges.GetForPayPlan(paySplit.PayPlanNum);
			List<long> listPayPlanChargeNums=new List<long>();
			for(int j=0;j<listCharges.Count;j++) {
				listPayPlanChargeNums.Add(listCharges[j].PayPlanChargeNum);
			}
			//Locate a charge to apply the credit to, if a reasonable match exists.
			for(int i=0;i<_listAccountCharges.Count;i++) {
				AccountEntry charge=_listAccountCharges[i];
				if(charge.AmountEnd==0) {
					continue;
				}
				bool isMatchFound=false;
				if(charge.GetType()==typeof(Procedure) && charge.PriKey==paySplit.ProcNum) {//New Split is for this proc
					isMatchFound=true;
				}
				else if(charge.GetType()==typeof(Adjustment) //New split is for this adjust
						&& paySplit.ProcNum==0 && paySplit.PayPlanNum==0 //Both being 0 is the only way we can tell it's for an Adj
						&& paySplit.ProcDate==charge.Date
						&& paySplit.ProvNum==charge.ProvNum)
				{
					isMatchFound=true;
				}
				else if(charge.GetType()==typeof(PayPlanCharge) && listPayPlanChargeNums.Contains(charge.PriKey)) {//Payplancharge of same payplan as paysplit
					isMatchFound=true;
				}				
				if(isMatchFound) {
					double amtOwed=charge.AmountEnd;
					if(Math.Abs(amtOwed)<Math.Abs(paySplit.SplitAmt)) {//Partial payment
						charge.AmountEnd=0;//Reflect payment in underlying datastructure
					}
					else {//Full payment
						charge.AmountEnd=amtOwed-paySplit.SplitAmt;
					}
					charge.ListPaySplits.Add(paySplit);
				}
				//If none of these, it's unattached to the best of our knowledge.				
			}			
			FillGridSplits();//Fills charge grid too.
		}
コード例 #24
0
ファイル: FormPaySplitEdit.cs プロジェクト: nampn/ODental
 private void ButCancel_Click(object sender, System.EventArgs e)
 {
     if(IsNew) {
         PaySplitCur=null;
     }
     DialogResult=DialogResult.Cancel;
 }
コード例 #25
0
 public PaySplitAssociated(PaySplit paySplitOrig, PaySplit paySplitLinked)
 {
     //assign passed-in values
     PaySplitOrig   = paySplitOrig;
     PaySplitLinked = paySplitLinked;
 }
コード例 #26
0
ファイル: FormPaySplitManage.cs プロジェクト: mnisl/OD
		///<summary>Creates paysplits associated to the patient passed in for the current payment until the payAmt has been met.  
		///Returns the list of new paysplits that have been created.  PaymentAmt will attempt to move towards 0 as paysplits are created.</summary>
		private List<PaySplit> AutoSplitForPayment(long payNum,DateTime date,bool isTest) {
			//Get the lists of items we'll be using to calculate with.
			List<Procedure> listProcs=Procedures.GetCompleteForPats(listPatNums);
			//listPayments should be empty, there isn't currently a way to make payments without at least one split.
			//During research however we found there were sometimes payments with no splits, so erred on the side of caution.
			List<Payment> listPayments=Payments.GetNonSplitForPats(listPatNums);
			List<Adjustment> listAdjustments=Adjustments.GetAdjustForPats(listPatNums);
			List<PaySplit> listPaySplits=PaySplits.GetForPats(listPatNums);//Might contain payplan payments.
			//Fix the memory locations of the existing pay splits for this payment within the list of pay splits for the entire family.
			//This is necessary for associating the correct tag values to grid rows.
			for(int i=0;i<listPaySplits.Count;i++) {
				for(int j=0;j<ListSplitsCur.Count;j++) {
					if(listPaySplits[i].SplitNum==ListSplitsCur[j].SplitNum) {
						listPaySplits[i]=ListSplitsCur[j];
					}
				}
			}
			List<ClaimProc> listInsPayAsTotal=ClaimProcs.GetByTotForPats(listPatNums);//Claimprocs paid as total, might contain ins payplan payments.
			List<PayPlan> listPayPlans=PayPlans.GetForPats(listPatNums,PatCur.PatNum);//Used to figure out how much we need to pay off procs with, also contains insurance payplans.
			List<PayPlanCharge> listPayPlanCharges=new List<PayPlanCharge>();
			if(listPayPlans.Count>0){
				listPayPlanCharges=PayPlanCharges.GetDueForPayPlans(listPayPlans,PatCur.PatNum);//Does not get charges for the future.
			}
			List<ClaimProc> listClaimProcs=new List<ClaimProc>();
			for(int i=0;i<listPatNums.Count;i++) {
				listClaimProcs.AddRange(ClaimProcs.Refresh(listPatNums[i]));//There is no ClaimProcs.Refresh() for a family.
			}
			//Calculated using writeoffs, inspayest, inspayamt.  Done the same way ContrAcct does it.				
			for(int i=0;i<listProcs.Count;i++) {
				listProcs[i].ProcFee=ClaimProcs.GetPatPortion(listProcs[i],listClaimProcs);
			}
			//Over the next 5 regions, we will do the following:
			//Create a list of account charges
			//Create a list of account credits
			//Explicitly link any of the credits to their corresponding charges if a link can be made. (ie. PaySplit.ProcNum to a Procedure.ProcNum)
			//Implicitly link any of the remaining credits to the non-zero charges FIFO by date.
			//Create Auto-splits for the current payment to any remaining non-zero charges FIFO by date.
			#region Construct List of Charges
			_listAccountCharges=new List<AccountEntry>();
			for(int i=0;i<listPayPlanCharges.Count;i++) {
				_listAccountCharges.Add(new AccountEntry(listPayPlanCharges[i]));
			}
			for(int i=0;i<listAdjustments.Count;i++) {
				if(listAdjustments[i].AdjAmt>0 && listAdjustments[i].ProcNum==0) {
					_listAccountCharges.Add(new AccountEntry(listAdjustments[i]));
				}
			}
			for(int i=0;i<listProcs.Count;i++) {
				_listAccountCharges.Add(new AccountEntry(listProcs[i]));
			}
			_listAccountCharges.Sort(AccountEntrySort);
			#endregion Construct List of Charges
			#region Construct List of Credits
			//Getting a date-sorted list of all credits that haven't been attributed to anything.
			double creditTotal=0;
			for(int i=0;i<listAdjustments.Count;i++) {
				if(listAdjustments[i].AdjAmt<0) {
					creditTotal-=listAdjustments[i].AdjAmt;
				}
			}
			for(int i=0;i<listPaySplits.Count;i++) {
				creditTotal+=listPaySplits[i].SplitAmt;
			}
			for(int i=0;i<ListSplitsCur.Count;i++) {
				if(ListSplitsCur[i].SplitNum==0) {
					//If they created new splits on an old payment we need to add those to the credits list since they won't be over-written unlike a new payment.
					creditTotal+=ListSplitsCur[i].SplitAmt;//Adding splits that haven't been entered into DB yet (re-opened split manager)
				}
			}
			for(int i=0;i<listPayments.Count;i++) {
				creditTotal+=listPayments[i].PayAmt;
			}
			for(int i=0;i<listInsPayAsTotal.Count;i++) {			
				creditTotal+=listInsPayAsTotal[i].InsPayAmt;
			}
			for(int i=0;i<listPayPlans.Count;i++) {
				creditTotal+=listPayPlans[i].CompletedAmt;
			}
			#endregion Construct List of Credits
			#region Explicitly Link Credits
			for(int i=0;i<_listAccountCharges.Count;i++) {
				AccountEntry charge=_listAccountCharges[i];
				for(int j=0;j<listPaySplits.Count;j++) {
					PaySplit paySplit=listPaySplits[j];
					if(charge.GetType()==typeof(Procedure) && paySplit.ProcNum==charge.PriKey) {
						charge.ListPaySplits.Add(paySplit);
						charge.AmountEnd-=paySplit.SplitAmt;
						creditTotal-=paySplit.SplitAmt;
						if(paySplit.PayNum!=PaymentCur.PayNum) {//This will make it so the AmountOriginal will reflect only what this payment paid.
							charge.AmountStart-=paySplit.SplitAmt;
						}
					}
					else if(charge.GetType()==typeof(PayPlanCharge) && ((PayPlanCharge)charge.Tag).PayPlanNum==paySplit.PayPlanNum && charge.AmountEnd>0 && paySplit.SplitAmt>0) {
						charge.AmountEnd-=paySplit.SplitAmt;
						creditTotal-=paySplit.SplitAmt;
					}
				}
				for(int j=0;j<ListSplitsCur.Count;j++) {//Explicitly join paysplits in ListSplitsCur that haven't been entered into DB yet.
					PaySplit paySplit=ListSplitsCur[j];
					if(paySplit.SplitNum!=0) {
						continue;//Skip splits that are already in DB, they're taken care of in the previous loop
					}
					if(charge.GetType()==typeof(Procedure) && paySplit.ProcNum==charge.PriKey) {
						charge.ListPaySplits.Add(paySplit);
						charge.AmountEnd-=paySplit.SplitAmt;
						creditTotal-=paySplit.SplitAmt;
					}
					else if(charge.GetType()==typeof(PayPlanCharge) && ((PayPlanCharge)charge.Tag).PayPlanNum==paySplit.PayPlanNum && charge.AmountEnd>0 && paySplit.SplitAmt>0) {
						charge.AmountEnd-=paySplit.SplitAmt;
						creditTotal-=paySplit.SplitAmt;
					}
				}
				for(int j=0;j<listAdjustments.Count;j++) {
					Adjustment adjustment=listAdjustments[j];
					if(charge.GetType()==typeof(Procedure) && adjustment.ProcNum==charge.PriKey) {
						charge.AmountEnd+=adjustment.AdjAmt;
						if(adjustment.AdjAmt<0) {
							creditTotal+=adjustment.AdjAmt;
						}
						charge.AmountStart+=adjustment.AdjAmt;//If the adjustment is attached to a procedure decrease the procedure's amountoriginal so we know what it was just prior to autosplitting.
					}
				}
			}
			#endregion Explicitly Link Credits
			//Apply negative charges as if they're credits.
			for(int i=0;i<_listAccountCharges.Count;i++) {
				AccountEntry entryCharge=_listAccountCharges[i];
				if(entryCharge.AmountEnd<0) {
					creditTotal-=entryCharge.AmountEnd;
					entryCharge.AmountEnd=0;
				}				
			}
			#region Implicitly Link Credits
			//Now we have a date-sorted list of all the unpaid charges as well as all non-attributed credits.  
			//We need to go through each and pay them off in order until all we have left is the most recent unpaid charges.
			for(int i=0;i<_listAccountCharges.Count && creditTotal>0;i++) {
				AccountEntry charge=_listAccountCharges[i];
				double amt=Math.Min(charge.AmountEnd,creditTotal);
				charge.AmountEnd-=amt;
				creditTotal-=amt;
				charge.AmountStart-=amt;//Decrease amount original for the charge so we know what it was just prior to when the autosplits were made.
			}
			#endregion Implicitly Link Credits
			#region Auto-Split Current Payment
			//At this point we have a list of procs, positive adjustments, and payplancharges that require payment if the Amount>0.   
			//Create and associate new paysplits to their respective charge items.
			List<PaySplit> listAutoSplits=new List<PaySplit>();
			PaySplit split;
			for(int i=0;i<_listAccountCharges.Count;i++) {
				if(PaymentAmt==0) {
					break;
				}
				AccountEntry charge=_listAccountCharges[i];
				if(charge.AmountEnd==0) {
					continue;//Skip charges which are already paid.
				}
				if(PaymentAmt<0 && charge.AmountEnd>0) {//If they're different signs, don't make any guesses.  
					//Remaining credits will always be all of one sign.
					if(!isTest) {
						MsgBox.Show(this,"Payment cannot be automatically allocated because there are no outstanding negative balances.");
					}
					return listAutoSplits;//Will be empty
				}
				split=new PaySplit();
				if(Math.Abs(charge.AmountEnd)<Math.Abs(PaymentAmt)) {//charge has "less" than the payment, use partial payment.
					split.SplitAmt=charge.AmountEnd;
					PaymentAmt-=charge.AmountEnd;
					charge.AmountEnd=0;
				}
				else {//Use full payment
					split.SplitAmt=PaymentAmt;
					charge.AmountEnd-=PaymentAmt;
					PaymentAmt=0;
				}
				split.DatePay=date;
				split.PatNum=charge.PatNum;
				split.ProcDate=charge.Date;
				split.ProvNum=charge.ProvNum;
				if(!PrefC.GetBool(PrefName.EasyNoClinics)) {//Clinics
					split.ClinicNum=charge.ClinicNum;
				}
				if(charge.GetType()==typeof(Procedure)) {
					split.ProcNum=charge.PriKey;
				}
				else if(charge.GetType()==typeof(PayPlanCharge)) {
					split.PayPlanNum=((PayPlanCharge)charge.Tag).PayPlanNum;
				}
				split.PayNum=payNum;
				charge.ListPaySplits.Add(split);
				listAutoSplits.Add(split);
			}
			if(listAutoSplits.Count==0 && ListSplitsCur.Count==0 && PaymentAmt!=0) {//Ensure there is at least one auto split if they entered a payAmt.
				split=new PaySplit();
				split.SplitAmt=PaymentAmt;
				PaymentAmt=0;
				split.DatePay=date;
				split.PatNum=PaymentCur.PatNum;
				split.ProcDate=PaymentCur.PayDate;
				split.ProvNum=0;
				if(!PrefC.GetBool(PrefName.EasyNoClinics)) {//Clinics
					split.ClinicNum=PaymentCur.ClinicNum;
				}
				split.PayNum=payNum;
				listAutoSplits.Add(split);
			}
			#endregion Auto-Split Current Payment
			return listAutoSplits;
		}
コード例 #27
0
ファイル: FormPayment.cs プロジェクト: nampn/ODental
 private void butPay_Click(object sender,EventArgs e)
 {
     if(gridBal.SelectedIndices.Length==0) {
         gridBal.SetSelected(true);
     }
     SplitList.Clear();
     double amt;
     PaySplit split;
     for(int i=0;i<gridBal.SelectedIndices.Length;i++) {
         if(PrefC.GetBool(PrefName.BalancesDontSubtractIns)) {
             amt=PIn.Double(tableBalances.Rows[gridBal.SelectedIndices[i]]["StartBal"].ToString());
         }
         else {
             amt=PIn.Double(tableBalances.Rows[gridBal.SelectedIndices[i]]["AfterIns"].ToString());
         }
         if(amt==0) {
             continue;
         }
         split=new PaySplit();
         split.PatNum=PIn.Long(tableBalances.Rows[gridBal.SelectedIndices[i]]["PatNum"].ToString());
         split.PayNum=PaymentCur.PayNum;
         split.ProcDate=PaymentCur.PayDate;//this may be updated upon closing
         split.DatePay=PaymentCur.PayDate;//this may be updated upon closing
         split.ProvNum=PIn.Long(tableBalances.Rows[gridBal.SelectedIndices[i]]["ProvNum"].ToString());
         split.ClinicNum=PIn.Long(tableBalances.Rows[gridBal.SelectedIndices[i]]["ClinicNum"].ToString());
         split.SplitAmt=amt;
         SplitList.Add(split);
     }
     FillMain();
     textAmount.Text=textTotal.Text;
 }
コード例 #28
0
        public static List <PaySplit> CreateSplitForPayPlan(Payment paymentCur, AccountEntry payPlanEntry, List <PayPlanCharge> listPayPlanCredits,
                                                            List <AccountEntry> listAccountCharges, decimal payAmt, bool isAutoSplit, out decimal paymentCurPayAmt)
        {
            //No remoting role check; no call to db. Plus this method has an out parameter.
            paymentCurPayAmt = (decimal)paymentCur.PayAmt;
            List <PaySplit> listSplits = new List <PaySplit>();
            DateTime        today      = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 0, 0, 0, DateTimeKind.Unspecified);
            //if the payAmt is > 0 and it's NOT an autosplit, we only want to pay up to the payAmt.
            bool          isPartial        = (payAmt > 0) && !isAutoSplit;
            PayPlanCharge payPlanChargeCur = (PayPlanCharge)payPlanEntry.Tag;
            //amtUnattached will also include principal payments if those payments are not allocated to a procedure.
            //This is accounted for when creating an unattached split.
            double amtUnattachedAlreadyPaid = (double)payPlanEntry.SplitCollection.Where(x => x.ProcNum == 0).Sum(y => y.SplitAmt);
            double amtAttachedAlreadyPaid   = (double)payPlanEntry.SplitCollection.Where(x => x.ProcNum != 0).Sum(y => y.SplitAmt);

            //Below is the logic of this method: For the passed in charge
            //create a split for the amount of the interest
            //create a split for the amount of the charge, attach it to the procedure if possible.
            //interest split, only create if interest hasn't already been paid.
            if (amtUnattachedAlreadyPaid < payPlanChargeCur.Interest)
            {
                PaySplit interest = new PaySplit();
                interest.DatePay = today;
                //the split should always go to the payplancharge's guarantor.
                interest.PatNum  = payPlanChargeCur.Guarantor;
                interest.ProvNum = payPlanChargeCur.ProvNum;
                if (PrefC.HasClinicsEnabled)                 //Clinics
                {
                    interest.ClinicNum = payPlanChargeCur.ClinicNum;
                }
                interest.PayPlanNum = payPlanChargeCur.PayPlanNum;
                interest.PayNum     = paymentCur.PayNum;
                //if it's an autoSplit, then only use up to the global PaymentAmt.
                //else if it's a partial split, then only use up to payAmt.
                //else it's a manual split, so just add a split for the entire charge.
                if (isAutoSplit)
                {
                    interest.SplitAmt = Math.Min(payPlanChargeCur.Interest - amtUnattachedAlreadyPaid, (double)paymentCurPayAmt);
                    paymentCurPayAmt -= (decimal)interest.SplitAmt;
                }
                else if (isPartial)
                {
                    interest.SplitAmt = Math.Min(payPlanChargeCur.Interest - amtUnattachedAlreadyPaid, (double)payAmt);
                    payAmt           -= (decimal)interest.SplitAmt;
                    paymentCurPayAmt -= (decimal)interest.SplitAmt;
                }
                else
                {
                    interest.SplitAmt = payPlanChargeCur.Interest - amtUnattachedAlreadyPaid;
                }
                //this is so the paysplit says (interest) in the grid.
                interest.IsInterestSplit = true;
                payPlanEntry.AmountEnd  -= (decimal)interest.SplitAmt;
                payPlanEntry.SplitCollection.Add(interest);
                listSplits.Add(interest);
            }
            //get all procs associated to this plan
            List <AccountEntry> listPayPlanProcsEntries = new List <AccountEntry>();

            foreach (PayPlanCharge payPlanCredit in listPayPlanCredits)         //For each credit
            {
                foreach (AccountEntry entry in listAccountCharges)              //Go through account entries
                {
                    if (entry.GetType() != typeof(Procedure))                   //If it's not a proc
                    {
                        continue;
                    }
                    Procedure proc = (Procedure)entry.Tag;
                    if (proc.ProcNum == payPlanCredit.ProcNum)                   //See if the proc has the credit's procnum
                    {
                        listPayPlanProcsEntries.Add(entry);                      //if so, add it so we then have a list of payplan's procs, and we can also show how much is left due for it
                    }
                }
            }
            listPayPlanProcsEntries = listPayPlanProcsEntries.OrderBy(x => x.Date).ToList();
            if (amtAttachedAlreadyPaid < payPlanChargeCur.Principal)
            {
                if (listPayPlanProcsEntries.Count > 0)
                {
                    double amtAvail = (double)payPlanEntry.AmountEnd;
                    foreach (AccountEntry entryProc in listPayPlanProcsEntries)
                    {
                        if (isAutoSplit && paymentCurPayAmt == 0)
                        {
                            break;
                        }
                        Procedure procCur   = (Procedure)entryProc.Tag;
                        PaySplit  procSplit = new PaySplit();
                        //get the amount of this procedure that's attached to this payment plan
                        double maxSplitForCurrentProc = listPayPlanCredits.Where(x => x.ProcNum == procCur.ProcNum).Sum(y => y.Principal);
                        //get the amount of this procedure that's already been paid off in this payment plan.
                        maxSplitForCurrentProc -= entryProc.SplitCollection.Where(x => x.PayPlanNum == payPlanChargeCur.PayPlanNum).Sum(y => y.SplitAmt);
                        if (maxSplitForCurrentProc == 0)
                        {
                            continue;
                        }
                        procSplit.DatePay = today;
                        //the payment should always go to the account of the payplancharge's guarantor.
                        procSplit.PatNum     = payPlanChargeCur.Guarantor;
                        procSplit.PayPlanNum = payPlanChargeCur.PayPlanNum;
                        procSplit.PayNum     = paymentCur.PayNum;
                        if (isAutoSplit)
                        {
                            //make a split for the procedure for no more than the sum of all the credits on the payment plan for that procedure.
                            procSplit.SplitAmt = Math.Min(maxSplitForCurrentProc, Math.Min(amtAvail, (double)paymentCurPayAmt));
                            paymentCurPayAmt  -= (decimal)procSplit.SplitAmt;
                        }
                        else if (isPartial)
                        {
                            if (payAmt == 0)
                            {
                                break;
                            }
                            procSplit.SplitAmt = Math.Min(maxSplitForCurrentProc, Math.Min(amtAvail, (double)payAmt));
                            payAmt            -= (decimal)procSplit.SplitAmt;
                            paymentCurPayAmt  -= (decimal)procSplit.SplitAmt;
                        }
                        else
                        {
                            procSplit.SplitAmt = Math.Min((double)maxSplitForCurrentProc, amtAvail);                          //make a split for the procedure for no more than the sum of all the credits on the payment plan for that procedure.
                        }
                        procSplit.ProvNum   = procCur.ProvNum;
                        procSplit.ClinicNum = procCur.ClinicNum;
                        procSplit.ProcNum   = procCur.ProcNum;
                        amtAvail           -= procSplit.SplitAmt;
                        entryProc.SplitCollection.Add(procSplit);
                        payPlanEntry.AmountEnd -= (decimal)procSplit.SplitAmt;
                        payPlanEntry.SplitCollection.Add(procSplit);
                        listSplits.Add(procSplit);
                    }
                    //if they have a mix of attached and unattached credits: (if there are payplan charges not linked to a procedure)
                    bool doCreateUnattachedSplit = payPlanEntry.AmountEnd > 0 && ((isAutoSplit && Math.Min(amtAvail, (double)paymentCurPayAmt) > 0) ||
                                                                                  (!isAutoSplit && Math.Min(amtAvail, (double)payAmt) > 0));
                    if (doCreateUnattachedSplit)
                    {
                        PaySplit unattachedSplit = new PaySplit();
                        unattachedSplit.DatePay = today;
                        //the payment should always go to the account of the payplancharge's guarantor.
                        unattachedSplit.PatNum     = payPlanChargeCur.Guarantor;
                        unattachedSplit.PayPlanNum = payPlanChargeCur.PayPlanNum;
                        unattachedSplit.PayNum     = paymentCur.PayNum;
                        if (isAutoSplit)
                        {
                            unattachedSplit.SplitAmt = Math.Min(amtAvail, (double)paymentCurPayAmt);
                            paymentCurPayAmt        -= (decimal)unattachedSplit.SplitAmt;
                        }
                        else if (isPartial)
                        {
                            unattachedSplit.SplitAmt = Math.Min(amtAvail, (double)payAmt);
                            payAmt           -= (decimal)unattachedSplit.SplitAmt;
                            paymentCurPayAmt -= (decimal)unattachedSplit.SplitAmt;
                        }
                        else
                        {
                            unattachedSplit.SplitAmt = amtAvail;
                        }
                        unattachedSplit.ProvNum   = payPlanEntry.ProvNum;
                        unattachedSplit.ClinicNum = payPlanEntry.ClinicNum;
                        unattachedSplit.ProcNum   = 0;
                        amtAvail -= unattachedSplit.SplitAmt;
                        payPlanEntry.AmountEnd -= (decimal)unattachedSplit.SplitAmt;
                        payPlanEntry.SplitCollection.Add(unattachedSplit);
                        listSplits.Add(unattachedSplit);
                    }
                }
                else
                {
                    PaySplit unattachedSplit = new PaySplit();
                    //for payplans with no attached procedures, all paysplits would end up in the interestAlreadyPaid amount.
                    //any extra money that was accidentally lumped into interestAlreadyPaid should be included in principleAlreadyPaid here.
                    amtAttachedAlreadyPaid  = (amtUnattachedAlreadyPaid - payPlanChargeCur.Interest > 0) ? amtUnattachedAlreadyPaid - payPlanChargeCur.Interest : 0;
                    unattachedSplit.DatePay = today;
                    //the payment should always go to the account of the payplancharge's guarantor.
                    unattachedSplit.PatNum     = payPlanChargeCur.Guarantor;
                    unattachedSplit.PayPlanNum = payPlanChargeCur.PayPlanNum;
                    unattachedSplit.PayNum     = paymentCur.PayNum;
                    if (isAutoSplit)
                    {
                        unattachedSplit.SplitAmt = Math.Min((double)paymentCurPayAmt, payPlanChargeCur.Principal - amtAttachedAlreadyPaid);
                        paymentCurPayAmt        -= (decimal)unattachedSplit.SplitAmt;
                    }
                    else if (isPartial)
                    {
                        unattachedSplit.SplitAmt = Math.Min((double)payAmt, payPlanChargeCur.Principal - amtAttachedAlreadyPaid);
                        payAmt           -= (decimal)unattachedSplit.SplitAmt;
                        paymentCurPayAmt -= (decimal)unattachedSplit.SplitAmt;
                    }
                    else
                    {
                        unattachedSplit.SplitAmt = payPlanChargeCur.Principal - amtAttachedAlreadyPaid;
                    }
                    unattachedSplit.ProvNum   = payPlanChargeCur.ProvNum;
                    unattachedSplit.ClinicNum = payPlanChargeCur.ClinicNum;
                    payPlanEntry.AmountEnd   -= (decimal)unattachedSplit.SplitAmt;
                    payPlanEntry.SplitCollection.Add(unattachedSplit);
                    listSplits.Add(unattachedSplit);
                }
            }
            return(listSplits);
        }
コード例 #29
0
ファイル: PaySplits.cs プロジェクト: nampn/ODental
 ///<summary>Used once in ContrAccount.  Usually returns 0 unless there is a payplan for this payment and patient.</summary>
 public static long GetPayPlanNum(long payNum,long patNum,PaySplit[] List)
 {
     //No need to check RemotingRole; no call to db.
     for(int i=0;i<List.Length;i++){
         if(List[i].PayNum==payNum && List[i].PatNum==patNum && List[i].PayPlanNum!=0){
             return List[i].PayPlanNum;
         }
     }
     return 0;
 }
コード例 #30
0
ファイル: PaySplits.cs プロジェクト: nampn/ODental
 ///<summary>Used once in ContrAccount.  WARNING!  The returned list of 'paysplits' are not real paysplits.  They are actually grouped by patient and date.  Only the ProcDate, SplitAmt, PatNum, and ProcNum(one of many) are filled. Must supply a list which would include all paysplits for this payment.</summary>
 public static ArrayList GetGroupedForPayment(long payNum,PaySplit[] List)
 {
     //No need to check RemotingRole; no call to db.
     ArrayList retVal=new ArrayList();
     int matchI;
     for(int i=0;i<List.Length;i++){
         if(List[i].PayNum==payNum){
             //find a 'paysplit' with matching procdate and patnum
             matchI=-1;
             for(int j=0;j<retVal.Count;j++){
                 if(((PaySplit)retVal[j]).ProcDate==List[i].ProcDate && ((PaySplit)retVal[j]).PatNum==List[i].PatNum){
                     matchI=j;
                     break;
                 }
             }
             if(matchI==-1){
                 retVal.Add(new PaySplit());
                 matchI=retVal.Count-1;
                 ((PaySplit)retVal[matchI]).ProcDate=List[i].ProcDate;
                 ((PaySplit)retVal[matchI]).PatNum=List[i].PatNum;
             }
             if(((PaySplit)retVal[matchI]).ProcNum==0 && List[i].ProcNum!=0){
                 ((PaySplit)retVal[matchI]).ProcNum=List[i].ProcNum;
             }
             ((PaySplit)retVal[matchI]).SplitAmt+=List[i].SplitAmt;
         }
     }
     return retVal;
 }
コード例 #31
0
ファイル: FormPayment.cs プロジェクト: mnisl/OD
		///<summary>Updates the passed in paysplit with the provider and clinic that is set for the payment plan charges.  PayPlanNum should already be set for the split.</summary>
		private void SetPaySplitProvAndClinicForPayPlan(PaySplit split) {
			if(split.PayPlanNum==0) {//PayPlanNum was not set, this should never happen.
				return;
			}
			List<PayPlanCharge> charges=PayPlanCharges.GetForPayPlan(split.PayPlanNum);//The payment plan doesn't save/store this information
			if(charges.Count>0) {//All charges linked to a payplan share the same clinic and provider.  Just use the first one in the list.
				if(charges[0].ProvNum>0) {//This should never fail.
					split.ProvNum=charges[0].ProvNum;
				}
				if(charges[0].ClinicNum>0) {//It is possible to not set a clinic for pay plan charges.
					split.ClinicNum=charges[0].ClinicNum;
				}
			}
		}
コード例 #32
0
ファイル: FormPaySplitEdit.cs プロジェクト: nampn/ODental
 private void butDelete_Click(object sender, System.EventArgs e)
 {
     if(!MsgBox.Show(this,true,"Delete Item?")) {
         return;
     }
     PaySplitCur=null;
     if(IsNew) {
         DialogResult=DialogResult.Cancel;
         return;
     }
     DialogResult=DialogResult.OK;
 }
コード例 #33
0
ファイル: FormPayment.cs プロジェクト: nampn/ODental
 /// <summary>Adds one split to work with.  Called when checkPayPlan click, or upon load if auto attaching to payplan.</summary>
 private void AddOneSplit()
 {
     PaySplit PaySplitCur=new PaySplit();
     PaySplitCur.PatNum=PatCur.PatNum;
     PaySplitCur.PayNum=PaymentCur.PayNum;
     PaySplitCur.ProcDate=PaymentCur.PayDate;//this may be updated upon closing
     PaySplitCur.DatePay=PaymentCur.PayDate;//this may be updated upon closing
     PaySplitCur.ProvNum=Patients.GetProvNum(PatCur);
     PaySplitCur.ClinicNum=PaymentCur.ClinicNum;
     PaySplitCur.SplitAmt=PIn.Double(textAmount.Text);
     SplitList.Add(PaySplitCur);
 }
コード例 #34
0
ファイル: Payments.cs プロジェクト: ChemBrain/OpenDental
        /// <summary>Only Called only from FormPayment.butOK click.  Only called if the user did not enter any splits.  Usually just adds one split for the current patient.  But if that would take the balance negative, then it loops through all other family members and creates splits for them.  It might still take the current patient negative once all other family members are zeroed out.</summary>
        public static List <PaySplit> Allocate(Payment pay)        //double amtTot,int patNum,Payment payNum){
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <List <PaySplit> >(MethodBase.GetCurrentMethod(), pay));
            }
            string command =
                "SELECT Guarantor FROM patient "
                + "WHERE PatNum = " + POut.Long(pay.PatNum);
            DataTable table = Db.GetTable(command);

            if (table.Rows.Count == 0)
            {
                return(new List <PaySplit>());
            }
            command =
                "SELECT patient.PatNum,EstBalance,PriProv,SUM(InsPayEst)+SUM(Writeoff) insEst_ "
                + "FROM patient "
                + "LEFT JOIN claimproc ON patient.PatNum=claimproc.PatNum "
                + "AND Status=0 "               //NotReceived
                + "WHERE Guarantor = " + table.Rows[0][0].ToString() + " "
                + "GROUP BY  patient.PatNum,EstBalance,PriProv";
            //+" ORDER BY PatNum!="+POut.PInt(pay.PatNum);//puts current patient in position 0 //Oracle does not allow
            table = Db.GetTable(command);
            List <Patient> pats = new List <Patient>();
            Patient        pat;

            //first, put the current patient at position 0.
            for (int i = 0; i < table.Rows.Count; i++)
            {
                if (table.Rows[i]["PatNum"].ToString() == pay.PatNum.ToString())
                {
                    pat            = new Patient();
                    pat.PatNum     = PIn.Long(table.Rows[i][0].ToString());
                    pat.EstBalance = PIn.Double(table.Rows[i][1].ToString());
                    if (!PrefC.GetBool(PrefName.BalancesDontSubtractIns))
                    {
                        pat.EstBalance -= PIn.Double(table.Rows[i]["insEst_"].ToString());
                    }
                    pat.PriProv = PIn.Long(table.Rows[i][2].ToString());
                    pats.Add(pat.Copy());
                }
            }
            //then, do all the rest of the patients.
            for (int i = 0; i < table.Rows.Count; i++)
            {
                if (table.Rows[i]["PatNum"].ToString() == pay.PatNum.ToString())
                {
                    continue;
                }
                pat            = new Patient();
                pat.PatNum     = PIn.Long(table.Rows[i][0].ToString());
                pat.EstBalance = PIn.Double(table.Rows[i][1].ToString());
                if (!PrefC.GetBool(PrefName.BalancesDontSubtractIns))
                {
                    pat.EstBalance -= PIn.Double(table.Rows[i]["insEst_"].ToString());
                }
                pat.PriProv = PIn.Long(table.Rows[i][2].ToString());
                pats.Add(pat.Copy());
            }
            //first calculate all the amounts
            double amtRemain = pay.PayAmt;          //start off with the full amount

            double[] amtSplits = new double[pats.Count];
            //loop through each family member, starting with current
            for (int i = 0; i < pats.Count; i++)
            {
                if (pats[i].EstBalance == 0 || pats[i].EstBalance < 0)
                {
                    continue;                       //don't apply paysplits to anyone with a negative balance
                }
                if (amtRemain < pats[i].EstBalance) //entire remainder can be allocated to this patient
                {
                    amtSplits[i] = amtRemain;
                    amtRemain    = 0;
                    break;
                }
                else                 //amount remaining is more than or equal to the estBal for this family member
                {
                    amtSplits[i] = pats[i].EstBalance;
                    amtRemain   -= pats[i].EstBalance;
                }
            }
            //add any remainder to the split for this patient
            amtSplits[0] += amtRemain;
            //now create a split for each non-zero amount
            PaySplit        PaySplitCur;
            List <PaySplit> retVal = new List <PaySplit>();

            for (int i = 0; i < pats.Count; i++)
            {
                if (amtSplits[i] == 0)
                {
                    continue;
                }
                PaySplitCur           = new PaySplit();
                PaySplitCur.PatNum    = pats[i].PatNum;
                PaySplitCur.PayNum    = pay.PayNum;
                PaySplitCur.DatePay   = pay.PayDate;
                PaySplitCur.ClinicNum = pay.ClinicNum;
                PaySplitCur.ProvNum   = Patients.GetProvNum(pats[i]);
                PaySplitCur.SplitAmt  = Math.Round(amtSplits[i], CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits);
                //PaySplitCur.InsertOrUpdate(true);
                retVal.Add(PaySplitCur);
            }
            //finally, adjust each EstBalance, but no need to do current patient
            //This no longer works here.  Must do it when closing payment window somehow

            /*for(int i=1;i<pats.Length;i++){
             *      if(amtSplits[i]==0){
             *              continue;
             *      }
             *      command="UPDATE patient SET EstBalance=EstBalance-"+POut.PDouble(amtSplits[i])
             +" WHERE PatNum="+POut.PInt(pats[i].PatNum);
             *      Db.NonQ(command);
             * }*/
            return(retVal);
        }
コード例 #35
0
ファイル: FormPayment.cs プロジェクト: nampn/ODental
 private void butAdd_Click(object sender,System.EventArgs e)
 {
     PaySplit PaySplitCur=new PaySplit();
     PaySplitCur.PayNum=PaymentCur.PayNum;
     PaySplitCur.DatePay=PIn.Date(textDate.Text);//this may be updated upon closing
     PaySplitCur.ProcDate=PIn.Date(textDate.Text);//this may be updated upon closing
     PaySplitCur.ProvNum=Patients.GetProvNum(PatCur);
     PaySplitCur.PatNum=PatCur.PatNum;
     PaySplitCur.ClinicNum=PaymentCur.ClinicNum;
     FormPaySplitEdit FormPS=new FormPaySplitEdit(FamCur);
     FormPS.PaySplitCur=PaySplitCur;
     FormPS.IsNew=true;
     FormPS.Remain=PaymentCur.PayAmt-PIn.Double(textTotal.Text);
     if(FormPS.ShowDialog()!=DialogResult.OK) {
         return;
     }
     SplitList.Add(PaySplitCur);
     FillMain();
 }
コード例 #36
0
		private void butSend_Click(object sender,EventArgs e) {
			//Assuming the use of XCharge.  If adding another vendor (PayConnect for example)
			//make sure to move XCharge validation in FillGrid() to here.
			if(prog==null) {//Gets filled in FillGrid()
				return;
			}
			if(gridMain.SelectedIndices.Length<1) {
				MsgBox.Show(this,"Must select at least one recurring charge.");
				return;
			}
			if(!PaymentsWithinLockDate()) {
				return;
			}
			string recurringResultFile="Recurring charge results for "+DateTime.Now.ToShortDateString()+" ran at "+DateTime.Now.ToShortTimeString()+"\r\n\r\n";
			int failed=0;
			int success=0;
			string user=ProgramProperties.GetPropVal(prog.ProgramNum,"Username");
			string password=CodeBase.MiscUtils.Decrypt(ProgramProperties.GetPropVal(prog.ProgramNum,"Password"));
			#region Card Charge Loop
			for(int i=0;i<gridMain.SelectedIndices.Length;i++) {
				#region X-Charge
				if(table.Rows[gridMain.SelectedIndices[i]]["XChargeToken"].ToString()!="" &&
					CreditCards.IsDuplicateXChargeToken(table.Rows[gridMain.SelectedIndices[i]]["XChargeToken"].ToString())) 
				{
					MessageBox.Show(Lan.g(this,"A duplicate token was found, the card cannot be charged for customer: ")+table.Rows[i]["PatName"].ToString());
					continue;
				}
				insertPayment=false;
				ProcessStartInfo info=new ProcessStartInfo(xPath);
				long patNum=PIn.Long(table.Rows[gridMain.SelectedIndices[i]]["PatNum"].ToString());
				string resultfile=Path.Combine(Path.GetDirectoryName(xPath),"XResult.txt");
				try {
					File.Delete(resultfile);//delete the old result file.
				}
				catch {
					//Probably did not have permissions to delete the file.  Don't do anything, because a message will show telling them that the cards left in the grid failed.
					//They will then go try and run the cards in the Account module and will then get a detailed message telling them what is wrong.
					continue;
				}
				info.Arguments="";
				double amt=PIn.Double(table.Rows[gridMain.SelectedIndices[i]]["ChargeAmt"].ToString());
				DateTime exp=PIn.Date(table.Rows[gridMain.SelectedIndices[i]]["CCExpiration"].ToString());
				string address=PIn.String(table.Rows[gridMain.SelectedIndices[i]]["Address"].ToString());
				string addressPat=PIn.String(table.Rows[gridMain.SelectedIndices[i]]["AddressPat"].ToString());
				string zip=PIn.String(table.Rows[gridMain.SelectedIndices[i]]["Zip"].ToString());
				string zipPat=PIn.String(table.Rows[gridMain.SelectedIndices[i]]["ZipPat"].ToString());
				info.Arguments+="/AMOUNT:"+amt.ToString("F2")+" /LOCKAMOUNT ";
				info.Arguments+="/TRANSACTIONTYPE:PURCHASE /LOCKTRANTYPE ";
				if(table.Rows[gridMain.SelectedIndices[i]]["XChargeToken"].ToString()!="") {
					info.Arguments+="/XCACCOUNTID:"+table.Rows[gridMain.SelectedIndices[i]]["XChargeToken"].ToString()+" ";
					info.Arguments+="/RECURRING ";
				}
				else {
					info.Arguments+="/ACCOUNT:"+table.Rows[gridMain.SelectedIndices[i]]["CCNumberMasked"].ToString()+" ";
				}
				if(exp.Year>1880) {
					info.Arguments+="/EXP:"+exp.ToString("MMyy")+" ";
				}
				if(address!="") {
					info.Arguments+="\"/ADDRESS:"+address+"\" ";
				}
				else if(addressPat!="") {
					info.Arguments+="\"/ADDRESS:"+addressPat+"\" ";
				}
				if(zip!="") {
					info.Arguments+="\"/ZIP:"+zip+"\" ";
				}
				else if(zipPat!="") {
					info.Arguments+="\"/ZIP:"+zipPat+"\" ";
				}
				info.Arguments+="/RECEIPT:Pat"+patNum+" ";//aka invoice#
				info.Arguments+="\"/CLERK:"+Security.CurUser.UserName+" R\" /LOCKCLERK ";
				info.Arguments+="/RESULTFILE:\""+resultfile+"\" ";
				info.Arguments+="/USERID:"+user+" ";
				info.Arguments+="/PASSWORD:"******" ";
				info.Arguments+="/HIDEMAINWINDOW ";
				info.Arguments+="/AUTOPROCESS ";
				info.Arguments+="/SMALLWINDOW ";
				info.Arguments+="/AUTOCLOSE ";
				info.Arguments+="/NORESULTDIALOG ";
				Cursor=Cursors.WaitCursor;
				Process process=new Process();
				process.StartInfo=info;
				process.EnableRaisingEvents=true;
				process.Start();
				while(!process.HasExited) {
					Application.DoEvents();
				}
				Thread.Sleep(200);//Wait 2/10 second to give time for file to be created.
				Cursor=Cursors.Default;
				string line="";
				string resultText="";
				recurringResultFile+="PatNum: "+patNum+" Name: "+table.Rows[i]["PatName"].ToString()+"\r\n";
				try {
					using(TextReader reader=new StreamReader(resultfile)) {
						line=reader.ReadLine();
						while(line!=null) {
							if(resultText!="") {
								resultText+="\r\n";
							}
							resultText+=line;
							if(line.StartsWith("RESULT=")) {
								if(line=="RESULT=SUCCESS") {
									success++;
									labelCharged.Text=Lan.g(this,"Charged=")+success;
									insertPayment=true;
								}
								else {
									failed++;
									labelFailed.Text=Lan.g(this,"Failed=")+failed;
								}
							}
							line=reader.ReadLine();
						}
						recurringResultFile+=resultText+"\r\n\r\n";
					}
				}
				catch {
					continue;//Cards will still be in the list if something went wrong.
				}
				#endregion
				if(insertPayment) {
					Patient patCur=Patients.GetPat(patNum);
					Payment paymentCur=new Payment();
					paymentCur.DateEntry=nowDateTime.Date;
					paymentCur.PayDate=GetPayDate(PIn.Date(table.Rows[gridMain.SelectedIndices[i]]["LatestPayment"].ToString()),
						PIn.Date(table.Rows[gridMain.SelectedIndices[i]]["DateStart"].ToString()));
					paymentCur.PatNum=patCur.PatNum;
					paymentCur.ClinicNum=PIn.Long(table.Rows[gridMain.SelectedIndices[i]]["ClinicNum"].ToString());
					paymentCur.PayType=PIn.Int(ProgramProperties.GetPropVal(prog.ProgramNum,"PaymentType"));
					paymentCur.PayAmt=amt;
					paymentCur.PayNote=resultText;
					paymentCur.IsRecurringCC=true;
					Payments.Insert(paymentCur);
					long provNum=PIn.Long(table.Rows[gridMain.SelectedIndices[i]]["ProvNum"].ToString());//for payment plans only
					if(provNum==0) {//Regular payments need to apply to the provider that the family owes the most money to.
						DataTable dt=Patients.GetPaymentStartingBalances(patCur.Guarantor,paymentCur.PayNum);
						double highestAmt=0;
						for(int j=0;j<dt.Rows.Count;j++) {
							double afterIns=PIn.Double(dt.Rows[j]["AfterIns"].ToString());
							if(highestAmt>=afterIns) {
								continue;
							}
							highestAmt=afterIns;
							provNum=PIn.Long(dt.Rows[j]["ProvNum"].ToString());
						}
					}
					PaySplit split=new PaySplit();
					split.PatNum=paymentCur.PatNum;
					split.ClinicNum=paymentCur.ClinicNum;
					split.PayNum=paymentCur.PayNum;
					split.ProcDate=paymentCur.PayDate;
					split.DatePay=paymentCur.PayDate;
					split.ProvNum=provNum;
					split.SplitAmt=paymentCur.PayAmt;
					split.PayPlanNum=PIn.Long(table.Rows[gridMain.SelectedIndices[i]]["PayPlanNum"].ToString());
					PaySplits.Insert(split);
					if(PrefC.GetBool(PrefName.AgingCalculatedMonthlyInsteadOfDaily)) {
						Ledgers.ComputeAging(patCur.Guarantor,PrefC.GetDate(PrefName.DateLastAging),false);
					}
					else {
						Ledgers.ComputeAging(patCur.Guarantor,DateTimeOD.Today,false);
						if(PrefC.GetDate(PrefName.DateLastAging) != DateTime.Today) {
							Prefs.UpdateString(PrefName.DateLastAging,POut.Date(DateTime.Today,false));
							//Since this is always called from UI, the above line works fine to keep the prefs cache current.
						}
					}
				}
			}
			#endregion
			try {
				File.WriteAllText(Path.Combine(Path.GetDirectoryName(xPath),"RecurringChargeResult.txt"),recurringResultFile);
			}
			catch { } //Do nothing cause this is just for internal use.
			FillGrid();
			labelCharged.Text=Lan.g(this,"Charged=")+success;
			labelFailed.Text=Lan.g(this,"Failed=")+failed;
			MsgBox.Show(this,"Done charging cards.\r\nIf there are any patients remaining in list, print the list and handle each one manually.");
		}
コード例 #37
0
ファイル: FormPayPlan.cs プロジェクト: mnisl/OD
		private ODGridRow CreateRowForPaySplit(DataRow rowBundlePayment,PaySplit paySplit) {
			string descript=DefC.GetName(DefCat.PaymentTypes,PIn.Long(rowBundlePayment["PayType"].ToString()));
			if(rowBundlePayment["CheckNum"].ToString()!="") {
				descript+=" #"+rowBundlePayment["CheckNum"].ToString();
			}
			descript+=" "+paySplit.SplitAmt.ToString("c");//Not sure if we really want to convert from string to double then back to string.. maybe a better way to format this?
			if(Convert.ToDouble(rowBundlePayment["PayAmt"].ToString())!=paySplit.SplitAmt) { 
				descript+=Lans.g(this,"(split)");
			}
			ODGridRow row=new ODGridRow();
			row.Cells.Add(paySplit.DatePay.ToShortDateString());//0 Date
			row.Cells.Add(Providers.GetAbbr(Convert.ToInt32(rowBundlePayment["ProvNum"])));//1 Prov Abbr
			row.Cells.Add(descript);//2 Descript
			row.Cells.Add("");//3 Principal
			row.Cells.Add("");//4 Interest
			row.Cells.Add("");//5 Due
			row.Cells.Add(paySplit.SplitAmt.ToString("n"));//6 Payment
			row.Cells.Add("");//7 Balance (filled later)
			row.Tag=paySplit;
			row.ColorText=_arrayAccountColors[3].ItemColor;//Setup | Definitions | Account Colors | Payment;
			return row;
		}