示例#1
0
 public void EnsureMaintenanceDonationAccountExists()
 {
     if (FinancialAccounts[OrganizationFinancialAccountType.CostsBitcoinFees] == null)
     {
         FinancialAccounts[OrganizationFinancialAccountType.CostsBitcoinFees] =
             FinancialAccount.Create(this, "[LOC]Cost_MaintenanceDonations", FinancialAccountType.Cost, FinancialAccounts.CostsBankFees);
     }
 }
示例#2
0
        public static int CreateAccount(string accountType)
        {
            AuthenticationData   authData        = GetAuthenticationDataAndCulture();
            FinancialAccountType accountTypeEnum =
                (FinancialAccountType)Enum.Parse(typeof(FinancialAccountType), accountType);

            FinancialAccount account = FinancialAccount.Create(authData.CurrentOrganization,
                                                               Resources.Pages.Ledgers.AccountPlan_NewAccount, accountTypeEnum, null);

            return(account.Identity);
        }
    protected void ButtonAdd_Click(object sender, EventArgs e)
    {
        if (!_authority.HasPermission(Permission.CanDoEconomyTransactions, _organizationId, -1, Authorization.Flag.ExactOrganization))
        {
            ScriptManager.RegisterStartupScript(this, Page.GetType(), "getlost",
                                                "alert ('You do not have access to change financial records.');", true);
            return;
        }
        FinancialAccountType pAccountType = (FinancialAccountType)Enum.Parse(typeof(FinancialAccountType), this.DropAccountType.SelectedValue);
        int pParentFinancialAccountId     = Int32.Parse(this.DropAccounts.SelectedValue);

        FinancialAccount.Create(_organizationId, TextAccountName.Text, pAccountType, pParentFinancialAccountId);

        ClientScript.RegisterStartupScript(Page.GetType(), "mykey", "CloseAndRebind();", true);
    }
示例#4
0
    private string ProcessCreateSubBudget()
    {
        int year = DateTime.Today.Year;

        FinancialAccount parentAccount = FinancialAccount.FromIdentity(Int32.Parse(this.DropBudgets.SelectedValue));
        string           budgetName    = this.TextDescription.Text;
        Person           owner         = this.ComboBudgetPerson.SelectedPerson;
        double           currentBudget = parentAccount.GetBudget(year);
        double           amount        = Double.Parse(this.TextAmount.Text, NumberStyles.Float, new CultureInfo("sv-SE"));

        FinancialAccount account = FinancialAccount.Create(Organization.PPSEid, budgetName, FinancialAccountType.Cost,
                                                           parentAccount.Identity);

        account.Owner = owner;
        account.SetBudget(year, -amount);                      // cost accounts have a negative budget
        parentAccount.SetBudget(year, currentBudget + amount); // cost accounts have a negative budget -- this will LOWER the budget

        return("The budget " + budgetName + " was created, owned by " + owner.Canonical +
               " and with an initial budget for " + year.ToString() + " of " +
               amount.ToString("N2") + ". Do not forget to instruct " + (owner.IsFemale? "her" : "him") +
               " on the duties associated, such as attesting expenses, etc.");
    }
