Exemple #1
0
        public static TransactionMatchabilityData GetTransactionMatchability(int transactionId)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

            if (transaction.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            TransactionMatchabilityData result = new TransactionMatchabilityData();

            result.TransactionDate = transaction.DateTime.ToString("yyyy-MMM-dd HH:mm");
            result.DifferingAmount = String.Format("{0} {1:+#,#.00;−#,#.00;0}",
                                                   // this is a UNICODE MINUS (U+2212), not the hyphen on the keyboard
                                                   authData.CurrentOrganization.Currency.DisplayCode, transaction.Rows.AmountCentsTotal / 100.0);

            result.OpenPayoutData = GetOpenPayoutData(transaction);

            return(result);
        }
    protected void ButtonExecute_Click(object sender, EventArgs e)
    {
        if (!_authority.HasPermission(Permission.CanDoEconomyTransactions, thisPayout.OrganizationId, -1, Authorization.Flag.ExactOrganization))
        {
            throw new UnauthorizedAccessException("Access Denied");
        }

        if (this.RadioManualMap.Checked)
        {
            int transactionId = Int32.Parse(this.DropTransactions.SelectedValue);
            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

            thisPayout.BindToTransactionAndClose(transaction, _currentUser);
        }
        else if (this.RadioManualMerge.Checked)
        {
            int    otherPayoutId = Int32.Parse(this.DropPayouts.SelectedValue);
            Payout otherPayout   = Payout.FromIdentity(otherPayoutId);

            otherPayout.MigrateDependenciesTo(thisPayout);
            otherPayout.Open     = false;
            thisPayout.Reference = GetDependencyString(thisPayout);
        }
        else if (this.RadioUndoPayout.Checked)
        {
            thisPayout.UndoPayout();
        }

        ClientScript.RegisterStartupScript(Page.GetType(), "mykey", "CloseAndRebind();", true);
    }
    protected void ButtonExecute_Click(object sender, EventArgs e)
    {
        if (!_authority.HasPermission(Permission.CanDoEconomyTransactions, thisInvoice.OrganizationId, -1, Authorization.Flag.ExactOrganization))
        {
            throw new UnauthorizedAccessException("Access Denied");
        }

        if (this.RadioManualMap.Checked)
        {
            int transactionId = Int32.Parse(this.DropTransactions.SelectedValue);
            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

            Payment payment = Payment.CreateSingle(thisInvoice.Organization, transaction.DateTime, thisInvoice.Currency, thisInvoice.AmountCents, thisInvoice, _currentUser);
            payment.AddInformation(PaymentInformationType.Freeform, "Mapped manually in PirateWeb");

            transaction.AddRow(thisInvoice.Organization.FinancialAccounts.AssetsOutboundInvoices, -thisInvoice.AmountCents, _currentUser);
            transaction.Dependency = payment.Group;
        }
        else if (this.RadioCreditInvoice.Checked)
        {
            thisInvoice.Credit(_currentUser);
        }

        ClientScript.RegisterStartupScript(Page.GetType(), "mykey", "CloseAndRebind();", true);
    }
Exemple #4
0
        public static void BalanceTransactionManually(int transactionId, int accountId)
        {
            if (transactionId == 0 || accountId == 0)
            {
                return;
            }

            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);
            FinancialAccount     account     = FinancialAccount.FromIdentity(accountId);

            if (transaction.OrganizationId != authData.CurrentOrganization.Identity || account.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            transaction.AddRow(account, -transaction.Rows.AmountCentsTotal, authData.CurrentUser);
        }
Exemple #5
0
        public static void MatchTransactionOpenPayout(int transactionId, int payoutId)
        {
            if (transactionId == 0 || payoutId == 0)
            {
                return;
            }

            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);
            Payout payout = Payout.FromIdentity(payoutId);

            if (transaction.OrganizationId != authData.CurrentOrganization.Identity || payout.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            if (transaction.Rows.AmountCentsTotal != -payout.AmountCents)
            {
                throw new InvalidOperationException();
            }

            payout.BindToTransactionAndClose(transaction, authData.CurrentUser);
        }
Exemple #6
0
    private FinancialTransaction GetTransaction()
    {
        int transactionId = Int32.Parse(Request.QueryString["TransactionId"]);
        FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

        return(transaction);
    }
