Created
April 15, 2013 10:06
-
-
Save PaulStovell/5387107 to your computer and use it in GitHub Desktop.
FastSpring/Xero integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This class takes the records from FastSpring and turns them into a Xero invoice for saving | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using XeroApi.Model; | |
using XeroFastSpring.FastSpring; | |
namespace XeroFastSpring.Xero | |
{ | |
public class InvoiceBuilder | |
{ | |
private readonly DateTime month; | |
private readonly decimal total; | |
private readonly TaxRate gstFreeExports; | |
private readonly TaxRate gstExempt; | |
readonly Invoice invoice = new Invoice(); | |
public InvoiceBuilder(DateTime month, Contact contact, decimal total, List<TaxRate> tax) | |
{ | |
var startOfMonth = new DateTime(month.Year, month.Month, 1); | |
var endOfMonth = new DateTime(month.Year, month.Month, DateTime.DaysInMonth(month.Year, month.Month)); | |
this.month = month; | |
this.total = total; | |
gstFreeExports = tax.Single(t => t.Name == "BAS Excluded"); | |
gstExempt = tax.Single(t => t.Name == "BAS Excluded"); | |
invoice.CurrencyCode = "USD"; | |
invoice.Reference = "Sales for " + startOfMonth.ToString("MMMM yyyy"); | |
invoice.SentToContact = true; | |
invoice.Date = endOfMonth; | |
invoice.Type = "ACCREC"; | |
invoice.DueDate = FastSpringRules.GetAnticipatedPaymentDate(endOfMonth); | |
invoice.LineItems = new LineItems(); | |
invoice.Contact = contact; | |
invoice.TotalTax = 0; | |
invoice.LineAmountTypes = LineAmountType.Inclusive; | |
invoice.InvoiceNumber = "FS-" + month.Year + "/" + month.Month; | |
} | |
public InvoiceBuilder AddLines(IEnumerable<FastSpringSalesRecord> records) | |
{ | |
var ordered = | |
from record in records | |
orderby record.Description descending | |
where record.Units > 0 | |
group record by record.Description into g | |
select g; | |
var sales = new List<LineItem>(); | |
var fees = new List<LineItem>(); | |
foreach (var grouped in ordered) | |
{ | |
var totalIncome = grouped.Sum(t => t.Income); | |
var totalExpense = grouped.Sum(t => t.Expense); | |
var units = grouped.Sum(t => t.Units); | |
sales.Add(new LineItem | |
{ | |
AccountCode = "201", // Octopus Sales | |
ItemCode = Configuration.ProductMapping[grouped.Key], | |
Description = grouped.Key, | |
Quantity = units, | |
TaxAmount = 0, | |
UnitAmount = Round((totalIncome / units)), | |
TaxType = gstFreeExports.TaxType | |
}); | |
fees.Add(new LineItem | |
{ | |
AccountCode = "403", // FastSpring Fees | |
ItemCode = "FastSpring Fees", | |
Description = "Fees: " + grouped.Key, | |
Quantity = units, | |
TaxAmount = 0, | |
UnitAmount = -Round((totalExpense / units)), | |
TaxType = gstExempt.TaxType | |
}); | |
} | |
invoice.LineItems.AddRange(sales); | |
invoice.LineItems.AddRange(fees); | |
return this; | |
} | |
public Invoice Build() | |
{ | |
var totalOnInvoice = Round(invoice.LineItems.Sum(i => (i.UnitAmount ?? 0M) * (i.Quantity ?? 0))); | |
var totalExpected = Round(total); | |
var correction = totalOnInvoice - totalExpected; | |
invoice.LineItems.Add(new LineItem | |
{ | |
AccountCode = "403", // FastSpring Fees | |
ItemCode = "FastSpring Fees", | |
Description = "Rounding correction", | |
Quantity = 1, | |
TaxAmount = 0, | |
UnitAmount = -correction, | |
TaxType = gstExempt.TaxType | |
}); | |
return invoice; | |
} | |
decimal Round(decimal? value) | |
{ | |
return decimal.Round(value ?? 0M, 2); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment