private static AjaxCallResult HandleAttestationDeattestation(string identifier, AttestationMode mode)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            IApprovable approvableItem;
            string      attestedTemplate;
            string      deattestedTemplate;

            char   costType = identifier[0];
            int    itemId   = Int32.Parse(identifier.Substring(1));
            Int64  amountCents;
            string beneficiary;
            string result;

            // Find the item we are attesting or deattesting

            switch (costType)
            {
            case 'A':     // Case advance
                CashAdvance advance = CashAdvance.FromIdentity(itemId);
                if (advance.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (advance.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    advance.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                approvableItem     = advance;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_AdvanceAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_AdvanceDeattested;
                beneficiary        = advance.Person.Name;
                amountCents        = advance.AmountCents;

                break;

            case 'E':     // Expense claim
                ExpenseClaim expense = ExpenseClaim.FromIdentity(itemId);
                if (expense.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (expense.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    expense.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                approvableItem     = expense;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_ExpenseAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_ExpenseDeattested;
                beneficiary        = expense.Claimer.Name;
                amountCents        = expense.AmountCents;

                break;

            case 'I':     // Inbound invoice
                InboundInvoice invoice = InboundInvoice.FromIdentity(itemId);
                if (invoice.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (invoice.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    invoice.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                approvableItem     = invoice;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_InvoiceAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_InvoiceDeattested;
                beneficiary        = invoice.Supplier;
                amountCents        = invoice.AmountCents;

                break;

            case 'S':     // Salary payout
                Salary salary = Salary.FromIdentity(itemId);
                if (salary.PayrollItem.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (salary.PayrollItem.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    salary.PayrollItem.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                approvableItem     = salary;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_SalaryAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_SalaryDeattested;
                beneficiary        = salary.PayrollItem.PersonCanonical;
                amountCents        = salary.GrossSalaryCents + salary.AdditiveTaxCents;

                break;

            case 'P':     // Parley, aka Conference
                Parley parley = Parley.FromIdentity(itemId);
                if (parley.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (parley.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    parley.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                approvableItem     = parley;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_ParleyAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_ParleyDeattested;
                beneficiary        = parley.Person.Name;
                amountCents        = parley.BudgetCents;

                break;

            default:
                throw new InvalidOperationException("Unknown Cost Type in HandleAttestationDeattestation: \"" +
                                                    identifier + "\"");
            }

            // Finally, attest or deattest

            if (mode == AttestationMode.Attestation)
            {
                Int64 budgetRemaining = approvableItem.Budget.GetBudgetCentsRemaining();

                result = string.Empty;

                if (amountCents > -budgetRemaining)
                {
                    if (
                        authData.Authority.HasAccess(new Access(authData.CurrentOrganization,
                                                                AccessAspect.Administration)))
                    {
                        // Admin rights, so allow (forced) overdraft

                        // Unless budget was nonzero and allocated, set protest message

                        if (approvableItem.Budget.Owner != null || approvableItem.Budget.GetBudgetCents() != 0)
                        {
                            result = Resources.Pages.Financial.AttestCosts_Overdrafted + " ";
                        }
                    }
                    else
                    {
                        // Do not allow overdraft

                        return(new AjaxCallResult
                        {
                            DisplayMessage = Resources.Pages.Financial.AttestCosts_OutOfBudget,
                            Success = false
                        });
                    }
                }

                approvableItem.Approve(authData.CurrentUser);
                result += string.Format(attestedTemplate, itemId, beneficiary,
                                        authData.CurrentOrganization.Currency.Code,
                                        amountCents / 100.0);
            }
            else if (mode == AttestationMode.Deattestation)
            {
                approvableItem.RetractApproval(authData.CurrentUser);
                result = string.Format(deattestedTemplate, itemId, beneficiary,
                                       authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else
            {
                throw new InvalidOperationException("Unknown Approval Mode: " + mode);
            }

            FinancialAccount.ClearApprovalAdjustmentsCache(authData.CurrentOrganization);

            return(new AjaxCallResult {
                DisplayMessage = result, Success = true
            });
        }
        private static string HandleValidationDevalidation(string identifier, AttestationMode mode)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            IValidatable validatableItem     = null;
            string       validatedTemplate   = string.Empty;
            string       devalidatedTemplate = string.Empty;

            char   costType = identifier[0];
            int    itemId   = Int32.Parse(identifier.Substring(1));
            Int64  amountCents;
            string beneficiary = string.Empty;
            string result      = string.Empty;

            // A lot of this code was copied from attest/deattest, even though validation only concerns expense receipts

            switch (costType)
            {
            case 'E':     // Expense claim
                ExpenseClaim expense = ExpenseClaim.FromIdentity(itemId);
                if (expense.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (!authData.CurrentUser.HasAccess(new Access(authData.CurrentOrganization, AccessAspect.Financials, AccessType.Write)))
                {
                    throw new UnauthorizedAccessException();
                }

                validatableItem     = expense;
                validatedTemplate   = Resources.Pages.Financial.ValidateReceipts_ReceiptsValidated;
                devalidatedTemplate = Resources.Pages.Financial.ValidateReceipts_ReceiptsDevalidated;
                amountCents         = expense.AmountCents;

                break;

            default:
                throw new InvalidOperationException("Unknown Cost Type in HandleValidationDevalidation: \"" + identifier + "\"");
            }

            // Finally, attest or deattest

            if (mode == AttestationMode.Attestation)
            {
                validatableItem.Validate(authData.CurrentUser);
                result = string.Format(validatedTemplate, itemId, authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else if (mode == AttestationMode.Deattestation)
            {
                validatableItem.Devalidate(authData.CurrentUser);
                result = string.Format(devalidatedTemplate, itemId, authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else
            {
                throw new InvalidOperationException("Unknown Attestation Mode: " + mode.ToString());
            }

            return(result);
        }
        private static string HandleValidationDevalidation (string identifier, AttestationMode mode)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            IValidatable validatableItem = null;
            string validatedTemplate = string.Empty;
            string devalidatedTemplate = string.Empty;

            char costType = identifier[0];
            int itemId = Int32.Parse(identifier.Substring(1));
            Int64 amountCents;
            string beneficiary = string.Empty;
            string result = string.Empty;

            // A lot of this code was copied from attest/deattest, even though validation only concerns expense receipts

            switch(costType)
            {
                case 'E': // Expense claim
                    ExpenseClaim expense = ExpenseClaim.FromIdentity(itemId);
                    if (expense.OrganizationId != authData.CurrentOrganization.Identity)
                    {
                        throw new InvalidOperationException("Called to attest out-of-org line item");
                    }
                    if (!authData.CurrentUser.HasAccess(new Access(authData.CurrentOrganization, AccessAspect.Financials, AccessType.Write)))
                    {
                        throw new UnauthorizedAccessException();
                    }

                    validatableItem = expense;
                    validatedTemplate = Resources.Pages.Financial.ValidateReceipts_ReceiptsValidated;
                    devalidatedTemplate = Resources.Pages.Financial.ValidateReceipts_ReceiptsDevalidated;
                    amountCents = expense.AmountCents;

                    break;
                default:
                    throw new InvalidOperationException("Unknown Cost Type in HandleValidationDevalidation: \"" + identifier + "\"");
            }

            // Finally, attest or deattest

            if (mode == AttestationMode.Attestation)
            {
                validatableItem.Validate(authData.CurrentUser);
                result = string.Format(validatedTemplate, itemId, authData.CurrentOrganization.Currency.Code,
                                       amountCents/100.0);
            }
            else if (mode == AttestationMode.Deattestation)
            {
                validatableItem.Devalidate(authData.CurrentUser);
                result = string.Format(devalidatedTemplate, itemId, authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else
            {
                throw new InvalidOperationException("Unknown Attestation Mode: " + mode.ToString());
            }

            return result;
        }
Example #4
0
        private static string HandleAttestationDeattestation(string identifier, AttestationMode mode)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            IAttestable attestableItem     = null;
            string      attestedTemplate   = string.Empty;
            string      deattestedTemplate = string.Empty;

            char   costType = identifier[0];
            int    itemId   = Int32.Parse(identifier.Substring(1));
            Int64  amountCents;
            string beneficiary = string.Empty;
            string result      = string.Empty;

            // Find the item we are attesting or deattesting

            switch (costType)
            {
            case 'A':     // Case advance
                CashAdvance advance = CashAdvance.FromIdentity(itemId);
                if (advance.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (advance.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    advance.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityAccessDeniedException("Called without attestation privileges");
                }

                attestableItem     = advance;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_AdvanceAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_AdvanceDeattested;
                beneficiary        = advance.Person.Name;
                amountCents        = advance.AmountCents;

                break;

            case 'E':     // Expense claim
                ExpenseClaim expense = ExpenseClaim.FromIdentity(itemId);
                if (expense.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (expense.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    expense.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityAccessDeniedException("Called without attestation privileges");
                }

                attestableItem     = expense;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_ExpenseAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_ExpenseDeattested;
                beneficiary        = expense.Claimer.Name;
                amountCents        = expense.AmountCents;

                break;

            case 'I':     // Inbound invoice
                InboundInvoice invoice = InboundInvoice.FromIdentity(itemId);
                if (invoice.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (invoice.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    invoice.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityAccessDeniedException("Called without attestation privileges");
                }

                attestableItem     = invoice;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_InvoiceAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_InvoiceDeattested;
                beneficiary        = invoice.Supplier;
                amountCents        = invoice.AmountCents;

                break;

            case 'S':     // Salary payout
                Salary salary = Salary.FromIdentity(itemId);
                if (salary.PayrollItem.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (salary.PayrollItem.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    salary.PayrollItem.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityAccessDeniedException("Called without attestation privileges");
                }

                attestableItem     = salary;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_SalaryAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_SalaryDeattested;
                beneficiary        = salary.PayrollItem.PersonCanonical;
                amountCents        = salary.GrossSalaryCents;

                break;

            case 'P':     // Parley, aka Conference
                Parley parley = Parley.FromIdentity(itemId);
                if (parley.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (parley.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    parley.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityAccessDeniedException("Called without attestation privileges");
                }

                attestableItem     = parley;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_ParleyAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_ParleyDeattested;
                beneficiary        = parley.Person.Name;
                amountCents        = parley.BudgetCents;

                break;

            default:
                throw new InvalidOperationException("Unknown Cost Type in HandleAttestationDeattestation: \"" +
                                                    identifier + "\"");
            }

            // Finally, attest or deattest

            if (mode == AttestationMode.Attestation)
            {
                attestableItem.Attest(authData.CurrentUser);
                result = string.Format(attestedTemplate, itemId, beneficiary,
                                       authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else if (mode == AttestationMode.Deattestation)
            {
                attestableItem.Deattest(authData.CurrentUser);
                result = string.Format(deattestedTemplate, itemId, beneficiary,
                                       authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else
            {
                throw new InvalidOperationException("Unknown Attestation Mode: " + mode);
            }

            return(result);
        }
Example #5
0
        private static string HandleAttestationDeattestation (string identifier, AttestationMode mode)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            IAttestable attestableItem = null;
            string attestedTemplate = string.Empty;
            string deattestedTemplate = string.Empty;

            char costType = identifier[0];
            int itemId = Int32.Parse(identifier.Substring(1));
            Int64 amountCents;
            string beneficiary = string.Empty;
            string result = string.Empty;

            // Find the item we are attesting or deattesting

            switch(costType)
            {
                case 'A': // Case advance
                    CashAdvance advance = CashAdvance.FromIdentity(itemId);
                    if (advance.OrganizationId != authData.CurrentOrganization.Identity)
                    {
                        throw new InvalidOperationException("Called to attest out-of-org line item");
                    }
                    if (advance.Budget.OwnerPersonId != authData.CurrentUser.Identity && advance.Budget.OwnerPersonId != Person.NobodyId)
                    {
                        throw new SecurityAccessDeniedException("Called without attestation privileges");
                    }

                    attestableItem = advance;
                    attestedTemplate = Resources.Pages.Financial.AttestCosts_AdvanceAttested;
                    deattestedTemplate = Resources.Pages.Financial.AttestCosts_AdvanceDeattested;
                    beneficiary = advance.Person.Name;
                    amountCents = advance.AmountCents;

                    break;
                case 'E': // Expense claim
                    ExpenseClaim expense = ExpenseClaim.FromIdentity(itemId);
                    if (expense.OrganizationId != authData.CurrentOrganization.Identity)
                    {
                        throw new InvalidOperationException("Called to attest out-of-org line item");
                    }
                    if (expense.Budget.OwnerPersonId != authData.CurrentUser.Identity && expense.Budget.OwnerPersonId != Person.NobodyId)
                    {
                        throw new SecurityAccessDeniedException("Called without attestation privileges");
                    }

                    attestableItem = expense;
                    attestedTemplate = Resources.Pages.Financial.AttestCosts_ExpenseAttested;
                    deattestedTemplate = Resources.Pages.Financial.AttestCosts_ExpenseDeattested;
                    beneficiary = expense.Claimer.Name;
                    amountCents = expense.AmountCents;

                    break;
                case 'I': // Inbound invoice
                    InboundInvoice invoice = InboundInvoice.FromIdentity(itemId);
                    if (invoice.OrganizationId != authData.CurrentOrganization.Identity)
                    {
                        throw new InvalidOperationException("Called to attest out-of-org line item");
                    }
                    if (invoice.Budget.OwnerPersonId != authData.CurrentUser.Identity && invoice.Budget.OwnerPersonId != Person.NobodyId)
                    {
                        throw new SecurityAccessDeniedException("Called without attestation privileges");
                    }

                    attestableItem = invoice;
                    attestedTemplate = Resources.Pages.Financial.AttestCosts_InvoiceAttested;
                    deattestedTemplate = Resources.Pages.Financial.AttestCosts_InvoiceDeattested;
                    beneficiary = invoice.Supplier;
                    amountCents = invoice.AmountCents;

                    break;
                case 'S': // Salary payout
                    Salary salary = Salary.FromIdentity(itemId);
                    if (salary.PayrollItem.OrganizationId != authData.CurrentOrganization.Identity)
                    {
                        throw new InvalidOperationException("Called to attest out-of-org line item");
                    }
                    if (salary.PayrollItem.Budget.OwnerPersonId != authData.CurrentUser.Identity && salary.PayrollItem.Budget.OwnerPersonId != Person.NobodyId)
                    {
                        throw new SecurityAccessDeniedException("Called without attestation privileges");
                    }

                    attestableItem = salary;
                    attestedTemplate = Resources.Pages.Financial.AttestCosts_SalaryAttested;
                    deattestedTemplate = Resources.Pages.Financial.AttestCosts_SalaryDeattested;
                    beneficiary = salary.PayrollItem.PersonCanonical;
                    amountCents = salary.GrossSalaryCents;

                    break;
                case 'P': // Parley, aka Conference
                    Parley parley = Parley.FromIdentity(itemId);
                    if (parley.OrganizationId != authData.CurrentOrganization.Identity)
                    {
                        throw new InvalidOperationException("Called to attest out-of-org line item");
                    }
                    if (parley.Budget.OwnerPersonId != authData.CurrentUser.Identity && parley.Budget.OwnerPersonId != Person.NobodyId)
                    {
                        throw new SecurityAccessDeniedException("Called without attestation privileges");
                    }

                    attestableItem = parley;
                    attestedTemplate = Resources.Pages.Financial.AttestCosts_ParleyAttested;
                    deattestedTemplate = Resources.Pages.Financial.AttestCosts_ParleyDeattested;
                    beneficiary = parley.Person.Name;
                    amountCents = parley.BudgetCents;

                    break;
                default:
                    throw new InvalidOperationException("Unknown Cost Type in HandleAttestationDeattestation: \"" + identifier + "\"");
            }

            // Finally, attest or deattest

            if (mode == AttestationMode.Attestation)
            {
                attestableItem.Attest(authData.CurrentUser);
                result = string.Format(attestedTemplate, itemId, beneficiary, authData.CurrentOrganization.Currency.Code,
                                       amountCents/100.0);
            }
            else if (mode == AttestationMode.Deattestation)
            {
                attestableItem.Deattest(authData.CurrentUser);
                result = string.Format(deattestedTemplate, itemId, beneficiary, authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else
            {
                throw new InvalidOperationException("Unknown Attestation Mode: " + mode.ToString());
            }

            return result;
        }