Added renames

This commit is contained in:
Franklin 2023-03-11 10:40:52 -04:00
parent 6b2e978eec
commit 9bef82126a
10 changed files with 134 additions and 110 deletions

1
Cargo.lock generated
View File

@ -848,6 +848,7 @@ dependencies = [
"chrono-tz",
"format_num",
"serde",
"serde_json",
"sqlx",
"uuid",
]

View File

@ -9,6 +9,7 @@ edition = "2021"
chrono = { version = "0.4.23", features = [ "serde" ] }
chrono-tz = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.88"
uuid = { version = "1.3.0", features = ["v4", "fast-rng", "macro-diagnostics", "serde"] }
format_num = "0.1.0"
sqlx = { version = "0.6.0", features = [ "runtime-tokio-rustls", "postgres", "chrono", "uuid" ] }

View File

@ -1,8 +1,11 @@
use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use crate::domain::{property_details::ListingType};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub enum PropertyFilter {
// By Time
Before(DateTime<Utc>),
@ -10,15 +13,15 @@ pub enum PropertyFilter {
// By Word matching
Title(String),
Description(String),
Location(Uuid),
// By cost
CheaperThan(u64),
MoreExpensiveThan(u64),
// By Contract type
ContractType(String),
CheaperThan(ListingType),
MoreExpensiveThan(ListingType),
// By Size
BiggerOrEqualTo(u32),
SmallerOrEqualTo(u32),
BiggerOrEqualTo(f32),
SmallerOrEqualTo(f32),
}

View File

@ -3,5 +3,4 @@ pub mod property;
pub mod location;
pub mod contact_info;
pub mod property_details;
pub mod filters;
pub mod money;
pub mod filters;

View File

@ -1,85 +0,0 @@
use std::fmt::Display;
use format_num::NumberFormat;
use serde::{Serialize, Deserialize};
use sqlx::{Postgres, postgres::{PgArgumentBuffer, PgValueRef, PgTypeInfo}, encode::IsNull, error::BoxDynError};
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Currency {
#[default]
Usd,
Dop,
Eur,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, PartialOrd)]
pub struct Money {
pub amount: f64,
pub currency: Currency,
}
impl Display for Money {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let number_formatter = NumberFormat::new();
let amount_fmted = number_formatter.format(".2f", self.amount);
match self.currency {
Currency::Usd => write!(f, "US${}", amount_fmted),
Currency::Dop => write!(f, "RD${}", amount_fmted),
Currency::Eur => write!(f, "EUR€{}", amount_fmted)
}
}
}
impl sqlx::Encode<'_, Postgres> for Currency {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let encoded_value = bincode::serialize(self).unwrap();
<Vec<u8> as sqlx::Encode<Postgres>>::encode(encoded_value, buf)
}
}
impl sqlx::Decode<'_, Postgres> for Currency {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_bytes()?;
match bincode::deserialize(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(error),
}
}
}
impl sqlx::Type<Postgres> for Currency {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("bytea")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}
impl sqlx::Encode<'_, Postgres> for Money {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let encoded_value = bincode::serialize(self).unwrap();
<Vec<u8> as sqlx::Encode<Postgres>>::encode(encoded_value, buf)
}
}
impl sqlx::Decode<'_, Postgres> for Money {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_bytes()?;
match bincode::deserialize(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(error),
}
}
}
impl sqlx::Type<Postgres> for Money {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("bytea")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

View File

@ -1,9 +1,9 @@
use std::fmt::Display;
use serde::{Serialize, Deserialize};
use sqlx::{Postgres, postgres::{PgArgumentBuffer, PgValueRef, PgTypeInfo}, encode::IsNull, error::BoxDynError};
use uuid::Uuid;
use super::money::Money;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd, Default)]
pub struct PropertyDetails {
@ -20,14 +20,23 @@ pub struct PropertyDetails {
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub enum ListingType {
Rent(Money),
Sale(Money),
Rent(f64),
Sale(f64),
/// Sale first, Rent Second
Both(Money, Money),
Both(f64, f64),
}
impl Default for ListingType {
fn default() -> Self {
Self::Sale(Money::default())
Self::Sale(0.0)
}
}
impl Display for ListingType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ListingType::Rent(amount) => write!(f, "rent {amount}"),
ListingType::Sale(amount) => write!(f, "sale {amount}"),
ListingType::Both(sale_amount, rent_amount) => write!(f, "both {sale_amount} {rent_amount}"),
}
}
}
@ -69,24 +78,24 @@ impl sqlx::Type<Postgres> for Photos {
impl sqlx::Encode<'_, Postgres> for ListingType {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let encoded_value = bincode::serialize(self).unwrap();
<Vec<u8> as sqlx::Encode<Postgres>>::encode(encoded_value, buf)
let encoded_value = serde_json::to_string(self).unwrap();
<&str as sqlx::Encode<Postgres>>::encode(encoded_value.as_str(), buf)
}
}
impl sqlx::Decode<'_, Postgres> for ListingType {
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
let column = value.as_bytes()?;
match bincode::deserialize(column) {
Ok(listing_state) => Ok(listing_state),
Err(error) => Err(error),
let column = value.as_str()?;
match serde_json::from_str(column) {
Ok(val) => Ok(val),
Err(error) => Err(Box::new(error)),
}
}
}
impl sqlx::Type<Postgres> for ListingType {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("bytea")
PgTypeInfo::with_name("VARCHAR")
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {

0
src/dto/joiners/mod.rs Normal file
View File

View File

@ -1,3 +1,4 @@
pub mod property;
pub mod agent;
pub mod payload;
pub mod payload;
pub mod joiners;

View File

@ -1,4 +1,5 @@
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use crate::domain::{agent::Agent, contact_info::ContactInformation};
@ -10,12 +11,16 @@ pub struct AgentWithContactInfo {
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub struct NewAgentPayload {
#[serde(rename = "fullName")]
pub full_name: String,
#[serde(rename = "phoneNumber")]
pub phone_number: String,
// Optional fields
pub email: Option<String>,
#[serde(rename = "profilePictureUrl")]
pub profile_picture_url: Option<String>,
#[serde(rename = "defaultMessage")]
pub default_message: Option<String>,
}
impl From<NewAgentPayload> for AgentWithContactInfo {
@ -34,3 +39,36 @@ impl From<NewAgentPayload> for AgentWithContactInfo {
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub struct UpdateAgentPayload {
pub id: Uuid,
#[serde(rename = "phoneNumber")]
pub phone_number: Option<String>,
pub email: Option<String>,
#[serde(rename = "profilePictureUrl")]
pub profile_picture_url: Option<String>,
#[serde(rename = "defaultMessage")]
pub default_message: Option<String>,
}
impl UpdateAgentPayload {
pub fn update_contact_info(self, contact_info: &mut ContactInformation) {
match self.phone_number {
Some(phone_number) => contact_info.phone_number = phone_number,
None => {},
};
match self.email {
Some(_) => contact_info.email = self.email,
None => {},
};
match self.profile_picture_url {
Some(_) => contact_info.profile_picture_url = self.profile_picture_url,
None => {},
};
match self.default_message {
Some(_) => contact_info.default_message = self.default_message,
None => {},
};
}
}

View File

@ -1,7 +1,8 @@
use chrono::Utc;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::domain::{property_details::{ListingType, Photos, PropertyDetails}, property::Property};
use crate::domain::{property_details::{ListingType, Photos, PropertyDetails}, property::{Property, ListingState}};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub struct PropertyWithDetails {
@ -39,4 +40,60 @@ impl From<NewPropertyPayload> for PropertyWithDetails {
},
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
pub struct UpdateListingPayload {
#[serde(rename = "propertyId")]
pub property_id: Uuid,
pub title: Option<String>,
pub description: Option<String>,
pub meters: Option<f32>,
#[serde(rename = "listingType")]
pub listing_type: Option<ListingType>,
#[serde(rename = "photoUrls")]
pub photo_urls: Option<Photos>,
#[serde(rename = "locationId")]
pub location_id: Option<Uuid>,
#[serde(rename = "agentId")]
pub agent_id: Option<Uuid>,
pub state: Option<ListingState>,
}
impl UpdateListingPayload {
pub fn update_listing(self, property: &mut Property, details: &mut PropertyDetails) {
match self.title {
Some(title) => property.title = title,
None => {},
};
match self.description {
Some(description) => property.description = description,
None => {},
};
match self.meters {
Some(meters) => details.meters = meters,
None => {},
};
match self.listing_type {
Some(listing_type) => details.listing_type = listing_type,
None => {},
};
match self.photo_urls {
Some(photo_urls) => details.photo_urls = photo_urls,
None => {},
};
match self.location_id {
Some(location_id) => details.location_id = location_id,
None => {},
};
match self.agent_id {
Some(agent_id) => property.agent_id = agent_id,
None => {},
};
match self.state {
Some(state) => property.state = state,
None => {},
};
property.last_updated = Utc::now();
}
}