private void butOK_Click(object sender, EventArgs e)
        {
            if (!Security.IsAuthorized(Permissions.PaymentCreate))
            {
                return;
            }
            double splitTotal = _listSplitsCur.Select(x => x.SplitAmt).Sum();

            if (!splitTotal.IsZero())              //income transfer
            {
                MsgBox.Show(this, "Income transfers must have a split total of 0.");
                return;
            }
            _listSplitsCur.RemoveAll(x => x.SplitAmt.IsZero());            //We don't want any zero splits.  They were there just for display purposes.
            if (_listSplitsCur.Count == 0)
            {
                Payments.Delete(_paymentCur);
            }
            else
            {
                foreach (PaySplit split in _listSplitsCur)
                {
                    PaySplits.Insert(split);
                }
                foreach (PaySplits.PaySplitAssociated split in _listSplitsAssociated)
                {
                    //Update the FSplitNum after inserts are made.
                    if (split.PaySplitLinked != null && split.PaySplitOrig != null)
                    {
                        PaySplits.UpdateFSplitNum(split.PaySplitOrig.SplitNum, split.PaySplitLinked.SplitNum);
                    }
                }
                if (_listSplitsCur.Count > 0)               //only make log when a payment with splits was made.
                {
                    string logText = Payments.GetSecuritylogEntryText(_paymentCur, _paymentCur, isNew: true) + ", " + Lans.g(this, "from Income Transfer Manager.");
                    SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, _paymentCur.PatNum, logText);
                }
                string strErrorMsg = Ledgers.ComputeAgingForPaysplitsAllocatedToDiffPats(_patCur.PatNum, _listSplitsCur);
                if (!string.IsNullOrEmpty(strErrorMsg))
                {
                    MessageBox.Show(strErrorMsg);
                }
            }
            DialogResult = DialogResult.OK;
        }
        ///<summary></summary>
        private void TransferUnallocatedToUnearned()
        {
            List <PaySplit> listSplitsForPats = PaySplits.GetForPats(_listFamilyPatNums);

            if (listSplitsForPats.IsNullOrEmpty())
            {
                return;
            }
            //Pass in an invalid payNum of 0 which will get set correctly later if there are in fact splits to transfer.
            PaymentEdit.IncomeTransferData unallocatedTransfers = PaymentEdit.TransferUnallocatedSplitToUnearned(listSplitsForPats, 0);
            if (unallocatedTransfers.ListSplitsCur.Count == 0)
            {
                return;
            }
            if (!unallocatedTransfers.ListSplitsCur.Sum(x => x.SplitAmt).IsZero())
            {
                //Display the UnearnedType and the SplitAmt for each split in the list.
                string splitInfo = string.Join("\r\n  ", unallocatedTransfers.ListSplitsCur
                                               .Select(x => $"SplitAmt: {x.SplitAmt}"));
                //Show the sum of all splits first and then give a breakdown of each individual split.
                string details = $"Sum of unallocatedTransfers.ListSplitsCur: {unallocatedTransfers.ListSplitsCur.Sum(x => x.SplitAmt)}\r\n"
                                 + $"Individual Split Info:\r\n  {splitInfo}";
                FriendlyException.Show("Error transferring unallocated paysplits.  Please call support.", new ApplicationException(details), "Close");
                //Close the window and do not let the user create transfers because something is wrong.
                DialogResult = DialogResult.Cancel;
                Close();
                return;
            }
            //There are unallocated paysplits that need to be transferred to unearned.
            _unallocatedPayNum = PaymentEdit.CreateAndInsertUnallocatedPayment(_patCur);
            foreach (PaySplit split in unallocatedTransfers.ListSplitsCur)
            {
                split.PayNum = _unallocatedPayNum;              //Set the PayNum because it was purposefully set to 0 above to save queries.
                PaySplits.Insert(split);
            }
            foreach (PaySplits.PaySplitAssociated splitAssociated in unallocatedTransfers.ListSplitsAssociated)
            {
                if (splitAssociated.PaySplitLinked != null && splitAssociated.PaySplitOrig != null)
                {
                    PaySplits.UpdateFSplitNum(splitAssociated.PaySplitOrig.SplitNum, splitAssociated.PaySplitLinked.SplitNum);
                }
            }
            SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, _patCur.PatNum
                                      , $"Unallocated splits automatically transferred to unearned for payment {_unallocatedPayNum}.");
        }