示例#5
0
        public void EnableEconomy(Currency currency)
        {
            if (IsEconomyEnabled)
            {
                throw new InvalidOperationException("Economy data already enabled");
            }

            // First, set hardwired accounts


            // TODO: Set names according to org default culture

            FinancialAccounts[OrganizationFinancialAccountType.AssetsBankAccountMain] =
                FinancialAccount.Create(this.Identity, "Bank Account", FinancialAccountType.Asset, 0);
            FinancialAccounts[OrganizationFinancialAccountType.AssetsOutboundInvoices] =
                FinancialAccount.Create(this.Identity, "Outbound Invoices", FinancialAccountType.Asset, 0);
            FinancialAccounts[OrganizationFinancialAccountType.AssetsOutstandingCashAdvances] =
                FinancialAccount.Create(this.Identity, "Cash Advances", FinancialAccountType.Asset, 0);
            //FinancialAccounts[OrganizationFinancialAccountType.AssetsPaypal] =
            //    FinancialAccount.Create(this.Identity, "Paypal Account", FinancialAccountType.Asset, 0);
            //FinancialAccounts[OrganizationFinancialAccountType.AssetsBitcoinHot] =
            //    FinancialAccount.Create(this.Identity, "Bitcoin Holdings (Hot)", FinancialAccountType.Asset, 0);
            //FinancialAccounts[OrganizationFinancialAccountType.AssetsBitcoinCold] =
            //    FinancialAccount.Create(this.Identity, "Bitcoin Cold Storage", FinancialAccountType.Asset, 0);
            FinancialAccounts[OrganizationFinancialAccountType.AssetsVat] =
                FinancialAccount.Create(this.Identity, "Inbound Value Added Tax", FinancialAccountType.Asset, 0);
            FinancialAccounts[OrganizationFinancialAccountType.CostsAllocatedFunds] =
                FinancialAccount.Create(this.Identity, "Allocated funds", FinancialAccountType.Cost, 0);
            FinancialAccounts[OrganizationFinancialAccountType.CostsBankFees] =
                FinancialAccount.Create(this.Identity, "Bank Fees", FinancialAccountType.Cost, 0);
            FinancialAccounts[OrganizationFinancialAccountType.CostsInfrastructure] =
                FinancialAccount.Create(this.Identity, "ICT and Infrastructure", FinancialAccountType.Cost, 0);
            FinancialAccounts[OrganizationFinancialAccountType.CostsYearlyResult] =
                FinancialAccount.Create(this.Identity, "Yearly result", FinancialAccountType.Cost, 0);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsEquity] =
                FinancialAccount.Create(this.Identity, "Equity", FinancialAccountType.Debt, 0);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsExpenseClaims] =
                FinancialAccount.Create(this.Identity, "Expense Claims", FinancialAccountType.Debt, 0);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsInboundInvoices] =
                FinancialAccount.Create(this.Identity, "Inbound Invoices", FinancialAccountType.Debt, 0);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsOther] =
                FinancialAccount.Create(this.Identity, "General Debt", FinancialAccountType.Debt, 0);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsSalary] =
                FinancialAccount.Create(this.Identity, "Salaries Due", FinancialAccountType.Debt, 0);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsTax] =
                FinancialAccount.Create(this.Identity, "Taxes Due", FinancialAccountType.Debt, 0);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsVat] =
                FinancialAccount.Create(this.Identity, "Outbound Value Added Tax", FinancialAccountType.Debt, 0);

            FinancialAccounts[OrganizationFinancialAccountType.IncomeDonations] =
                FinancialAccount.Create(this.Identity, "Donations", FinancialAccountType.Income, 0);
            FinancialAccounts[OrganizationFinancialAccountType.IncomeSales] =
                FinancialAccount.Create(this.Identity, "Sales", FinancialAccountType.Income, 0);


            // Then, create various cost accounts that are probably needed, or that could be used as a starting point

            FinancialAccount.Create(this.Identity, "Offices", FinancialAccountType.Cost, 0);
            FinancialAccount.Create(this.Identity, "Unforeseen", FinancialAccountType.Cost, 0);
            FinancialAccount.Create(this.Identity, "Staff", FinancialAccountType.Cost, 0);
            FinancialAccount.Create(this.Identity, "Marketing and Campaigns", FinancialAccountType.Cost, 0);
            FinancialAccount.Create(this.Identity, "Research and Development", FinancialAccountType.Cost, 0);

            // Finally, create the first conference parent

            FinancialAccount conferenceBase = FinancialAccount.Create(this.Identity, "Conferences",
                                                                      FinancialAccountType.Cost, 0);

            conferenceBase.IsConferenceParent = true;

            // Set the currency

            OptionalData.SetOptionalDataString(ObjectOptionalDataType.OrgCurrency, currency.Code);

            // Set current year to first fiscal year

            this.OptionalData.SetOptionalDataInt(ObjectOptionalDataType.OrgFirstFiscalYear, DateTime.Today.Year);

            // Finally, flag the org as enabled

            this.OptionalData.SetOptionalDataBool(ObjectOptionalDataType.OrgEconomyEnabled, true);
        }
