Import Xero sales invoice flat-file

Feature complete and tested
This commit is contained in:
Bobbie Hodgetts
2020-01-31 11:32:54 +00:00
committed by GitHub
parent aea82da897
commit 88159d4cc3
34 changed files with 1166 additions and 358 deletions

View File

@@ -0,0 +1,136 @@
using CsvHelper;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic.FileIO;
namespace BealeEngineering.Core.Logic.Import
{
public class XeroInvoiceFlatFile
{
private List<Model.Import.XeroInvoiceFlatFile> XeroInvoiceData { get; set; }
private List<Model.Sale.Invoice> DbInvoiceData { get; set; }
public XeroInvoiceFlatFile(string sqlConnectionString)
{
SqlConnectionString = sqlConnectionString;
}
private string SqlConnectionString { get; set; }
public void ByFilePath(string filePath, bool updateContacts = true)
{
// get xero data
var data = new Data.Xero.FlatFile.ReadXeroInvoiceFlatFile();
XeroInvoiceData = data.ByFilePath(filePath);
// update db contacts
UpdateContacts();
// populate/map xero data to invoice model list
MapInvoiceDetails();
//check
if (XeroInvoiceData.Count != DbInvoiceData.Count)
{
throw new Exception("Something went wrong while mapping the data.");
}
// send list to database (it will get validated in data layer)
if (DbInvoiceData.Any())
{
var updateInvoice = new Data.Database.Sale.UpdateInvoice(SqlConnectionString);
updateInvoice.ByInvoiceList(DbInvoiceData);
}
}
/// <summary>
/// Get a dictionary of contacts, referenced by unique 'Contact Name'. Any contacts not found in db are
/// automatically added.
/// </summary>
/// <returns></returns>
private void UpdateContacts()
{
var dicContacts = new Dictionary<string, Model.Contact.Contact>();
for (var i = 0; i < XeroInvoiceData.Count; i++)
{
if (!dicContacts.ContainsKey(XeroInvoiceData[0].ContactName))
{
dicContacts.Add(XeroInvoiceData[0].ContactName, MapContactDetails(XeroInvoiceData[0]));
}
}
if (dicContacts.Any())
{
var updateContact = new Data.Database.Contact.UpdateContact(SqlConnectionString);
updateContact.ByContactList(dicContacts.Values.ToList());
}
}
private Model.Contact.Contact MapContactDetails(Model.Import.XeroInvoiceFlatFile xeroData)
{
var contact = new Model.Contact.Contact();
contact.ContactName = xeroData.ContactName;
if (string.IsNullOrWhiteSpace(xeroData.EmailAddress)) { contact.EmailAddress = null; }
else { contact.EmailAddress = xeroData.EmailAddress; }
var address = new Model.Contact.Address();
address.AddressLine1 = xeroData.POAddressLine1;
address.AddressLine2 = xeroData.POAddressLine2;
address.AddressLine3 = xeroData.POAddressLine3;
address.AddressLine4 = xeroData.POAddressLine4;
address.City = xeroData.POCity;
address.Country = xeroData.POCountry;
address.PostalCode = xeroData.POPostalCode;
address.Region = xeroData.PORegion;
if (address.IsValid()) { contact.PostalAddress = address; }
return contact;
}
private void MapInvoiceDetails()
{
DbInvoiceData = new List<Model.Sale.Invoice>();
for (var i = 0; i < XeroInvoiceData.Count; i++)
{
if (XeroInvoiceData[i] == null) { throw new NullReferenceException(); }
var invoice = new Model.Sale.Invoice();
invoice.ContactName = XeroInvoiceData[i].ContactName;
invoice.CurrencyCode = XeroInvoiceData[i].Currency;
invoice.DueDate = XeroInvoiceData[i].DueDate;
invoice.InvoiceDate = XeroInvoiceData[i].InvoiceDate;
invoice.InvoiceTotal = XeroInvoiceData[i].Total;
if (XeroInvoiceData[i].Type == "Sales invoice") { invoice.IsCreditNote = false; }
else if (XeroInvoiceData[i].Type == "Sales credit note") { invoice.IsCreditNote = true; }
else { throw new FormatException("Unknow value '" + XeroInvoiceData[i].Type + "' found in 'Type' field"); }
invoice.Reference = XeroInvoiceData[i].Reference;
invoice.SaleInvoiceNumber = XeroInvoiceData[i].InvoiceNumber;
invoice.TaxTotal = XeroInvoiceData[i].TaxTotal;
invoice.InvoiceLineList = new List<Model.Sale.Invoice.InvoiceLine>();
for (int j = 0; j < XeroInvoiceData[i].LineItems.Count; j++)
{
if (XeroInvoiceData[i].LineItems[j] == null) { throw new NullReferenceException(); }
var invoiceLine = new Model.Sale.Invoice.InvoiceLine();
invoiceLine.LineNumber = j + 1;
invoiceLine.AccountCode = XeroInvoiceData[i].LineItems[j].AccountCode;
invoiceLine.Description = XeroInvoiceData[i].LineItems[j].Description;
invoiceLine.Discount = XeroInvoiceData[i].LineItems[j].Discount;
invoiceLine.InventoryItemCode = XeroInvoiceData[i].LineItems[j].InventoryItemCode;
invoiceLine.Quantity = XeroInvoiceData[i].LineItems[j].Quantity;
invoiceLine.TaxAmount = XeroInvoiceData[i].LineItems[j].TaxAmount;
invoiceLine.TaxType = XeroInvoiceData[i].LineItems[j].TaxType;
invoiceLine.UnitAmount = XeroInvoiceData[i].LineItems[j].UnitAmount;
//check, as line amount is same as calculated in model
if (invoiceLine.LineAmount != XeroInvoiceData[i].LineItems[j].LineAmount)
{
throw new Exception("Imported line total does not equal caluclated.");
}
invoice.InvoiceLineList.Add(invoiceLine);
}
DbInvoiceData.Add(invoice);
}
}
}
}