Exemplo n.º 3
0
        ///<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();
        }
Exemplo n.º 4
0
        ///<summary>Balances all selected accounts.</summary>
        private void butTransfer_Click(object sender, EventArgs e)
        {
            //FormIncomeTransferManage requires PaymentCreate to run.
            //This form requires SecurityAdmin and a password to open, and although rare,
            // a SecuirtyAdmin doesn't have to have PaymentCreate permission
            if (!Security.IsAuthorized(Permissions.PaymentCreate))
            {
                return;
            }
            //Make sure the user wants to run the tool.
            if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "This process can take a long time and cannot be reversed.\r\n\r\nContinue?"))
            {
                return;
            }
            Action actionCloseProgress = ODProgress.Show(ODEventType.Billing);

            //Build list of families based off of selected rows.
            _logger.WriteLine("This is the summary of all transactions that took place.This can be saved for later reference if one or more"
                              + " transactions need to be undone outside of the tool.\r\n", LogLevel.Information);
            //Do income transfers if applicable.
            for (int i = _batchNum - 1; i < _listBatches.Count(); i++)     //_batchNum is 1-based, so drop i by 1 to make sure the current batch is included
            {
                string logText = "";
                if (checkAllocateCharges.Checked)
                {
                    ODEvent.Fire(ODEventType.Billing, Lan.g(this, $"Creating income transfers for batch {_batchNum}/{_listBatches.Count()} please wait..."));
                    foreach (FamilyAccount famAccountCur in _dictCurrentFamilyBatch.Select(x => x.Value))
                    {
                        //Clear the list of splits in case any are hanging around from a previous run.
                        famAccountCur.ListSplits.Clear();
                        famAccountCur.ListSplitsAssociated.Clear();
                        //Make lists of positive and negative charges.
                        List <AccountEntry> listPosCharges        = famAccountCur.Account.ListAccountCharges.Where(x => x.AmountEnd > 0).ToList();
                        List <AccountEntry> listNegCharges        = famAccountCur.Account.ListAccountCharges.Where(x => x.AmountEnd < 0).ToList();
                        List <long>         listPatNumsForCharges = listPosCharges.Select(x => x.PatNum).Distinct().ToList();
                        List <AccountEntry> listEntriesForPats    = famAccountCur.Account.ListAccountCharges.FindAll(x => x.PatNum.In(listPatNumsForCharges));
                        //This catch will save us some time if they run the tool on the same family twice.
                        if (listPosCharges.Count() == 0 || listNegCharges.Count() == 0)
                        {
                            continue;                            //No need to add to logText, CreateTransfers wouldn't return anything either.
                        }
                        Payment payCur = CreatePaymentTransferHelper(famAccountCur.Guarantor);
                        logText += CreateTransfers(listPosCharges, listNegCharges, listEntriesForPats, famAccountCur, payCur);
                        logText += CreditsToUnallocated(listNegCharges, famAccountCur, payCur);
                        //Remove any $0 splits created from CreateTransfers.
                        famAccountCur.ListSplits.RemoveAll(x => x.SplitAmt == 0);
                        foreach (PaySplit split in famAccountCur.ListSplits)
                        {
                            PaySplits.Insert(split);
                        }
                        //Go through family accounts and update FSplitNums.
                        foreach (PaySplits.PaySplitAssociated split in famAccountCur.ListSplitsAssociated)
                        {
                            //Update the FSplitNum after inserts are made.
                            if (split.PaySplitLinked != null && split.PaySplitOrig != null)
                            {
                                PaySplits.UpdateFSplitNum(split.PaySplitOrig.SplitNum, split.PaySplitLinked.SplitNum);
                            }
                        }
                    }
                }
                //Transfer balances to guarantor if applicable.
                if (checkGuarAllocate.Checked)
                {
                    ODEvent.Fire(ODEventType.Billing, Lan.g(this, $"Transferring remaining balance to guarantor for batch {_batchNum}/{_listBatches.Count()} please wait..."));
                    logText += "Balances transferred to Guarantor:\r\n";
                    logText += TransferToGuarantor();
                }
                //load up the next batch
                ODEvent.Fire(ODEventType.Billing, Lan.g(this, $"Loading next batch please wait..."));
                FillNextBatch();
                _logger.WriteLine(logText, LogLevel.Information);
            }
            actionCloseProgress();
        }