Пример #1
0
        public ActionResult Add(string key)
        {
            var msg = new JsonMessage(false, "Thêm mới dữ liệu thành công.");

            try
            {
                var model = new CashAdvance();
                if (key != Keyapi)
                {
                    return(Json(0, JsonRequestBehavior.AllowGet));
                }
                UpdateModel(model);
                model.Note     = HttpUtility.UrlDecode(model.Note);
                model.IsDelete = false;
                model.IsActive = false;
                model.Code     = DateTime.Now.ToString("yyMMddHHmm");
                var startDate = Request["DateReturn_"];
                model.DateReturn  = startDate.StringToDecimal();
                model.DateCreated = DateTime.Now.TotalSeconds();
                _da.Add(model);
                _da.Save();
            }
            catch (Exception ex)
            {
                msg.Erros   = true;
                msg.Message = "Dữ liệu chưa được thêm mới.";
            }
            return(Json(msg, JsonRequestBehavior.AllowGet));
        }
Пример #2
0
        static private Int64 GetSumCentsTotal(string prototypeId)
        {
            string[] payoutComponents = prototypeId.Split('|');

            Int64 amountCentsTotal = 0;

            foreach (string payoutComponent in payoutComponents)
            {
                switch (payoutComponent[0])
                {
                case 'C':
                    amountCentsTotal += ExpenseClaim.FromIdentity(Int32.Parse(payoutComponent.Substring(1))).AmountCents;
                    break;

                case 'A':      // Advance pay-OUT
                    amountCentsTotal += CashAdvance.FromIdentity(Int32.Parse(payoutComponent.Substring(1))).AmountCents;
                    break;

                case 'a':      // Advance pay-BACK
                    amountCentsTotal -= CashAdvance.FromIdentity(Int32.Parse(payoutComponent.Substring(1))).AmountCents;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            return(amountCentsTotal);
        }
Пример #3
0
        protected void ButtonRequest_Click(object sender, EventArgs e)
        {
            // The data has been validated client-side already. We'll throw unfriendly exceptions if invalid data is passed here.

            double amount = Double.Parse(this.TextAmount.Text, NumberStyles.Number);
            // parses in current culture - intentional
            Int64 amountCents = (Int64)amount * 100;

            string description = this.TextPurpose.Text;

            FinancialAccount budget = FinancialAccount.FromIdentity(Int32.Parse(this.Request.Form["DropBudgets"]));

            // sanity check

            if (budget.Organization.Identity != CurrentOrganization.Identity)
            {
                throw new InvalidOperationException("Budget-organization mismatch; won't file cash advance");
            }

            // Store bank details for current user

            CurrentUser.BankName     = this.TextBank.Text;
            CurrentUser.BankClearing = this.TextClearing.Text;
            CurrentUser.BankAccount  = this.TextAccount.Text;

            // Create cash advance

            CashAdvance cashAdvance = CashAdvance.Create(CurrentOrganization, CurrentUser, CurrentUser, amountCents,
                                                         budget,
                                                         description);

            // Create success message

            string successMessage = string.Format(Resources.Pages.Financial.RequestCashAdvance_SuccessMessagePartOne,
                                                  HttpUtility.HtmlEncode(CurrentUser.Name),
                                                  HttpUtility.HtmlEncode(description), CurrentOrganization.Currency.Code,
                                                  (double)(amountCents / 100.0));

            if (budget.OwnerPersonId != CurrentUser.Identity)
            {
                successMessage += "<br/><br/>" + Resources.Pages.Financial.RequestCashAdvance_SuccessMessagePartTwo +
                                  "<br/>";
            }
            else
            {
                successMessage += "<br/><br/>" +
                                  Resources.Pages.Financial.RequestCashAdvance_SuccessMessagePartTwoOwnBudget +
                                  "<br/>";
                cashAdvance.Attest(CurrentUser);
            }

            Response.AppendCookie(new HttpCookie("DashboardMessage", HttpUtility.UrlEncode(successMessage)));

            // Redirect to dashboard

            Response.Redirect("/", true);
        }
Пример #4
0
        private static string GetObjectDetails(IHasIdentity identifiableObject)
        {
            switch (identifiableObject.GetType().Name)
            {
            case "ExpenseClaim":
                ExpenseClaim claim = (ExpenseClaim)identifiableObject;

                return("<strong>" +
                       String.Format(Global.Financial_ExpenseClaimLongSpecification, claim.Identity) +
                       ":</strong> " + claim.Organization.Currency.Code + " " +
                       (claim.AmountCents / 100.0).ToString("N2") + ". " +
                       HttpUtility.HtmlEncode(GetValidationDetails(claim.Validations)) + " " +
                       GetDocumentDetails(claim.Documents, claim));

            case "CashAdvance":
                CashAdvance advance = (CashAdvance)identifiableObject;

                return("<strong>" +
                       String.Format(Global.Financial_CashAdvanceSpecification, advance.Identity) +
                       ":</strong> " + advance.Organization.Currency.Code + " " +
                       (advance.AmountCents / 100.0).ToString("N2") + ". " +
                       HttpUtility.HtmlEncode(GetValidationDetails(advance.Validations)));

            case "InboundInvoice":
                InboundInvoice invoice = (InboundInvoice)identifiableObject;

                return("<strong>" +
                       String.Format(Global.Financial_InboundInvoiceSpecification, invoice.Identity) +
                       ":</strong> " + invoice.Organization.Currency.Code + " " +
                       (invoice.AmountCents / 100.0).ToString("N2") + ". " +
                       GetValidationDetails(invoice.Validations) + " " +
                       GetDocumentDetails(invoice.Documents, invoice));

            case "Salary":
                Salary salary = (Salary)identifiableObject;

                return("<strong>" +
                       String.Format(Global.Financial_SalaryIdentity, salary.Identity) +
                       ":</strong> " +
                       String.Format(Resources.Pages.Ledgers.InspectLedgers_TxDetail_SalaryDetail,
                                     salary.PayrollItem.Organization.Currency.Code,
                                     salary.BaseSalaryCents / 100.0,                             // base salary
                                     (salary.GrossSalaryCents - salary.BaseSalaryCents) / 100.0, // before-tax adjustments
                                     salary.GrossSalaryCents / 100.0,                            // before-tax adjusted salary
                                     salary.SubtractiveTaxCents / 100.0,                         // tax deduction
                                     (salary.NetSalaryCents + salary.SubtractiveTaxCents -
                                      salary.GrossSalaryCents) / 100.0,                          // after-tax adjustments
                                     salary.NetSalaryCents / 100.0) +                            // actual payout amount
                       " " + GetValidationDetails(salary.Validations));

            default:
                throw new NotImplementedException("Unhandled object type in GetObjectDetails: " +
                                                  identifiableObject.GetType().Name);
            }
        }
Пример #5
0
        protected void ButtonRequest_Click(object sender, EventArgs e)
        {
            // The data has been validated client-side already. We'll throw unfriendly exceptions if invalid data is passed here.

            Int64 amountCents = this.TextAmount.Cents;

            string description = this.TextPurpose.Text;

            FinancialAccount budget = this.ComboBudgets.SelectedAccount;

            // sanity check

            if (budget.Organization.Identity != CurrentOrganization.Identity)
            {
                throw new InvalidOperationException("Budget-organization mismatch; won't file cash advance");
            }

            // Store bank details for current user

            CurrentUser.BankName     = this.TextBank.Text;
            CurrentUser.BankClearing = this.TextClearing.Text;
            CurrentUser.BankAccount  = this.TextAccount.Text;

            // Create cash advance

            CashAdvance cashAdvance = CashAdvance.Create(CurrentOrganization, CurrentUser, CurrentUser, amountCents,
                                                         budget, description);

            // Create success message

            string successMessage = string.Format(Resources.Pages.Financial.RequestCashAdvance_SuccessMessagePartOne,
                                                  HttpUtility.HtmlEncode(CurrentUser.Name),
                                                  HttpUtility.HtmlEncode(description), CurrentOrganization.Currency.Code,
                                                  amountCents / 100.0);

            if (budget.OwnerPersonId != CurrentUser.Identity)
            {
                successMessage += "<br/><br/>" + Resources.Pages.Financial.RequestCashAdvance_SuccessMessagePartTwo +
                                  "<br/>";
            }
            else
            {
                successMessage += "<br/><br/>" +
                                  Resources.Pages.Financial.RequestCashAdvance_SuccessMessagePartTwoOwnBudget +
                                  "<br/>";
                cashAdvance.Approve(CurrentUser);
            }

            DashboardMessage.Set(successMessage);

            // Redirect to dashboard

            Response.Redirect("/", true);
        }
Пример #6
0
            public static OutstandingAccount FromCashAdvance(CashAdvance advance, DateTime dateTimePaidOut)
            {
                OutstandingAccount result = new OutstandingAccount
                {
                    AmountCents     = advance.AmountCents,
                    Description     = advance.Description,
                    Identity        = advance.Identity,
                    Recipient       = advance.Person.Canonical,
                    CreatedDateTime = dateTimePaidOut,
                    ExpectedClosed  = dateTimePaidOut.AddDays(90)
                };

                return(result);
            }
Пример #7
0
        static protected IPayable PayableFromRecordId(string recordId)
        {
            char recordType = recordId[0];
            int  itemId     = Int32.Parse(recordId.Substring(1));

            switch (recordType)
            {
            case 'E':     // Expense claim
                return(ExpenseClaim.FromIdentity(itemId));

            case 'A':     // Cash advance
                return(CashAdvance.FromIdentity(itemId));

            case 'I':     // Inbound invoice
                return(InboundInvoice.FromIdentity(itemId));

            default:
                throw new NotImplementedException("Unknown record type");
            }
        }
Пример #8
0
        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
            });
        }
