示例#1
0
    private void PopulateGrid()
    {
        OutboundInvoices invoices = OutboundInvoices.ForOrganization(this.Organization, true);

        invoices.Reverse();

        this.GridInvoices.DataSource = invoices;
        this.GridInvoices.Rebind();
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        // Get invoices and attestation rights

        this._invoices = OutboundInvoices.ForOrganization(this.CurrentOrganization, true);

        _invoices.Sort(SortInvoicesByCreatedDateReverse);

        // Format as JSON and return

        Response.ContentType = "application/json";
        string json = FormatAsJson();

        Response.Output.WriteLine(json);
        Response.End();
    }
        private void PopulateOutboundInvoices()
        {
            OutboundInvoices invoices = OutboundInvoices.ForOrganization(CurrentOrganization, true);

            foreach (OutboundInvoice invoice in invoices)
            {
                Documents dox    = invoice.Documents;
                bool      hasDox = (dox.Count > 0 ? true : false);

                if (hasDox)
                {
                    AddDocuments(invoice.Documents, "O" + invoice.Identity.ToString(CultureInfo.InvariantCulture),
                                 String.Format(Global.Financial_OutboundInvoiceSpecificationWithCustomer + " - ",
                                               invoice.OrganizationSequenceId, invoice.CustomerName) + Global.Global_ImageSpecification);
                }
            }
        }
示例#4
0
        private static DropdownOption[] GetOpenOutboundInvoiceData(FinancialTransaction transaction)
        {
            DateTime txDateTime  = transaction.DateTime;
            Int64    matchAmount = transaction.Rows.AmountCentsTotal;

            DropdownOptions result = new DropdownOptions();

            List <DropdownOption> listExact    = new List <DropdownOption>();
            List <DropdownOption> listTolerant = new List <DropdownOption>();
            List <DropdownOption> listRefMatch = new List <DropdownOption>();

            OutboundInvoices invoices = OutboundInvoices.ForOrganization(transaction.Organization);

            foreach (OutboundInvoice invoice in invoices)
            {
                if (invoice.AmountCents > matchAmount * 95 / 100 &&
                    invoice.AmountCents < matchAmount * 105 / 100)
                {
                    string description = String.Format(Resources.Pages.Ledgers.BalanceTransactions_OutboundInvoiceMatch, invoice.OrganizationSequenceId,
                                                       invoice.CustomerName, invoice.DueDate, invoice.DisplayNativeAmount);

                    if (invoice.HasNativeCurrency)
                    {
                        description += " (" + transaction.Organization.Currency.DisplayCode + " " +
                                       (invoice.AmountCents / 100.0).ToString("N2") + ")";
                    }

                    bool invoiceIdMatch = DescriptionContainsInvoiceReference(invoice.Reference, invoice.TheirReference, transaction.Description);

                    if (invoiceIdMatch)
                    {
                        listRefMatch.Add(new DropdownOption
                        {
                            id     = invoice.Identity.ToString(CultureInfo.InvariantCulture),
                            @group = Resources.Pages.Ledgers.BalanceTransactions_MostProbableMatch,
                            text   = description
                        });
                    }
                    if (invoice.AmountCents == matchAmount)
                    {
                        listExact.Add(new DropdownOption
                        {
                            id     = invoice.Identity.ToString(CultureInfo.InvariantCulture),
                            @group = Resources.Pages.Ledgers.BalanceTransactions_ExactMatches,
                            text   = description
                        });
                    }
                    else
                    {
                        listTolerant.Add(new DropdownOption
                        {
                            id     = invoice.Identity.ToString(CultureInfo.InvariantCulture),
                            @group = Resources.Pages.Ledgers.BalanceTransactions_FivePercentMatches,
                            text   = description
                        });
                    }
                }
            }

            List <DropdownOption> listCombined = new List <DropdownOption>();

            listCombined.AddRange(listRefMatch);
            listCombined.AddRange(listExact);
            listCombined.AddRange(listTolerant);

            return(listCombined.ToArray());
        }
 protected void PopulateOutboundInvoices(int organizationId)
 {
     this.GridOutboundInvoices.DataSource = OutboundInvoices.ForOrganization(Organization.FromIdentity(organizationId));
 }