Exemple #7
0
        public static void MatchTransactionOpenPayout(int transactionId, int payoutId)
        {
            if (transactionId == 0 || payoutId == 0)
            {
                return;
            }

            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);
            Payout payout = Payout.FromIdentity(payoutId);

            if (transaction.OrganizationId != authData.CurrentOrganization.Identity || payout.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            Int64 transactionCents = transaction.Rows.AmountCentsTotal;
            Int64 payoutCents      = payout.AmountCents;

            FinancialAccount forexSpillAccount =
                authData.CurrentOrganization.FinancialAccounts.IncomeCurrencyFluctuations;

            if (forexSpillAccount == null && payoutCents != -transactionCents)                           // the tx-negative is because it's a payout
            {
                throw new InvalidOperationException("Need forex gain/loss accounts for this operation"); // TODO: Autocreate?
            }

            if ((-transactionCents) > payoutCents)  // the tx-negative is because it's a payout
            {
                // This is a forex loss, not a gain which is the default
                forexSpillAccount = authData.CurrentOrganization.FinancialAccounts.CostsCurrencyFluctuations;
            }

            if (-transactionCents != payoutCents)
            {
                // Forex adjust
                transaction.AddRow(forexSpillAccount, -(payoutCents + transactionCents),
                                                          // plus because transactionCents is negative
                                   authData.CurrentUser); // Adds the forex adjustment so we can bind payout to tx and close
            }

            // The amounts should match now

            if (transaction.Rows.AmountCentsTotal != -payout.AmountCents)
            {
                throw new InvalidOperationException();
            }


            payout.BindToTransactionAndClose(transaction, authData.CurrentUser);
        }
Exemple #8
0
        public static string GetTransactionDisplayIdentity(int transactionId)
        {
            GetAuthenticationDataAndCulture(); // Sets culture

            FinancialTransaction tx = FinancialTransaction.FromIdentity(transactionId);

            return(tx.OrganizationSequenceId.ToString("N0"));
        }
Exemple #9
0
        public static void MatchTransactionOpenPayoutForeign(int transactionId, int payoutId)
        {
            // This is like the non-foreign version except this one chalks up the difference to forex gain/loss accounts

            if (transactionId == 0 || payoutId == 0)
            {
                return;
            }

            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialAccount forexSpillAccount =
                authData.CurrentOrganization.FinancialAccounts.IncomeCurrencyFluctuations;

            if (forexSpillAccount == null)
            {
                throw new InvalidOperationException("Need forex gain/loss accounts for this operation");  // TODO: Autocreate?
            }

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);
            Payout payout = Payout.FromIdentity(payoutId);

            if (transaction.OrganizationId != authData.CurrentOrganization.Identity || payout.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            if (-transaction.Rows.AmountCentsTotal > payout.AmountCents)
            {
                // This is a forex loss, not a gain which is the default
                forexSpillAccount = authData.CurrentOrganization.FinancialAccounts.CostsCurrencyFluctuations;
            }

            transaction.AddRow(forexSpillAccount, -(payout.AmountCents + transaction.Rows.AmountCentsTotal), // plus because AmountCentsTotal is negative
                               authData.CurrentUser);                                                        // Adds the forex adjustment so we can bind payout to tx and close

            if (transaction.Rows.AmountCentsTotal != -payout.AmountCents)
            {
                throw new InvalidOperationException();
            }

            payout.BindToTransactionAndClose(transaction, authData.CurrentUser);
        }
Exemple #10
0
        public static void MatchTransactionOpenVatReport(int transactionId, int vatReportId)
        {
            if (transactionId == 0 || vatReportId == 0)
            {
                return;
            }

            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);
            VatReport            vatReport   = VatReport.FromIdentity(vatReportId);

            if (authData.CurrentOrganization.Identity != transaction.OrganizationId ||
                authData.CurrentOrganization.Identity != vatReport.OrganizationId)
            {
                throw new InvalidOperationException("Organization mismatch");
            }

            Int64 diffCents = vatReport.VatInboundCents - vatReport.VatOutboundCents;

            if (transaction.Rows.AmountCentsTotal != diffCents)
            {
                throw new InvalidOperationException("Amount mismatch");
            }

            // Go ahead and close

            vatReport.CloseTransaction = transaction; // throws if already closed
            vatReport.Open             = false;

            if (diffCents > 0)
            {
                // Positive amount - asset account
                transaction.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsVatInboundReported, -diffCents,
                                   null);
            }
            else
            {
                // Negative amount - liability account
                transaction.AddRow(authData.CurrentOrganization.FinancialAccounts.DebtsVatOutboundReported, -diffCents,
                                   null);
            }
        }
