V1 test phase started

This commit is contained in:
Franklin 2023-03-11 10:44:21 -04:00
parent a672434ad4
commit 21e38519d2
4 changed files with 128 additions and 11 deletions

View File

@ -18,4 +18,4 @@ async fn main() {
routes::main_router::start_all_routes(start_time, db_conn)
.await
.unwrap();
}
}

View File

@ -17,7 +17,7 @@ pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(
App::new()
.wrap(cors_policy)
.app_data(client_state.clone())
.app_data(db_conn.clone())
.app_data(web::Data::new(db_conn.clone()))
.service(web::scope("/admin")
.service(super::admin::create_new_agent_profile)
.service(super::admin::create_new_location)
@ -25,9 +25,9 @@ pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(
.service(super::admin::update_agent_info)
.service(super::admin::update_listing))
.service(web::scope("/read")
)
.service(super::read::get_all_agents)
.service(super::read::get_listing_container)
.service(super::read::get_property_listings_paged))
})
.bind((HOST_ADDR, HOST_PORT))?
.run();

View File

@ -1,3 +1,109 @@
//TODO: Property
// - Get properties by novelty, by title, by size, by page, by cost, by contract_type
// - Properties should come with agents, property details, contact_info
use std::{sync::Arc, collections::HashMap, str::FromStr};
use actix_web::{web, get};
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use chrono::{DateTime, Utc};
use err::MessageResource;
use remax_types::{dto::{property::{PropertyContainer, ListingContainer}, agent::AgentContainer}, domain::{filters::property::PropertyFilter, property_details::ListingType}};
use sqlx::PgPool;
use uuid::Uuid;
use crate::service;
#[get("/properties/{page}")]
pub async fn get_property_listings_paged(
db_conn: web::Data<Arc<PgPool>>,
page: web::Path<i64>,
query_params: web::Query<HashMap<String, String>>
) -> TypedHttpResponse<Vec<PropertyContainer>> {
let filters = match parse_params_into_filters(query_params.0) {
Ok(filters) => filters,
Err(msg) => return TypedHttpResponse::return_standard_error(400, msg),
};
service::read::get_property_listings_paged(&db_conn, &filters, &page).await
}
#[get("/property/{property_id}")]
pub async fn get_listing_container(
db_conn: web::Data<Arc<PgPool>>,
property_id: web::Path<Uuid>,
) -> TypedHttpResponse<ListingContainer> {
service::read::get_listing_container(&db_conn, &property_id).await
}
#[get("/agents/{page}")]
pub async fn get_all_agents(
db_conn: web::Data<Arc<PgPool>>,
page: web::Path<i64>,
) -> TypedHttpResponse<Vec<AgentContainer>> {
service::read::get_all_agents(&db_conn, &page).await
}
fn parse_params_into_filters(params: HashMap<String, String>) -> Result<Vec<PropertyFilter>, MessageResource> {
let mut filters: Vec<PropertyFilter> = Vec::new();
for key in params.keys() {
match key.as_str() {
"before" => {
let parsed_date = match DateTime::<Utc>::from_str(params.get(key).unwrap()) {
Ok(date) => date,
Err(error) => return Err(MessageResource::new_from_string(error.to_string())),
};
filters.push(PropertyFilter::Before(parsed_date));
},
"after" => {
let parsed_date = match DateTime::<Utc>::from_str(params.get(key).unwrap()) {
Ok(date) => date,
Err(error) => return Err(MessageResource::new_from_string(error.to_string())),
};
filters.push(PropertyFilter::After(parsed_date));
},
"title" => {
let title_like = params.get(key).unwrap();
filters.push(PropertyFilter::Title(title_like.clone()));
},
"description" => {
let description_like = params.get(key).unwrap();
filters.push(PropertyFilter::Description(description_like.clone()));
},
"location" => {
let uid = match Uuid::from_str(params.get(key).unwrap()) {
Ok(id) => id,
Err(error) => return Err(MessageResource::new_from_string(error.to_string())),
};
filters.push(PropertyFilter::Location(uid));
},
"cheaperthan" => {
let cheaper_than = params.get(key).unwrap().clone();
let listing_type: ListingType = match serde_json::from_str(&cheaper_than) {
Ok(value) => value,
Err(error) => return Err(MessageResource::new_from_string(error.to_string())),
};
filters.push(PropertyFilter::CheaperThan(listing_type));
},
"moreexpensivethan" => {
let more_expensive_than = params.get(key).unwrap().clone();
let listing_type: ListingType = match serde_json::from_str(&more_expensive_than) {
Ok(value) => value,
Err(error) => return Err(MessageResource::new_from_string(error.to_string())),
};
filters.push(PropertyFilter::MoreExpensiveThan(listing_type));
},
"biggerorquealto" => {
let bigger_than = match f32::from_str(&params.get(key).unwrap().clone()) {
Ok(value) => value,
Err(error) => return Err(MessageResource::new_from_string(error.to_string())),
};
filters.push(PropertyFilter::BiggerOrEqualTo(bigger_than));
},
"smallerorequalto" => {
let smaller_than = match f32::from_str(&params.get(key).unwrap().clone()) {
Ok(value) => value,
Err(error) => return Err(MessageResource::new_from_string(error.to_string())),
};
filters.push(PropertyFilter::SmallerOrEqualTo(smaller_than));
},
_ => {}
};
}
Ok(filters)
}

View File

@ -1,6 +1,6 @@
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use remax_types::{
domain::{agent::Agent, filters::property::PropertyFilter},
domain::{filters::property::PropertyFilter},
dto::{
agent::AgentContainer,
property::{ListingContainer, PropertyContainer},
@ -121,7 +121,18 @@ pub async fn get_listing_container(
})
}
pub async fn get_all_agents(conn: &PgPool, page: &i64) -> TypedHttpResponse<Vec<Agent>> {
pub async fn get_all_agents(conn: &PgPool, page: &i64) -> TypedHttpResponse<Vec<AgentContainer>> {
let agents = handle_db_read_op!(dao::agent::get_agents_paged(conn, page));
success!(agents)
let agent_ids: Vec<Uuid> = agents.iter().map(|agent| agent.id.clone()).collect();
let contact_infos = handle_db_read_op!(dao::contact_info::get_contact_infos_with_ids(conn, &agent_ids));
let mut agent_containers = Vec::new();
for agent in agents {
let contact = unwrap_or_not_found!(contact_infos.iter().find(|contact_info| contact_info.agent_id == agent.id), "contact_infos").clone();
agent_containers.push(AgentContainer {
agent,
contact,
})
}
success!(agent_containers)
}