示例#6
0
        public static ImportExternalTransactionDataResults ImportExternalTransactionData(ExternalBankData import, ImportExternalTransactionDataArgs args)
        {
            FinancialAccount assetAccount       = args.Account;
            FinancialAccount autoDepositAccount = args.Organization.FinancialAccounts.IncomeDonations;
            int autoDepositLimit = 0; // Disabled; TODO: this.CurrentOrganization.Parameters.AutoDonationLimit;

            bool autosetInitialBalance = false;
            ImportExternalTransactionDataResults result = new ImportExternalTransactionDataResults();
            int   count = 0;
            int   progressUpdateInterval = import.Records.Length / 40;
            Int64 importedCentsTotal     = 0;

            if (progressUpdateInterval > 100)
            {
                progressUpdateInterval = 100;
            }

            ProgressBarBackend progressDisplay = new ProgressBarBackend(args.Guid);

            Currency organizationCurrency = assetAccount.Organization.Currency;
            Currency accountCurrency      = assetAccount.ForeignCurrency;

            if (accountCurrency == null)
            {
                accountCurrency = organizationCurrency;
            }

            FinancialAccountRows existingRows = assetAccount.GetRows(Constants.DateTimeLow, Constants.DateTimeHigh);

            // gets all
            if (existingRows.Count == 0)
            {
                autosetInitialBalance = true;
            }


            foreach (ExternalBankDataRecord row in import.Records)
            {
                // Update progress.

                count++;
                if (progressUpdateInterval < 2 || count % progressUpdateInterval == 0)
                {
                    int percent = (count * 99) / import.Records.Length;

                    progressDisplay.Set(percent);
                }

                // Update high- and low-water marks.

                if (row.DateTime < result.EarliestTransaction)
                {
                    result.EarliestTransaction = row.DateTime;
                }

                if (row.DateTime > result.LatestTransaction)
                {
                    result.LatestTransaction = row.DateTime;
                }


                string importKey = row.ImportHash;

                Int64 amountCents = row.TransactionNetCents;

                if (amountCents == 0)
                // defensive programming - these _should_ be duplicated in the interpreter if no "fee" field
                {
                    amountCents = row.TransactionGrossCents;
                }

                Int64 foreignCents = amountCents;
                importedCentsTotal += amountCents;

                if (accountCurrency.Identity != organizationCurrency.Identity)
                {
                    amountCents =
                        new Money(amountCents, accountCurrency, row.DateTime).ToCurrency(organizationCurrency).Cents;
                }

                FinancialTransaction transaction = FinancialTransaction.ImportWithStub(args.Organization.Identity,
                                                                                       row.DateTime,
                                                                                       assetAccount.Identity, amountCents,
                                                                                       row.Description, importKey, Sha256.Compute(row.RawData),
                                                                                       args.CurrentUser.Identity);

                if (transaction != null)
                {
                    // The transaction was created.

                    result.TransactionsImported++;

                    // If non-presentation currency, log the account currency amount as well.

                    if (accountCurrency.Identity != organizationCurrency.Identity)
                    {
                        transaction.Rows[0].AmountForeignCents = new Money(foreignCents, accountCurrency);
                    }

                    if (row.Description.ToLowerInvariant().StartsWith(args.Organization.IncomingPaymentTag))
                    {
                        // Check for previously imported payment group

                        // TODO: MAKE FLEXIBLE - CALL PAYMENTREADERINTERFACE!
                        // HACK HACK HACK HACK

                        PaymentGroup group = PaymentGroup.FromTag(args.Organization,
                                                                  "SEBGM" + DateTime.Today.Year + // TODO: Get tags from org
                                                                  row.Description.Substring(args.Organization.IncomingPaymentTag.Length).Trim());

                        if (group != null && group.Open)
                        {
                            // There was a previously imported and not yet closed payment group matching this transaction
                            // Close the payment group and match the transaction against accounts receivable

                            transaction.Dependency = group;
                            group.Open             = false;
                            transaction.AddRow(args.Organization.FinancialAccounts.AssetsOutboundInvoices, -amountCents,
                                               args.CurrentUser);
                        }
                    }
                    else if (amountCents < 0)
                    {
                        // Autowithdrawal mechanisms removed, condition kept because of downstream else-if conditions
                    }
                    else if (amountCents > 0)
                    {
                        if (row.FeeCents < 0)
                        {
                            // This is always an autodeposit, if there is a fee (which is never > 0.0)

                            transaction.AddRow(args.Organization.FinancialAccounts.CostsBankFees, -row.FeeCents,
                                               args.CurrentUser);
                            transaction.AddRow(autoDepositAccount, -row.TransactionGrossCents, args.CurrentUser);
                        }
                        else if (amountCents < autoDepositLimit * 100)
                        {
                            // Book against autoDeposit account.

                            transaction.AddRow(autoDepositAccount, -amountCents, args.CurrentUser);
                        }
                    }
                }
                else
                {
                    // Transaction was not imported; assume duplicate

                    result.DuplicateTransactions++;
                }
            }

            // Import complete. Return true if the bookkeeping account matches the bank data.

            Int64 databaseAccountBalanceCents;

            if (accountCurrency.Identity == organizationCurrency.Identity)
            {
                databaseAccountBalanceCents = assetAccount.BalanceTotalCents;
            }
            else
            {
                // foreign-currency account
                databaseAccountBalanceCents = assetAccount.ForeignCurrencyBalance.Cents;
            }


            // Subtract any transactions made after the most recent imported transaction.
            // This is necessary in case of Paypal and others which continuously feed the
            // bookkeeping account with new transactions; it will already have fed transactions
            // beyond the end-of-file.

            Int64 beyondEofCents = assetAccount.GetDeltaCents(result.LatestTransaction.AddSeconds(1),
                                                              DateTime.Now.AddDays(2));

            // Caution: the "AddSeconds(1)" is not foolproof, there may be other new txs on the same second.

            if (databaseAccountBalanceCents - beyondEofCents == import.LatestAccountBalanceCents)
            {
                Payouts.AutomatchAgainstUnbalancedTransactions(args.Organization);
                OutboundInvoices.AutomatchAgainstUnbalancedTransactions(args.Organization, args.CurrentUser);
                result.AccountBalanceMatchesBank = true;
                result.BalanceMismatchCents      = 0;
            }
            else
            {
                result.AccountBalanceMatchesBank = false;
                result.BalanceMismatchCents      = (databaseAccountBalanceCents - beyondEofCents) -
                                                   import.LatestAccountBalanceCents;

                if (autosetInitialBalance)
                {
                    Int64 newInitialBalanceCents = -result.BalanceMismatchCents;
                    Money initialBalance         = new Money(newInitialBalanceCents, accountCurrency);

                    assetAccount.InitialBalance       = initialBalance;
                    result.InitialBalanceCents        = newInitialBalanceCents;
                    result.InitialBalanceCurrencyCode = accountCurrency.Code;

                    // make an approximation of conversion rate set for initial balance in presentation to tell user
                    initialBalance.ValuationDateTime = new DateTime(assetAccount.Organization.FirstFiscalYear, 1, 1);
                    result.BalanceMismatchCents      = initialBalance.ToCurrency(assetAccount.Organization.Currency).Cents;
                }
            }

            result.CurrencyCode = args.Organization.Currency.Code;
            GuidCache.Set(args.Guid + "-Results", result);
            return(result);
        }