///<summary>Creates micro-allocations intelligently based on most to least matching criteria of selected charges.</summary>
        private string CreateTransfers(List <AccountEntry> listPosCharges, List <AccountEntry> listNegCharges, List <AccountEntry> listAccountEntries
                                       , FamilyAccount famAccount, Payment payCur)
        {
            PaymentEdit.IncomeTransferData transferResults = new PaymentEdit.IncomeTransferData();
            List <PayPlanCharge>           listCredits     = famAccount.Account.ListPayPlanCharges.FindAll(x => x.ChargeType == PayPlanChargeType.Credit);
            string retVal = "";

            transferResults = PaymentEdit.CreatePayplanLoop(listPosCharges, listNegCharges, listAccountEntries, payCur.PayNum, listCredits, datePicker.Value);
            transferResults.MergeIncomeTransferData(PaymentEdit.CreateTransferLoop(listPosCharges, listNegCharges, listAccountEntries, payCur.PayNum
                                                                                   , listCredits, datePicker.Value, famAccount.Guarantor.PatNum));
            famAccount.ListSplits.AddRange(transferResults.ListSplitsCur);
            famAccount.ListSplitsAssociated.AddRange(transferResults.ListSplitsAssociated);
            retVal += transferResults.SummaryText;
            return(retVal);
        }
        public IActionResult Post([FromBody] FamilyAccount familyAccount)
        {
            OperationResult operationResult   = new OperationResult();
            string          appointmentString = string.Empty;

            FairfieldAllergeryRepository fairfieldAllergeryRepository = new FairfieldAllergeryRepository();

            operationResult = fairfieldAllergeryRepository.AddFamilyAccount(familyAccount);

            if (operationResult.Success)
            {
                return(Ok(new { status = "Success" }));
            }
            else
            {
                return(Ok(new { status = operationResult.ErrorMessage }));
            }
        }
        ///<summary>Fills the main grid.  If reload Data is true, account data will be (re)fetched from the database.
        ///If false then data already in memory is used.</summary>
        private void FillGridMain()
        {
            gridMain.BeginUpdate();
            gridMain.ListGridColumns.Clear();
            GridColumn col;

            col = new GridColumn(Lan.g(this, "Name"), 240);
            gridMain.ListGridColumns.Add(col);
            col = new GridColumn(Lan.g(this, "Balance"), 100, GridSortingStrategy.AmountParse);
            gridMain.ListGridColumns.Add(col);
            gridMain.ListGridRows.Clear();
            GridRow row;

            PaymentEdit.ConstructResults results;
            //Make a row for every guarantor that has family members with positive and negative balances.
            List <long> listPatNumsForBatch = _dictCurrentFamilyBatch.Values.Select(x => x.ListFamilyMembers)
                                              .SelectMany(y => y.Select(z => z.PatNum)).ToList();
            List <PaySplit>  listSplitsForBatch           = PaySplits.GetForPats(listPatNumsForBatch);
            List <ClaimProc> listClaimsPayAsTotalForBatch = ClaimProcs.GetByTotForPats(listPatNumsForBatch);

            foreach (KeyValuePair <long, FamilyAccount> kvp in _dictCurrentFamilyBatch)
            {
                //Get all family members now so we cut down on memory used.
                FamilyAccount   famAccount                = kvp.Value;
                List <Patient>  listPatients              = famAccount.ListFamilyMembers;
                List <long>     listFamilyPatNums         = listPatients.Select(x => x.PatNum).ToList();
                long            guarantorNum              = kvp.Key;
                List <PaySplit> listSplitsForPats         = listSplitsForBatch.FindAll(x => x.PatNum.In(listFamilyPatNums));
                long            unallocatedTransferPayNum = PaymentEdit.CreateAndInsertUnallocatedPayment(listPatients.First(x => x.PatNum == guarantorNum));
                if (!listSplitsForPats.IsNullOrEmpty())
                {
                    PaymentEdit.IncomeTransferData txfrResults = PaymentEdit.TransferUnallocatedSplitToUnearned(listSplitsForPats, unallocatedTransferPayNum);
                    foreach (PaySplit split in txfrResults.ListSplitsCur)
                    {
                        split.PayNum = unallocatedTransferPayNum;       //Set the PayNum because it was purposefully set to 0 above to save queries.
                        PaySplits.Insert(split);                        //Need to insert in a loop to get the PrimaryKey
                    }
                    foreach (PaySplits.PaySplitAssociated splitAssociated in txfrResults.ListSplitsAssociated)
                    {
                        if (splitAssociated.PaySplitLinked != null && splitAssociated.PaySplitOrig != null)
                        {
                            PaySplits.UpdateFSplitNum(splitAssociated.PaySplitOrig.SplitNum, splitAssociated.PaySplitLinked.SplitNum);
                        }
                    }
                }
                List <ClaimProc> listClaimsAsTotalForPats = listClaimsPayAsTotalForBatch.FindAll(x => x.PatNum.In(listFamilyPatNums));
                ClaimProcs.TransferClaimsAsTotalToProcedures(listPatients.Select(x => x.PatNum).ToList(), listClaimsAsTotalForPats);
                results = PaymentEdit.ConstructAndLinkChargeCredits(listPatients.Select(x => x.PatNum).ToList(), guarantorNum, new List <PaySplit>(),
                                                                    new Payment(), new List <AccountEntry>(), true);
                famAccount.Account = results;
                List <AccountEntry> listAccountEntries = results.ListAccountCharges;
                //Get guarantor info and fill the row/grid
                Patient guarantor = listPatients.FirstOrDefault(x => x.PatNum == guarantorNum);
                row = new GridRow();
                row.Cells.Add(guarantor.GetNameLFnoPref());
                row.Cells.Add((listAccountEntries.Sum(x => x.AmountEnd)).ToString("f"));
                row.Tag = famAccount;         //Store relevant family info in the guarantor row.
                row.DropDownInitiallyDown = false;
                row.Bold = true;              //Bold parent rows to show it is giving the family balance.
                gridMain.ListGridRows.Add(row);
                //Make child rows
                foreach (Patient p in listPatients)
                {
                    GridRow rowChild = new GridRow();
                    rowChild.Cells.Add(p.GetNameLFnoPref());
                    rowChild.Cells.Add(listAccountEntries.Where(x => x.PatNum == p.PatNum).Sum(x => x.AmountEnd).ToString("f"));
                    rowChild.DropDownParent = row;
                    gridMain.ListGridRows.Add(rowChild);
                }
            }
            gridMain.EndUpdate();
            gridMain.Update();
            labelBatchCount.Text = $"Current batch: {_batchNum} Total batches: {_listBatches.Count()}";
            //Invalidate and update the label to force it to be in sync with the progress bar that is on a separate thread.
            labelBatchCount.Invalidate();
            labelBatchCount.Update();
        }
        ///<summary>Turns all entries in listCredits into Unallocated. Needs to be called for each family after creating transfers. </summary>
        private string CreditsToUnallocated(List <AccountEntry> listCredits, FamilyAccount famAccount, Payment payCur)
        {
            List <PaySplit> listPaySplitsCreated = new List <PaySplit>();
            string          retVal = "";

            //Loop through each family member as unallocated is by patient, so each family member needs their own paysplit.
            foreach (Patient patCur in famAccount.ListFamilyMembers)
            {
                //Get all non-zero credits for this patient.
                List <AccountEntry> listCreditsForPat = listCredits.FindAll(x => x.PatNum == patCur.PatNum && x.AmountEnd != 0);
                //Skip this pat if there are no credits.
                if (!listCreditsForPat.Any())
                {
                    continue;
                }
                bool doInsertSplits = false;
                //One large paysplit into unallocated
                PaySplit splitUnallocated = new PaySplit();
                splitUnallocated.DatePay      = datePicker.Value;
                splitUnallocated.PatNum       = patCur.PatNum;
                splitUnallocated.PayNum       = payCur.PayNum;
                splitUnallocated.ProvNum      = 0;
                splitUnallocated.ClinicNum    = 0;
                splitUnallocated.UnearnedType = PrefC.GetLong(PrefName.PrepaymentUnearnedType);
                //create offsetting paysplits for each credit
                double totalCreditAmount = 0;
                foreach (AccountEntry credit in listCreditsForPat)
                {
                    //Prevents us from spliting unearned into unearned, which would be a major problem.
                    if (credit.GetType() == typeof(PaySplit) && ((PaySplit)credit.Tag).UnearnedType != 0)
                    {
                        continue;
                    }
                    PaySplit splitCredit = new PaySplit();
                    splitCredit.DatePay      = datePicker.Value;
                    splitCredit.PatNum       = credit.PatNum;
                    splitCredit.PayNum       = payCur.PayNum;
                    splitCredit.ProvNum      = credit.ProvNum;
                    splitCredit.ClinicNum    = credit.ClinicNum;
                    splitCredit.UnearnedType = 0;
                    splitCredit.ProcNum      = credit.GetType() == typeof(PaySplit) ? ((PaySplit)credit.Tag).ProcNum : credit.GetType() == typeof(Adjustment) ? ((Adjustment)credit.Tag).ProcNum : 0;
                    splitCredit.AdjNum       = credit.GetType() == typeof(Adjustment) ? credit.PriKey : 0;          //Money may be coming from an adjustment.
                    //Since we're moving all credits to unallocated, we set the split amount to the balance.
                    splitCredit.SplitAmt = (double)credit.AmountEnd;
                    totalCreditAmount   += splitCredit.SplitAmt;
                    credit.SplitCollection.Add(splitCredit);
                    listPaySplitsCreated.Add(splitCredit);
                    //A split for a credit was added, flag that we want to split to unearned.
                    doInsertSplits   = true;
                    credit.AmountEnd = 0;
                }
                if (doInsertSplits)
                {
                    splitUnallocated.SplitAmt = -totalCreditAmount;                  //Split is the opposite amount of the total of the other splits.
                    retVal += $"Total credits of {splitUnallocated.SplitAmt.ToString("f")} moved to unallocated for PatNum: {patCur.PatNum}\r\n";
                    listPaySplitsCreated.Add(splitUnallocated);
                }
            }
            famAccount.ListSplits.AddRange(listPaySplitsCreated);
            return(retVal);
        }
 public unsafe static void Main(string[] args)
 {
     FamilyAccount commetuveux = new FamilyAccount();
 }