private BudgetData GetBudgetData(int budgetId, int year) { FinancialAccount account = FinancialAccount.FromIdentity(budgetId); double budget = -account.GetBudget(year); Int64 actualCents = account.GetDeltaCents(new DateTime(year, 1, 1), new DateTime(year + 1, 1, 1)); double actual = actualCents / 100.0; // Get suballocated FinancialAccounts accountTree = account.GetTree(); double budgetTotal = -accountTree.GetBudgetSum(year); Int64 deltaTotalCents = accountTree.GetDeltaCents(new DateTime(year, 1, 1), new DateTime(year + 1, 1, 1)); double deltaTotal = deltaTotalCents / 100.0; BudgetData result = new BudgetData(); result.AccountName = account.Name; if (budgetTotal > 0.0) { result.PercentActual = actual / budgetTotal * 100.0; result.PercentSuballocated = (budgetTotal - budget) / budgetTotal * 100.0; result.PercentSuballocatedUsed = (deltaTotal - actual) / budgetTotal * 100.0; } return(result); }
protected void ButtonSetBudgets_Click(object sender, EventArgs e) { foreach (RepeaterItem repeaterItem in this.RepeaterAccountBudgets.Items) { HiddenField hiddenAccountId = (HiddenField)repeaterItem.FindControl("HiddenAccountId"); TextBox textBudget = (TextBox)repeaterItem.FindControl("TextBudget"); FinancialAccount account = FinancialAccount.FromIdentity(Int32.Parse(hiddenAccountId.Value)); // TODO: Possible race condition here, fix with HiddenField Int64 newBudgetAmount = Int64.Parse(textBudget.Text.Replace(",", "").Replace(" ", ""), Thread.CurrentThread.CurrentCulture); // TODO: May throw -- catch and send error message Int64 currentBudgetAmount = account.GetTree().GetBudgetSumCents(_year) / 100; // Set the new amount to the difference between the single budget of this account and the intended amount if (newBudgetAmount != currentBudgetAmount) { account.SetBudgetCents(_year, account.GetBudgetCents(_year) + (newBudgetAmount - currentBudgetAmount) * 100); } } // After updating budgets, rebind repeater FinancialAccounts accounts = GetRootLevelResultAccounts(); UpdateYearlyResult(accounts); this.RepeaterAccountBudgets.DataSource = accounts; this.RepeaterAccountBudgets.DataBind(); }
public static JsonAccountData GetAccountData(int accountId) { AuthenticationData authData = GetAuthenticationDataAndCulture(); FinancialAccount account = FinancialAccount.FromIdentity(accountId); if (account.OrganizationId != authData.CurrentOrganization.Identity) { throw new UnauthorizedAccessException("A million nopes"); } FinancialAccounts accountTree = account.GetTree(); int year = DateTime.Today.Year; JsonAccountData result = new JsonAccountData(); result.AccountName = account.Name; result.ParentAccountId = account.ParentIdentity; result.ParentAccountName = account.ParentFinancialAccountId == 0 ? Global.ResourceManager.GetString("Financial_" + account.AccountType) : account.Parent.Name; result.Expensable = account.Expensable; result.Administrative = account.Administrative; result.Active = account.Active; result.Open = account.Open; result.AccountOwnerName = account.OwnerPersonId != 0 ? account.Owner.Name : Global.Global_NoOwner; result.AccountOwnerAvatarUrl = account.OwnerPersonId != 0 ? account.Owner.GetSecureAvatarLink(24) : "/Images/Icons/iconshock-warning-24px.png"; result.Budget = (accountTree.GetBudgetSumCents(year) / 100L).ToString("N0", CultureInfo.CurrentCulture); if (account.AccountType == FinancialAccountType.Asset || account.AccountType == FinancialAccountType.Debt) { result.Balance = (accountTree.GetDeltaCents(new DateTime(1900, 1, 1), new DateTime(year + 1, 1, 1)) / 100L).ToString ( "N0"); result.InitialBalance = ((accountTree.GetDeltaCents(new DateTime(1900, 1, 1), new DateTime(authData.CurrentOrganization.FirstFiscalYear, 1, 1)) / 100.0).ToString("N2")); } else { result.Balance = (-accountTree.GetDeltaCents(new DateTime(year, 1, 1), new DateTime(year + 1, 1, 1)) / 100L) .ToString( "N0"); result.InitialBalance = "N/A"; // unused } result.CurrencyCode = account.Organization.Currency.DisplayCode; return(result); }
public void Populate(FinancialAccount root) { this.Tree.Nodes.Clear(); FinancialAccounts accounts = root.GetTree(); accounts.Remove(root); if (accounts.Count > 0) { Populate(accounts); } }
protected void RepeaterAccountBudgets_ItemDataBound(object sender, RepeaterItemEventArgs e) { RepeaterItem item = e.Item; if (item.DataItem == null) { return; } FinancialAccount account = (FinancialAccount)item.DataItem; TextBox textBudget = (TextBox)e.Item.FindControl("TextBudget"); if (this._year > 0) // called from after viewstate parsed { textBudget.Text = String.Format("{0:N0}", account.GetTree().GetBudgetSumCents(this._year) / 100); textBudget.Style[HtmlTextWriterStyle.TextAlign] = "right"; textBudget.Style[HtmlTextWriterStyle.Width] = "80px"; } Label labelOwnerName = (Label)e.Item.FindControl("LabelBudgetOwner"); Person accountOwner = account.Owner; if (accountOwner == null) { labelOwnerName.Text = Global.Global_NoOwner; } else { labelOwnerName.Text = accountOwner.Formal; } // RadToolTip toolTip = (RadToolTip)e.Item.FindControl("ToolTip"); // Swarmops.Controls.Swarm.PersonDetailPopup personDetail = (PersonDetailPopup)toolTip.FindControl("PersonDetail"); // personDetail.PersonChanged += new PersonChangedEventHandler(PersonDetail_PersonChanged); if (!Page.IsPostBack && CurrentAuthority != null) { /* * personDetail.Person = accountOwner; * personDetail.Cookie = account;*/ } HiddenField hiddenAccountId = (HiddenField)e.Item.FindControl("HiddenAccountId"); hiddenAccountId.Value = account.Identity.ToString(); // this.TooltipManager.TargetControls.Add(labelBudgetOwner.ClientID, line.AccountIdentity.ToString(), true); }
protected void DropBudgets_SelectedIndexChanged(object sender, EventArgs e) { if (this.DropBudgets.SelectedValue != "0") { FinancialAccount selectedBudget = FinancialAccount.FromIdentity(Int32.Parse(this.DropBudgets.SelectedValue)); if (selectedBudget.GetTree().Count > 1) { this.DropSubBudget.Populate(selectedBudget); this.DropMethod.Items[4].Enabled = true; } else { this.DropMethod.Items[4].Enabled = false; } } }
public static ChangeAccountDataResult SetAccountBudget(int accountId, string budget) { AuthenticationData authData = GetAuthenticationDataAndCulture(); FinancialAccount account = FinancialAccount.FromIdentity(accountId); if (!PrepareAccountChange(account, authData, false)) { return(new ChangeAccountDataResult { Result = ChangeAccountDataOperationsResult.NoPermission }); } Int64 newTreeBudget; budget = budget.Replace("%A0", "%20"); // some very weird browser space-to-otherspace translation weirds out number parsing budget = HttpContext.Current.Server.UrlDecode(budget); if (budget.Trim().Length > 0 && Int64.TryParse(budget, NumberStyles.Currency, CultureInfo.CurrentCulture, out newTreeBudget)) { newTreeBudget *= 100; // convert to cents int year = DateTime.Today.Year; FinancialAccounts accountTree = account.GetTree(); Int64 currentTreeBudget = accountTree.GetBudgetSumCents(year); Int64 currentSingleBudget = account.GetBudgetCents(year); Int64 suballocatedBudget = currentTreeBudget - currentSingleBudget; Int64 newSingleBudget = newTreeBudget - suballocatedBudget; account.SetBudgetCents(DateTime.Today.Year, newSingleBudget); return(new ChangeAccountDataResult { Result = ChangeAccountDataOperationsResult.Changed, NewData = (newTreeBudget / 100).ToString("N0", CultureInfo.CurrentCulture) }); } else { return(new ChangeAccountDataResult { Result = ChangeAccountDataOperationsResult.Invalid }); } }
/* * protected void RebindTooltips() * { * foreach (RepeaterItem repeaterItem in this.RepeaterAccountBudgets.Items) * { * HiddenField hiddenAccountId = (HiddenField)repeaterItem.FindControl("HiddenAccountId"); * FinancialAccount child = FinancialAccount.FromIdentity(Int32.Parse(hiddenAccountId.Value)); * RadToolTip toolTip = (RadToolTip)repeaterItem.FindControl("ToolTip"); * * PersonDetailPopup personDetail = (PersonDetailPopup)toolTip.FindControl("PersonDetail"); * * FinancialAccount account = FinancialAccount.FromIdentity(Int32.Parse(hiddenAccountId.Value)); * personDetail.Person = account.Owner; * personDetail.Cookie = child; * } * }*/ protected void RepeaterAccountActuals_ItemDataBound(object sender, RepeaterItemEventArgs e) { RepeaterItem item = e.Item; if (item.DataItem == null) { return; } FinancialAccount account = (FinancialAccount)item.DataItem; Label labelActuals = (Label)e.Item.FindControl("LabelAccountActuals"); Int64 actuals = (account.GetTree().GetDeltaCents(new DateTime(_year, 1, 1), new DateTime(_year + 1, 1, 1)) + 50) / 100; labelActuals.Text = String.Format("{0:N0}", -actuals); // negative as results accounts are sign reversed }
public static ChangeAccountDataResult SetAccountBudget(int accountId, string budget) { try { AuthenticationData authData = GetAuthenticationDataAndCulture(); FinancialAccount account = FinancialAccount.FromIdentity(accountId); if (!PrepareAccountChange(account, authData, false)) { return(new ChangeAccountDataResult { Result = ChangeAccountDataOperationsResult.NoPermission }); } Int64 newTreeBudget; budget = budget.Replace("%A0", "%20"); // some very weird browser space-to-otherspace translation weirds out number parsing budget = HttpContext.Current.Server.UrlDecode(budget); if (budget.Trim().Length > 0 && Int64.TryParse(budget, NumberStyles.Currency, CultureInfo.CurrentCulture, out newTreeBudget)) { newTreeBudget *= 100; // convert to cents int year = DateTime.Today.Year; FinancialAccounts accountTree = account.GetTree(); Int64 currentTreeBudget = accountTree.GetBudgetSumCents(year); Int64 currentSingleBudget = account.GetBudgetCents(year); Int64 suballocatedBudget = currentTreeBudget - currentSingleBudget; Int64 newSingleBudget = newTreeBudget - suballocatedBudget; account.SetBudgetCents(DateTime.Today.Year, newSingleBudget); // Once we've set the budget, also update the "yearly result" budget. // The "yearly result" budget isn't shown in the account plan, but is // abstracted to "projected loss" or "projected gain" pseudobudgets. int thisYear = DateTime.UtcNow.Year; FinancialAccounts allProfitLossAccounts = FinancialAccounts.ForOrganization(authData.CurrentOrganization); Int64 newProfitLossProjection = allProfitLossAccounts.Where(queryAccount => queryAccount.Identity != authData.CurrentOrganization.FinancialAccounts.CostsYearlyResult.Identity).Sum(queryAccount => queryAccount.GetBudgetCents(thisYear)); authData.CurrentOrganization.FinancialAccounts.CostsYearlyResult.SetBudgetCents(thisYear, -newProfitLossProjection); return(new ChangeAccountDataResult { Result = ChangeAccountDataOperationsResult.Changed, NewData = (newTreeBudget / 100).ToString("N0", CultureInfo.CurrentCulture) }); } return(new ChangeAccountDataResult { Result = ChangeAccountDataOperationsResult.Invalid }); } catch (Exception weirdException) { // Exceptions are happening here in deployment ONLY. We're logging it to find which one and why. // TODO: This really needs to be in Logic. DO NOT DO NOT DO NOT call Database layer directly from Site layer. SwarmDb.GetDatabaseForWriting() .CreateExceptionLogEntry(DateTime.UtcNow, "AccountPlan-SetBudget", weirdException); throw; } }
protected void ButtonReallocate_Click(object sender, EventArgs e) { FinancialAccounts children = _account.Children; double deltaTotal = 0.0; int budgetAttempt; int budgetTotal = 0; // In a first round, verify that all numbers are parsable foreach (RepeaterItem repeaterItem in this.RepeaterBudgetTextBoxes.Items) { HiddenField hiddenAccountId = (HiddenField)repeaterItem.FindControl("HiddenAccountId"); FinancialAccount child = FinancialAccount.FromIdentity(Int32.Parse(hiddenAccountId.Value)); TextBox box = (TextBox)repeaterItem.FindControl("TextChildBudget"); string boxText = box.Text; if (!Int32.TryParse(boxText, NumberStyles.Number, new CultureInfo("sv-SE"), out budgetAttempt)) { ScriptManager.RegisterStartupScript(this, Page.GetType(), "error", "alert('The budget for the account \"" + Server.HtmlEncode(child.Name).Replace("'", "''") + "\" does not appear to be a valid number. Please correct this and try again.');", true); return; } budgetTotal += budgetAttempt; } // Verify that the budget is not overrun by suballocations if (Math.Abs(budgetTotal) > Math.Abs(_account.GetTree().GetBudgetSum(_year))) { ScriptManager.RegisterStartupScript(this, Page.GetType(), "error", "alert('You are trying to overallocate the budget. Please correct this and try again.');", true); return; } // Then, move on to actually mod the budgets foreach (RepeaterItem repeaterItem in this.RepeaterBudgetTextBoxes.Items) { HiddenField hiddenAccountId = (HiddenField)repeaterItem.FindControl("HiddenAccountId"); FinancialAccount child = FinancialAccount.FromIdentity(Int32.Parse(hiddenAccountId.Value)); TextBox box = (TextBox)repeaterItem.FindControl("TextChildBudget"); string boxText = box.Text; double newBudget = (double)Int32.Parse(boxText, NumberStyles.Number, new CultureInfo("sv-SE")); double curBudget = child.GetTree().GetBudgetSum(_year); // since we don't know here how much has been suballocated in turn, we need to produce a delta from the child's tree budget total and apply it to the child node double delta = newBudget - curBudget; child.SetBudget(_year, child.GetBudget(_year) + delta); deltaTotal += delta; } // Last, apply the total delta to the master account _account.SetBudget(_year, _account.GetBudget(_year) - deltaTotal); // Rewrite controls PopulateBudgetData(); }