Skip to content

Instantly share code, notes, and snippets.

@PaulStovell
Created April 15, 2013 10:06
Show Gist options
  • Save PaulStovell/5387107 to your computer and use it in GitHub Desktop.
Save PaulStovell/5387107 to your computer and use it in GitHub Desktop.
FastSpring/Xero integration
// 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