Exemple #11
0
        public static string GetUnbalancedAmount(int txId)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (
                !authData.Authority.HasAccess(new Access(authData.CurrentOrganization,
                                                         AccessAspect.Bookkeeping, AccessType.Read)))
            {
                return(string.Empty); // leave no clue to an attacker why the call failed
            }

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(txId);

            return((-transaction.Rows.AmountCentsTotal / 100.0).ToString("N2"));
        }
    protected void ButtonAutoBalance_Click(object sender, EventArgs e)
    {
        Person    currentUser = Person.FromIdentity(Int32.Parse(HttpContext.Current.User.Identity.Name));
        Authority authority   = currentUser.GetAuthority();

        if (!authority.HasPermission(Permission.CanDoEconomyTransactions, Int32.Parse(this.DropOrganizations.SelectedValue), -1, Authorization.Flag.ExactOrganization))
        {
            ScriptManager.RegisterStartupScript(this, Page.GetType(), "validationfailed",
                                                "alert ('You do not have access to changing financial records.');",
                                                true);
            return;
        }


        if (this.DropAutoBalanceAccount.SelectedValue == "0")
        {
            ScriptManager.RegisterStartupScript(this, Page.GetType(), "validationfailed",
                                                "alert ('Please select an account to auto-balance against.');",
                                                true);
            return;
        }

        FinancialAccount autoBalanceAccount = FinancialAccount.FromIdentity(Int32.Parse(this.DropAutoBalanceAccount.SelectedValue));

        if (this.GridTransactions.SelectedIndexes.Count == 0)
        {
            ScriptManager.RegisterStartupScript(this, Page.GetType(), "validationfailed",
                                                "alert ('Please select one or more transactions to auto-balance.');",
                                                true);

            return;
        }

        foreach (string indexString in this.GridTransactions.SelectedIndexes)
        {
            int index         = Int32.Parse(indexString);
            int transactionId = (int)this.GridTransactions.MasterTableView.DataKeyValues[index]["Identity"];

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

            transaction.AddRow(autoBalanceAccount, -transaction.Rows.AmountCentsTotal, currentUser);
        }

        PopulateGrid();
        this.GridTransactions.Rebind();
        this.DropAutoBalanceAccount.SelectedValue = "0";
    }
Exemple #13
0
        public static TransactionMatchabilityData GetTransactionMatchability(int transactionId)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

            if (transaction.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            TransactionMatchabilityData result = new TransactionMatchabilityData();

            Int64 transactionCents = transaction.Rows.AmountCentsTotal;

            result.TransactionDate        = transaction.DateTime.ToString("yyyy-MMM-dd HH:mm");
            result.TransactionDescription = transaction.Description;
            result.AmountAsPurchase       = ((-transactionCents) / 100.0).ToString("N2");
            result.DifferingAmount        = String.Format("{0} {1:+#,#.00;−#,#.00;0}",
                                                          // this is a UNICODE MINUS (U+2212), not the hyphen on the keyboard
                                                          authData.CurrentOrganization.Currency.DisplayCode, transactionCents / 100.0);

            if (transaction.Rows.AmountCentsTotal > 0)
            {
                result.OpenOutboundInvoiceData = GetOpenOutboundInvoiceData(transaction);
                result.AmountSign = 1;
            }
            else
            {
                // Negative difference

                result.AmountSign     = -1;
                result.OpenPayoutData = GetOpenPayoutData(transaction);
            }

            result.OpenVatReportData = GetOpenVatReportData(transaction);

            return(result);
        }
    private void UpdateExecute()
    {
        bool   valid   = false;
        string message = string.Empty;

        Dictionary <double, List <int> > transactionDeltas = new Dictionary <double, List <int> >();

        this.ButtonExecute.Enabled = false;

        if (this.RadioManualMap.Checked)
        {
            int transactionId = Int32.Parse(this.DropTransactions.SelectedValue);

            if (transactionId > 0)
            {
                FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

                this.LabelActionDescription.Text =
                    String.Format(
                        "Outbound Invoice #{0} to {1}, supposed date {2:yyyy-MM-dd}, will be mapped to Transaction #{3} on date {4:yyyy-MM-dd}. Transaction #{3} will be balanced, documented, and tied to a new payment group with a single payment referring to Outbound Invoice #{0}. Outbound Invoice #{0} will be closed.",
                        thisInvoice.Identity, thisInvoice.CustomerName, thisInvoice.DueDate, transaction.Identity, transaction.DateTime);
                valid = true;
                this.ButtonExecute.Text    = "Execute MAP";
                this.ButtonExecute.Enabled = true;
            }
        }

        if (this.RadioCreditInvoice.Checked)
        {
            this.LabelActionDescription.Text =
                String.Format("A credit invoice for the same amount as Outbound Invoice #{0}, {1} {2:N2}, will be issued to {3} and closed immediately together with Outbound Invoice #{0}.",
                              thisInvoice.Identity, thisInvoice.Currency.Code, thisInvoice.Amount, thisInvoice.CustomerName);
            valid = true;
            this.ButtonExecute.Text    = "Execute CREDIT";
            this.ButtonExecute.Enabled = true;
        }

        if (!valid)
        {
            this.ButtonExecute.Enabled       = false;
            this.ButtonExecute.Text          = "Execute Nothing";
            this.LabelActionDescription.Text = "Nothing.";
        }
    }
