private string GetProgressTicks(InboundInvoice invoice)
    {
        StringBuilder ticks = new StringBuilder(512);

        // The first tick is whether the invoice was even received yet, in anticipation of Purchase Orders
        // For now, it is always filled

        ticks.Append(_greenTick);

        // The second tick is whether the invoice has been attested

        if (invoice.Attested)
        {
            ticks.Append(_greenTick);

            // Is it also paid?

            if (invoice.PaidOut)
            {
                ticks.Append(_greenTick);

                // Is the payout closed, that is, registered closed with the bank?

                try
                {
                    if (Payout.FromDependency(invoice).Open)
                    {
                        ticks.Append(_emptyTick);
                    }
                    else
                    {
                        ticks.Append(_greenTick);
                    }
                }
                catch (ArgumentException)
                {
                    // There was no payout; the invoice was closed another way.

                    ticks.Append(_redCross);
                }
            }
            else
            {
                // attested but not paid yet

                ticks.Append(_emptyTick + _emptyTick);
            }
        }
        else // not attested
        {
            // Is the invoice closed? If so, it was denied entirely

            if (invoice.Open)
            {
                ticks.Append(_emptyTick + _emptyTick + _emptyTick);
            }
            else
            {
                // Closed, and therefore it was denied attestation
                ticks.Append(_redCross + _filler + _filler);
            }
        }

        return(ticks.ToString());
    }
        public List <PaymentHistoryLineItem> GetAmountsOwed()
        {
            List <PaymentHistoryLineItem> items = new List <PaymentHistoryLineItem>();

            // Expense claims

            ExpenseClaims expenses = ExpenseClaims.FromClaimingPersonAndOrganization(_person,
                                                                                     _authenticationData.CurrentOrganization);

            foreach (ExpenseClaim claim in expenses)
            {
                if (claim.Open || claim.PaidOut) // if both these are false, the claim was denied and shouldn't be listed
                {
                    PaymentHistoryLineItem newItem = new PaymentHistoryLineItem();
                    newItem.Id           = "E" + claim.Identity.ToString(CultureInfo.InvariantCulture);
                    newItem.Name         = String.Format(Resources.Global.Financial_ExpenseClaimLongSpecification, claim.Identity);
                    newItem.Description  = claim.Description;
                    newItem.OpenedDate   = claim.CreatedDateTime;
                    newItem.OwedToPerson = claim.AmountCents;

                    Payout payout = claim.Payout;
                    if (payout != null && payout.Open == false)
                    {
                        _payoutLookup[payout.Identity] = payout;
                        newItem.ClosedDate             = payout.FinancialTransaction.DateTime;
                    }

                    items.Add(newItem);
                }
            }

            // Salaries

            Salaries salaries = Salaries.ForPersonAndOrganization(_person, _authenticationData.CurrentOrganization, true);

            foreach (Salary salary in salaries)
            {
                if (salary.Open || salary.NetPaid) // either of these must be open for the salary to be valid
                {
                    PaymentHistoryLineItem newItem = new PaymentHistoryLineItem();
                    newItem.Id           = "S" + salary.Identity.ToString(CultureInfo.InvariantCulture);
                    newItem.Name         = Resources.Global.Financial_Salary;
                    newItem.Description  = String.Format(Resources.Global.Financial_SalaryDualSpecification, salary.Identity, salary.PayoutDate);
                    newItem.OwedToPerson = salary.NetSalaryCents;

                    FinancialTransaction openTx = FinancialTransaction.FromDependency(salary);
                    if (openTx != null)
                    {
                        newItem.OpenedDate = openTx.DateTime;
                    }

                    Payout payout = Payout.FromDependency(salary, FinancialDependencyType.Salary);
                    if (payout != null && payout.Open == false)
                    {
                        _payoutLookup[payout.Identity] = payout;
                        newItem.ClosedDate             = payout.FinancialTransaction.DateTime;
                    }

                    items.Add(newItem);
                }
            }

            // Cash advances

            CashAdvances advances = CashAdvances.ForPersonAndOrganization(_person,
                                                                          _authenticationData.CurrentOrganization, true);

            foreach (CashAdvance advance in advances)
            {
                if (advance.Open || advance.PaidOut)
                {
                    Payout payout = advance.PayoutOut;
                    if (payout != null)
                    {
                        _payoutLookup[payout.Identity] = payout;
                        _payoutDescriptionOverride[payout.Identity] =
                            String.Format(Resources.Global.Financial_CashAdvanceSpecification, advance.Identity.ToString("N0"));
                    }
                }
            }

            return(items);
        }