Пример #9
0
        static public object FromBasic(IHasIdentity basic)
        {
            string argumentType = basic.GetType().ToString();

            switch (argumentType)
            {
            // ----- Is there any way to make self-writing code here through replication or similar, so
            // ----- that every case doesn't need to be listed?


            // ------------ COMMUNICATION CLASSES ------------

            case "Swarmops.Basic.Types.BasicCommunicationTurnaround":
                return(CommunicationTurnaround.FromBasic((BasicCommunicationTurnaround)basic));

            case "Swarmops.Basic.Types.Communications.BasicOutboundComm":
                return(OutboundComm.FromBasic((BasicOutboundComm)basic));

            case "Swarmops.Basic.Types.Communications.BasicOutboundCommRecipient":
                return(OutboundCommRecipient.FromBasic((BasicOutboundCommRecipient)basic));


            // ----------- FINANCIAL CLASSES ----------

            case "Swarmops.Basic.Types.BasicExpenseClaim":
                return(ExpenseClaim.FromBasic((BasicExpenseClaim)basic));

            case "Swarmops.Basic.Types.Financial.BasicCashAdvance":
                return(CashAdvance.FromBasic((BasicCashAdvance)basic));

            case "Swarmops.Basic.Types.BasicInboundInvoice":
                return(InboundInvoice.FromBasic((BasicInboundInvoice)basic));

            case "Swarmops.Basic.Types.Financial.BasicFinancialAccount":
                return(FinancialAccount.FromBasic((BasicFinancialAccount)basic));

            case "Swarmops.Basic.Types.Financial.BasicFinancialTransaction":
                return(FinancialTransaction.FromBasic((BasicFinancialTransaction)basic));

            case "Swarmops.Basic.Types.BasicFinancialValidation":
                return(FinancialValidation.FromBasic((BasicFinancialValidation)basic));

            case "Swarmops.Basic.Types.BasicOutboundInvoice":
                return(OutboundInvoice.FromBasic((BasicOutboundInvoice)basic));

            case "Swarmops.Basic.Types.BasicOutboundInvoiceItem":
                return(OutboundInvoiceItem.FromBasic((BasicOutboundInvoiceItem)basic));

            case "Swarmops.Basic.Types.BasicPayment":
                return(Payment.FromBasic((BasicPayment)basic));

            case "Swarmops.Basic.Types.BasicPaymentGroup":
                return(PaymentGroup.FromBasic((BasicPaymentGroup)basic));

            case "Swarmops.Basic.Types.BasicPayout":
                return(Payout.FromBasic((BasicPayout)basic));

            case "Swarmops.Basic.Types.BasicPayrollAdjustment":
                return(PayrollAdjustment.FromBasic((BasicPayrollAdjustment)basic));

            case "Swarmops.Basic.Types.BasicPayrollItem":
                return(PayrollItem.FromBasic((BasicPayrollItem)basic));

            case "Swarmops.Basic.Types.BasicSalary":
                return(Salary.FromBasic((BasicSalary)basic));

            case "Swarmops.Basic.Types.Financial.BasicFinancialTransactionTagSet":
                return(FinancialTransactionTagSet.FromBasic((BasicFinancialTransactionTagSet)basic));

            case "Swarmops.Basic.Types.Financial.BasicFinancialTransactionTagType":
                return(FinancialTransactionTagType.FromBasic((BasicFinancialTransactionTagType)basic));

            // ------------ GOVERNANCE CLASSES ------------

            case "Swarmops.Basic.Types.BasicBallot":
                return(Ballot.FromBasic((BasicBallot)basic));

            case "Swarmops.Basic.Types.BasicMeetingElectionCandidate":
                return(MeetingElectionCandidate.FromBasic((BasicInternalPollCandidate)basic));

            case "Swarmops.Basic.Types.BasicMeetingElection":
                return(MeetingElection.FromBasic((BasicInternalPoll)basic));

            case "Swarmops.Basic.Types.BasicMeetingElectionVote":
                return(MeetingElectionVote.FromBasic((BasicInternalPollVote)basic));

            case "Swarmops.Basic.Types.Governance.BasicMotion":
                return(Motion.FromBasic((BasicMotion)basic));

            case "Swarmops.Basic.Types.Governance.BasicMotionAmendment":
                return(MotionAmendment.FromBasic((BasicMotionAmendment)basic));


            // ------------ PARLEY/ACTIVISM CLASSES ------------

            case "Swarmops.Basic.Types.BasicExternalActivity":
                return(ExternalActivity.FromBasic((BasicExternalActivity)basic));

            case "Swarmops.Basic.Types.BasicParley":
                return(Parley.FromBasic((BasicParley)basic));

            case "Swarmops.Basic.Types.BasicParleyAttendee":
                return(ParleyAttendee.FromBasic((BasicParleyAttendee)basic));

            case "Swarmops.Basic.Types.BasicParleyOption":
                return(ParleyOption.FromBasic((BasicParleyOption)basic));

            case "Swarmops.Basic.Types.BasicPerson":
                return(Person.FromBasic((BasicPerson)basic));

            // ------------------ FAIL ----------------

            default:
                throw new NotImplementedException("Unimplemented argument type: " + argumentType);
            }
        }
