Skip to content

Commit 45cbfe3

Browse files
committed
I added the inital setup for the transactions flow.
1 parent a8269dc commit 45cbfe3

File tree

2 files changed

+87
-38
lines changed

2 files changed

+87
-38
lines changed

pallets/proxy-financial/src/functions.rs

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -749,13 +749,66 @@ impl<T: Config> Pallet<T> {
749749
// For now transactions functions are private, but in the future they may be public
750750
// TOREVIEW: Each transaction has an amount and it refers to a selected expenditure,
751751
// so each drawdown sums the amount of each transaction -> drawdown.total_amount = transaction.amount + transaction.amount + transaction.amount
752-
// when a drawdown is approved, the amount is transfered to every expenditure
752+
// when a drawdown is approved, the amount is transfered to each expenditure
753753
// using the storage map, transactions_by_drawdown, we can get the transactions for a specific drawdown
754754

755-
fn do_execute_transaction(
755+
pub fn do_execute_transactions(
756+
project_id: [u8;32],
757+
drawdown_id: [u8;32],
758+
_user: T::AccountId, //TODO: remove underscore when permissions are implemented
759+
transactions: BoundedVec<(
760+
[u8;32], // expenditure_id
761+
u64, // amount
762+
Option<Documents<T>>, //Documents
763+
CUDAction, // Action
764+
Option<[u8;32]>, // transaction_id
765+
), T::MaxRegistrationsAtTime>,
756766
) -> DispatchResult {
767+
// Check permissions here so helper private functions doesn't need to check it
768+
// TODO: Ensure admin & builder permissions
769+
770+
// Ensure project exists so helper private functions doesn't need to check it
771+
ensure!(ProjectsInfo::<T>::contains_key(project_id), Error::<T>::ProjectNotFound);
772+
773+
//Ensure drawdown exists so helper private functions doesn't need to check it
774+
ensure!(DrawdownsInfo::<T>::contains_key(drawdown_id), Error::<T>::DrawdownNotFound);
775+
776+
// Ensure transactions are not empty
777+
ensure!(!transactions.is_empty(), Error::<T>::EmptyTransactions);
778+
779+
for transaction in transactions {
780+
match transaction.3 {
781+
CUDAction::Create => {
782+
// Create transaction only needs (expenditure_id, amount, documents)
783+
Self::do_create_transaction(
784+
project_id,
785+
drawdown_id,
786+
transaction.0,
787+
transaction.1,
788+
transaction.2,
789+
)?;
790+
},
791+
CUDAction::Update => {
792+
// Update transaction needs (
793+
Self::do_update_transaction(
794+
transaction.1,
795+
transaction.2,
796+
transaction.4.ok_or(Error::<T>::TransactionIdNotFound)?,
797+
)?;
798+
},
799+
CUDAction::Delete => {
800+
// Delete transaction needs (expenditure_id, transaction_id)
801+
Self::do_delete_transaction(
802+
transaction.4.ok_or(Error::<T>::TransactionIdNotFound)?,
803+
)?;
804+
},
805+
}
757806

807+
}
808+
809+
// TOOD: update total_amount of drawdown -> submit/draft drawdown
758810

811+
Self::deposit_event(Event::TransactionsCompleted);
759812
Ok(())
760813
}
761814

@@ -765,9 +818,7 @@ impl<T: Config> Pallet<T> {
765818
drawdown_id: [u8;32],
766819
expenditure_id: [u8;32],
767820
amount: u64,
768-
feedback: FieldDescription,
769-
//TOREVIEW: Is mandatory to upload documents with every transaction? If not we can wrap this field in an Option
770-
documents: Option<Documents<T>>
821+
documents: Option<Documents<T>>,
771822
) -> DispatchResult {
772823
// TODO:Ensure builder permissions
773824

@@ -777,10 +828,8 @@ impl<T: Config> Pallet<T> {
777828
// Ensure amount is valid
778829
Self::is_amount_valid(amount)?;
779830

780-
// Ensure documents is not empty
781-
if let Some(mod_documents) = documents.clone() {
782-
ensure!(mod_documents.len() > 0, Error::<T>::DocumentsIsEmpty);
783-
}
831+
//TOREVIEW: If documents are mandatory, we need to check if they are provided
832+
// TOOD: Ensure documents is not empty
784833

785834
// Get timestamp
786835
let timestamp = Self::get_timestamp_in_milliseconds().ok_or(Error::<T>::TimestampError)?;
@@ -796,7 +845,7 @@ impl<T: Config> Pallet<T> {
796845
created_date: timestamp,
797846
updated_date: timestamp,
798847
closed_date: 0,
799-
feedback,
848+
feedback: None,
800849
amount,
801850
status: TransactionStatus::default(),
802851
documents,
@@ -819,23 +868,16 @@ impl<T: Config> Pallet<T> {
819868

820869
}
821870

822-
fn do_edit_transaction(
823-
admin: T::AccountId,
871+
fn do_update_transaction(
872+
amount: u64,
873+
documents: Option<Documents<T>>,
824874
transaction_id: [u8;32],
825-
amount: Option<u64>,
826-
feedback: Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>,
827-
documents: Option<Documents<T>>
828875
) -> DispatchResult {
829-
// Ensure admin permissions
830-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
831-
832876
// Ensure transaction exists
833877
ensure!(TransactionsInfo::<T>::contains_key(transaction_id), Error::<T>::TransactionNotFound);
834878

835879
// Ensure amount is valid.
836-
if let Some(mod_amount) = amount.clone() {
837-
Self::is_amount_valid(mod_amount)?;
838-
}
880+
Self::is_amount_valid(amount)?;
839881

840882
// Ensure documents is not empty
841883
if let Some(mod_documents) = documents.clone() {
@@ -861,13 +903,8 @@ impl<T: Config> Pallet<T> {
861903
// Ensure expenditure exists
862904
ensure!(ExpendituresInfo::<T>::contains_key(mod_transaction_data.expenditure_id), Error::<T>::ExpenditureNotFound);
863905

864-
if let Some(amount) = amount.clone() {
865-
mod_transaction_data.amount = amount;
866-
}
867-
if let Some(feedback) = feedback.clone() {
868-
let mod_feedback = feedback.into_inner();
869-
mod_transaction_data.feedback = mod_feedback[0].clone();
870-
}
906+
mod_transaction_data.amount = amount;
907+
871908
if let Some(documents) = documents.clone() {
872909
mod_transaction_data.documents = Some(documents);
873910
}
@@ -882,12 +919,8 @@ impl<T: Config> Pallet<T> {
882919
}
883920

884921
fn do_delete_transaction(
885-
admin: T::AccountId,
886922
transaction_id: [u8;32]
887923
) -> DispatchResult {
888-
// Ensure admin permissions
889-
Self::is_superuser(admin.clone(), &Self::get_global_scope(), ProxyRole::Administrator.id())?;
890-
891924
// Ensure transaction exists and get transaction data
892925
let transaction_data = TransactionsInfo::<T>::get(transaction_id).ok_or(Error::<T>::TransactionNotFound)?;
893926

pallets/proxy-financial/src/lib.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,15 @@ pub mod pallet {
265265
ExpenditureEdited([u8;32]),
266266
/// Expenditure was deleted successfully
267267
ExpenditureDeleted([u8;32]),
268+
/// Trasactions was completed successfully
269+
TransactionsCompleted,
268270
/// Transaction was created successfully
269271
TransactionCreated([u8;32]),
270272
/// Transaction was edited successfully
271273
TransactionEdited([u8;32]),
272274
/// Transaction was deleted successfully
273275
TransactionDeleted([u8;32]),
276+
274277
}
275278

276279
// E R R O R S
@@ -380,6 +383,10 @@ pub mod pallet {
380383
InvalidExpenditureType,
381384
/// User does not have the specified role
382385
UserDoesNotHaveRole,
386+
/// Transactions vector is empty
387+
EmptyTransactions,
388+
/// Transaction ID was not found in do_execute_transaction
389+
TransactionIdNotFound,
383390

384391
}
385392

@@ -597,12 +604,21 @@ pub mod pallet {
597604
Self::do_delete_expenditure(who, project_id, expenditure_id)
598605
}
599606

600-
601-
602-
603-
604-
605-
607+
// /// Testing extrinsic
608+
// #[transactional]
609+
// #[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
610+
// pub fn testing_extrinsic(
611+
// origin: OriginFor<T>,
612+
// transactions: BoundedVec<(
613+
// [u8;32], // expenditure_id
614+
// u64, // amount
615+
// Option<Documents<T>> //Documents
616+
// ), T::MaxRegistrationsAtTime>,
617+
// ) -> DispatchResult {
618+
// let who = ensure_signed(origin)?; // origin need to be an admin
619+
620+
// Self::do_execute_transactions(who, transactions)
621+
// }
606622

607623

608624
}

0 commit comments

Comments
 (0)