public static AjaxInputCallResult CreateTransaction(string dateTimeString, string amountString, string description,
                                                            int budgetId)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();
            FinancialAccount   budget   = FinancialAccount.FromIdentity(budgetId);

            if (budget.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }
            if (!authData.Authority.HasAccess(new Access(authData.CurrentOrganization, AccessAspect.BookkeepingDetails)))
            {
                throw new UnauthorizedAccessException();
            }

            Int64 amountCents = Formatting.ParseDoubleStringAsCents(amountString);

            DateTime txTime = DateTime.Parse(dateTimeString);

            // TODO: Return better error codes/messages if one of these fail

            FinancialTransaction transaction = FinancialTransaction.Create(authData.CurrentOrganization, txTime,
                                                                           description);

            transaction.AddRow(budget, amountCents, authData.CurrentUser);

            AjaxInputCallResult result = new AjaxInputCallResult
            {
                Success        = true,
                ObjectIdentity = transaction.Identity,
                NewValue       = (amountCents / 100.0).ToString("N2")
            };

            return(result);
        }
        static public AjaxInputCallResult StoreCallback(string newValue, string cookie)
        {
            AjaxInputCallResult result             = new AjaxInputCallResult();
            AuthenticationData  authenticationData = GetAuthenticationDataAndCulture();

            if (!authenticationData.Authority.HasAccess(new Access(authenticationData.CurrentOrganization, AccessAspect.Administration, AccessType.Write)))
            {
                result.Success    = false; // this is the default on initialization, but let's be explicit about it
                result.FailReason = AjaxInputCallResult.ErrorAccessDenied;
                return(result);
            }

            switch (cookie)
            {
            case "VanityDomain":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.VanityDomain = result.NewValue;
                break;

            case "OpenLedgersDomain":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.OpenLedgersDomain = result.NewValue;
                break;

            case "PaypalAccountAddress":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.PaypalAccountMailAddress = result.NewValue;
                break;

            case "GovernmentRegistrationId":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.GovernmentRegistrationId = result.NewValue;
                break;

            case "TaxPaymentOcr":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.TaxPaymentOcr = result.NewValue;
                break;

            case "VatReportFrequency":
                result.Success  = true;
                result.NewValue = newValue;
                authenticationData.CurrentOrganization.VatReportFrequencyMonths = Int32.Parse(newValue);
                break;

            default:
                throw new NotImplementedException("Unknown cookie in StoreCallback");
            }

            return(result);
        }
示例#3
0
        static public AjaxInputCallResult StoreCallback(string newValue, string cookie)
        {
            AjaxInputCallResult result             = new AjaxInputCallResult();
            AuthenticationData  authenticationData = GetAuthenticationDataAndCulture();

            if (!authenticationData.Authority.HasAccess(new Access(authenticationData.CurrentOrganization, AccessAspect.Administration, AccessType.Write)))
            {
                result.Success    = false; // this is the default on initialization, but let's be explicit about it
                result.FailReason = AjaxInputCallResult.ErrorAccessDenied;
                return(result);
            }

            switch (cookie)
            {
            case "VanityDomain":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.VanityDomain = result.NewValue;
                break;

            case "OpenLedgersDomain":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.OpenLedgersDomain = result.NewValue;
                break;

            case "PaypalAccountAddress":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.PaypalAccountMailAddress = result.NewValue;
                break;

            case "GovernmentRegistrationId":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.GovernmentRegistrationId = result.NewValue;
                break;

            case "TaxPaymentOcr":
                result.Success  = true;
                result.NewValue = newValue.Trim();
                authenticationData.CurrentOrganization.TaxPaymentOcr = result.NewValue;
                break;

            case "VatReportFrequency":
                result.Success  = true;
                result.NewValue = newValue;
                authenticationData.CurrentOrganization.VatReportFrequencyMonths = Int32.Parse(newValue);
                break;

            case "ParticipationEntry":
                result.Success  = true;
                result.NewValue = newValue;
                authenticationData.CurrentOrganization.Parameters.ParticipationEntry = newValue;
                break;

            case "ParticipationDuration":
                result.Success  = true;
                result.NewValue = newValue;
                authenticationData.CurrentOrganization.Parameters.ParticipationDuration = newValue;
                break;

            case "SidebarOrgInfo":
                result.Success = true;
                authenticationData.CurrentOrganization.Parameters.SidebarOrgInfo = newValue;
                break;

            case "SignupFirstPage":
                result.Success = true;
                authenticationData.CurrentOrganization.Parameters.SignupFirstPage = newValue;
                break;

            case "SignupLastPage":
                result.Success = true;
                authenticationData.CurrentOrganization.Parameters.SignupLastPage = newValue;
                break;

            case "ApplicationCompleteMail":
                result.Success = true;
                authenticationData.CurrentOrganization.Parameters.ApplicationCompleteMail = newValue;
                break;

            case "ParticipationAcceptedMail":
                result.Success = true;
                authenticationData.CurrentOrganization.Parameters.ParticipationAcceptedMail = newValue;
                break;

            case "ApplicationQualifyingScore":
                int qualifyingScore = Int32.Parse(newValue, NumberStyles.Number);
                authenticationData.CurrentOrganization.Parameters.ApplicationQualifyingScore = qualifyingScore;
                result.NewValue = qualifyingScore.ToString("N0");
                result.Success  = true;    // this comes last in this section, because parsing int may fail
                break;

            default:
                throw new NotImplementedException("Unknown cookie in StoreCallback");
            }

            return(result);
        }
