MRO Material Management
Contents
MRO Material Management
Summary: The MRO material management features provide the foundation for handling materials, material master data, reservations, storage locations, and goods movements in MRO workflows. The central objects are Material, MaterialMaster, Reservation, GoodsMovement, and StorageLocation. Materials are linked to master data and storage locations. Reservations link materials to tasks and define planned or actual quantities for maintenance work.
MRO material management is used to support maintenance work with the required spare parts, consumables, tools, or other material items.
In a maintenance workflow, users may need to know:
- which material is required for a task
- which material master data belongs to a material
- where the material is stored
- how much material is available
- how much material is already reserved
- which reservations exist for a task
- whether a reservation is planned, confirmed, issued, cancelled, or expired
The material management implementation separates the general material catalogue from the actual material quantity and reservation handling.
Basic concept
The material management implementation is built around the following main objects:
| Object | Type | Purpose |
|---|---|---|
| MaterialMaster | Master data | Defines the catalogue entry for a material, including item number, unit, packaging, manufacturer data, and material type. |
| Material | Quantity-bearing MRO object | Represents a material instance or stock entry in MRO. It links to a material master and a storage location and exposes quantity, reserved quantity, and available quantity logic. |
| Reservation | Workflow / transaction object | Represents a material reservation for a task. It links a material to a task and stores planned and actual quantities. |
| GoodsMovement | Base class | Provides the common QUANTITY property used by both materials and reservations. |
| StorageLocation | Storage master / location object | Represents a physical storage location and stores storage-related information such as storage type, dimensions, access type, and occupancy status. |
Core idea: MaterialMaster defines what the material is. Material represents the material in the MRO stock or material context. Reservation links a material to a task and reserves a planned quantity for maintenance execution.
Object overview
| Object | Class name | Base / inheritance | Main relations |
|---|---|---|---|
| Material | UBIK.MRO.Material | Inherits from GoodsMovement | LK_MATERIAL_MASTER, LK_STORAGE_LOCATION |
| Material Master | UBIK.MRO.MaterialMaster | Master data class | Referenced by Material via LK_MATERIAL_MASTER |
| Reservation | UBIK.MRO.Reservation | Inherits from GoodsMovement | LK_TASK, LK_MATERIAL |
| Goods Movement | UBIK.MRO.GoodsMovement | Base class | Provides QUANTITY to derived objects |
| Storage Location | UBIK.MRO.StorageLocation | Functional location specialization | Referenced by Material via LK_STORAGE_LOCATION |
GoodsMovement
Purpose
GoodsMovement is the base class for material-related quantity-bearing objects.
It defines the common quantity concept used by both:
- Material
- Reservation
Important properties
| Property | Type | Meaning |
|---|---|---|
| QUANTITY | double | Quantity value for the goods movement. For Material, this is the material quantity. For Reservation, this is the actual reservation quantity and has reservation-specific validation. |
MaterialMaster
Purpose
MaterialMaster represents the material master or catalogue entry.
It stores item-level master data that can be referenced by material instances in MRO.
A material master describes the material independently from a concrete reservation or task.
Important properties
| Property | Type | Meaning |
|---|---|---|
| ITEM_NUMBER | string | Item number or material number of the material master. |
| PACKAGING_UNIT | string | Packaging unit of the material. |
| PACKAGING_SIZE | double | Packaging size. |
| ACTIVE | bool | Defines whether the material master is active. |
| UNIT_OF_MEASURE | string | Unit of measure used for the material. |
| MATERIAL_TYPE | int | Underlying integer value for the material type. |
| MaterialType | enum | Typed accessor for MATERIAL_TYPE. |
| MANUFACTURER_COMPANY_NAME | string | Manufacturer company name. |
| MANUFACTURER_PRODUCT_TAG | string | Manufacturer product tag or product identifier. |
Material type
The typed material type accessor is MaterialType.
Known values are:
- SpareParts
- Consumables
- Tools
Open point: No explicit SAP or ERP synchronization behavior was found in the inspected classes. ITEM_NUMBER may correspond to an external material number, but the exact SAP/ERP mapping is unclear from the available code information.
Material
Purpose
Material represents a material instance or stock entry in MRO.
It inherits from GoodsMovement and therefore uses the inherited QUANTITY property as its material quantity.
A material links to:
- a material master via LK_MATERIAL_MASTER
- a storage location via LK_STORAGE_LOCATION
It also exposes calculated reservation and availability logic.
Important properties
| Property | Type | Meaning | Stored or calculated |
|---|---|---|---|
| LK_MATERIAL_MASTER | MaterialMaster | Link to the material master data. | Stored link |
| LK_STORAGE_LOCATION | StorageLocation | Link to the storage location where the material is located. | Stored link |
| QUANTITY | double | Material quantity. Inherited from GoodsMovement. | Stored property |
| RESERVED_QUANTITY | double | Sum of planned quantities of confirmed reservations for this material. | Calculated property |
| MATERIAL_STATUS | int | Underlying integer value for the material status. | Stored property |
| MaterialStatus | enum | Typed accessor for MATERIAL_STATUS. | Stored through MATERIAL_STATUS |
Material status
The material status is stored in MATERIAL_STATUS and exposed through the typed accessor MaterialStatus.
Known values are:
| Value | Numeric value | Meaning |
|---|---|---|
| Undefined | 0 | No specific material status is defined. |
| Inactive | 10 | Material is inactive. |
| Active | 20 | Material is active. |
Open point: The inspected class information does not show specific methods that automatically change MaterialStatus. Status changes outside these classes are unclear from code.
Reserved quantity
RESERVED_QUANTITY is calculated at read time.
The calculation uses reservations where:
- LK_MATERIAL points to the current material
- STATUS is ReservationStatus.Confirmed
The calculated value is the sum of QTY_PLANNED of these confirmed reservations.
Important: RESERVED_QUANTITY is not treated as a normal stored quantity in the business logic. It is computed from confirmed Reservation objects.
Available quantity
The available material quantity is calculated by the method AvailableQuantity().
AvailableQuantity = QUANTITY - RESERVED_QUANTITY
Active reservations
The method HasActiveReservation() checks whether active reservations exist for the material.
It queries reservations where:
- LK_MATERIAL points to the current material
- STATUS is lower than or equal to ReservationStatus.Confirmed
This means the method considers reservations up to the confirmed state as active.
Delete behavior
Material.InternalDeleteAllowed() prevents deleting a material if it still has quantity or active reservations.
Deletion is only allowed if the base delete conditions are fulfilled and:
- QUANTITY is lower than or equal to 0
- HasActiveReservation() returns false
Restriction: A Material cannot be deleted while it has a quantity greater than 0 or active reservations.
Reservation
Purpose
Reservation represents a material reservation for a task.
It links:
- a task via LK_TASK
- a material via LK_MATERIAL
It stores the planned reservation quantity in QTY_PLANNED and can also store an actual quantity through the overridden QUANTITY property.
Important properties
| Property | Type | Meaning | Important behavior |
|---|---|---|---|
| LK_TASK | Task | Link to the task for which the material is reserved. | Setter is blocked when status is Issued or Confirmed. |
| LK_MATERIAL | Material | Link to the material being reserved. | Setter is blocked when status is Issued or Confirmed. |
| STATUS | int | Underlying integer value for the reservation status. | Changes are validated by AllowStatusChange(int newStatus). |
| Status | ReservationStatus | Typed accessor for STATUS. | Uses the ReservationStatus enum. |
| QTY_PLANNED | double | Planned quantity for the reservation. | Setter validates through AllowQuantityPlanned(double). |
| QUANTITY | double | Actual reservation quantity. Overrides GoodsMovement.QUANTITY. | Setter validates through AllowQuantity(double). |
Reservation status
The reservation status is stored in STATUS and exposed through the typed accessor Status.
Known values of ReservationStatus are:
| Status | Numeric value | Meaning |
|---|---|---|
| Planned | 0 | Reservation is planned. |
| Confirmed | 10 | Reservation is confirmed and contributes to the material's reserved quantity. |
| Issued | 20 | Material has been physically issued. |
| Cancelled | 30 | Reservation was cancelled. This is only allowed if the reservation has not been issued. |
| Expired | 50 | Reservation has expired. |
Status change rules
Status changes are controlled by AllowStatusChange(int newStatus).
The following rules are applied:
- no status change is allowed when the current status is Issued
- changing from Confirmed back to Planned is not allowed
- other status changes are allowed by this method
Restriction: Once a reservation has status Issued, its status can no longer be changed by the normal status setter logic.
Planned quantity validation
The setter of QTY_PLANNED validates changes through AllowQuantityPlanned(double).
A new planned quantity is only allowed if:
- Status is ReservationStatus.Planned
- LK_MATERIAL is assigned
- the new quantity is greater than 0
- the new quantity is lower than or equal to LK_MATERIAL.AvailableQuantity()
Quantity rule: A planned reservation quantity can only be set while the reservation is still Planned and only if the selected material has enough available quantity.
Actual quantity validation
The overridden QUANTITY setter validates changes through AllowQuantity(double).
A new actual quantity is only allowed if:
- the new quantity is greater than 0
- the status is either Planned or Confirmed
Link editing rules
The setters of LK_TASK and LK_MATERIAL are guarded by reservation status.
The links cannot be changed when the reservation is:
- Issued
- Confirmed
This prevents changing the task or material after the reservation has reached a more binding status.
StorageLocation
Purpose
StorageLocation represents a physical storage location.
It is a functional location specialization and can be linked from Material via LK_STORAGE_LOCATION.
A storage location stores information about storage type, dimensions, access type, label, level, position, and occupancy.
Important properties
| Property | Type | Meaning |
|---|---|---|
| STORAGE_TYPE | int | Underlying integer value for storage type. |
| StorageType | enum | Typed accessor for STORAGE_TYPE. |
| MAX_WEIGHT | double | Maximum allowed weight for the storage location. |
| MAX_VOLUME | double | Maximum allowed volume for the storage location. |
| LENGTH | double | Length of the storage location. |
| WIDTH | double | Width of the storage location. |
| HEIGHT | double | Height of the storage location. |
| ACCESS_TYPE | int | Underlying integer value for access type. |
| AccessType | enum | Typed accessor for ACCESS_TYPE. |
| STORAGE_LABEL | string | Label of the storage location. |
| LEVEL | int | Level of the storage location. |
| POSITION | string | Position identifier. |
| OCCUPANCY_STATUS | int | Underlying integer value for occupancy status. |
| OccupancyStatus | enum | Typed accessor for OCCUPANCY_STATUS. |
Storage type
Known values of StorageType are:
- Floor
- Shelf
- Rack
- Bin
- Pallet
- Container
Access type
Known values of AccessType are:
- Manual
- Forklift
- Crane
- Automated
Occupancy status
Known values of OccupancyStatus are:
- Empty
- Partial
- Full
- Reserved
- Blocked
- OutOfService
Open point: The inspected StorageLocation information does not show automatic occupancy calculation. It is unclear from code whether OCCUPANCY_STATUS is updated manually, by workflow logic, or by another module.
Relations
The following relations are relevant for material management.
| Relation | Source | Target | Meaning |
|---|---|---|---|
| LK_MATERIAL_MASTER | Material | MaterialMaster | Links a material instance to its master data. |
| LK_STORAGE_LOCATION | Material | StorageLocation | Defines where the material is stored. |
| LK_MATERIAL | Reservation | Material | Defines which material is reserved. |
| LK_TASK | Reservation | Task | Defines the task for which the material is reserved. |
Quantity concepts
Material quantity
The material quantity is stored in Material.QUANTITY.
Because Material inherits from GoodsMovement, the property is inherited from the base class.
Reserved quantity
The reserved quantity is exposed through Material.RESERVED_QUANTITY.
It is calculated by summing the QTY_PLANNED values of confirmed reservations for the material.
Only reservations with Status equal to ReservationStatus.Confirmed are included in this calculation.
Available quantity
Available quantity is calculated by Material.AvailableQuantity().
AvailableQuantity = QUANTITY - RESERVED_QUANTITY
Planned reservation quantity
The planned reservation quantity is stored in Reservation.QTY_PLANNED.
It can only be set if:
- the reservation is still Planned
- a material is assigned
- the quantity is greater than 0
- the quantity does not exceed the material's available quantity
Actual reservation quantity
The actual reservation quantity is stored in Reservation.QUANTITY.
This property overrides GoodsMovement.QUANTITY and can only be set if the status is Planned or Confirmed and the new quantity is greater than 0.
Quantity overview
| Quantity | Property / method | Object | Stored or calculated | Notes |
|---|---|---|---|---|
| Material quantity | QUANTITY | Material | Stored | Inherited from GoodsMovement. |
| Reserved quantity | RESERVED_QUANTITY | Material | Calculated | Sum of QTY_PLANNED of confirmed reservations for the material. |
| Available quantity | AvailableQuantity() | Material | Calculated | QUANTITY minus RESERVED_QUANTITY. |
| Planned reservation quantity | QTY_PLANNED | Reservation | Stored | Validated by AllowQuantityPlanned(double). |
| Actual reservation quantity | QUANTITY | Reservation | Stored | Overrides GoodsMovement.QUANTITY and is validated by AllowQuantity(double). |
Reservation workflow
Creating or editing a reservation
A reservation links a material to a task.
For a reservation to define its planned quantity correctly:
- LK_MATERIAL must be set.
- LK_TASK should point to the task requiring the material.
- Status must still be Planned.
- QTY_PLANNED must be greater than 0.
- QTY_PLANNED must not exceed LK_MATERIAL.AvailableQuantity().
Confirmed reservations
When a reservation is confirmed, it contributes to the material's reserved quantity.
This affects the available quantity of the material because:
AvailableQuantity = QUANTITY - sum(QTY_PLANNED of confirmed reservations)
Finishing a task
When a task is finished, the task logic calls CloseReservations().
The method processes active reservations for the task:
- if a reservation has status Confirmed, it is set to Issued
- otherwise, it is set to Cancelled
The changed reservations are added to the unsaved children through AddToUnsavedChildren(reservation) so that the changes are persisted.
Workflow effect: Finishing a task closes its reservations. Confirmed reservations become Issued; other active reservations become Cancelled.
Usage in tasks
Reservations are the central link between material handling and task execution.
A reservation connects:
- the required material through LK_MATERIAL
- the task through LK_TASK
- the planned quantity through QTY_PLANNED
- the reservation state through Status
This means that material usage is tracked at task level in the inspected implementation.
Open point: The inspected information explicitly confirms the relation to tasks. Direct relations to work packages or work orders were not confirmed in the provided code analysis. If work packages or work orders use materials indirectly through tasks, that should be documented with the exact relation or navigation path.
Goods movement usage
GoodsMovement is the common base class for quantity-bearing material objects.
Both Material and Reservation inherit from it and expose QUANTITY.
In the inspected implementation:
- Material.QUANTITY represents the material quantity
- Reservation.QUANTITY represents the actual quantity for the reservation and applies reservation-specific validation
- Reservation.QTY_PLANNED represents the planned reserved quantity
- Material.RESERVED_QUANTITY is calculated from confirmed reservations
Example workflow
Scenario
A task requires one spare part from stock.
Step 1: Material master exists
The spare part is defined as a MaterialMaster.
| Field | Example |
|---|---|
| ITEM_NUMBER | OF-10045 |
| UNIT_OF_MEASURE | Piece |
| MaterialType | SpareParts |
Step 2: Material exists in a storage location
A Material object references the material master and a storage location.
| Property | Example |
|---|---|
| LK_MATERIAL_MASTER | Oil Filter Type A |
| LK_STORAGE_LOCATION | Storage Shelf A |
| QUANTITY | 10 |
| RESERVED_QUANTITY | 0 |
| AvailableQuantity() | 10 |
Step 3: Reservation is created for a task
A Reservation links the material to the task.
| Property | Example |
|---|---|
| LK_TASK | Replace oil filter |
| LK_MATERIAL | Oil Filter Type A |
| Status | Planned |
| QTY_PLANNED | 1 |
The planned quantity is allowed because the material has enough available quantity.
Step 4: Reservation is confirmed
The reservation status is changed to Confirmed.
After confirmation, the material's reserved quantity includes the reservation's planned quantity.
| Quantity | Value |
|---|---|
| Material.QUANTITY | 10 |
| Material.RESERVED_QUANTITY | 1 |
| Material.AvailableQuantity() | 9 |
Step 5: Task is finished
When the task is finished, CloseReservations() is called.
The confirmed reservation is changed to Issued.
Validation and business rules
The following business rules are implemented in the inspected material management logic.
| Area | Rule | Implemented by |
|---|---|---|
| Planned reservation quantity | QTY_PLANNED must be greater than 0. | AllowQuantityPlanned(double) |
| Planned reservation quantity | QTY_PLANNED can only be changed while the reservation is Planned. | AllowQuantityPlanned(double) |
| Planned reservation quantity | QTY_PLANNED must not exceed LK_MATERIAL.AvailableQuantity(). | AllowQuantityPlanned(double) |
| Actual reservation quantity | QUANTITY must be greater than 0. | AllowQuantity(double) |
| Actual reservation quantity | QUANTITY can only be changed while the reservation is Planned or Confirmed. | AllowQuantity(double) |
| Reservation status | Status cannot be changed once the reservation is Issued. | AllowStatusChange(int newStatus) |
| Reservation status | A reservation cannot be changed from Confirmed back to Planned. | AllowStatusChange(int newStatus) |
| Reservation links | LK_TASK and LK_MATERIAL cannot be changed when status is Issued or Confirmed. | Property setters |
| Material deletion | Material cannot be deleted while QUANTITY is greater than 0. | InternalDeleteAllowed() |
| Material deletion | Material cannot be deleted while active reservations exist. | InternalDeleteAllowed() and HasActiveReservation() |