Пример #10
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);
        }
Пример #11
0
        private static string GetTrackingDetails(object someObject)
        {
            string objectType = someObject.GetType().Name;

            switch (objectType)
            {
            case "Payout":
                Payout payout = (Payout)someObject;
                string result =
                    String.Format(Resources.Pages.Ledgers.InspectLedgers_TxDetail_ThisIsPayoutX, payout.Identity) +
                    " ";

                List <string> subValidations = new List <string>();
                List <string> subResults     = new List <string>();

                if (payout.DependentExpenseClaims.Count > 0)
                {
                    if (payout.DependentExpenseClaims.Count == 1)
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_ExpenseClaimSpecificationWithClaimer,
                                                     payout.DependentExpenseClaims[0].Identity,
                                                     HttpUtility.HtmlEncode(payout.DependentExpenseClaims[0].Claimer.Name)) +
                                       ".</strong>");
                    }
                    else
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_ExpenseClaimsSpecificationWithClaimer,
                                                     Formatting.GenerateRangeString(payout.DependentExpenseClaims.Identities),
                                                     HttpUtility.HtmlEncode(payout.DependentExpenseClaims[0].Claimer.Name)) +
                                       ".</strong>");
                    }

                    foreach (ExpenseClaim claim in payout.DependentExpenseClaims)
                    {
                        subValidations.Add(GetObjectDetails(claim));
                    }
                }

                if (payout.DependentCashAdvancesPayback.Count > 0)
                {
                    if (payout.DependentCashAdvancesPayback.Count == 1)
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_CashAdvancePaybackSpecification,
                                                     payout.DependentCashAdvancesPayback[0].Identity) + ".</strong>");
                    }
                    else
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_CashAdvancePaybacksSpecification,
                                                     Formatting.GenerateRangeString(payout.DependentExpenseClaims.Identities)) +
                                       ".</strong>");
                    }
                }

                if (payout.DependentCashAdvancesPayout.Count > 0)
                {
                    CashAdvance advance0 = payout.DependentCashAdvancesPayout[0];

                    if (payout.DependentCashAdvancesPayout.Count == 1)
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_CashAdvanceLongSpecificationWithRecipient,
                                                     advance0.Identity, advance0.Person.Name) + ".</strong>");
                    }
                    else
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_CashAdvancesLongSpecificationWithRecipient,
                                                     Formatting.GenerateRangeString(payout.DependentExpenseClaims.Identities),
                                                     advance0.Person.Name) + ".</strong>");
                    }

                    foreach (CashAdvance advance in payout.DependentCashAdvancesPayout)
                    {
                        subValidations.Add(GetObjectDetails(advance));
                    }
                }

                if (payout.DependentInvoices.Count > 0)
                {
                    // Assume _one_ invoice

                    InboundInvoice invoice = payout.DependentInvoices[0];

                    subResults.Add("<strong>" + String.Format(
                                       Global.Financial_InboundInvoiceSpecificationWithSender, invoice.Identity,
                                       invoice.Supplier) + "</strong>");

                    subValidations.Add(GetObjectDetails(invoice));
                }

                if (payout.DependentSalariesNet.Count > 0)
                {
                    // Assume one salary

                    Salary salary = payout.DependentSalariesNet[0];

                    subResults.Add("<strong>" +
                                   String.Format(Global.Financial_SalaryDualSpecificationWithRecipient,
                                                 salary.Identity, salary.PayoutDate,
                                                 HttpUtility.HtmlEncode(salary.PayrollItem.PersonCanonical)) +
                                   "</strong>");

                    subValidations.Add(GetObjectDetails(salary));
                }

                if (payout.DependentSalariesTax.Count > 0)
                {
                    Salary salary0 = payout.DependentSalariesTax[0];

                    if (payout.DependentSalariesTax.Count == 1)
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_SalaryTaxDualSpecification, salary0.Identity,
                                                     salary0.PayoutDate) + "</strong>");
                    }
                    else
                    {
                        subResults.Add("<strong>" +
                                       String.Format(Global.Financial_SalariesTaxSpecification, salary0.PayoutDate) +
                                       "</strong>");
                    }
                }


                result +=
                    String.Join(" " + Resources.Pages.Ledgers.InspectLedgers_TxDetail_CombinedWith + " ",
                                subResults) + ". " +
                    String.Format(Resources.Pages.Ledgers.InspectLedgers_TxDetail_PaidOutBy,
                                  payout.CreatedByPerson.Canonical);

                return("<p>" + result + "</p><p>" + String.Join("</p><p>", subValidations) + "</p>");

            case "ExpenseClaim":
            case "CashAdvance":
            case "InboundInvoice":
            case "Salary":
                return("<p>" + GetObjectDetails((IHasIdentity)someObject) + "</p>");

            default:
                return("Unimplemented dependency type: " + objectType);
            }
        }
