pub async fn sync_users(db: &Database, github: &Github, users: BTreeMap<String, UserConfig>) {
    // Get everything we need to authenticate with GSuite.
    // Initialize the GSuite client.
    let gsuite_customer = env::var("GADMIN_ACCOUNT_ID").unwrap();
    let token = get_gsuite_token("").await;
    let gsuite = GSuite::new(&gsuite_customer, GSUITE_DOMAIN, token);

    // Initialize the Ramp client.
    let ramp = Ramp::new_from_env().await;
    let ru = ramp.list_users().await.unwrap();
    let mut ramp_users: HashMap<String, ramp_api::User> = HashMap::new();
    for r in ru {
        ramp_users.insert(r.email.to_string(), r);
    }
    println!("{:?}", ramp_users);
    let rd = ramp.list_departments().await.unwrap();
    let mut ramp_departments: HashMap<String, ramp_api::Department> = HashMap::new();
    for r in rd {
        ramp_departments.insert(r.name.to_string(), r);
    }

    // Find the anniversary calendar.
    // Get the list of our calendars.
    let calendars = gsuite.list_calendars().await.unwrap();

    let mut anniversary_cal_id = "".to_string();

    // Iterate over the calendars.
    for calendar in calendars {
        if calendar.summary.contains("Anniversaries") {
            // We are on the anniversaries calendar.
            anniversary_cal_id = calendar.id;
            break;
        }
    }

    // Get all the users.
    let db_users = Users::get_from_db(db);
    // Create a BTreeMap
    let mut user_map: BTreeMap<String, User> = Default::default();
    for u in db_users {
        user_map.insert(u.username.to_string(), u);
    }
    // Sync users.
    for (_, mut user) in users {
        // Check if we already have the new user in the database.
        let existing = User::get_from_db(db, user.username.to_string());

        // Update or create the user in the database.
        if let Some(e) = existing.clone() {
            user.google_anniversary_event_id = e.google_anniversary_event_id.to_string();

            // TODO: remove this when we populate from Gusto.
            let airtable_record = e.get_existing_airtable_record().await.unwrap();
            user.home_address_street_1 = airtable_record.fields.home_address_street_1.to_string();
            user.home_address_street_2 = airtable_record.fields.home_address_street_2.to_string();
            user.home_address_city = airtable_record.fields.home_address_city.to_string();
            user.home_address_state = airtable_record.fields.home_address_state.to_string();
            user.home_address_zipcode = airtable_record.fields.home_address_zipcode.to_string();
            user.home_address_country = airtable_record.fields.home_address_country.to_string();
            user.birthday = airtable_record.fields.birthday;

            // Keep the start date in airtable if we already have one.
            if user.start_date == crate::utils::default_date() && airtable_record.fields.start_date != crate::utils::default_date() {
                user.start_date = airtable_record.fields.start_date;
            }
        }

        user.expand(db).await;

        let new_user = user.upsert(db).await;

        if existing.is_none() {
            // Now we need to update Okta to include the new user.
            // We do this so that when we send emails from ramp and for the new user,
            // they should have a Google account by then.
            // Sync okta users and group from the database.
            // Do this after we update the users and groups in the database.
            generate_terraform_files_for_okta(github, db).await;
            // TODO: this is horrible, but we will sleep here to allow the terraform
            // job to run.
            // We also need a better way to ensure the terraform job passed...
            thread::sleep(time::Duration::from_secs(120));

            // The user did not already exist in the database.
            // We should send them an email about setting up their account.
            println!("sending email to new user: {}", new_user.username);
            if new_user.is_consultant() {
                new_user.send_email_new_consultant().await;
            } else {
                new_user.send_email_new_user().await;
            }
        }

        if !new_user.is_consultant() && !new_user.is_system_account() {
            // Check if we have a Ramp user for the user.
            match ramp_users.get(&new_user.email()) {
                // We have the user, we don't need to do anything.
                Some(_) => (),
                None => {
                    println!("inviting new ramp user {}", new_user.username);
                    // Invite the new ramp user.
                    let mut ramp_user: ramp_api::User = Default::default();
                    ramp_user.email = new_user.email();
                    ramp_user.first_name = new_user.first_name.to_string();
                    ramp_user.last_name = new_user.last_name.to_string();
                    ramp_user.phone = new_user.recovery_phone.to_string();
                    ramp_user.role = "BUSINESS_USER".to_string();
                    ramp_user.amount_limit = "10000.00".to_string();
                    if let Some(department) = ramp_departments.get(&new_user.department) {
                        ramp_user.department_id = department.id.to_string();
                    }
                    let _r = ramp.invite_new_user(&ramp_user).await.unwrap();

                    // TODO: Create them a card.
                }
            }
        }

        // Remove the user from the BTreeMap.
        user_map.remove(&user.username);
    }
    // Remove any users that should no longer be in the database.
    // This is found by the remaining users that are in the map since we removed
    // the existing repos from the map above.
    for (username, user) in user_map {
        println!("deleting user {} from the database", username);

        if !user.google_anniversary_event_id.is_empty() {
            // First delete the recurring event for their anniversary.
            gsuite.delete_calendar_event(&anniversary_cal_id, &user.google_anniversary_event_id).await.unwrap();
            println!("deleted user {} event {} from google", username, user.google_anniversary_event_id);
        }

        // Delete the user from the database and Airtable.
        user.delete(db).await;
    }
    println!("updated configs users in the database");

    // Update users in airtable.
    Users::get_from_db(db).update_airtable().await;
}
/// Sync our users with our database and then update Airtable from the database.
Sync our users with our database and then update Airtable from the database.
Sync our users with our database and then update Airtable from the database .
pub async fn sync_users(db: &Database, github: &Github, users: BTreeMap<String, UserConfig>) {
    // Get everything we need to authenticate with GSuite.
    // Initialize the GSuite client.
    let gsuite_customer = env::var("GADMIN_ACCOUNT_ID").unwrap();
    let token = get_gsuite_token("").await;
    let gsuite = GSuite::new(&gsuite_customer, GSUITE_DOMAIN, token);
    // Initialize the Ramp client.
    let ramp = Ramp::new_from_env().await;
    let ru = ramp.list_users().await.unwrap();
    let mut ramp_users: HashMap<String, ramp_api::User> = HashMap::new();
    for r in ru {
        ramp_users.insert(r.email.to_string(), r);
    }
    println!("{:?}", ramp_users);
    let rd = ramp.list_departments().await.unwrap();
    let mut ramp_departments: HashMap<String, ramp_api::Department> = HashMap::new();
    for r in rd {
        ramp_departments.insert(r.name.to_string(), r);
    }
    // Find the anniversary calendar.
    // Get the list of our calendars.
    let calendars = gsuite.list_calendars().await.unwrap();
    let mut anniversary_cal_id = "".to_string();
    // Iterate over the calendars.
    for calendar in calendars {
        if calendar.summary.contains("Anniversaries") {
            // We are on the anniversaries calendar.
            anniversary_cal_id = calendar.id;
            break;
        }
    }
    // Get all the users.
    let db_users = Users::get_from_db(db);
    // Create a BTreeMap
    let mut user_map: BTreeMap<String, User> = Default::default();
    for u in db_users {
        user_map.insert(u.username.to_string(), u);
    }
    // Sync users.
    for (_, mut user) in users {
        // Check if we already have the new user in the database.
        let existing = User::get_from_db(db, user.username.to_string());
        // Update or create the user in the database.
        if let Some(e) = existing.clone() {
            user.google_anniversary_event_id = e.google_anniversary_event_id.to_string();
            // TODO: remove this when we populate from Gusto.
            let airtable_record = e.get_existing_airtable_record().await.unwrap();
            user.home_address_street_1 = airtable_record.fields.home_address_street_1.to_string();
            user.home_address_street_2 = airtable_record.fields.home_address_street_2.to_string();
            user.home_address_city = airtable_record.fields.home_address_city.to_string();
            user.home_address_state = airtable_record.fields.home_address_state.to_string();
            user.home_address_zipcode = airtable_record.fields.home_address_zipcode.to_string();
            user.home_address_country = airtable_record.fields.home_address_country.to_string();
            user.birthday = airtable_record.fields.birthday;
            // Keep the start date in airtable if we already have one.
            if user.start_date == crate::utils::default_date() && airtable_record.fields.start_date != crate::utils::default_date() {
                user.start_date = airtable_record.fields.start_date;
            }
        }
        user.expand(db).await;
        let new_user = user.upsert(db).await;
        if existing.is_none() {
            // Now we need to update Okta to include the new user.
            // We do this so that when we send emails from ramp and for the new user,
            // they should have a Google account by then.
            // Sync okta users and group from the database.
            // Do this after we update the users and groups in the database.
            generate_terraform_files_for_okta(github, db).await;
            // TODO: this is horrible, but we will sleep here to allow the terraform
            // job to run.
            // We also need a better way to ensure the terraform job passed...
            thread::sleep(time::Duration::from_secs(120));
            // The user did not already exist in the database.
            // We should send them an email about setting up their account.
            println!("sending email to new user: {}", new_user.username);
            if new_user.is_consultant() {
                new_user.send_email_new_consultant().await;
            } else {
                new_user.send_email_new_user().await;
            }
        }
        if !new_user.is_consultant() && !new_user.is_system_account() {
            // Check if we have a Ramp user for the user.
            match ramp_users.get(&new_user.email()) {
                // We have the user, we don't need to do anything.
                Some(_) => (),
                None => {
                    println!("inviting new ramp user {}", new_user.username);
                    // Invite the new ramp user.
                    let mut ramp_user: ramp_api::User = Default::default();
                    ramp_user.email = new_user.email();
                    ramp_user.first_name = new_user.first_name.to_string();
                    ramp_user.last_name = new_user.last_name.to_string();
                    ramp_user.phone = new_user.recovery_phone.to_string();
                    ramp_user.role = "BUSINESS_USER".to_string();
                    ramp_user.amount_limit = "10000.00".to_string();
                    if let Some(department) = ramp_departments.get(&new_user.department) {
                        ramp_user.department_id = department.id.to_string();
                    }
                    let _r = ramp.invite_new_user(&ramp_user).await.unwrap();
                    // TODO: Create them a card.
                }
            }
        }
        // Remove the user from the BTreeMap.
        user_map.remove(&user.username);
    }
    // Remove any users that should no longer be in the database.
    // This is found by the remaining users that are in the map since we removed
    // the existing repos from the map above.
    for (username, user) in user_map {
        println!("deleting user {} from the database", username);
        if !user.google_anniversary_event_id.is_empty() {
            // First delete the recurring event for their anniversary.
            gsuite.delete_calendar_event(&anniversary_cal_id, &user.google_anniversary_event_id).await.unwrap();
            println!("deleted user {} event {} from google", username, user.google_anniversary_event_id);
        }
        // Delete the user from the database and Airtable.
        user.delete(db).await;
    }
    println!("updated configs users in the database");
    // Update users in airtable.
    Users::get_from_db(db).update_airtable().await;
}
pub async fn sync_users ( db : & Database , github : & Github , users : BTreeMap < String , UserConfig > ) { // Get everything we need to authenticate with GSuite. // Initialize the GSuite client. let gsuite_customer = env :: var ( " " ) . unwrap ( ) ; let token = get_gsuite_token ( " " ) . await ; let gsuite = GSuite :: new ( & gsuite_customer , GSUITE_DOMAIN , token ) ; // Initialize the Ramp client. let ramp = Ramp :: new_from_env ( ) . await ; let ru = ramp . list_users ( ) . await . unwrap ( ) ; let mut ramp_users : HashMap < String , ramp_api :: User > = HashMap :: new ( ) ; for r in ru { ramp_users . insert ( r . email . to_string ( ) , r ) ; } println ! ( " " ramp_users ) ; let rd = ramp . list_departments ( ) . await . unwrap ( ) ; let mut ramp_departments : HashMap < String , ramp_api :: Department > = HashMap :: new ( ) ; for r in rd { ramp_departments . insert ( r . name . to_string ( ) , r ) ; } // Find the anniversary calendar. // Get the list of our calendars. let calendars = gsuite . list_calendars ( ) . await . unwrap ( ) ; let mut anniversary_cal_id = " " . to_string ( ) ; // Iterate over the calendars. for calendar in calendars { if calendar . summary . contains ( " " ) { // We are on the anniversaries calendar. anniversary_cal_id = calendar . id ; break ; } } // Get all the users. let db_users = Users :: get_from_db ( db ) ; // Create a BTreeMap let mut user_map : BTreeMap < String , User > = Default :: default ( ) ; for u in db_users { user_map . insert ( u . username . to_string ( ) , u ) ; } // Sync users. for ( _ , mut user ) in users { // Check if we already have the new user in the database. let existing = User :: get_from_db ( db , user . username . to_string ( ) ) ; // Update or create the user in the database. if let Some ( e ) = existing . clone ( ) { user . google_anniversary_event_id = e . google_anniversary_event_id . to_string ( ) ; // TODO: remove this when we populate from Gusto. let airtable_record = e . get_existing_airtable_record ( ) . await . unwrap ( ) ; user . home_address_street_1 = airtable_record . fields . home_address_street_1 . to_string ( ) ; user . home_address_street_2 = airtable_record . fields . home_address_street_2 . to_string ( ) ; user . home_address_city = airtable_record . fields . home_address_city . to_string ( ) ; user . home_address_state = airtable_record . fields . home_address_state . to_string ( ) ; user . home_address_zipcode = airtable_record . fields . home_address_zipcode . to_string ( ) ; user . home_address_country = airtable_record . fields . home_address_country . to_string ( ) ; user . birthday = airtable_record . fields . birthday ; // Keep the start date in airtable if we already have one. if user . start_date == crate :: utils :: default_date ( ) && airtable_record . fields . start_date != crate :: utils :: default_date ( ) { user . start_date = airtable_record . fields . start_date ; } } user . expand ( db ) . await ; let new_user = user . upsert ( db ) . await ; if existing . is_none ( ) { // Now we need to update Okta to include the new user. // We do this so that when we send emails from ramp and for the new user, // they should have a Google account by then. // Sync okta users and group from the database. // Do this after we update the users and groups in the database. generate_terraform_files_for_okta ( github , db ) . await ; // TODO: this is horrible, but we will sleep here to allow the terraform // job to run. // We also need a better way to ensure the terraform job passed... thread :: sleep ( time :: Duration :: from_secs ( 120 ) ) ; // The user did not already exist in the database. // We should send them an email about setting up their account. println ! ( " " new_user username ) ; if new_user . is_consultant ( ) { new_user . send_email_new_consultant ( ) . await ; } else { new_user . send_email_new_user ( ) . await ; } } if ! new_user . is_consultant ( ) && ! new_user . is_system_account ( ) { // Check if we have a Ramp user for the user. match ramp_users . get ( & new_user . email ( ) ) { // We have the user, we don't need to do anything. Some ( _ ) => ( ) , None => { println ! ( " " new_user username ) ; // Invite the new ramp user. let mut ramp_user : ramp_api :: User = Default :: default ( ) ; ramp_user . email = new_user . email ( ) ; ramp_user . first_name = new_user . first_name . to_string ( ) ; ramp_user . last_name = new_user . last_name . to_string ( ) ; ramp_user . phone = new_user . recovery_phone . to_string ( ) ; ramp_user . role = " " . to_string ( ) ; ramp_user . amount_limit = " " . to_string ( ) ; if let Some ( department ) = ramp_departments . get ( & new_user . department ) { ramp_user . department_id = department . id . to_string ( ) ; } let _r = ramp . invite_new_user ( & ramp_user ) . await . unwrap ( ) ; // TODO: Create them a card. } } } // Remove the user from the BTreeMap. user_map . remove ( & user . username ) ; } // Remove any users that should no longer be in the database. // This is found by the remaining users that are in the map since we removed // the existing repos from the map above. for ( username , user ) in user_map { println ! ( " " username ) ; if ! user . google_anniversary_event_id . is_empty ( ) { // First delete the recurring event for their anniversary. gsuite . delete_calendar_event ( & anniversary_cal_id , & user . google_anniversary_event_id ) . await . unwrap ( ) ; println ! ( " " username user google_anniversary_event_id ) ; } // Delete the user from the database and Airtable. user . delete ( db ) . await ; } println ! ( " " ) ; // Update users in airtable. Users :: get_from_db ( db ) . update_airtable ( ) . await ; }
Sync our users with our database and then update Airtable from the database.
Sync our users with our database and then update Airtable from the database .
db
&Database
github
&Github
users
BTreeMap<String, UserConfig>
db
&Database
github
&Github
users
BTreeMap<String, UserConfig>