Created
February 22, 2025 17:43
-
-
Save jkereako/76dbb9e0f1dc56f35209d9a93fa3e64d to your computer and use it in GitHub Desktop.
Convert a Fidelity CSV to a TaxSlayer CSV for import
This file contains hidden or 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
// Generated by Copilot | |
package main | |
import ( | |
"bufio" | |
"encoding/csv" | |
"fmt" | |
"os" | |
"strconv" | |
"strings" | |
"time" | |
) | |
func main() { | |
// Open the fidelity.csv file | |
inputFile, err := os.Open("fidelity.csv") | |
if err != nil { | |
fmt.Println("Error opening fidelity.csv:", err) | |
return | |
} | |
defer inputFile.Close() | |
// Create a new file to save the normalized data | |
normalizedFile, err := os.Create("fidelity-normalized.csv") | |
if err != nil { | |
fmt.Println("Error creating fidelity-normalized.csv:", err) | |
return | |
} | |
defer normalizedFile.Close() | |
writer := bufio.NewWriter(normalizedFile) | |
scanner := bufio.NewScanner(inputFile) | |
// Read the file line by line and save relevant lines | |
for scanner.Scan() { | |
line := scanner.Text() | |
if strings.Contains(line, "1099-B-Detail") && (strings.Contains(line, "BUY") || strings.Contains(line, "SALE")) && !strings.Contains(line, "NONCOVERED") { | |
_, err := writer.WriteString(line + "\n") | |
if err != nil { | |
fmt.Println("Error writing to fidelity-normalized.csv:", err) | |
return | |
} | |
} | |
} | |
if err := scanner.Err(); err != nil { | |
fmt.Println("Error reading fidelity.csv:", err) | |
return | |
} | |
writer.Flush() | |
// Open the normalized file for reading | |
normalizedFile, err = os.Open("fidelity-normalized.csv") | |
if err != nil { | |
fmt.Println("Error opening fidelity-normalized.csv:", err) | |
return | |
} | |
defer normalizedFile.Close() | |
reader := csv.NewReader(normalizedFile) | |
reader.LazyQuotes = true | |
// Read all records from the normalized file | |
records, err := reader.ReadAll() | |
if err != nil { | |
fmt.Println("Error reading fidelity-normalized.csv:", err) | |
return | |
} | |
// Open the taxslayer.csv file for writing | |
outputFile, err := os.Create("taxslayer.csv") | |
if err != nil { | |
fmt.Println("Error creating taxslayer.csv:", err) | |
return | |
} | |
defer outputFile.Close() | |
csvWriter := csv.NewWriter(outputFile) | |
defer csvWriter.Flush() | |
// Write the header row | |
header := []string{"Owner", "Description", "DtAcquired", "DtSold", "SalesPrice", "Cost"} | |
if err := csvWriter.Write(header); err != nil { | |
fmt.Println("Error writing header:", err) | |
return | |
} | |
// Process each record and map to taxslayer.csv format | |
batchSize := 500 | |
rowCount := 0 | |
for _, record := range records { | |
if len(record) < 20 { | |
continue // Skip rows that don't have enough columns | |
} | |
// Extract and map the required fields | |
description := extractDescription(record[8]) | |
dtAcquired := formatDate(record[11]) | |
dtSold := formatDate(record[12]) | |
cost := roundToNearestDollar(record[14]) | |
salesPrice := roundToNearestDollar(record[17]) | |
if salesPrice == "0" { | |
salesPrice = roundToNearestDollar(record[18]) | |
} | |
// Create the new row for taxslayer.csv | |
newRow := []string{"T", description, dtAcquired, dtSold, salesPrice, cost} | |
if err := csvWriter.Write(newRow); err != nil { | |
fmt.Println("Error writing row:", err) | |
return | |
} | |
rowCount++ | |
// Flush the writer every batchSize rows | |
if rowCount%batchSize == 0 { | |
csvWriter.Flush() | |
} | |
} | |
// Final flush to ensure all data is written | |
csvWriter.Flush() | |
fmt.Println("CSV mapping complete. Output written to taxslayer.csv") | |
} | |
func extractDescription(field string) string { | |
parts := strings.Fields(strings.TrimSpace(field)) | |
if len(parts) > 1 { | |
return parts[len(parts)-2] | |
} | |
return "" | |
} | |
func formatDate(field string) string { | |
date, err := time.Parse("01/02/06", strings.TrimSpace(field)) | |
if err != nil { | |
fmt.Println("Error parsing date:", err) | |
return "" | |
} | |
return date.Format("01/02/2006") | |
} | |
func roundToNearestDollar(field string) string { | |
value, err := strconv.ParseFloat(strings.TrimSpace(field), 64) | |
if err != nil { | |
fmt.Println("Error parsing float:", err) | |
return "0" | |
} | |
return strconv.Itoa(int(value + 0.5)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
Converts an CSV exported from Fidelity, named fidelity.csv, to the format TaxSlayer expects. This was written by Copilot.
Fidelity's CSV is malformed, at least mine was, so the first thing this script does is normalize the CSV and extracts the rows that actually matter. It saves that as a new CSV, opens it, and then converts it to the format TaxSlayer expects.
Prompt
Below is the prompt I used. It was a series of trial and error.