Пример #12
0
        public static PaymentTransferInfoResult GetPaymentTransferInfo(string prototypeId)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            // TODO: Authentication check

            string[] payoutComponents = prototypeId.Split('|');

            if (payoutComponents.Length < 1)
            {
                throw new InvalidOperationException("Prototype ID can't be empty");
            }

            PaymentTransferInfo info = new PaymentTransferInfo();

            // Some payouts are composites of multiple objects, but all these will share the same
            // payout data, so we can safely use just the first object to determine payment
            // target information
            //
            // with one exception -- we need to determine the amount by adding all the objects
            // together, if applicable

            DateTime paymentDueBy = Constants.DateTimeLow;

            switch (Char.ToUpperInvariant(payoutComponents[0][0]))
            {
            case 'C':     // expense claim
                info =
                    PaymentTransferInfo.FromObject(
                        ExpenseClaim.FromIdentity(Int32.Parse(payoutComponents[0].Substring(1))),
                        new Money(GetSumCentsTotal(prototypeId), authData.CurrentOrganization.Currency));
                break;

            case 'A':     // cash advance (payout or payback, same logic either way)
                info =
                    PaymentTransferInfo.FromObject(
                        CashAdvance.FromIdentity(Int32.Parse(payoutComponents[0].Substring(1))),
                        new Money(GetSumCentsTotal(prototypeId), authData.CurrentOrganization.Currency));
                break;

            case 'S':     // salary
                Salary salary = Salary.FromIdentity(Int32.Parse(payoutComponents[0].Substring(1)));
                info         = PaymentTransferInfo.FromObject(salary);
                paymentDueBy = salary.PayoutDate;
                break;

            case 'I':     // inbound invoice
                InboundInvoice invoice = InboundInvoice.FromIdentity(Int32.Parse(payoutComponents[0].Substring(1)));
                info         = PaymentTransferInfo.FromObject(invoice);
                paymentDueBy = invoice.DueDate;
                break;

            default:
                throw new NotImplementedException("Unrecognized payment type");
            }

            PaymentTransferInfoResult result = new PaymentTransferInfoResult
            {
                Success        = true,
                CurrencyAmount = info.CurrencyAmount,
                DisplayMessage = string.Empty,
                Recipient      = info.Recipient,
                Reference      = info.Reference,
                TransferMethod = info.LocalizedPaymentMethodName
            };

            if (paymentDueBy < Constants.DateTimeLowThreshold)
            {
                result.DueBy = Resources.Global.Global_ASAP;
            }
            else
            {
                DateTime nowUtc = DateTime.UtcNow;

                if (paymentDueBy.Year != nowUtc.Year || paymentDueBy < nowUtc.AddMonths(-3))
                {
                    result.DueBy = paymentDueBy.ToString(Resources.Global.Global_DateFormatLongSansWeekday);
                }
                else
                {
                    result.DueBy = paymentDueBy.ToString(Resources.Global.Global_DateFormatLongDateMonth);
                }

                if (paymentDueBy < nowUtc.AddDays(-1))
                {
                    result.DueBy += " - " + Resources.Pages.Financial.PayOutMoney_PaymentLate;
                }
            }

            List <string> listTransferMethodLabels = new List <string>();
            List <string> listTransferMethodData   = new List <string>();

            foreach (string label in info.LocalizedPaymentInformation.Keys)
            {
                listTransferMethodLabels.Add(HttpUtility.HtmlEncode(label));
                listTransferMethodData.Add(HttpUtility.HtmlEncode(info.LocalizedPaymentInformation [label]));
            }

            result.TransferMethodLabels = listTransferMethodLabels.ToArray();
            result.TransferMethodData   = listTransferMethodData.ToArray();
            result.OcrData = info.OcrData;  // can be null and that's ok

            return(result);
        }
Пример #13
0
 public void Add(CashAdvance item)
 {
     FDIDB.CashAdvances.Add(item);
 }