示例#4
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);
        }
示例#5
0
        static public AjaxInputCallResult StoreCallback(string newValue, string cookie)
        {
            AjaxInputCallResult result   = new AjaxInputCallResult();
            AuthenticationData  authData = GetAuthenticationDataAndCulture();

            if (!authData.Authority.HasAccess(new Access(AccessAspect.Administration, AccessType.Write)))
            {
                result.Success    = false; // this is default on init, but let's be explicit about it
                result.FailReason = AjaxInputCallResult.ErrorAccessDenied;
                return(result);            // fail silently
            }

            switch (cookie)
            {
            case "Smtp":
                Match match = Regex.Match(newValue, "((?<user>[a-z0-9_]+)(:(?<pass>[^@]+))?@)?(?<host>[a-z0-9_\\-\\.]+)(:(?<port>[0-9]+))?", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    string user       = match.Groups["user"].Value;
                    string pass       = match.Groups["pass"].Value;
                    string host       = match.Groups["host"].Value;
                    string portString = match.Groups["port"].Value;
                    int    port       = 25;

                    if (!string.IsNullOrEmpty(portString))
                    {
                        try
                        {
                            port = Int32.Parse(portString);
                        }
                        catch (FormatException)
                        {
                            result.DisplayMessage = Resources.Pages.Admin.SystemSettings_Error_SmtpHostPort;
                            result.FailReason     = AjaxInputCallResult.ErrorInvalidFormat;
                            result.Success        = false;
                            return(result);    // return early
                        }
                    }

                    SystemSettings.SmtpUser     = user ?? string.Empty;
                    SystemSettings.SmtpPassword = pass ?? string.Empty;
                    SystemSettings.SmtpHost     = host;
                    SystemSettings.SmtpPort     = port;

                    OutboundComm.CreateNotification(Organization.Sandbox, Logic.Communications.Payload.NotificationResource.System_MailServerTest);

                    result.Success        = true;
                    result.NewValue       = FormatSmtpAccessString(user, pass, host, port);
                    result.DisplayMessage = Resources.Pages.Admin.SystemSettings_TestMailSent;
                }
                else
                {
                    result.Success        = false;
                    result.FailReason     = AjaxInputCallResult.ErrorInvalidFormat;
                    result.DisplayMessage = Resources.Pages.Admin.SystemSettings_Error_SmtpSyntax;
                }
                break;

            case "ExtUrl":
                if (!newValue.EndsWith("/"))
                {
                    newValue = newValue + "/";
                }
                if (!newValue.StartsWith("http://") && !newValue.StartsWith("https://"))
                {
                    newValue = "https://" + newValue;
                }

                SystemSettings.ExternalUrl = newValue;

                result.NewValue = newValue;
                result.Success  = true;
                break;

            case "InstallationName":
                result.NewValue = newValue.Trim();
                result.Success  = true;
                SystemSettings.InstallationName = result.NewValue;
                break;

            case "AdminSender":
                result.NewValue = newValue.Trim();
                result.Success  = true;
                SystemSettings.InstallationName = result.NewValue;
                break;

            case "AdminAddress":
                result.NewValue = newValue.Trim();
                result.Success  = true;
                SystemSettings.AdminNotificationAddress = result.NewValue;
                break;

            case "BackendHost":
                result.NewValue = newValue.Trim();
                result.Success  = true;
                SystemSettings.BackendHostnameOverride = result.NewValue;
                break;

            case "WebsocketFrontend":
                try
                {
                    int newPort = Int32.Parse(newValue);
                    if (newPort < 1 || newPort > 32767)
                    {
                        throw new ArgumentException();
                    }
                    result.NewValue = newValue.Trim();
                    result.Success  = true;
                    SystemSettings.WebsocketPortFrontend = newPort;
                }
                catch (Exception)
                {
                    result.Success    = false;
                    result.FailReason = AjaxInputCallResult.ErrorInvalidFormat;
                    result.NewValue   = SystemSettings.WebsocketPortFrontend.ToString(CultureInfo.InvariantCulture);
                }
                break;

            case "WebsocketBackend":
                try
                {
                    int newPort = Int32.Parse(newValue);
                    if (newPort < 1 || newPort > 32767)
                    {
                        throw new ArgumentException();
                    }

                    result.NewValue = newValue.Trim();
                    result.Success  = true;
                    SystemSettings.WebsocketPortBackend = newPort;
                }
                catch (Exception)
                {
                    result.Success    = false;
                    result.FailReason = AjaxInputCallResult.ErrorInvalidFormat;
                    result.NewValue   = SystemSettings.WebsocketPortBackend.ToString(CultureInfo.InvariantCulture);
                }
                break;

            default:
                throw new NotImplementedException("Unknown cookie in StoreCallback");
            }

            return(result);
        }