Last active
April 9, 2022 09:22
-
-
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.
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
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