Python script to convert an Etsy sales export CSV into a Xero import CSV
We handle the accounting for our pop out cards shop using Xero. There are convenient pre-built integrations that handle Stripe and PayPal data in Xero, but nothing for Etsy, so I had to do a little Python script to generate a Xero import CSV file from the Etsy orders export CSV.
Here’s the script for future reference:
#!/usr/bin/python3
# https://www.etsy.com/uk/your/shops/YourShopName/download
# Sold Orders
# e.g. EtsySoldOrders2020.csv
import argparse
import csv
from datetime import datetime
from io import TextIOWrapper
from typing import Dict
SALES_ACCOUNT_CODE = "200"
NOW = datetime.now()
XERO_FIELDS = [
"*ContactName",
"EmailAddress",
"POAddressLine1",
"POAddressLine2",
"POAddressLine3",
"POAddressLine4",
"POCity",
"PORegion",
"POPostalCode",
"POCountry",
"*InvoiceNumber",
"Reference",
"*InvoiceDate",
"*DueDate",
"Total",
"InventoryItemCode",
"*Description",
"*Quantity",
"*UnitAmount",
"Discount",
"*AccountCode",
"*TaxType",
"TaxAmount",
"TrackingName1",
"TrackingOption1",
"TrackingName2",
"TrackingOption2",
"Currency",
"BrandingTheme",
]
def convert_etsy_to_xero(etsy_file: TextIOWrapper):
output_file = f"etsy_xero_orders_{etsy_file.name}"
with open(output_file, "w", newline="") as output_file:
etsy_reader = csv.DictReader(etsy_file, delimiter=",", quotechar='"')
xero_writer = csv.DictWriter(output_file, XERO_FIELDS,
delimiter=",", quotechar='"')
xero_writer.writeheader()
for etsy_order in etsy_reader:
xero_writer.writerow(
etsy_order_to_xero_row(etsy_order)
)
def etsy_order_to_xero_row(etsy_order: Dict[str, str]) -> Dict[str, str]:
return {
"*ContactName": etsy_order.get("Full Name"),
"EmailAddress": "",
"POAddressLine1": etsy_order.get("Street 1"),
"POAddressLine2": etsy_order.get("Street 2"),
"POAddressLine3": etsy_order.get(""),
"POAddressLine4": etsy_order.get(""),
"POCity": etsy_order.get("Delivery City"),
"PORegion": etsy_order.get("Delivery State"),
"POPostalCode": etsy_order.get("Delivery Zipcode"),
"POCountry": etsy_order.get("Delivery Country"),
"*InvoiceNumber": etsy_order.get("Order ID"),
"Reference": etsy_order.get(""),
"*InvoiceDate": etsy_date_to_xero_date(etsy_order.get("Sale Date")),
"*DueDate": etsy_date_to_xero_date(etsy_order.get("Sale Date")),
"Total": etsy_order.get("Order total"),
"InventoryItemCode": "",
"*Description": f"Etsy Order {etsy_order.get('Order ID')}",
"*Quantity": "1",
"*UnitAmount": etsy_order.get("Order total"),
"Discount": "",
"*AccountCode": SALES_ACCOUNT_CODE,
"*TaxType": etsy_order.get("Sales"),
"TaxAmount": "",
"TrackingName1": "",
"TrackingOption1": "",
"TrackingName2": "",
"TrackingOption2": "",
"Currency": etsy_order.get("Currency"),
"BrandingTheme": "",
}
def etsy_date_to_xero_date(etsy_date: str) -> str:
return datetime.strptime(etsy_date, "%m/%d/%y").strftime("%d %b %Y")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Convert an Etsy sales export CSV into a xero invoices CSV")
parser.add_argument("etsy_file", default=f"EtsySoldOrders{NOW.year}.csv",
type=argparse.FileType("r", encoding="UTF-8"),
help="Path to Etsy sales export CSV file")
args = parser.parse_args()
convert_etsy_to_xero(args.etsy_file)
args.etsy_file.close()