Exemple #15
0
        public static string GetTransactionTracking(int txId)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (
                !authData.Authority.HasAccess(new Access(authData.CurrentOrganization,
                                                         AccessAspect.BookkeepingDetails, AccessType.Read)))
            {
                return(string.Empty); // leave no clue to an attacker why the call failed
            }

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(txId);

            IHasIdentity dependency = transaction.Dependency;

            if (dependency == null)
            {
                return(string.Empty);
            }

            return(GetTrackingDetails(dependency));
        }
Exemple #16
0
        public static bool AddTransactionRow(int txId, int accountId, string amountString)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (
                !authData.Authority.HasAccess(new Access(authData.CurrentOrganization,
                                                         AccessAspect.Bookkeeping, AccessType.Write)))
            {
                return(false); // fail
            }

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(txId);

            if (authData.CurrentOrganization.Parameters.FiscalBooksClosedUntilYear >= transaction.DateTime.Year)
            {
                return(false); // can't edit closed books
            }

            FinancialAccount account = FinancialAccount.FromIdentity(accountId);

            Double amountFloat = Double.Parse(amountString);
            Int64  amountCents = (Int64)(amountFloat * 100.0);

            if (account.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new InvalidOperationException("Account/Organization mismatch");
            }

            if (amountCents == 0)
            {
                return(false);
            }

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

            return(true);
        }
