diff --git a/custom-pallets/create-department/src/extras.rs b/custom-pallets/create-department/src/extras.rs new file mode 100644 index 0000000..82b0b29 --- /dev/null +++ b/custom-pallets/create-department/src/extras.rs @@ -0,0 +1,14 @@ +use super::*; + +impl Pallet { + pub fn check_member_is_admin(who: T::AccountId, department_id: DepartmentId) -> DispatchResult { + match >::get(department_id) { + Some(department) => { + let admin = department.department_admin; + ensure!(admin == who, Error::::NotAdmin); + }, + None => Err(Error::::DepartmentDontExists)?, + } + Ok(()) + } +} diff --git a/custom-pallets/create-department/src/lib.rs b/custom-pallets/create-department/src/lib.rs index 202c17d..b208e8a 100644 --- a/custom-pallets/create-department/src/lib.rs +++ b/custom-pallets/create-department/src/lib.rs @@ -59,10 +59,12 @@ mod tests; mod benchmarking; pub mod weights; pub use weights::*; +pub mod extras; pub mod types; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; pub use types::{DepartmentDetails, FIRST_DEPARTMENT_ID}; - type DepartmentId = u64; use pallet_support::{ ensure_content_is_valid, new_who_and_when, remove_from_vec, Content, WhoAndWhen, WhoAndWhenOf, @@ -73,8 +75,6 @@ use pallet_support::{ pub mod pallet { // Import various useful types required by all FRAME pallets. use super::*; - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; // The `Pallet` struct serves as a placeholder to implement traits, methods and dispatchables // (`Call`s) in this pallet. @@ -135,6 +135,8 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { DepartmentCreated { account: T::AccountId, department_id: DepartmentId }, + MemberAdded { new_member: T::AccountId, department_id: DepartmentId }, + MemberRemoved { remove_member: T::AccountId, department_id: DepartmentId }, } /// Errors that can be returned by this pallet. @@ -154,6 +156,9 @@ pub mod pallet { DepartmentDontExists, NotAdmin, AccountAlreadyExits, + AlreadyMember, + NotMember, + NoAccounts, } /// The pallet's dispatchable functions ([`Call`]s). @@ -197,36 +202,81 @@ pub mod pallet { /// Add member to department #[pallet::call_index(1)] #[pallet::weight(0)] - pub fn add_members_to_department( + pub fn add_member_to_department( origin: OriginFor, department_id: DepartmentId, - account: T::AccountId, + new_member: T::AccountId, ) -> DispatchResult { let who = ensure_signed(origin)?; - match >::get(department_id) { - Some(department) => { - let admin = department.department_admin; - ensure!(admin == who, Error::::NotAdmin); + Self::check_member_is_admin(who, department_id)?; + + match >::get(department_id) { + Some(mut accounts) => match accounts.binary_search(&new_member) { + Ok(_) => Err(Error::::AlreadyMember)?, + Err(index) => { + accounts.insert(index, new_member.clone()); + >::mutate(&department_id, |account_option| { + *account_option = Some(accounts); + }); + Self::deposit_event(Event::MemberAdded { new_member, department_id }); + }, + }, + None => { + >::insert(department_id, vec![new_member]); }, - None => Err(Error::::DepartmentDontExists)?, } - match >::get(department_id) { - Some(mut old_accounts) => { - // Check if account already exists in old_accounts - if old_accounts.contains(&account) { - Err(Error::::AccountAlreadyExits)? - } + Ok(()) + } + + #[pallet::call_index(2)] + #[pallet::weight(0)] + pub fn remove_member_from_department( + origin: OriginFor, + department_id: DepartmentId, + remove_member: T::AccountId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; - old_accounts.push(account); + Self::check_member_is_admin(who, department_id)?; - >::mutate(&department_id, |account_option| { - *account_option = Some(old_accounts); - }) + match >::get(department_id) { + Some(mut accounts) => match accounts.binary_search(&remove_member) { + Ok(index) => { + accounts.remove(index); + >::mutate(&department_id, |account_option| { + *account_option = Some(accounts); + }); + Self::deposit_event(Event::MemberRemoved { remove_member, department_id }); + }, + Err(_) => Err(Error::::NotMember)?, }, - None => { - >::insert(department_id, vec![account]); + None => Err(Error::::NoAccounts)?, + } + + Ok(()) + } + + #[pallet::call_index(3)] + #[pallet::weight(0)] + pub fn change_the_admin( + origin: OriginFor, + department_id: DepartmentId, + new_admin: T::AccountId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + match >::get(department_id) { + Some(mut department) => { + let admin = department.department_admin; + ensure!(admin == who, Error::::NotAdmin); + department.department_admin = new_admin; + + >::mutate(&department_id, |department_option| { + *department_option = Some(department); + }); }, + None => Err(Error::::DepartmentDontExists)?, } Ok(())