Skip to content

Commit

Permalink
Add InventoryLocale storage, Add calls to this storage for respective…
Browse files Browse the repository at this point in the history
… extrinsics that perform creates or moves
  • Loading branch information
Wolfenheimm committed Nov 18, 2024
1 parent ccc691e commit d41c56a
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 10 deletions.
4 changes: 4 additions & 0 deletions pallets/assembly/src/blogic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ impl<T: Config> Pallet<T> {
..Default::default()
};

// TODO -> Check if the assembled product already exists, also add to global inventory
// If the product already exists, mutate the quantity instead of inserting a new entry

// Insert the assembled product into storage
AssembledProducts::<T>::insert(
(who, sku.clone(), serial_number.clone()),
Expand Down Expand Up @@ -58,6 +61,7 @@ impl<T: Config> Pallet<T> {
// Take the required number of items from the inventory.
// First check the component quantity and then remove items from the inventory.
// remove the item from inventory if the entire quantity is taken, otherwise update the quantity using mutate.
// TODO: This should not be done here... Setting qty to 0 should be done after assembly...
let mut qty = component.qty;
for item in items.iter_mut() {
if qty == 0 {
Expand Down
1 change: 0 additions & 1 deletion pallets/assembly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ pub use weights::*;
// Import the types and other modules from the inventory pallet
use crate::types::{Bom, WorkOrder, WorkOrderNumber};
use pallet_inventory::types::{Item, SerialNumber, Sku};
use weights::WeightInfo;

// Define the pallet and its configuration
#[frame_support::pallet]
Expand Down
5 changes: 0 additions & 5 deletions pallets/inventory/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
#![cfg(feature = "runtime-benchmarks")]
use super::*;

use crate::types::{
AbcCode, CycleCount, Employee, InventoryType, LotNumber, ProductType, Qty, SerialNumber,
ShelfLife, Sku, WeightLbs,
};

#[allow(unused)]
use crate::Pallet as Template;
use frame_benchmarking::v2::*;
Expand Down
82 changes: 79 additions & 3 deletions pallets/inventory/src/blogic.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::Config;
use crate::Error;
use crate::InventoryLocale;
use crate::{pallet::Pallet, types::*};
use crate::{AdjustInventory, GlobalInventory, Inventory, Recipes, ScrapInventory};
use codec::{Encode, MaxEncodedLen};
use frame_support::pallet_prelude::DispatchError;
use frame_support::sp_runtime::DispatchResult;
use frame_support::BoundedBTreeMap;

impl<T: Config> Pallet<T> {
pub fn do_inventory_insertion(who: &T::AccountId, item: Item) -> DispatchResult {
Expand All @@ -19,6 +22,31 @@ impl<T: Config> Pallet<T> {
<Inventory<T>>::insert((who, item.sku.clone(), item.serial_number), item.clone());
<GlobalInventory<T>>::insert(item.sku.clone(), item.qty);

// Fist, check if the location already exists in the InventoryLocale storage
// If it does, append the item to the existing Vec<Item> and insert it back into storage
// If it does not, create a new Vec<Item> and insert it into the InventoryLocale storage
<InventoryLocale<T>>::try_mutate_exists(
item.location.clone(),
|inventory| -> DispatchResult {
match inventory {
Some(ref mut map) => {
// Insert the item using its serial number as the key
map.try_insert(item.serial_number.clone(), item.clone())
.map_err(|_| Error::<T>::InventoryFull)?;
}
None => {
// Create a new BoundedBTreeMap and insert the item
let mut new_map = BoundedBTreeMap::default();
new_map
.try_insert(item.serial_number.clone(), item.clone())
.map_err(|_| Error::<T>::InventoryFull)?;
*inventory = Some(new_map);
}
}
Ok(())
},
)?;

Ok(())
}

Expand Down Expand Up @@ -54,6 +82,18 @@ impl<T: Config> Pallet<T> {
Err(Error::<T>::InventoryNotFound.into())
}
})?;
// Remove the item from InventoryLocale
<InventoryLocale<T>>::try_mutate_exists(
item.location.clone(),
|location_items| -> DispatchResult {
if let Some(ref mut map) = location_items {
map.remove(&serial_number); // Remove the item by its SerialNumber
} else {
return Err(Error::<T>::LocationNotFound.into());
}
Ok(())
},
)?;

Ok(())
}
Expand All @@ -67,13 +107,49 @@ impl<T: Config> Pallet<T> {
// Get the enum variant of the AdjustDetails
match adjust_details {
AdjustDetails::Location {
ref new_location, ..
ref new_location,
ref original_location,
..
} => {
// Update the item's location field
// Update the item's fields
item.moved_by = moved_by.clone();
item.location = new_location.clone();

// Remove the item from the old location
<InventoryLocale<T>>::try_mutate_exists(
original_location.clone(),
|location_items| -> DispatchResult {
if let Some(ref mut map) = location_items {
map.remove(&item.serial_number); // Remove the item by its SerialNumber
if map.is_empty() {
*location_items = None; // Clean up if the location is empty
}
Ok(())
} else {
Err(Error::<T>::LocationNotFound.into())
}
},
)?;

// Insert the item into the new location
<InventoryLocale<T>>::try_mutate(
new_location.clone(),
|location_items| -> Result<(), DispatchError> {
if let Some(ref mut map) = location_items {
map.try_insert(item.serial_number.clone(), item.clone())
.map_err(|_| DispatchError::from(Error::<T>::InventoryFull))?;
} else {
let mut new_map = BoundedBTreeMap::default();
new_map
.try_insert(item.serial_number.clone(), item.clone())
.map_err(|_| DispatchError::from(Error::<T>::InventoryFull))?;
*location_items = Some(new_map);
}
Ok(())
},
)?;
}
// Fail if the AdjustDetails variant was Quantity
// Fail if the AdjustDetails variant is not Location
_ => return Err(Error::<T>::InvalidAdjustDetails.into()),
}

Expand Down
11 changes: 10 additions & 1 deletion pallets/inventory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ pub use weights::*;
// All pallet logic is defined in its own module and must be annotated by the `pallet` attribute.
#[frame_support::pallet]
pub mod pallet {

// Import various useful types required by all FRAME pallets.
use super::*;
use crate::WeightInfo;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use types::*;
use types::{SerialNumber, *};

// The `Pallet` struct serves as a placeholder to implement traits, methods and dispatchables
// (`Call`s) in this pallet.
Expand Down Expand Up @@ -185,6 +186,10 @@ pub mod pallet {
#[pallet::storage]
pub type Recipes<T: Config> = StorageMap<_, Twox64Concat, Sku, Recipe>;

#[pallet::storage]
pub type InventoryLocale<T: Config> =
StorageMap<_, Twox64Concat, Location, BoundedBTreeMap<SerialNumber, Item, ConstU32<1000>>>;

/// Errors that can be returned by this pallet.
///
/// Errors tell users that something went wrong so it's important that their naming is
Expand All @@ -207,6 +212,10 @@ pub mod pallet {
InsufficientInventory,
/// The incorrect Adjust Details were provided
InvalidAdjustDetails,
/// The inventory is full
InventoryFull,
/// The location was not found
LocationNotFound,
}

/// The pallet's dispatchable functions ([`Call`]s).
Expand Down

0 comments on commit d41c56a

Please sign in to comment.