Exemple #17
0
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.ContentType = "application/json";

            string transactionIdString = Request.QueryString["TxId"];

            string emptyResponse = "[{\"id\":\"-\",\"accountName\":\"" +
                                   JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_EmptyTransaction) + "\"}]";

            if (string.IsNullOrEmpty(transactionIdString) || transactionIdString == "undefined")
            {
                Response.Output.WriteLine(emptyResponse);
                Response.End();
            }

            int transactionId = Int32.Parse(transactionIdString);

            DateTime dawnOfMankind = new DateTime(1901, 1, 1);

            // no org will ever import bookkeeping from before this date

            if (transactionId <= 0)
            {
                Response.Output.WriteLine(emptyResponse);
                Response.End();
            }

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

            if (transaction.OrganizationId != CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException("All the nopes in the world");
            }

            if (!CurrentAuthority.HasAccess(new Access(CurrentOrganization, AccessAspect.Bookkeeping, AccessType.Read)))
            {
                throw new UnauthorizedAccessException("Access denied because security tokens say so");
            }

            FinancialTransactionRows rows = transaction.Rows;

            StringBuilder result = new StringBuilder(16384);

            foreach (FinancialTransactionRow row in rows)
            {
                string creditString = string.Empty;
                string debitString  = string.Empty;

                if (row.AmountCents < 0)
                {
                    creditString = String.Format("{0:N2}", row.AmountCents / 100.0);
                }
                else if (row.AmountCents > 0)
                {
                    debitString = String.Format("{0:N2}", row.AmountCents / 100.0);
                }

                result.Append("{" + String.Format(
                                  "\"id\":\"{0}\",\"dateTime\":\"{1:yyyy-MMM-dd HH:mm}\",\"accountName\":\"{2}\"," +
                                  "\"deltaPos\":\"{3}\",\"deltaNeg\":\"{4}\",\"initials\":\"{5}\"",
                                  row.FinancialTransactionId,
                                  row.CreatedDateTime,
                                  JsonSanitize(row.AccountName),
                                  debitString,
                                  creditString,
                                  row.CreatedByPerson != null? row.CreatedByPerson.Initials: Resources.Global.Global_System) + "},");
            }

            Int64 amountCentsTotal = transaction.Rows.AmountCentsTotal;

            if (amountCentsTotal != 0)
            {
                // If the transaction is unbalanced, make a huge deal about it

                result.Append("{\"accountName\":\"<img src='/Images/Icons/iconshock-warning-24px.png' height='16px' width='16px' class='elementFloatFar' />" +
                              JsonSanitize(Resources.Pages.Ledgers.InspectLedgers_UnbalancedTransaction) + "\",");

                if (amountCentsTotal < 0)
                {
                    result.AppendFormat("\"deltaPos\":\"<span class='spanAnnoyingBlink'>{0:N2}</span>\"",
                                        -amountCentsTotal / 100.0);
                }
                else if (amountCentsTotal > 0)
                {
                    result.AppendFormat("\"deltaNeg\":\"<span class='spanAnnoyingBlink'>{0:N2}</span>\"",
                                        -amountCentsTotal / 100.0);
                }

                result.Append("},");   // the comma isn't really necessary here but will be stripped later and is kept for cut&paste consistency of this code block
            }

            Response.Output.WriteLine("[" + result.ToString().TrimEnd(',') + "]");
            Response.End();
        }
    private void UpdateExecute()
    {
        bool   valid   = false;
        string message = string.Empty;

        Dictionary <decimal, List <int> > transactionDeltas = new Dictionary <decimal, List <int> >();
        FinancialTransactions             transactions      = FinancialTransactions.GetUnbalanced(thisPayout.Organization);

        this.ButtonExecute.Enabled = false;

        foreach (FinancialTransaction transaction in transactions)
        {
            decimal diff = transaction.Rows.AmountTotal;

            if (!transactionDeltas.ContainsKey(-diff))
            {
                transactionDeltas[-diff] = new List <int>();
            }

            transactionDeltas[-diff].Add(transaction.Identity);
        }

        if (this.RadioManualMap.Checked)
        {
            int transactionId = Int32.Parse(this.DropTransactions.SelectedValue);

            if (transactionId > 0)
            {
                FinancialTransaction transaction = FinancialTransaction.FromIdentity(transactionId);

                this.LabelActionDescription.Text =
                    String.Format(
                        "Payout #{0}, supposed date {1:yyyy-MM-dd}, will be mapped to Transaction #{2} on date {3:yyyy-MM-dd}. Transaction #{2} will be balanced and documented and tied to {4}. Payout #{0} will be closed.",
                        thisPayout.Identity, thisPayout.ExpectedTransactionDate, transaction.Identity, transaction.DateTime, GetDependencyString(thisPayout));
                valid = true;
                this.ButtonExecute.Text    = "Execute MAP";
                this.ButtonExecute.Enabled = true;
            }
        }

        if (this.RadioManualMerge.Checked)
        {
            int payoutId = Int32.Parse(this.DropPayouts.SelectedValue);

            if (payoutId > 0)
            {
                Payout  payout    = Payout.FromIdentity(payoutId);
                decimal newAmount = (decimal)(payout.Amount + thisPayout.Amount);
                this.LabelActionDescription.Text =
                    String.Format(
                        "Payout #{0} will be zeroed and closed. Payout #{1} will take over the dependencies of Payout #{0}. It will cover {2} and have an amount of {3:N2}.",
                        payout.Identity, thisPayout.Identity, GetDependencyString(thisPayout, payout), newAmount);

                if (transactionDeltas.ContainsKey(newAmount))
                {
                    this.LabelActionDescription.Text += " This matches Transaction " +
                                                        Formatting.GenerateRangeString(transactionDeltas[newAmount]) +
                                                        ".";
                }
                valid = true;
                this.ButtonExecute.Text    = "Execute MERGE";
                this.ButtonExecute.Enabled = true;
            }
        }

        if (this.RadioUndoPayout.Checked)
        {
            this.LabelActionDescription.Text =
                String.Format("Payout #{0} will be zeroed and closed. {1} will be re-opened and ready for payout.",
                              thisPayout.Identity, GetDependencyString(thisPayout));
            valid = true;
            this.ButtonExecute.Text    = "Execute UNDO";
            this.ButtonExecute.Enabled = true;
        }

        if (!valid)
        {
            this.ButtonExecute.Enabled       = false;
            this.ButtonExecute.Text          = "Execute Nothing";
            this.LabelActionDescription.Text = "Nothing.";
        }
    }
Exemple #19
0
        public static AjaxCallResult MarkDirectPurchase(int transactionId, int budgetId, string vatAmountString,
                                                        string newDescription, string guid)
        {
            if (transactionId == 0 | budgetId == 0)
            {
                return(new AjaxCallResult {
                    Success = false
                });
            }

            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialAccount budget = FinancialAccount.FromIdentity(budgetId);

            if (authData.CurrentOrganization.Identity != budget.Organization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            newDescription = newDescription.Trim();
            if (newDescription.Length < 1)
            {
                return(new AjaxCallResult
                {
                    Success = false,
                    DisplayMessage = Resources.Pages.Ledgers.BalanceTransactions_Error_NeedDescription
                });
            }

            Documents docs = Documents.RecentFromDescription(guid).WhereNotAssociated;

            if (docs.Count < 1)
            {
                return(new AjaxCallResult
                {
                    Success = false,
                    DisplayMessage = Resources.Pages.Ledgers.BalanceTransactions_Error_NeedDocumentation
                });
            }

            Int64 vatCents   = 0;
            bool  vatEnabled = authData.CurrentOrganization.VatEnabled;

            if (vatEnabled)
            {
                try
                {
                    vatCents = Swarmops.Logic.Support.Formatting.ParseDoubleStringAsCents(vatAmountString);
                }
                catch (ArgumentException)
                {
                    return(new AjaxCallResult
                    {
                        Success = false,
                        DisplayMessage = Resources.Pages.Ledgers.BalanceTransactions_Error_VatAmountParseError
                    });

                    throw;
                }
            }

            // We're FINALLY ready to update the transaction

            FinancialTransaction tx = FinancialTransaction.FromIdentity(transactionId);

            tx.Description = newDescription;
            docs.SetForeignObjectForAll(tx);

            Int64 centsDiff = tx.Rows.AmountCentsTotal;

            if (vatEnabled)
            {
                tx.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsVatInboundUnreported, vatCents, authData.CurrentUser);
                tx.AddRow(budget, (-centsDiff) - vatCents, authData.CurrentUser);
            }
            else
            {
                tx.AddRow(budget, -centsDiff, authData.CurrentUser);
            }

            return(new AjaxCallResult {
                Success = true
            });
        }
Exemple #20
0
        public static void MatchTransactionOpenOutboundInvoice(int transactionId, int invoiceId)
        {
            if (transactionId == 0 || invoiceId == 0)
            {
                return;
            }

            AuthenticationData authData = GetAuthenticationDataAndCulture();

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

            FinancialTransaction transaction     = FinancialTransaction.FromIdentity(transactionId);
            OutboundInvoice      outboundInvoice = OutboundInvoice.FromIdentity(invoiceId);

            if (transaction.OrganizationId != authData.CurrentOrganization.Identity || outboundInvoice.OrganizationId != authData.CurrentOrganization.Identity)
            {
                throw new UnauthorizedAccessException();
            }

            Int64 transactionCents = transaction.Rows.AmountCentsTotal;
            Int64 invoiceCents     = outboundInvoice.AmountCents;



            FinancialAccount forexSpillAccount =
                authData.CurrentOrganization.FinancialAccounts.IncomeCurrencyFluctuations;

            if (forexSpillAccount == null && invoiceCents != transactionCents)
            {
                throw new InvalidOperationException("Need forex gain/loss accounts for this operation");  // TODO: Autocreate?
            }

            if (transaction.Rows.AmountCentsTotal < outboundInvoice.AmountCents)
            {
                // This is a forex loss, not a gain which is the default
                forexSpillAccount = authData.CurrentOrganization.FinancialAccounts.CostsCurrencyFluctuations;
            }

            // Close invoice

            Payment payment = Payment.CreateSingle(authData.CurrentOrganization, transaction.DateTime,
                                                   authData.CurrentOrganization.Currency, outboundInvoice.AmountCents, outboundInvoice,
                                                   authData.CurrentUser);

            // TODO: Notify?

            // TODO: Log?

            // Close transaction

            if (transactionCents != invoiceCents)
            {
                transaction.AddRow(forexSpillAccount, invoiceCents - transactionCents,
                                   authData.CurrentUser); // Adds the forex adjustment so we can bind payout to tx and close
            }

            transaction.AddRow(authData.CurrentOrganization.FinancialAccounts.AssetsOutboundInvoices,
                               -outboundInvoice.AmountCents, authData.CurrentUser);
        }