示例#6
0
        public static AjaxInputCallResult SwitchToggled(string cookie, bool newValue)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (authData.CurrentOrganization == null || authData.CurrentUser == null)
            {
                return(null); // just don't... don't anything, actually
            }

            AjaxInputCallResult result = new AjaxInputCallResult();

            result.Success  = true;
            result.NewValue = newValue? "true": "false";

            bool bitcoinNative = (authData.CurrentOrganization.Currency.Code == "BTC");

            FinancialAccounts workAccounts = new FinancialAccounts();

            switch (cookie)
            {
            case "BitcoinCold":

                FinancialAccount coldAccount = authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold;
                if (coldAccount == null)
                {
                    coldAccount = FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Asset_BitcoinCold",
                                                          FinancialAccountType.Asset, null);
                    FinancialAccount.Create(authData.CurrentOrganization, "Cold Address 1",
                                            FinancialAccountType.Asset, coldAccount);
                    FinancialAccount.Create(authData.CurrentOrganization, "Cold Address 2 (rename these)",
                                            FinancialAccountType.Asset, coldAccount);
                    FinancialAccount.Create(authData.CurrentOrganization, "Cold Address... etc",
                                            FinancialAccountType.Asset, coldAccount);

                    authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold = coldAccount;

                    result.DisplayMessage =
                        "Bitcoin cold accounts were created. Edit names and addresses in Connected Accounts.";     // LOC
                }
                else
                {
                    workAccounts.Add(coldAccount);
                }
                break;

            case "BitcoinHot":
                FinancialAccount hotAccount = authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot;
                if (hotAccount == null)
                {
                    authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot =
                        FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Asset_BitcoinHot",
                                                FinancialAccountType.Asset, null);

                    result.DisplayMessage =
                        "Bitcoin HD hotwallet was created along with an account for the hotwallet.";
                }
                else
                {
                    workAccounts.Add(hotAccount);
                }
                break;

            case "Forex":
                FinancialAccount forexGain =
                    authData.CurrentOrganization.FinancialAccounts.IncomeCurrencyFluctuations;
                FinancialAccount forexLoss =
                    authData.CurrentOrganization.FinancialAccounts.CostsCurrencyFluctuations;

                if (forexGain == null)
                {
                    if (forexLoss != null)
                    {
                        throw new InvalidOperationException();
                    }

                    authData.CurrentOrganization.FinancialAccounts.IncomeCurrencyFluctuations =
                        FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Income_ForexGains",
                                                FinancialAccountType.Income, null);
                    authData.CurrentOrganization.FinancialAccounts.CostsCurrencyFluctuations =
                        FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Cost_ForexLosses",
                                                FinancialAccountType.Cost, null);

                    result.DisplayMessage =
                        "Forex gain/loss accounts were created and will be used to account for currency fluctuations.";
                }
                else
                {
                    if (forexLoss == null)
                    {
                        throw new InvalidOperationException();
                    }

                    if (!bitcoinNative && newValue == false &&
                        ((authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold != null &&
                          authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold.Active) ||
                         (authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot != null &&
                          authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot.Active)))
                    {
                        // bitcoin is active, and we're not bitcoin native, so we're not turning off forex

                        result.Success        = false;
                        result.NewValue       = "true";
                        result.DisplayMessage =
                            "Cannot disable forex: bitcoin accounts are active in a non-bitcoin-native organization.";
                    }
                    else
                    {
                        workAccounts.Add(forexGain);
                        workAccounts.Add(forexLoss);
                    }
                }
                break;

            case "Vat":
                FinancialAccount vatInbound  = authData.CurrentOrganization.FinancialAccounts.AssetsVatInbound;
                FinancialAccount vatOutbound = authData.CurrentOrganization.FinancialAccounts.DebtsVatOutbound;

                if (vatInbound == null)
                {
                    if (vatOutbound != null)
                    {
                        throw new InvalidOperationException();
                    }

                    authData.CurrentOrganization.FinancialAccounts.AssetsVatInbound =
                        FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Asset_InboundVat",
                                                FinancialAccountType.Asset, null);
                    authData.CurrentOrganization.FinancialAccounts.DebtsVatOutbound =
                        FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Debt_OutboundVat",
                                                FinancialAccountType.Debt, null);

                    result.DisplayMessage = "Inbound and outbound VAT accounts were created.";
                }
                else
                {
                    if (vatOutbound == null)
                    {
                        throw new InvalidOperationException();
                    }

                    // If the VAT Inbound/Outbound already exist, but subaccounts don't:

                    if (authData.CurrentOrganization.FinancialAccounts.AssetsVatInboundUnreported == null)
                    {
                        // create unreported/reported VAT inbound/outbound - four accounts total

                        authData.CurrentOrganization.FinancialAccounts.AssetsVatInboundUnreported =
                            FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Asset_InboundVatUnreported",
                                                    FinancialAccountType.Asset,
                                                    authData.CurrentOrganization.FinancialAccounts.AssetsVatInbound);
                        authData.CurrentOrganization.FinancialAccounts.DebtsVatOutboundUnreported =
                            FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Debt_OutboundVatUnreported",
                                                    FinancialAccountType.Debt,
                                                    authData.CurrentOrganization.FinancialAccounts.DebtsVatOutbound);

                        authData.CurrentOrganization.FinancialAccounts.AssetsVatInboundReported =
                            FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Asset_InboundVatReported",
                                                    FinancialAccountType.Asset,
                                                    authData.CurrentOrganization.FinancialAccounts.AssetsVatInbound);
                        authData.CurrentOrganization.FinancialAccounts.DebtsVatOutboundReported =
                            FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Debt_OutboundVatReported",
                                                    FinancialAccountType.Debt,
                                                    authData.CurrentOrganization.FinancialAccounts.DebtsVatOutbound);
                    }
                    else     // the accounts exist, need to be re-enabled or disabled, as per the switch direction
                    {
                        workAccounts.Add(authData.CurrentOrganization.FinancialAccounts.AssetsVatInboundReported);
                        workAccounts.Add(authData.CurrentOrganization.FinancialAccounts.AssetsVatInboundUnreported);
                        workAccounts.Add(authData.CurrentOrganization.FinancialAccounts.DebtsVatOutboundReported);
                        workAccounts.Add(authData.CurrentOrganization.FinancialAccounts.DebtsVatOutboundUnreported);
                    }

                    workAccounts.Add(vatInbound);
                    workAccounts.Add(vatOutbound);
                }
                break;

            case "Paypal":
                FinancialAccount assetsPaypal = authData.CurrentOrganization.FinancialAccounts.AssetsPaypal;
                if (assetsPaypal == null)
                {
                    authData.CurrentOrganization.FinancialAccounts.AssetsPaypal =
                        FinancialAccount.Create(authData.CurrentOrganization, "[LOC]Asset_Paypal",
                                                FinancialAccountType.Asset, null);

                    result.DisplayMessage = "An account was created for Paypal account tracking.";
                }
                else
                {
                    workAccounts.Add(assetsPaypal);
                }
                break;

            case "ParticipantFinancials":
                authData.CurrentOrganization.ParticipantFinancialsEnabled = newValue;
                break;

            case "AskPartipantStreet":
                authData.CurrentOrganization.Parameters.AskParticipantStreet = newValue;
                break;

            default:
                throw new NotImplementedException();
            }

            if (workAccounts.Count > 0 && String.IsNullOrEmpty(result.DisplayMessage))
            {
                if (newValue) // switch has been turned on
                {
                    // accounts can always be re-enabled. This is not a create, it is a re-enable.

                    foreach (FinancialAccount account in workAccounts)
                    {
                        account.Active = true;
                    }

                    if (workAccounts.Count > 1)
                    {
                        result.DisplayMessage = "The accounts were re-enabled.";
                    }
                    else
                    {
                        result.DisplayMessage = "The account was re-enabled.";
                    }
                }
                else // switch is being set to off position
                {
                    // if the accounts are currently enabled, we must first check there aren't
                    // any transactions in them before disabling
                    bool transactionsOnAccount = false;

                    foreach (FinancialAccount account in workAccounts)
                    {
                        if (account.GetLastRows(5).Count > 0)
                        {
                            transactionsOnAccount = true;
                        }
                    }

                    if (transactionsOnAccount)
                    {
                        if (workAccounts.Count > 1)
                        {
                            result.DisplayMessage = "Can't disable these accounts: there are transactions";
                        }
                        else
                        {
                            result.DisplayMessage = "Can't disable this account: there are transactions";
                        }

                        result.Success  = false;
                        result.NewValue = "true";
                    }
                    else
                    {
                        // Disable accounts

                        foreach (FinancialAccount account in workAccounts)
                        {
                            account.Active = false;
                        }

                        if (workAccounts.Count > 1)
                        {
                            result.DisplayMessage = "The accounts were disabled.";
                        }
                        else
                        {
                            result.DisplayMessage = "The account was disabled.";
                        }
                    }
                }
            }

            return(result);
        }
