Basic rest implementation for connecting user to sales-person
This commit is contained in:
parent
e3ec694876
commit
bf94ec33de
10 changed files with 181 additions and 1 deletions
|
|
@ -26,6 +26,7 @@ pub trait PermissionDao {
|
||||||
|
|
||||||
async fn create_user(&self, user: &UserEntity, process: &str) -> Result<(), DaoError>;
|
async fn create_user(&self, user: &UserEntity, process: &str) -> Result<(), DaoError>;
|
||||||
async fn all_users(&self) -> Result<Arc<[UserEntity]>, DaoError>;
|
async fn all_users(&self) -> Result<Arc<[UserEntity]>, DaoError>;
|
||||||
|
async fn find_user(&self, username: &str) -> Result<Option<UserEntity>, DaoError>;
|
||||||
async fn delete_user(&self, username: &str) -> Result<(), DaoError>;
|
async fn delete_user(&self, username: &str) -> Result<(), DaoError>;
|
||||||
|
|
||||||
async fn create_role(&self, role: &RoleEntity, process: &str) -> Result<(), DaoError>;
|
async fn create_role(&self, role: &RoleEntity, process: &str) -> Result<(), DaoError>;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ pub struct SalesPersonEntity {
|
||||||
pub trait SalesPersonDao {
|
pub trait SalesPersonDao {
|
||||||
async fn all(&self) -> Result<Arc<[SalesPersonEntity]>, DaoError>;
|
async fn all(&self) -> Result<Arc<[SalesPersonEntity]>, DaoError>;
|
||||||
async fn find_by_id(&self, id: Uuid) -> Result<Option<SalesPersonEntity>, DaoError>;
|
async fn find_by_id(&self, id: Uuid) -> Result<Option<SalesPersonEntity>, DaoError>;
|
||||||
|
async fn find_by_user(&self, user_id: &str) -> Result<Option<SalesPersonEntity>, DaoError>;
|
||||||
async fn create(&self, entity: &SalesPersonEntity, process: &str) -> Result<(), DaoError>;
|
async fn create(&self, entity: &SalesPersonEntity, process: &str) -> Result<(), DaoError>;
|
||||||
async fn update(&self, entity: &SalesPersonEntity, process: &str) -> Result<(), DaoError>;
|
async fn update(&self, entity: &SalesPersonEntity, process: &str) -> Result<(), DaoError>;
|
||||||
|
async fn get_assigned_user(&self, sales_person_id: Uuid) -> Result<Option<Arc<str>>, DaoError>;
|
||||||
|
async fn assign_to_user(&self, sales_person_id: Uuid, user_id: &str, process: &str) -> Result<(), DaoError>;
|
||||||
|
async fn discard_assigned_user(&self, sales_person_id: Uuid) -> Result<(), DaoError>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,18 @@ impl dao::PermissionDao for PermissionDaoImpl {
|
||||||
.map_db_error()?;
|
.map_db_error()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
async fn find_user(&self, username: &str) -> Result<Option<dao::UserEntity>, DaoError> {
|
||||||
|
let result = query!(
|
||||||
|
r"SELECT name FROM user WHERE name = ?",
|
||||||
|
username
|
||||||
|
)
|
||||||
|
.fetch_optional(self.pool.as_ref())
|
||||||
|
.await
|
||||||
|
.map_db_error()?;
|
||||||
|
Ok(result.map(|row| dao::UserEntity {
|
||||||
|
name: row.name.clone().into(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
async fn create_role(&self, role: &dao::RoleEntity, process: &str) -> Result<(), DaoError> {
|
async fn create_role(&self, role: &dao::RoleEntity, process: &str) -> Result<(), DaoError> {
|
||||||
let name = role.name.as_ref();
|
let name = role.name.as_ref();
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,21 @@ impl SalesPersonDao for SalesPersonDaoImpl {
|
||||||
.map(SalesPersonEntity::try_from)
|
.map(SalesPersonEntity::try_from)
|
||||||
.transpose()?)
|
.transpose()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn find_by_user(&self, user_id: &str) -> Result<Option<SalesPersonEntity>, DaoError> {
|
||||||
|
Ok(query_as!(
|
||||||
|
SalesPersonDb,
|
||||||
|
"SELECT sp.id, sp.name, sp.inactive, sp.deleted, sp.update_version FROM sales_person sp JOIN sales_person_user spu ON sp.id = spu.sales_person_id WHERE spu.user_id = ?",
|
||||||
|
user_id
|
||||||
|
)
|
||||||
|
.fetch_optional(self.pool.as_ref())
|
||||||
|
.await
|
||||||
|
.map_db_error()?
|
||||||
|
.as_ref()
|
||||||
|
.map(SalesPersonEntity::try_from)
|
||||||
|
.transpose()?)
|
||||||
|
}
|
||||||
|
|
||||||
async fn create(&self, entity: &SalesPersonEntity, process: &str) -> Result<(), DaoError> {
|
async fn create(&self, entity: &SalesPersonEntity, process: &str) -> Result<(), DaoError> {
|
||||||
let id = entity.id.as_bytes().to_vec();
|
let id = entity.id.as_bytes().to_vec();
|
||||||
let version = entity.version.as_bytes().to_vec();
|
let version = entity.version.as_bytes().to_vec();
|
||||||
|
|
@ -96,4 +111,34 @@ impl SalesPersonDao for SalesPersonDaoImpl {
|
||||||
.map_db_error()?;
|
.map_db_error()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn assign_to_user(&self, sales_person_id: Uuid, user_id: &str, process: &str) -> Result<(), DaoError> {
|
||||||
|
let sales_person_id = sales_person_id.as_bytes().to_vec();
|
||||||
|
query!("INSERT INTO sales_person_user (user_id, sales_person_id, update_process) VALUES (?, ?, ?)", user_id, sales_person_id, process)
|
||||||
|
.execute(self.pool.as_ref())
|
||||||
|
.await
|
||||||
|
.map_db_error()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn discard_assigned_user(&self, sales_person_id: Uuid) -> Result<(), DaoError> {
|
||||||
|
let sales_person_id = sales_person_id.as_bytes().to_vec();
|
||||||
|
query!("DELETE FROM sales_person_user WHERE sales_person_id = ?", sales_person_id)
|
||||||
|
.execute(self.pool.as_ref())
|
||||||
|
.await
|
||||||
|
.map_db_error()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_assigned_user(&self, sales_person_id: Uuid) -> Result<Option<Arc<str>>, DaoError> {
|
||||||
|
let sales_person_id = sales_person_id.as_bytes().to_vec();
|
||||||
|
Ok(query!(
|
||||||
|
"SELECT user_id FROM sales_person_user WHERE sales_person_id = ?",
|
||||||
|
sales_person_id
|
||||||
|
)
|
||||||
|
.fetch_optional(self.pool.as_ref())
|
||||||
|
.await
|
||||||
|
.map_db_error()?
|
||||||
|
.map(|result| result.user_id.into()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,15 @@ CREATE TABLE sales_person (
|
||||||
update_process TEXT NOT NULL,
|
update_process TEXT NOT NULL,
|
||||||
update_version blob(16) NOT NULL
|
update_version blob(16) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE sales_person_user (
|
||||||
|
sales_person_id blob(16) NOT NULL,
|
||||||
|
user_id TEXT NOT NULL,
|
||||||
|
update_timestamp TEXT,
|
||||||
|
update_process TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (sales_person_id, user_id),
|
||||||
|
UNIQUE(sales_person_id),
|
||||||
|
UNIQUE(user_id),
|
||||||
|
FOREIGN KEY (sales_person_id) REFERENCES sales_person(id)
|
||||||
|
FOREIGN KEY (user_id) REFERENCES user(name)
|
||||||
|
)
|
||||||
|
|
@ -55,6 +55,9 @@ pub fn generate_route<RestState: RestStateDef>() -> Router<RestState> {
|
||||||
.route("/", post(create_sales_person::<RestState>))
|
.route("/", post(create_sales_person::<RestState>))
|
||||||
.route("/:id", put(update_sales_person::<RestState>))
|
.route("/:id", put(update_sales_person::<RestState>))
|
||||||
.route("/:id", delete(delete_sales_person::<RestState>))
|
.route("/:id", delete(delete_sales_person::<RestState>))
|
||||||
|
.route("/:id/user", get(get_sales_person_user::<RestState>))
|
||||||
|
.route("/:id/user", post(set_sales_person_user::<RestState>))
|
||||||
|
.route("/:id/user", delete(delete_sales_person_user::<RestState>))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_sales_persons<RestState: RestStateDef>(
|
pub async fn get_all_sales_persons<RestState: RestStateDef>(
|
||||||
|
|
@ -158,3 +161,56 @@ pub async fn delete_sales_person<RestState: RestStateDef>(
|
||||||
.await,
|
.await,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn get_sales_person_user<RestState: RestStateDef>(
|
||||||
|
rest_state: State<RestState>,
|
||||||
|
Path(sales_person_id): Path<Uuid>,
|
||||||
|
) -> Response {
|
||||||
|
error_handler(
|
||||||
|
(async {
|
||||||
|
let user = rest_state
|
||||||
|
.sales_person_service()
|
||||||
|
.get_assigned_user(sales_person_id, ())
|
||||||
|
.await?;
|
||||||
|
Ok(Response::builder()
|
||||||
|
.status(200)
|
||||||
|
.body(Body::new(serde_json::to_string(&user).unwrap()))
|
||||||
|
.unwrap())
|
||||||
|
})
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_sales_person_user<RestState: RestStateDef>(
|
||||||
|
rest_state: State<RestState>,
|
||||||
|
Path(sales_person_id): Path<Uuid>,
|
||||||
|
Json(user): Json<Arc<str>>,
|
||||||
|
) -> Response {
|
||||||
|
error_handler(
|
||||||
|
(async {
|
||||||
|
rest_state
|
||||||
|
.sales_person_service()
|
||||||
|
.set_user(sales_person_id, user.into(), ())
|
||||||
|
.await?;
|
||||||
|
Ok(Response::builder().status(204).body(Body::empty()).unwrap())
|
||||||
|
})
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_sales_person_user<RestState: RestStateDef>(
|
||||||
|
rest_state: State<RestState>,
|
||||||
|
Path(sales_person_id): Path<Uuid>,
|
||||||
|
) -> Response {
|
||||||
|
error_handler(
|
||||||
|
(async {
|
||||||
|
rest_state
|
||||||
|
.sales_person_service()
|
||||||
|
.set_user(sales_person_id, None, ())
|
||||||
|
.await?;
|
||||||
|
Ok(Response::builder().status(204).body(Body::empty()).unwrap())
|
||||||
|
})
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -53,6 +53,7 @@ pub trait PermissionService {
|
||||||
) -> Result<(), ServiceError>;
|
) -> Result<(), ServiceError>;
|
||||||
|
|
||||||
async fn create_user(&self, user: &str, context: Self::Context) -> Result<(), ServiceError>;
|
async fn create_user(&self, user: &str, context: Self::Context) -> Result<(), ServiceError>;
|
||||||
|
async fn user_exists(&self, user: &str, context: Self::Context) -> Result<bool, ServiceError>;
|
||||||
async fn delete_user(&self, user: &str, context: Self::Context) -> Result<(), ServiceError>;
|
async fn delete_user(&self, user: &str, context: Self::Context) -> Result<(), ServiceError>;
|
||||||
async fn get_all_users(&self, context: Self::Context) -> Result<Arc<[User]>, ServiceError>;
|
async fn get_all_users(&self, context: Self::Context) -> Result<Arc<[User]>, ServiceError>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,4 +56,15 @@ pub trait SalesPersonService {
|
||||||
context: Self::Context,
|
context: Self::Context,
|
||||||
) -> Result<SalesPerson, ServiceError>;
|
) -> Result<SalesPerson, ServiceError>;
|
||||||
async fn delete(&self, id: Uuid, context: Self::Context) -> Result<(), ServiceError>;
|
async fn delete(&self, id: Uuid, context: Self::Context) -> Result<(), ServiceError>;
|
||||||
|
async fn get_assigned_user(
|
||||||
|
&self,
|
||||||
|
sales_person_id: Uuid,
|
||||||
|
context: Self::Context,
|
||||||
|
) -> Result<Option<Arc<str>>, ServiceError>;
|
||||||
|
async fn set_user(
|
||||||
|
&self,
|
||||||
|
sales_person_id: Uuid,
|
||||||
|
user_id: Option<Arc<str>>,
|
||||||
|
context: Self::Context,
|
||||||
|
) -> Result<(), ServiceError>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use service::ServiceError;
|
||||||
|
|
||||||
pub struct PermissionServiceImpl<PermissionDao, UserService>
|
pub struct PermissionServiceImpl<PermissionDao, UserService>
|
||||||
where
|
where
|
||||||
|
|
@ -75,6 +76,11 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn user_exists(&self, user: &str, context: Self::Context) -> Result<bool, ServiceError> {
|
||||||
|
self.check_permission("hr", context).await?;
|
||||||
|
Ok(self.permission_dao.find_user(user).await.map(|x| x.is_some())?)
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_all_users(
|
async fn get_all_users(
|
||||||
&self,
|
&self,
|
||||||
context: Self::Context,
|
context: Self::Context,
|
||||||
|
|
|
||||||
|
|
@ -188,4 +188,36 @@ where
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_assigned_user(
|
||||||
|
&self,
|
||||||
|
sales_person_id: Uuid,
|
||||||
|
context: Self::Context,
|
||||||
|
) -> Result<Option<Arc<str>>, ServiceError> {
|
||||||
|
self.permission_service
|
||||||
|
.check_permission("hr", context)
|
||||||
|
.await?;
|
||||||
|
Ok(self.sales_person_dao.get_assigned_user(sales_person_id).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_user(
|
||||||
|
&self,
|
||||||
|
sales_person_id: Uuid,
|
||||||
|
user_id: Option<Arc<str>>,
|
||||||
|
context: Self::Context,
|
||||||
|
) -> Result<(), ServiceError> {
|
||||||
|
self.permission_service
|
||||||
|
.check_permission("hr", context)
|
||||||
|
.await?;
|
||||||
|
self.sales_person_dao
|
||||||
|
.discard_assigned_user(sales_person_id)
|
||||||
|
.await?;
|
||||||
|
if let Some(user) = user_id {
|
||||||
|
self.sales_person_dao
|
||||||
|
.assign_to_user(sales_person_id, user.as_ref(), SALES_PERSON_SERVICE_PROCESS)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue