コード例 #1
0
    private void PopulateCashAdvances()
    {
        CashAdvances advances = CashAdvances.ForOrganization(CurrentOrganization);

        foreach (CashAdvance advance in advances)
        {
            if (this._attestationRights.ContainsKey(advance.BudgetId) ||
                advance.Budget.OwnerPersonId == Person.NobodyId)
            {
                AttestableItem item = new AttestableItem(
                    "A" + advance.Identity.ToString(CultureInfo.InvariantCulture),
                    advance.Person.Name, advance.AmountCents, advance.Budget,
                    advance.Description, "Financial_CashAdvance", false, advance);

                if (advance.Attested)
                {
                    this._attestedItems.Add(item);
                }
                else
                {
                    this._items.Add(item);
                }
            }
        }
    }
コード例 #2
0
    private void PopulateCashAdvances()
    {
        CashAdvances advances = CashAdvances.ForOrganization(CurrentOrganization);

        foreach (CashAdvance advance in advances)
        {
            if (this._approvalRights.ContainsKey(advance.BudgetId) ||
                advance.Budget.OwnerPersonId == Person.NobodyId)
            {
                ApprovableCost cost = new ApprovableCost(
                    "A" + advance.Identity.ToString(CultureInfo.InvariantCulture),
                    advance.Person.Name, advance.AmountCents, advance.Budget,
                    advance.Description, "Financial_CashAdvance", false, advance);

                if (!advance.Attested) // if not attested
                {
                    this._approvableCosts.Add(cost);
                }
                else if (!advance.PaidOut) // if attested, but still reversible
                {
                    this._approvedCosts.Add(cost);
                }
            }
        }
    }
コード例 #3
0
        private void AddCashAdvanceAttestations(Person person, Organization organization)
        {
            CashAdvances advances       = CashAdvances.ForOrganization(organization);
            List <int>   cashAdvanceIds = new List <int>();

            bool isPersonOrgAdmin = false;

            if (person.Identity == 1)
            {
                isPersonOrgAdmin = true; // TODO: Make more advanced, obviously
            }

            foreach (CashAdvance advance in advances)
            {
                if (advance.Attested)
                {
                    continue;
                }

                bool attestable = false;

                if (advance.Budget.OwnerPersonId == 0 && isPersonOrgAdmin)
                {
                    attestable = true;
                }
                else if (advance.Budget.OwnerPersonId == person.Identity)
                {
                    attestable = true;
                }


                if (attestable)
                {
                    cashAdvanceIds.Add(advance.Identity);
                }
            }

            if (cashAdvanceIds.Count > 0)
            {
                DashboardTodo todo = new DashboardTodo();

                if (cashAdvanceIds.Count > 1)
                {
                    todo.Description = String.Format(Logic_Swarm_DashboardTodos.Attest_CashAdvance_Many,
                                                     Formatting.GenerateRangeString(cashAdvanceIds));
                }
                else
                {
                    todo.Description = String.Format(Logic_Swarm_DashboardTodos.Attest_CashAdvance_One,
                                                     cashAdvanceIds[0]);
                }

                todo.Icon = "/Images/PageIcons/iconshock-stamped-paper-16px.png";
                todo.Url  = "/Pages/v5/Financial/AttestCosts.aspx";

                Add(todo);
            }
        }