Exemple #21
0
    protected void GridTransactions_ItemCreated(object sender, GridItemEventArgs e)
    {
        const string imageUrlNone = "~/Images/Public/Fugue/icons-shadowless/minus-small.png";
        const string imageUrlDoc  = "~/Images/Public/Fugue/icons-shadowless/report.png";
        const string imageUrlDoc2 = "~/Images/Public/Fugue/icons-shadowless/reports.png";
        const string imageUrlDoc3 = "~/Images/Public/Fugue/icons-shadowless/reports-stack.png";
        const string imageUrlLink = "~/Images/Public/Fugue/icons-shadowless/chain.png";


        if (e.Item is GridDataItem)
        {
            LedgerRow row = (LedgerRow)e.Item.DataItem;

            if (row == null)
            {
                return;
            }

            decimal delta   = row.Amount;
            decimal balance = row.Balance;

            if (_simplifiedView)
            {
                delta   = -delta;
                balance = -balance;  // Change accountant's worldview (costs are positive) to normal people's (expenses are negative)
            }


            string field = "LabelDebit";

            if (row.Amount < 0.0m)
            {
                field = "LabelCredit";
            }

            Label labelDelta = (Label)e.Item.FindControl(field);
            labelDelta.Text = delta.ToString("+#,##0.00;-#,##0.00", new CultureInfo("sv-SE"));

            Label labelAccountName = (Label)e.Item.FindControl("LabelAccountName");
            labelAccountName.Text = _accountNames[row.FinancialAccountId];

            Label labelLedgered = (Label)e.Item.FindControl("LabelLedgered");

            if (!_peopleInitials.ContainsKey(row.RowCreatedByPersonId))
            {
                if (row.RowCreatedByPersonId > 0)
                {
                    _peopleInitials[row.RowCreatedByPersonId] = Person.FromIdentity(row.RowCreatedByPersonId).Initials;
                }
                else
                {
                    _peopleInitials[0] = "bot";
                }
            }

            labelLedgered.Text = String.Format("{0:yyMMdd}/{1}", row.RowDateTime,
                                               _peopleInitials[row.RowCreatedByPersonId]);


            Label labelBalance = (Label)e.Item.FindControl("LabelBalance");
            labelBalance.Text = balance.ToString("N2", new CultureInfo("sv-SE"));

            Image imageDoxored = (Image)e.Item.FindControl("ImageDocumented");
            Image imageLinked  = (Image)e.Item.FindControl("ImageLinked");

            FinancialTransaction transaction = FinancialTransaction.FromIdentity(row.FinancialTransactionId);
            int  docCount      = Documents.ForObject(transaction).Count;
            bool hasDependency = transaction.Dependency == null ? false : true;

            if (hasDependency)
            {
                imageLinked.ImageUrl  = imageUrlLink;
                imageDoxored.ImageUrl = imageUrlDoc;
            }
            else
            {
                imageLinked.ImageUrl = imageUrlNone;

                if (docCount == 0)
                {
                    imageDoxored.ImageUrl = imageUrlNone;
                }
                else if (docCount == 1)
                {
                    imageDoxored.ImageUrl = imageUrlDoc;
                }
                else if (docCount == 2)
                {
                    imageDoxored.ImageUrl = imageUrlDoc2;
                }
                else
                {
                    imageDoxored.ImageUrl = imageUrlDoc3;
                }
            }

            HyperLink editLink = (HyperLink)e.Item.FindControl("LinkManage");
            editLink.Attributes["href"]    = "#";
            editLink.Attributes["onclick"] = String.Format("return ShowTransactionForm('{0}','{1}');",
                                                           row.FinancialTransactionId, e.Item.ItemIndex);
        }
    }