public static void AutomatchAgainstUnbalancedTransactions(Organization organization, Person person) { // Matches unbalanced financial transactions against unclosed outbound invoices // Should this be in bot? OutboundInvoices invoices = ForOrganization(organization); // gets all open // build a hash of all invoice reference numbers, ours and theirs (and let's hope for no collision...) // TODO: Collision detection Dictionary <string, OutboundInvoice> invoiceLookup = new Dictionary <string, OutboundInvoice>(); foreach (OutboundInvoice invoice in invoices) { invoiceLookup[RemoveNoise(invoice.TheirReference)] = invoice; invoiceLookup[RemoveNoise(invoice.Reference)] = invoice; } FinancialTransactions transactions = FinancialTransactions.GetUnbalanced(organization); foreach (FinancialTransaction transaction in transactions) { string[] words = transaction.Description.Split(' '); bool collision = false; int invoiceId = 0; OutboundInvoice identifiedInvoice = null; foreach (string word in words) { string cleanWord = RemoveNoise(word); if (invoiceLookup.ContainsKey(cleanWord)) { OutboundInvoice invoice = invoiceLookup[cleanWord]; if (transaction.Rows.AmountCentsTotal == invoice.AmountCents) { // Matching description and amount if (invoiceId != 0 && invoiceId != invoice.Identity) { collision = true; } else if (invoice.Open) // double check it wasn't closed previously in loop { invoiceId = invoice.Identity; identifiedInvoice = invoice; } } } } // If invoiceId != 0 and collision == false, we've found exactly one match if (invoiceId != 0 && !collision) { Payment.CreateSingle(organization, transaction.DateTime, identifiedInvoice.Currency, identifiedInvoice.AmountCents, identifiedInvoice, person); // Balance transaction against outbound invoices transaction.AddRow(organization.FinancialAccounts.AssetsOutboundInvoices, -identifiedInvoice.AmountCents, person); } } }