コード例 #4
0
ファイル: Payout.cs プロジェクト: SwarmCorp/Swarmops
        private void LoadDependencies()
        {
            DependentExpenseClaims = new ExpenseClaims();
            DependentInvoices = new InboundInvoices();
            DependentSalariesNet = new Salaries();
            DependentSalariesTax = new Salaries();
            DependentCashAdvancesPayout = new CashAdvances();
            DependentCashAdvancesPayback = new CashAdvances();

            BasicFinancialDependency[] dependencies = SwarmDb.GetDatabaseForReading().GetPayoutDependencies(this.Identity);

            foreach (BasicFinancialDependency dependency in dependencies)
            {
                switch (dependency.DependencyType)
                {
                    case FinancialDependencyType.ExpenseClaim:
                        DependentExpenseClaims.Add(ExpenseClaim.FromIdentity(dependency.ForeignId));
                        break;
                    case FinancialDependencyType.InboundInvoice:
                        DependentInvoices.Add(InboundInvoice.FromIdentity(dependency.ForeignId));
                        break;
                    case FinancialDependencyType.Salary:
                        Salary salary = Salary.FromIdentity(dependency.ForeignId);
                        if (salary.NetSalaryCents == this.AmountCents)  // HACK: Assumes that tax total is not identical
                        {
                            DependentSalariesNet.Add(salary);
                        }
                        else
                        {
                            DependentSalariesTax.Add(salary);
                        }
                        break;

                    case FinancialDependencyType.CashAdvance:
                        DependentCashAdvancesPayout.Add(CashAdvance.FromIdentity(dependency.ForeignId));
                        break;

                    case FinancialDependencyType.CashAdvancePayback:
                        DependentCashAdvancesPayback.Add(CashAdvance.FromIdentity(dependency.ForeignId));
                        break;

                    default:
                        throw new NotImplementedException("Unknown financial dependency type in Payout.LoadDependencies(): " + dependency.ToString());
                }
            }
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        private OutstandingAccounts GetOutstandingCashAdvances(bool renderPresentTime, DateTime targetDateTime)
        {
            OutstandingAccounts outstandingAccounts = new OutstandingAccounts();

            // This is a very expensive op. We need to load ALL the cash advances, and determine the opening date from its associated
            // payout. Then, we need to determine when it was paid pack through another associated payout (or invoice payment) which
            // I don't know how to find at the time of writing this comment, and if the target date is in between those two, then the
            // cash advance was outstanding on the target date (or is outstanding now)

            // A possible optimization could be to load the payouts into a hash table initially instead of looking them up
            // with two dbroundtrips per expense claim. It should be more efficient to have three dbroundtrips to load expenses,
            // payouts, and the relevant transactions, then stuff it all into hash tables keyed by identity and process it
            // in-memory.

            // A future optimization involves adding "ClosedDateTime" to some tables.

            // Load all (ALL) cash advances for org

            CashAdvances allCashAdvances = CashAdvances.ForOrganization(_authenticationData.CurrentOrganization, true);

            // includes closed

            // For each advance, determine whether it was open or not at targetDateTime

            foreach (CashAdvance cashAdvance in allCashAdvances)
            {
                // if it wasn't opened until after target datetime, discard (optimization)

                if (cashAdvance.CreatedDateTime > targetDateTime)
                {
                    continue;
                }

                // At this point, we are iterating over full set of cash advances opened before targetDateTime, but not necessarily
                // paid out before targetDateTime. We want the set of advances that had been paid out, and had not been paid back,
                // as determined by the ledger account Cash Advances - on targetDateTime.

                bool     includeThisAdvance = false;
                DateTime dateTimePaidBack   = DateTime.MinValue;
                DateTime dateTimePaidOut    = DateTime.MaxValue;


                if (!cashAdvance.PaidOut)
                {
                    // This cash advance hasn't entered the ledger yet

                    continue;
                }


                Payout payoutOut  = cashAdvance.PayoutOut;
                Payout payoutBack = cashAdvance.PayoutBack;

                if (payoutOut == null)
                {
                    continue;
                    // This cash advance has not been paid out yet
                }

                try
                {
                    dateTimePaidOut = payoutOut.FinancialTransaction.DateTime;
                }
                catch (ArgumentException)
                {
                    // It's possible the payout exists, but hasn't found its transaction yet. If so, this will throw
                    // an ArgumentException here. In either case, it's not in the ledger, so don't include it.

                    continue;
                }

                if (dateTimePaidOut > targetDateTime)
                {
                    // This cash advance falls outside the scope of our window, so ignore
                    continue;
                }

                if (payoutBack != null)
                {
                    try
                    {
                        dateTimePaidBack = payoutBack.FinancialTransaction.DateTime;
                    }
                    catch (ArgumentException)
                    {
                        // as above
                        continue;
                    }

                    if (dateTimePaidBack > targetDateTime)
                    {
                        includeThisAdvance = true;
                    }
                }
                else
                {
                    // As there is no payback, this advance is paid out and still open.

                    includeThisAdvance = true;

                    // TODO: If there is no payout where the cash advance is deducted, it may be
                    // invoiced to close it.

                    // TODO: Find OutboundInvoiceItem that depends on this CashAdvance. Look at the invoice date. That's our PaidBack datetime.
                }


                if (includeThisAdvance)
                {
                    outstandingAccounts.Add(OutstandingAccount.FromCashAdvance(cashAdvance, dateTimePaidOut));
                }
            }

            return(outstandingAccounts);
        }