Skip to content

Instantly share code, notes, and snippets.

@CorgiTaco
Last active April 9, 2022 09:22
Show Gist options
  • Save CorgiTaco/870e10b56af41d69e9bac4df32010485 to your computer and use it in GitHub Desktop.
Save CorgiTaco/870e10b56af41d69e9bac4df32010485 to your computer and use it in GitHub Desktop.
Prints out the total payment of a given payer for each month as well as the total paid/losses to a given vendor from a Paypal CSV file in the given user's currency and it uses the currency exchange rate for the day of the transaction. Good for taxes.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.Month;
import java.util.Map;
import java.util.TreeMap;
public class PaypalCSVReader {
// Get an API Key from: https://www.exchangerate-api.com/
// Requires Pro account to access exchange rate history.
private static final String API_KEY = "api_key";
private static final String USER_CURRENCY_ID = "USD";
public static void main(String[] args) {
parsePaypalCSV(new File("").getAbsolutePath() + File.separator + "/src/main/resources/taxes.csv");
}
private static void parsePaypalCSV(String filePath) {
try {
String line;
BufferedReader br = new BufferedReader(new FileReader(filePath));
Map<Month, Map<String, Double>> totalsByPayerByMonth = new TreeMap<>();
Map<Month, Map<String, Double>> lossesByVendorByMonth = new TreeMap<>();
boolean skipFirstLine = false;
while ((line = br.readLine()) != null) {
String[] split = line.split("\",\"");
if (!skipFirstLine) {
skipFirstLine = true;
continue;
}
int month = Integer.parseInt(split[0].substring(1, 3));
Month month1 = Month.of(month);
Map<String, Double> payerToTotal = totalsByPayerByMonth.computeIfAbsent(month1, payer -> new TreeMap<>());
Map<String, Double> vendorToLosses = lossesByVendorByMonth.computeIfAbsent(month1, payment -> new TreeMap<>());
String payer = split[3];
String amount = split[7].replaceAll("\"", "");
if (amount.isEmpty()) {
continue;
}
double total = Double.parseDouble(amount);
String currencyID = split[6];
double conversionRate = getConversionRate(currencyID, split[0]);
double usdValue = total / conversionRate;
if (total > 0) {
payerToTotal.put(payer, payerToTotal.getOrDefault(payer, 0D) + usdValue);
} else {
vendorToLosses.put(payer, vendorToLosses.getOrDefault(payer, 0D) + usdValue);
}
}
Gson GSON = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
String earnings = GSON.toJson(totalsByPayerByMonth);
String losses = GSON.toJson(lossesByVendorByMonth);
System.out.println("Earnings: \n" + earnings);
System.out.println("\n");
System.out.println("Losses: \n" + losses);
} catch (IOException e) {
e.printStackTrace();
}
}
private static double getConversionRate(String currencyID, String date) {
if (currencyID.equals(USER_CURRENCY_ID)) {
return 1;
}
String[] split = date.replaceAll("\"", "").split("/");
try {
URL url = new URL("https://v6.exchangerate-api.com/v6/" + API_KEY + "/history/" + USER_CURRENCY_ID + "/" + split[2] + "/" + split[0] + "/" + split[1]);
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
JsonObject root = JsonParser.parseReader(new InputStreamReader((InputStream) request.getContent())).getAsJsonObject();
JsonObject conversionRates = root.get("conversion_rates").getAsJsonObject();
return conversionRates.get(currencyID).getAsDouble();
} catch (IOException e) {
throw new IllegalArgumentException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment