From d3a93dafe854af0fad85127ca3413c1df169019d Mon Sep 17 00:00:00 2001 From: didiermis Date: Wed, 9 Nov 2022 15:20:28 -0600 Subject: [PATCH 1/5] Update do_delete_project function in order to delete all the stored information related to a project id --- pallets/fund-admin/src/functions.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pallets/fund-admin/src/functions.rs b/pallets/fund-admin/src/functions.rs index ba27d4a4..e7b462ed 100644 --- a/pallets/fund-admin/src/functions.rs +++ b/pallets/fund-admin/src/functions.rs @@ -250,6 +250,35 @@ impl Pallet { // Delete from UsersByProject storagemap >::remove(project_id); + // Delete expenditures from ExpendituresInfo storagemap + let expenditures_by_project = Self::expenditures_by_project(project_id).iter().cloned().collect::>(); + for expenditure_id in expenditures_by_project { + >::remove(expenditure_id); + } + + // Deletes all expenditures from ExpendituresByProject storagemap + >::remove(project_id); + + let drawdowns_by_project = Self::drawdowns_by_project(project_id).iter().cloned().collect::>(); + for drawdown_id in drawdowns_by_project { + // Delete transactions from TransactionsInfo storagemap + let transactions_by_drawdown = Self::transactions_by_drawdown(project_id, drawdown_id).iter().cloned().collect::>(); + for transaction_id in transactions_by_drawdown { + >::remove(transaction_id); + } + + // Deletes all transactions from TransactionsByDrawdown storagemap + >::remove(project_id, drawdown_id); + + // Delete drawdown from DrawdownsInfo storagemap + >::remove(drawdown_id); + + } + + // Deletes all drawdowns from DrawdownsByProject storagemap + >::remove(project_id); + + //Event Self::deposit_event(Event::ProjectDeleted(project_id)); Ok(()) From d1d6041630a2c01f836c874c82ce302a7822f1f2 Mon Sep 17 00:00:00 2001 From: didiermis Date: Wed, 9 Nov 2022 15:45:27 -0600 Subject: [PATCH 2/5] Update internal documentation --- pallets/fund-admin/src/functions.rs | 1 - pallets/fund-admin/src/lib.rs | 106 ++++++++++++++++++++++++---- 2 files changed, 93 insertions(+), 14 deletions(-) diff --git a/pallets/fund-admin/src/functions.rs b/pallets/fund-admin/src/functions.rs index e7b462ed..ded55f26 100644 --- a/pallets/fund-admin/src/functions.rs +++ b/pallets/fund-admin/src/functions.rs @@ -278,7 +278,6 @@ impl Pallet { // Deletes all drawdowns from DrawdownsByProject storagemap >::remove(project_id); - //Event Self::deposit_event(Event::ProjectDeleted(project_id)); Ok(()) diff --git a/pallets/fund-admin/src/lib.rs b/pallets/fund-admin/src/lib.rs index 421a5f2b..b193a38c 100644 --- a/pallets/fund-admin/src/lib.rs +++ b/pallets/fund-admin/src/lib.rs @@ -431,6 +431,8 @@ pub mod pallet { /// - This function can only be called using the sudo pallet /// - This function is used to add the first administrator to the site /// - If the user is already registered, the function will return an error: UserAlreadyRegistered + /// - This function grants administator permissions to the user from the rbac pallet + /// - Administator role have global scope permissions #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(10))] pub fn sudo_add_administrator( @@ -453,6 +455,7 @@ pub mod pallet { /// - This function can only be called using the sudo pallet /// - This function is used to remove any administrator from the site /// - If the user is not registered, the function will return an error: UserNotFound + /// - This function removes administator permissions of the user from the rbac pallet /// /// # Note: /// WARNING: Administrators can remove themselves from the site, @@ -471,7 +474,7 @@ pub mod pallet { // U S E R S // -------------------------------------------------------------------------------------------- - /// This extrinsic is used to register, update, or delete a user account + /// This extrinsic is used to create, update, or delete a user account /// /// # Parameters: /// - origin: The administrator account @@ -490,13 +493,15 @@ pub mod pallet { /// - This function can only be called by an administrator account /// - Multiple users can be registered, updated, or deleted at the same time, but /// the user account must be unique. Multiple actions over the same user account - /// in the same call will result in an unexpected behavior. + /// in the same call, it could result in an unexpected behavior. /// - If the user is already registered, the function will return an error: UserAlreadyRegistered /// - If the user is not registered, the function will return an error: UserNotFound /// /// # Note: /// WARNING: It is possible to register, update, or delete administators accounts using this extrinsic, /// but administrators can not delete themselves. + /// WARNING: This function only registers, updates, or deletes users from the site. + /// DOESN'T grant or remove permissions from the rbac pallet. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn users( @@ -578,7 +583,11 @@ pub mod pallet { /// - For expenditures, apart from the expenditure id, naics code & jopbs multiplier, ALL parameters are required because for this /// flow, the expenditures are always created. The naics code & the jobs multiplier /// can be added later by the administrator. - #[transactional] + /// - Creating a project will automatically create a scope for the project. + /// + /// # Note: + /// WARNING: If users are provided, the function will assign the users to the project, granting them + /// permissions in the rbac pallet. #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn projects_create_project( origin: OriginFor, @@ -608,6 +617,30 @@ pub mod pallet { Self::do_create_project(who, title, description, image, address, creation_date, completion_date, expenditures, users) } + /// Edits a project. + /// + /// # Parameters: + /// - origin: The administrator account + /// - project_id: The selected project id that will be edited + /// - title: The title of the project to be edited + /// - description: The description of the project to be edited + /// - image: The image of the project to be edited + /// - address: The address of the project to be edited + /// - creation_date: The creation date of the project to be edited + /// - completion_date: The completion date of the project to be edited + /// + /// # Considerations: + /// - This function can only be called by an administrator account + /// - ALL parameters are optional because depends on what is being edited + /// - The project id is required because it is the only way to identify the project + /// - The project id must be registered. If the project is not registered, + /// the function will return an error: ProjectNotFound + /// - It is not possible to edit the expenditures or the users assigned to the project + /// through this function. For that, the administrator must use the extrinsics: + /// * expenditures + /// * projects_assign_user + /// - Project can only be edited in the Started status + /// - Completion date must be greater than creation date #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn projects_edit_project( @@ -625,6 +658,21 @@ pub mod pallet { Self::do_edit_project(who, project_id, title, description, image, address, creation_date, completion_date) } + /// Deletes a project. + /// + /// # Parameters: + /// - origin: The administrator account + /// - project_id: The selected project id that will be deleted + /// + /// # Considerations: + /// - This function can only be called by an administrator account + /// - The project id is required because it is the only way to identify the project + /// - The project id must be registered. If the project is not registered, + /// the function will return an error: ProjectNotFound + /// + /// # Note: + /// - WARNING: Deleting a project will delete ALL stored information associated with the project. + /// BE CAREFUL. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn projects_delete_project( @@ -636,7 +684,40 @@ pub mod pallet { Self::do_delete_project(who, project_id) } - // Users: (user, role, assign action) + /// Assigns a user to a project. + /// + /// # Parameters: + /// - origin: The administrator account + /// - project_id: The selected project id where user will be assigned + /// - users: The users to be assigned to the project. This is a vector of tuples + /// where each entry is composed by: + /// * 0: The user account id + /// * 1: The user role + /// * 2: The AssignAction to be performed. (Assign or Unassign) + /// + /// # Considerations: + /// - This function can only be called by an administrator account + /// - This extrinsic allows multiple users to be assigned/unassigned at the same time. + /// - The project id is required because it is the only way to identify the project + /// - This extrinsic is used for both assigning and unassigning users to a project + /// depending on the AssignAction. + /// - After a user is assigned to a project, the user will be able to perform actions + /// in the project depending on the role assigned to the user. + /// - After a user is unassigned from a project, the user will not be able to perform actions + /// in the project anymore. + /// - If the user is already assigned to the project, the function will return an erro. + /// + /// # Note: + /// - WARNING: ALL provided users needs to be registered in the site. If any of the users + /// is not registered, the function will return an error. + /// - Assigning or unassigning a user to a project will add or remove permissions to the user + /// from the RBAC pallet. + /// - Warning: Cannot assign a user to a project with a different role than the one they + /// have in UsersInfo. If the user has a different role, the function will return an error. + /// - Warning: Cannot unassign a user from a project with a different role than the one they + /// have in UsersInfo. If the user has a different role, the function will return an error. + /// - Warning: Do not perfom multiple actions over the same user in the same call, it could + /// result in an unexpected behavior. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn projects_assign_user( @@ -655,21 +736,20 @@ pub mod pallet { // B U D G E T E X P E N D I T U R E // -------------------------------------------------------------------------------------------- - - // Expenditures: (name, type, amount, naics code, jobs multiplier, CUDAction, expenditure_id) + /// This extrinsic is used to create, update or delete expenditures. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn expenditures( origin: OriginFor, project_id: [u8;32], expenditures: BoundedVec<( - Option>, - Option, - Option, - Option>, - Option, - CUDAction, - Option<[u8;32]>, + Option>, // name + Option, // type + Option, // amount + Option>, // naics code + Option, // jobs multiplier + CUDAction, // action + Option<[u8;32]>, // expenditure_id ), T::MaxRegistrationsAtTime>, ) -> DispatchResult { let who = ensure_signed(origin)?; // origin need to be an admin From 9b9838f0e233f9459001ff8b632cfd1edcd8a25e Mon Sep 17 00:00:00 2001 From: didiermis Date: Thu, 10 Nov 2022 10:41:56 -0600 Subject: [PATCH 3/5] Split the rejection drawdown flow depending if the drawdown type is EB5 or bulk upload (Construction Loan & Developer Equity). Fix #255 --- pallets/fund-admin/src/functions.rs | 87 ++++++++++++++++++----------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/pallets/fund-admin/src/functions.rs b/pallets/fund-admin/src/functions.rs index ded55f26..edda1254 100644 --- a/pallets/fund-admin/src/functions.rs +++ b/pallets/fund-admin/src/functions.rs @@ -975,51 +975,72 @@ impl Pallet { // Ensure drawdown is in submitted status ensure!(drawdown_data.status == DrawdownStatus::Submitted, Error::::DrawdownIsNotInSubmittedStatus); - // Ensure drawdown has transactions if drawdown type == EB5 - if drawdown_data.drawdown_type == DrawdownType::EB5 { - ensure!(>::contains_key(project_id, drawdown_id), Error::::DrawdownHasNoTransactions); - } - - // Get drawdown transactions - let drawdown_transactions = TransactionsByDrawdown::::try_get(project_id, drawdown_id).map_err(|_| Error::::DrawdownNotFound)?; + // Match drawdown type in order to update transactions status + match drawdown_data.drawdown_type { + DrawdownType::EB5 => { + // Ensure drawdown has transactions + ensure!(>::contains_key(project_id, drawdown_id), Error::::DrawdownHasNoTransactions); - // Update each transaction status to rejected - for transaction_id in drawdown_transactions { - // Get transaction data - let transaction_data = TransactionsInfo::::get(transaction_id).ok_or(Error::::TransactionNotFound)?; + // Get drawdown transactions + let drawdown_transactions = TransactionsByDrawdown::::try_get(project_id, drawdown_id).map_err(|_| Error::::DrawdownNotFound)?; - // Ensure transaction is in submitted status - ensure!(transaction_data.status == TransactionStatus::Submitted, Error::::TransactionIsNotInSubmittedStatus); + // Update each transaction status to rejected + for transaction_id in drawdown_transactions { + // Get transaction data + let transaction_data = TransactionsInfo::::get(transaction_id).ok_or(Error::::TransactionNotFound)?; - // Update transaction status to rejected - >::try_mutate::<_,_,DispatchError,_>(transaction_id, |transaction_data| { - let transaction_data = transaction_data.as_mut().ok_or(Error::::TransactionNotFound)?; - transaction_data.status = TransactionStatus::Rejected; - Ok(()) - })?; - } + // Ensure transaction is in submitted status + ensure!(transaction_data.status == TransactionStatus::Submitted, Error::::TransactionIsNotInSubmittedStatus); - // Match drawdown type in order to provide a feedback - match drawdown_data.drawdown_type { - DrawdownType::EB5 => { - // Ensure transactions_feedback is some + // Update transaction status to rejected + >::try_mutate::<_,_,DispatchError,_>(transaction_id, |transaction_data| { + let transaction_data = transaction_data.as_mut().ok_or(Error::::TransactionNotFound)?; + transaction_data.status = TransactionStatus::Rejected; + Ok(()) + })?; + } + + // Ensure transactions feedback is provided let mod_transactions_feedback = transactions_feedback.ok_or(Error::::EB5MissingFeedback)?; - for (transaction_id, field_description) in mod_transactions_feedback { + for (transaction_id, feedback) in mod_transactions_feedback { // Update transaction feedback - >::try_mutate::<_,_,DispatchError,_>(transaction_id, |transaction_info| { - let transaction_data = transaction_info.as_mut().ok_or(Error::::TransactionNotFound)?; - transaction_data.feedback = Some(field_description); + >::try_mutate::<_,_,DispatchError,_>(transaction_id, |transaction_data| { + let transaction_data = transaction_data.as_mut().ok_or(Error::::TransactionNotFound)?; + transaction_data.feedback = Some(feedback); Ok(()) - }).map_err(|_| Error::::TransactionNotFound)?; + })?; } - + }, _ => { - // Ensure drawdown_feedback is some - let mod_drawdown_feedback = drawdown_feedback.clone().ok_or(Error::::NoFeedbackProvidedForBulkUpload)?; + // Construction Loan & Developer Equity drawdowns + // If drawdown has transactions, update each transaction status to rejected + if >::contains_key(project_id, drawdown_id) { + // Get drawdown transactions + let drawdown_transactions = TransactionsByDrawdown::::try_get(project_id, drawdown_id).map_err(|_| Error::::DrawdownNotFound)?; + + // Update each transaction status to rejected + for transaction_id in drawdown_transactions { + // Get transaction data + let transaction_data = TransactionsInfo::::get(transaction_id).ok_or(Error::::TransactionNotFound)?; + + // Ensure transaction is in submitted status + ensure!(transaction_data.status == TransactionStatus::Submitted, Error::::TransactionIsNotInSubmittedStatus); + + // Update transaction status to rejected + >::try_mutate::<_,_,DispatchError,_>(transaction_id, |transaction_data| { + let transaction_data = transaction_data.as_mut().ok_or(Error::::TransactionNotFound)?; + transaction_data.status = TransactionStatus::Rejected; + Ok(()) + })?; + } + } + + // Ensure drawdown feedback is provided + let mod_drawdown_feedback = drawdown_feedback.ok_or(Error::::NoFeedbackProvidedForBulkUpload)?; - // Update feedback for bulkupload. + // Update drawdown feedback >::try_mutate::<_,_,DispatchError,_>(drawdown_id, |drawdown_data| { let drawdown_data = drawdown_data.as_mut().ok_or(Error::::DrawdownNotFound)?; drawdown_data.feedback = Some(mod_drawdown_feedback[0].clone()); From a8e6999ed6937576b874584d9f8d70d5799b8d49 Mon Sep 17 00:00:00 2001 From: didiermis Date: Thu, 10 Nov 2022 10:53:39 -0600 Subject: [PATCH 4/5] Update internal documenttion. Fix #252, it also includes Fix #256 --- pallets/fund-admin/src/lib.rs | 207 ++++++++++++++++++++++++++-------- 1 file changed, 162 insertions(+), 45 deletions(-) diff --git a/pallets/fund-admin/src/lib.rs b/pallets/fund-admin/src/lib.rs index b193a38c..d9760cbb 100644 --- a/pallets/fund-admin/src/lib.rs +++ b/pallets/fund-admin/src/lib.rs @@ -737,6 +737,33 @@ pub mod pallet { // B U D G E T E X P E N D I T U R E // -------------------------------------------------------------------------------------------- /// This extrinsic is used to create, update or delete expenditures. + /// + /// # Parameters: + /// - origin: The administrator account + /// - project_id: The selected project id where the expenditures will be created/updated/deleted + /// - expenditures: The expenditures to be created/updated/deleted. This is a vector of tuples + /// where each entry is composed by: + /// * 0: The name of the expenditure + /// * 1: The expenditure type + /// * 2: The amount of the expenditure + /// * 3: The naics code of the expenditure + /// * 4: The jobs multiplier of the expenditure + /// * 5: The expenditure action to be performed. (Create, Update or Delete) + /// * 6: The expenditure id. This is only used when updating or deleting an expenditure. + /// + /// # Considerations: + /// - Naics code and jobs multiplier are always optional. + /// - This function can only be called by an administrator account + /// - This extrinsic allows multiple expenditures to be created/updated/deleted at the same time. + /// - The project id is required because it is the only way to identify the project + /// - Expentiture parameters are optional because depends on the action to be performed: + /// * **Create**: Name, Type & Amount are required. Nacis code & Jobs multiplier are optional. + /// * **Update**: Except for the expenditure id & action, all parameters are optional. + /// * **Delete**: Only the expenditure id & action is required. + /// - Multiple actions can be performed at the same time. For example, you can create a new + /// expenditure and update another one at the same time. + /// - Do not perform multiple actions over the same expenditure in the same call, it could + /// result in an unexpected behavior. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn expenditures( @@ -760,20 +787,39 @@ pub mod pallet { // T R A N S A C T I O N S & D R A W D O W N S // -------------------------------------------------------------------------------------------- - /// Create a transaction - /// - /// - `project_id`: The project id - /// - `drawdown_id`: The drawdown id - /// - `transactions`: The array of transactions as follows: - /// - `expenditure_id`: The expenditure id - /// - `amount`: The amount - /// - `documents`: The array of documents - /// - `CUDAction`: The action to perform (create, update, delete) - /// - `transaction_id`: The transaction id - /// Note that all parameters are optional because - /// it depends on the action to perform - /// - `submit`: Boolean to indicate if the drawdown is submitted or - /// saved as draft + /// This extrinsic is used to create, update or delete transactions. + /// Transactions status can be saved as draft or submitted. + /// + /// # Parameters: + /// - origin: The user account who is creating the transactions + /// - project_id: The selected project id where the transactions will be created + /// - drawdown_id: The selected drawdown id where the transactions will be created + /// - transactions: The transactions to be created/updated/deleted. This is a vector of tuples + /// where each entry is composed by: + /// * 0: The expenditure id where the transaction will be created + /// * 1: The transaction amount + /// * 2: Documents associated to the transaction + /// * 3: The transaction action to be performed. (Create, Update or Delete) + /// * 4: The transaction id. This is only used when updating or deleting a transaction. + /// - submit: If true, the transactions will be submitted. + /// If false, the transactions will be saved as draft. + /// + /// # Considerations: + /// - This function can only be called by a builder role account + /// - This extrinsic allows multiple transactions to be created/updated/deleted at the same time. + /// - The project id and drawdown id are required because are required for the reports. + /// - Transaction parameters are optional because depends on the action to be performed: + /// * **Create**: Expenditure id, Amount, Documents & Action are required. + /// * **Update**: Except for the transaction id & action, all parameters are optional. + /// * **Delete**: Only the transaction id & action is required. + /// - Multiple actions can be performed at the same time. For example, you can create a new + /// transaction and update another one at the same time. + /// - Do not perform multiple actions over the same transaction in the same call, it could + /// result in an unexpected behavior. + /// - If a drawdown is submitted, all transactions must be submitted too. If the drawdown do not contain + /// any transaction, it will be returned an error. + /// - After a drawdown is submitted, it can not be updated or deleted. + /// - After a drawdown is rejected, builders will use this extrinsic to update the transactions. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn submit_drawdown( @@ -820,11 +866,42 @@ pub mod pallet { } - /// Approve a drawdown + /// Approves a drawdown /// - /// - `origin`: The admin - /// - `project_id`: The project id - /// - `drawdown_id`: The drawdown id + /// # Parameters: + /// ### For EB5 drawdowns: + /// - origin: The administator account who is approving the drawdown + /// - project_id: The selected project id where the drawdown will be approved + /// - drawdown_id: The selected drawdown id to be approved + /// + /// ### For Construction Loan & Developer Equity (bulk uploads) drawdowns: + /// - origin: The administator account who is approving the drawdown + /// - project_id: The selected project id where the drawdown will be approved + /// - drawdown_id: The selected drawdown id to be approved. + /// - bulkupload: Optional bulkupload parameter. If true, the drawdown will be saved in a pseudo + /// draft status. If false, the drawdown will be approved directly. + /// - transactions: The transactions to be created/updated/deleted. This is a vector of tuples + /// where each entry is composed by: + /// * 0: The expenditure id where the transaction will be created + /// * 1: The transaction amount + /// * 2: Documents associated to the transaction + /// * 3: The transaction action to be performed. (Create, Update or Delete) + /// * 4: The transaction id. This is only used when updating or deleting a transaction. + /// + /// # Considerations: + /// - This function can only be called by an administrator account + /// - This extrinsic allows multiple transactions to be created/updated/deleted at the same time + /// (only for Construction Loan & Developer Equity drawdowns). + /// - Transaction parameters are optional because depends on the action to be performed: + /// * **Create**: Expenditure id, Amount, Documents & Action are required. + /// * **Update**: Except for the transaction id & action, all parameters are optional. + /// * **Delete**: Only the transaction id & action is required. + /// - Multiple actions can be performed at the same time. For example, you can create a new + /// transaction and update another one at the same time. + /// - Do not perform multiple actions over the same transaction in the same call, it could + /// result in an unexpected behavior. + /// - After a drawdown is approved, it can not be updated or deleted. + /// - After a drawdown is approved, the next drawdown will be automatically created. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn approve_drawdown( @@ -887,12 +964,36 @@ pub mod pallet { } - /// Reject a drawdown + /// Rejects a drawdown + /// + /// # Parameters: + /// - origin: The administator account who is rejecting the drawdown + /// - project_id: The selected project id where the drawdown will be rejected + /// - drawdown_id: The selected drawdown id to be rejected + /// + /// Then the next two feedback parameters are optional because depends on the drawdown type: + /// #### EB5 drawdowns: + /// - transactions_feedback: Administrator will provide feedback for each transaction + /// that is wrong. This is a vector of tuples where each entry is composed by: + /// * 0: The transaction id + /// * 1: The transaction feedback /// - /// - `origin`: The admin - /// - `project_id`: The project id - /// - `drawdown_id`: The drawdown id + /// #### Construction Loan & Developer Equity drawdowns: + /// - drawdown_feedback: Administrator will provide feedback for the WHOLE drawdown. /// + /// # Considerations: + /// - This function can only be called by an administrator account + /// - This extrinsic allows multiple transactions to be rejected at the same time + /// (only for EB5 drawdowns). + /// - For EB5 drawdowns, the administrator can provide feedback for each transaction + /// that is wrong. + /// - For Construction Loan & Developer Equity drawdowns, the administrator can provide + /// feedback for the WHOLE drawdown. + /// - After a builder re-submits a drawdown, the administrator will have to review + /// the drawdown again. + /// - After a builder re-submits a drawdown, the feedback field will be cleared automatically. + /// - If a single EB5 transaction is wrong, the administrator WILL reject the WHOLE drawdown. + /// There is no way to reject a single transaction. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn reject_drawdown( @@ -907,9 +1008,26 @@ pub mod pallet { Self::do_reject_drawdown(who, project_id, drawdown_id, transactions_feedback, drawdown_feedback) } - /// Bulk upload drawdowns + /// Bulk upload drawdowns. /// - /// This extrinsic is called by the builder + /// # Parameters: + /// - origin: The administator account who is uploading the drawdowns + /// - project_id: The selected project id where the drawdowns will be uploaded + /// - drawdown_id: The drawdowns to be uploaded + /// - description: The description of the drawdown provided by the builder + /// - total_amount: The total amount of the drawdown + /// - documents: The documents provided by the builder for the drawdown + /// + /// # Considerations: + /// - This function can only be called by a builder account + /// - This extrinsic allows only one drawdown to be uploaded at the same time. + /// - The drawdown will be automatically submitted. + /// - Only available for Construction Loan & Developer Equity drawdowns. + /// - After a builder uploads a drawdown, the administrator will have to review it. + /// - After a builder re-submits a drawdown, the feedback field will be cleared automatically. + /// - Bulkuploads does not allow individual transactions. + /// - After a builder uploads a drawdown, the administrator will have to + /// insert each transaction manually. #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn up_bulkupload( @@ -925,21 +1043,37 @@ pub mod pallet { Self::do_up_bulk_upload(who, project_id, drawdown_id, description, total_amount, documents) } - /// Modify inflation rate + /// Modifies the inflation rate of a project. + /// + /// # Parameters: + /// - origin: The administator account who is modifying the inflation rate + /// - projects: The projects where the inflation rate will be modified. + /// This is a vector of tuples where each entry is composed by: + /// * 0: The project id + /// * 1: The inflation rate + /// * 2: The action to be performed (Create, Update or Delete) + /// + /// # Considerations: + /// - This function can only be called by an administrator account + /// - This extrinsic allows multiple projects to be modified at the same time. + /// - The inflation rate can be created, updated or deleted. + /// - The inflation rate is optional because depends on the CUDAction parameter: + /// * **Create**: The inflation rate will be created. Project id, inflation rate and action are required. + /// * **Update**: The inflation rate will be updated. Project id, inflation rate and action are required. + /// * **Delete**: The inflation rate will be deleted. Project id and action are required. + /// - The inflation rate can only be modified if the project is in the "started" status. /// - /// projects: project_id, inflation_rate, CUDAction #[transactional] #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] pub fn inflation_rate( origin: OriginFor, projects: BoundedVec<([u8;32], Option, CUDAction), T::MaxRegistrationsAtTime>, ) -> DispatchResult { - let who = ensure_signed(origin)?; // origin need to be a builder + let who = ensure_signed(origin)?; Self::do_execute_inflation_adjustment(who, projects) } - /// Kill all the stored data. /// /// This function is used to kill ALL the stored data. @@ -972,22 +1106,5 @@ pub mod pallet { Ok(()) } - // /// Testing extrinsic - // #[transactional] - // #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] - // pub fn testing_extrinsic( - // origin: OriginFor, - // transactions: BoundedVec<( - // [u8;32], // expenditure_id - // u64, // amount - // Option> //Documents - // ), T::MaxRegistrationsAtTime>, - // ) -> DispatchResult { - // let who = ensure_signed(origin)?; // origin need to be an admin - - // Self::do_execute_transactions(who, transactions) - // } - - } } \ No newline at end of file From d16309cd56139e49bdc21fc18f80ba249852e76a Mon Sep 17 00:00:00 2001 From: Erick Casanova Date: Thu, 10 Nov 2022 11:14:39 -0600 Subject: [PATCH 5/5] Release 127 --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 89be8bcc..09ce3d65 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -106,7 +106,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 126, + spec_version: 127, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,