pub async fn refresh_expensify_transactions() {
    // Initialize the database.
    let db = Database::new();

    let mut path = env::current_dir().unwrap();
    path.push("expensify.csv");

    if !path.exists() {
        // Return early the path does not exist.
        println!("Expensify csv at {} does not exist, returning early", path.to_str().unwrap());
        return;
    }

    println!("Reading csv from {}", path.to_str().unwrap());
    let f = File::open(&path).unwrap();
    let mut rdr = csv::Reader::from_reader(f);
    for result in rdr.deserialize() {
        let mut record: NewExpensedItem = result.unwrap();
        record.expenses_vendor = "Expensify".to_string();
        record.state = "CLEARED".to_string();

        // Parse the user's last name.
        // We stored it in the merchant ID as a hack.
        let name = record.merchant_id.trim().to_string();
        let split = name.split(' ');
        let vec: Vec<&str> = split.collect();
        // Get the last item in the vector.
        let last_name = vec.last().unwrap().trim_end_matches("@oxidecomputer.com").to_string();

        // Reset the merchand id so it is clean.
        record.merchant_id = "".to_string();

        // Try to get the user by their last name.
        match users::dsl::users
            .filter(users::dsl::last_name.eq(last_name.to_string()).or(users::dsl::username.eq(last_name.to_string())))
            .first::<User>(&db.conn())
        {
            Ok(user) => {
                // Set the user's email.
                record.employee_email = user.email();
            }
            Err(e) => {
                if last_name == "Volpe" || last_name == "jared" {
                    record.employee_email = "jared@oxidecomputer.com".to_string();
                } else if last_name == "Randal" || last_name == "allison" {
                    record.employee_email = "allison@oxidecomputer.com".to_string();
                } else {
                    println!("could not find user with name `{}` last name `{}`: {}", name, last_name, e);
                }
            }
        }

        // Grab the card_id and set it as part of receipts.
        if !record.card_id.is_empty() && record.employee_email != "allison@oxidecomputer.com" {
            // Get the URL.
            let body = reqwest::get(&record.card_id).await.unwrap().text().await.unwrap();
            let split = body.split(' ');
            let vec: Vec<&str> = split.collect();

            for word in vec {
                if word.contains("https://www.expensify.com/receipts/") || word.contains("https://s3.amazonaws.com/receipts.expensify.com/") {
                    let receipt = word.trim_start_matches("href=\"").trim_end_matches("\">Download").to_string();
                    println!("{}", receipt);
                    record.receipts = vec![receipt.to_string()];

                    // Stop the loop.
                    break;
                }
            }

            // Reset the card id.
            record.card_id = String::new();
        }

        // Make sure we have a transaction id.
        if record.transaction_id.is_empty() {
            println!("transaction_id is missing: {:?}", record);
            // We don't want to save it to our database.
            continue;
        }

        // Try to link to the correct vendor.
        let vendor = clean_vendor_name(&record.merchant_name);
        // Try to find the merchant in our list of vendors.
        match SoftwareVendor::get_from_db(&db, vendor.to_string()) {
            Some(v) => {
                record.link_to_vendor = vec![v.airtable_record_id.to_string()];
            }
            None => {
                println!("could not find vendor that matches {}", vendor);
            }
        }

        // Let's add the record to our database.
        record.upsert(&db).await;
    }
}
/// Read the Expensify transactions from a csv.
/// We don't run this except locally.
Read the Expensify transactions from a csv.
We don't run this except locally.
Read the Expensify transactions from a csv . We don ' t run this except locally .
pub async fn refresh_expensify_transactions() {
    // Initialize the database.
    let db = Database::new();
    let mut path = env::current_dir().unwrap();
    path.push("expensify.csv");
    if !path.exists() {
        // Return early the path does not exist.
        println!("Expensify csv at {} does not exist, returning early", path.to_str().unwrap());
        return;
    }
    println!("Reading csv from {}", path.to_str().unwrap());
    let f = File::open(&path).unwrap();
    let mut rdr = csv::Reader::from_reader(f);
    for result in rdr.deserialize() {
        let mut record: NewExpensedItem = result.unwrap();
        record.expenses_vendor = "Expensify".to_string();
        record.state = "CLEARED".to_string();
        // Parse the user's last name.
        // We stored it in the merchant ID as a hack.
        let name = record.merchant_id.trim().to_string();
        let split = name.split(' ');
        let vec: Vec<&str> = split.collect();
        // Get the last item in the vector.
        let last_name = vec.last().unwrap().trim_end_matches("@oxidecomputer.com").to_string();
        // Reset the merchand id so it is clean.
        record.merchant_id = "".to_string();
        // Try to get the user by their last name.
        match users::dsl::users
            .filter(users::dsl::last_name.eq(last_name.to_string()).or(users::dsl::username.eq(last_name.to_string())))
            .first::<User>(&db.conn())
        {
            Ok(user) => {
                // Set the user's email.
                record.employee_email = user.email();
            }
            Err(e) => {
                if last_name == "Volpe" || last_name == "jared" {
                    record.employee_email = "jared@oxidecomputer.com".to_string();
                } else if last_name == "Randal" || last_name == "allison" {
                    record.employee_email = "allison@oxidecomputer.com".to_string();
                } else {
                    println!("could not find user with name `{}` last name `{}`: {}", name, last_name, e);
                }
            }
        }
        // Grab the card_id and set it as part of receipts.
        if !record.card_id.is_empty() && record.employee_email != "allison@oxidecomputer.com" {
            // Get the URL.
            let body = reqwest::get(&record.card_id).await.unwrap().text().await.unwrap();
            let split = body.split(' ');
            let vec: Vec<&str> = split.collect();
            for word in vec {
                if word.contains("https://www.expensify.com/receipts/") || word.contains("https://s3.amazonaws.com/receipts.expensify.com/") {
                    let receipt = word.trim_start_matches("href=\"").trim_end_matches("\">Download").to_string();
                    println!("{}", receipt);
                    record.receipts = vec![receipt.to_string()];
                    // Stop the loop.
                    break;
                }
            }
            // Reset the card id.
            record.card_id = String::new();
        }
        // Make sure we have a transaction id.
        if record.transaction_id.is_empty() {
            println!("transaction_id is missing: {:?}", record);
            // We don't want to save it to our database.
            continue;
        }
        // Try to link to the correct vendor.
        let vendor = clean_vendor_name(&record.merchant_name);
        // Try to find the merchant in our list of vendors.
        match SoftwareVendor::get_from_db(&db, vendor.to_string()) {
            Some(v) => {
                record.link_to_vendor = vec![v.airtable_record_id.to_string()];
            }
            None => {
                println!("could not find vendor that matches {}", vendor);
            }
        }
        // Let's add the record to our database.
        record.upsert(&db).await;
    }
}
pub async fn refresh_expensify_transactions ( ) { // Initialize the database. let db = Database :: new ( ) ; let mut path = env :: current_dir ( ) . unwrap ( ) ; path . push ( " " ) ; if ! path . exists ( ) { // Return early the path does not exist. println ! ( " " path to_str ( ) unwrap ( ) ) ; return ; } println ! ( " " path to_str ( ) unwrap ( ) ) ; let f = File :: open ( & path ) . unwrap ( ) ; let mut rdr = csv :: Reader :: from_reader ( f ) ; for result in rdr . deserialize ( ) { let mut record : NewExpensedItem = result . unwrap ( ) ; record . expenses_vendor = " " . to_string ( ) ; record . state = " " . to_string ( ) ; // Parse the user's last name. // We stored it in the merchant ID as a hack. let name = record . merchant_id . trim ( ) . to_string ( ) ; let split = name . split ( ' ' ) ; let vec : Vec < & str > = split . collect ( ) ; // Get the last item in the vector. let last_name = vec . last ( ) . unwrap ( ) . trim_end_matches ( " " ) . to_string ( ) ; // Reset the merchand id so it is clean. record . merchant_id = " " . to_string ( ) ; // Try to get the user by their last name. match users :: dsl :: users . filter ( users :: dsl :: last_name . eq ( last_name . to_string ( ) ) . or ( users :: dsl :: username . eq ( last_name . to_string ( ) ) ) ) . first :: < User > ( & db . conn ( ) ) { Ok ( user ) => { // Set the user's email. record . employee_email = user . email ( ) ; } Err ( e ) => { if last_name == " " || last_name == " " { record . employee_email = " " . to_string ( ) ; } else if last_name == " " || last_name == " " { record . employee_email = " " . to_string ( ) ; } else { println ! ( " " name last_name e ) ; } } } // Grab the card_id and set it as part of receipts. if ! record . card_id . is_empty ( ) && record . employee_email != " " { // Get the URL. let body = reqwest :: get ( & record . card_id ) . await . unwrap ( ) . text ( ) . await . unwrap ( ) ; let split = body . split ( ' ' ) ; let vec : Vec < & str > = split . collect ( ) ; for word in vec { if word . contains ( " " ) || word . contains ( " " ) { let receipt = word . trim_start_matches ( " \" " ) . trim_end_matches ( " \" " ) . to_string ( ) ; println ! ( " " receipt ) ; record . receipts = vec ! [ receipt to_string ( ) ] ; // Stop the loop. break ; } } // Reset the card id. record . card_id = String :: new ( ) ; } // Make sure we have a transaction id. if record . transaction_id . is_empty ( ) { println ! ( " " record ) ; // We don't want to save it to our database. continue ; } // Try to link to the correct vendor. let vendor = clean_vendor_name ( & record . merchant_name ) ; // Try to find the merchant in our list of vendors. match SoftwareVendor :: get_from_db ( & db , vendor . to_string ( ) ) { Some ( v ) => { record . link_to_vendor = vec ! [ v airtable_record_id to_string ( ) ] ; } None => { println ! ( " " vendor ) ; } } // Let's add the record to our database. record . upsert ( & db ) . await ; } }
Read the Expensify transactions from a csv.
Read the Expensify transactions from a csv .