示例#7
0
        public void Attest(Person attester)
        {
            if (Attested)
            {
                return;
            }

            // If needed, create new account for parley

            FinancialAccount ourBudget;
            FinancialAccount parentBudget;
            int year = DateTime.Today.Year;

            if (base.BudgetId < 0) // no account created yet
            {
                ourBudget = FinancialAccount.Create(Budget.Organization,
                                                    "Conf: " + Name,
                                                    FinancialAccountType.Cost,
                                                    Budget);

                parentBudget = Budget;

                base.BudgetId   = ourBudget.Identity;
                ourBudget.Owner = Person;
                SwarmDb.GetDatabaseForWriting().SetParleyBudget(Identity, ourBudget.Identity);
            }
            else
            {
                // The budget has been created already - we should already be initialized. Verify this
                // by checking that we were already attested once.

                if (!AttestedOnce)
                {
                    throw new InvalidOperationException(
                              "Budget exists despite parley not having been attested. This should not be possible.");
                }

                ourBudget    = Budget;
                parentBudget = ParentBudget;
            }

            ourBudget.SetBudgetCents(DateTime.Today.Year, -BudgetCents);
            parentBudget.SetBudgetCents(DateTime.Today.Year,
                                        parentBudget.GetBudgetCents(year) + BudgetCents); // cost budgets are negative

            // Reserve the guarantee money

            FinancialTransaction guaranteeFundsTx = FinancialTransaction.Create(OrganizationId, DateTime.Now,
                                                                                "Conference #" +
                                                                                Identity + " Guarantee");

            guaranteeFundsTx.AddRow(Budget, -GuaranteeCents, attester);
            guaranteeFundsTx.AddRow(Budget.Parent, GuaranteeCents, attester);

            // Finally, set as attested

            PWEvents.CreateEvent(
                EventSource.PirateWeb, EventType.ParleyAttested, attester.Identity,
                OrganizationId, 0, 0, Identity, string.Empty);

            base.Attested = true;
            SwarmDb.GetDatabaseForWriting().SetParleyAttested(Identity, true);
            SwarmDb.GetDatabaseForWriting().CreateFinancialValidation(FinancialValidationType.Attestation,
                                                                      FinancialDependencyType.Parley, Identity,
                                                                      DateTime.Now, attester.Identity, (double)(GuaranteeDecimal));
        }
示例#8
0
        public void EnableEconomy(Currency currency)
        {
            if (IsEconomyEnabled)
            {
                throw new InvalidOperationException("Economy data already enabled");
            }

            // First, set hardwired accounts

            FinancialAccounts[OrganizationFinancialAccountType.AssetsBankAccountMain] =
                FinancialAccount.Create(this, "[LOC]Asset_BankAccounts", FinancialAccountType.Asset, null);
            FinancialAccounts[OrganizationFinancialAccountType.AssetsOutboundInvoices] =
                FinancialAccount.Create(this, "[LOC]Asset_OutboundInvoices", FinancialAccountType.Asset, null);
            FinancialAccounts[OrganizationFinancialAccountType.AssetsOutstandingCashAdvances] =
                FinancialAccount.Create(this, "[LOC]Asset_CashAdvances", FinancialAccountType.Asset, null);
            FinancialAccounts[OrganizationFinancialAccountType.AssetsTaxAdvances] =
                FinancialAccount.Create(this, "[LOC]Asset_TaxAdvances", FinancialAccountType.Asset, null);

            FinancialAccount shortTermAssets = FinancialAccount.Create(this, "[LOC]Asset_ShortTerm",
                                                                       FinancialAccountType.Asset, null);

            FinancialAccounts[OrganizationFinancialAccountType.AssetsShortTerm]           = shortTermAssets;
            FinancialAccounts[OrganizationFinancialAccountType.AssetsTransfersInProgress] =
                FinancialAccount.Create(this, "[LOC]Asset_TransfersInProgress", FinancialAccountType.Asset,
                                        shortTermAssets);

            FinancialAccounts [OrganizationFinancialAccountType.AssetsBitcoinHot] =
                FinancialAccount.Create(this, "[LOC]Asset_BitcoinHot",
                                        FinancialAccountType.Asset, null);


            FinancialAccounts[OrganizationFinancialAccountType.CostsAllocatedFunds] =
                FinancialAccount.Create(this, "[LOC]Cost_AllocatedFunds", FinancialAccountType.Cost, null);
            FinancialAccounts[OrganizationFinancialAccountType.CostsInfrastructure] =
                FinancialAccount.Create(this, "[LOC]Cost_IctInfrastructure", FinancialAccountType.Cost, null);
            FinancialAccounts[OrganizationFinancialAccountType.CostsYearlyResult] =
                FinancialAccount.Create(this, "[LOC]Cost_AnnualResult", FinancialAccountType.Cost, null);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsEquity] =
                FinancialAccount.Create(this, "[LOC]Debt_Equity", FinancialAccountType.Debt, null);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsExpenseClaims] =
                FinancialAccount.Create(this, "[LOC]Debt_ExpenseClaims", FinancialAccountType.Debt, null);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsInboundInvoices] =
                FinancialAccount.Create(this, "[LOC]Debt_InboundInvoices", FinancialAccountType.Debt, null);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsOther] =
                FinancialAccount.Create(this, "[LOC]Debt_General", FinancialAccountType.Debt, null);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsSalary] =
                FinancialAccount.Create(this, "[LOC]Debt_Salaries", FinancialAccountType.Debt, null);
            FinancialAccounts[OrganizationFinancialAccountType.DebtsTax] =
                FinancialAccount.Create(this, "[LOC]Debt_Taxes", FinancialAccountType.Debt, null);

            FinancialAccount financialFeesMaster = FinancialAccount.Create(this, "[LOC]Cost_FinancialFees",
                                                                           FinancialAccountType.Cost, null);

            FinancialAccounts[OrganizationFinancialAccountType.CostsBankFees] =
                FinancialAccount.Create(this, "[LOC]Cost_BankFees", FinancialAccountType.Cost, financialFeesMaster);
            FinancialAccounts[OrganizationFinancialAccountType.CostsBitcoinFees] =
                FinancialAccount.Create(this, "[LOC]Cost_BitcoinFees", FinancialAccountType.Cost, financialFeesMaster);

            FinancialAccounts[OrganizationFinancialAccountType.IncomeDonations] =
                FinancialAccount.Create(this, "[LOC]Income_Donations", FinancialAccountType.Income, null);
            FinancialAccounts[OrganizationFinancialAccountType.IncomeSales] =
                FinancialAccount.Create(this, "[LOC]Income_Sales", FinancialAccountType.Income, null);

            // Then, create various cost accounts that are probably needed, or that could be used as a starting point

            FinancialAccount officeMaster = FinancialAccount.Create(this, "[LOC]Cost_Offices", FinancialAccountType.Cost, null);

            FinancialAccount.Create(this, "[LOC]Cost_OfficeSpace", FinancialAccountType.Cost, officeMaster);
            FinancialAccount.Create(this, "[LOC]Cost_OfficeEquipment", FinancialAccountType.Cost, officeMaster);
            FinancialAccount.Create(this, "[LOC]Cost_OfficeSupplies", FinancialAccountType.Cost, officeMaster);

            FinancialAccount.Create(this, "[LOC]Cost_BusinessServices", FinancialAccountType.Cost, null);

            FinancialAccount.Create(this, "[LOC]Cost_Unforeseen", FinancialAccountType.Cost, null);
            FinancialAccount.Create(this, "[LOC]Cost_MarketingCampaigns", FinancialAccountType.Cost, null);
            FinancialAccount.Create(this, "[LOC]Cost_ResearchDevelopment", FinancialAccountType.Cost, null);

            FinancialAccount staffMaster = FinancialAccount.Create(this, "[LOC]Cost_Staff", FinancialAccountType.Cost, null);

            FinancialAccount.Create(this, "[LOC]Cost_StaffSalaries", FinancialAccountType.Cost, staffMaster);
            FinancialAccount.Create(this, "[LOC]Cost_StaffExpenses", FinancialAccountType.Cost, staffMaster);
            FinancialAccount.Create(this, "[LOC]Cost_StaffBenefits", FinancialAccountType.Cost, staffMaster);


            FinancialAccount travelMaster = FinancialAccount.Create(this, "[LOC]Cost_Travel", FinancialAccountType.Cost,
                                                                    null);
            FinancialAccount airfare = FinancialAccount.Create(this, "[LOC]Cost_Airfare", FinancialAccountType.Cost, travelMaster);

            FinancialAccount.Create(this, "[LOC]Cost_AirfareBusiness", FinancialAccountType.Cost, airfare);
            FinancialAccount.Create(this, "[LOC]Cost_AirfareCoach", FinancialAccountType.Cost, airfare);
            FinancialAccount.Create(this, "[LOC]Cost_TaxiTransport", FinancialAccountType.Cost, travelMaster);
            FinancialAccount.Create(this, "[LOC]Cost_PublicTransit", FinancialAccountType.Cost, travelMaster);
            FinancialAccount lodging = FinancialAccount.Create(this, "[LOC]Cost_TravelLodging", FinancialAccountType.Cost, travelMaster);

            FinancialAccount.Create(this, "[LOC]Cost_LodgingHostel", FinancialAccountType.Cost, lodging);
            FinancialAccount.Create(this, "[LOC]Cost_LodgingShared", FinancialAccountType.Cost, lodging);
            FinancialAccount.Create(this, "[LOC]Cost_LodgingThreeStar", FinancialAccountType.Cost, lodging);
            FinancialAccount.Create(this, "[LOC]Cost_LodgingFourStar", FinancialAccountType.Cost, lodging);
            FinancialAccount.Create(this, "[LOC]Cost_LodgingFiveStar", FinancialAccountType.Cost, lodging);
            FinancialAccount.Create(this, "[LOC]Cost_TrainsFerries", FinancialAccountType.Cost, travelMaster);
            FinancialAccount.Create(this, "[LOC]Cost_TravelPerDiem", FinancialAccountType.Cost, travelMaster);
            FinancialAccount.Create(this, "[LOC]Cost_EventTickets", FinancialAccountType.Cost, travelMaster);

            FinancialAccount.Create(this, "[LOC]Cost_Taxes", FinancialAccountType.Cost, null);

            // Finally, create the first conference parent

            FinancialAccount conferenceBase = FinancialAccount.Create(this, "[LOC]Cost_Conferences",
                                                                      FinancialAccountType.Cost, null);

            conferenceBase.IsConferenceParent = true;

            // Set the currency

            OptionalData.SetOptionalDataString(ObjectOptionalDataType.OrgCurrency, currency.Code);

            // If presentation currency is something else than bitcoin cash, then we also
            // need forex gain/loss accounts to account for (at least) the hotwallet

            if (!currency.IsBitcoinCash)
            {
                this.FinancialAccounts.IncomeCurrencyFluctuations =
                    FinancialAccount.Create(this, "[LOC]Income_ForexGains",
                                            FinancialAccountType.Income, null);
                this.FinancialAccounts.CostsCurrencyFluctuations =
                    FinancialAccount.Create(this, "[LOC]Cost_ForexLosses",
                                            FinancialAccountType.Cost, null);
            }

            // Set current year to first fiscal year

            OptionalData.SetOptionalDataInt(ObjectOptionalDataType.OrgFirstFiscalYear, DateTime.Today.Year);

            // Finally, flag the org as enabled

            OptionalData.SetOptionalDataBool(ObjectOptionalDataType.OrgEconomyEnabled, true);
        }
        public static CallResult SwitchToggled(string switchName, bool switchValue)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (authData.CurrentOrganization == null || authData.CurrentUser == null)
            {
                return(null); // just don't... don't anything, actually
            }

            CallResult result = new CallResult();

            result.Success = true;

            bool bitcoinNative = (authData.CurrentOrganization.Currency.Code == "BTC");

            FinancialAccounts workAccounts = new FinancialAccounts();

            switch (switchName)
            {
            case "BitcoinCold":

                if (switchValue && !bitcoinNative)
                {
                    result.RequireForex = true;
                }

                FinancialAccount coldAccount = authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold;
                if (coldAccount == null)
                {
                    coldAccount = FinancialAccount.Create(authData.CurrentOrganization, "Bitcoin Assets Cold",
                                                          FinancialAccountType.Asset, null);
                    FinancialAccount.Create(authData.CurrentOrganization, "Cold Address 1",
                                            FinancialAccountType.Asset, coldAccount);
                    FinancialAccount.Create(authData.CurrentOrganization, "Cold Address 2 (rename these)",
                                            FinancialAccountType.Asset, coldAccount);
                    FinancialAccount.Create(authData.CurrentOrganization, "Cold Address... etc",
                                            FinancialAccountType.Asset, coldAccount);

                    authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold = coldAccount;

                    result.DisplayMessage =
                        "Bitcoin cold accounts were created. Edit names and addresses in Account Plan.";     // LOC
                }
                else
                {
                    workAccounts.Add(coldAccount);
                }
                break;

            case "BitcoinHot":
                if (switchValue && !bitcoinNative)
                {
                    result.RequireForex = true;
                }

                FinancialAccount hotAccount = authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot;
                if (hotAccount == null)
                {
                    authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot =
                        FinancialAccount.Create(authData.CurrentOrganization, "Bitcoin Wallet Hot",
                                                FinancialAccountType.Asset, null);

                    result.DisplayMessage =
                        "Bitcoin hotwallet account was created. Upload its wallet file in Account Plan.";
                }
                else
                {
                    workAccounts.Add(hotAccount);
                }
                break;

            case "Forex":
                FinancialAccount forexGain =
                    authData.CurrentOrganization.FinancialAccounts.IncomeCurrencyFluctuations;
                FinancialAccount forexLoss =
                    authData.CurrentOrganization.FinancialAccounts.CostsCurrencyFluctuations;

                if (forexGain == null)
                {
                    if (forexLoss != null)
                    {
                        throw new InvalidOperationException();
                    }

                    authData.CurrentOrganization.FinancialAccounts.IncomeCurrencyFluctuations =
                        FinancialAccount.Create(authData.CurrentOrganization, "Forex holding gains",
                                                FinancialAccountType.Income, null);
                    authData.CurrentOrganization.FinancialAccounts.CostsCurrencyFluctuations =
                        FinancialAccount.Create(authData.CurrentOrganization, "Forex holding losses",
                                                FinancialAccountType.Cost, null);

                    result.DisplayMessage =
                        "Forex gain/loss accounts were created and will be used to account for currency fluctuations.";
                }
                else
                {
                    if (forexLoss == null)
                    {
                        throw new InvalidOperationException();
                    }

                    if (!bitcoinNative && switchValue == false &&
                        ((authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold != null &&
                          authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinCold.Active) ||
                         (authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot != null &&
                          authData.CurrentOrganization.FinancialAccounts.AssetsBitcoinHot.Active)))
                    {
                        // bitcoin is active, and we're not bitcoin native, so we're not turning off forex

                        result.Success        = false;
                        result.DisplayMessage =
                            "Cannot disable forex: bitcoin accounts are active in a non-bitcoin-native organization.";
                        result.RequireForex = true;
                    }
                    else
                    {
                        workAccounts.Add(forexGain);
                        workAccounts.Add(forexLoss);
                    }
                }
                break;

            case "Vat":
                FinancialAccount vatInbound  = authData.CurrentOrganization.FinancialAccounts.AssetsVatInbound;
                FinancialAccount vatOutbound = authData.CurrentOrganization.FinancialAccounts.DebtsVatOutbound;

                if (vatInbound == null)
                {
                    if (vatOutbound != null)
                    {
                        throw new InvalidOperationException();
                    }

                    authData.CurrentOrganization.FinancialAccounts.AssetsVatInbound =
                        FinancialAccount.Create(authData.CurrentOrganization, "Inbound VAT",
                                                FinancialAccountType.Asset, null);
                    authData.CurrentOrganization.FinancialAccounts.DebtsVatOutbound =
                        FinancialAccount.Create(authData.CurrentOrganization, "Outbound VAT",
                                                FinancialAccountType.Debt, null);

                    result.DisplayMessage = "Inbound and outbound VAT accounts were created.";
                }
                else
                {
                    if (vatOutbound == null)
                    {
                        throw new InvalidOperationException();
                    }

                    workAccounts.Add(vatInbound);
                    workAccounts.Add(vatOutbound);
                }
                break;

            case "Paypal":
                FinancialAccount assetsPaypal = authData.CurrentOrganization.FinancialAccounts.AssetsPaypal;
                if (assetsPaypal == null)
                {
                    authData.CurrentOrganization.FinancialAccounts.AssetsPaypal =
                        FinancialAccount.Create(authData.CurrentOrganization, "Paypal account",
                                                FinancialAccountType.Asset, null);

                    result.DisplayMessage = "An account was created for Paypal account tracking.";
                }
                else
                {
                    workAccounts.Add(assetsPaypal);
                }
                break;

            default:
                throw new NotImplementedException();
            }

            if (workAccounts.Count > 0 && String.IsNullOrEmpty(result.DisplayMessage))
            {
                if (switchValue) // switch has been turned on
                {
                    // accounts can always be re-enabled. This is not a create, it is a re-enable.

                    foreach (FinancialAccount account in workAccounts)
                    {
                        account.Active = true;
                    }

                    if (workAccounts.Count > 1)
                    {
                        result.DisplayMessage = "The accounts were re-enabled.";
                    }
                    else
                    {
                        result.DisplayMessage = "The account was re-enabled.";
                    }
                }
                else // switch is being set to off position
                {
                    // if the accounts are currently enabled, we must first check there aren't
                    // any transactions in them before disabling
                    bool transactionsOnAccount = false;

                    foreach (FinancialAccount account in workAccounts)
                    {
                        if (account.GetLastRows(5).Count > 0)
                        {
                            transactionsOnAccount = true;
                        }
                    }

                    if (transactionsOnAccount)
                    {
                        if (workAccounts.Count > 1)
                        {
                            result.DisplayMessage = "Can't disable these accounts: there are transactions";
                        }
                        else
                        {
                            result.DisplayMessage = "Can't disable this account: there are transactions";
                        }

                        result.Success = false;
                    }
                    else
                    {
                        // Disable accounts

                        foreach (FinancialAccount account in workAccounts)
                        {
                            account.Active = false;
                        }

                        if (workAccounts.Count > 1)
                        {
                            result.DisplayMessage = "The accounts were disabled.";
                        }
                        else
                        {
                            result.DisplayMessage = "The account was disabled.";
                        }
                    }
                }
            }

            return(result);
        }