InventoryItemMapper.java
package com.smartsupplypro.inventory.mapper;
import java.math.BigDecimal;
import com.smartsupplypro.inventory.dto.InventoryItemDTO;
import com.smartsupplypro.inventory.model.InventoryItem;
/**
* Enterprise entity-DTO mapping utility for inventory items with calculated field support.
*
* <p>Provides bidirectional transformation between {@link InventoryItem} entities and
* {@link InventoryItemDTO} data transfer objects with enterprise-specific business logic
* including computed total values and supplier relationship handling.</p>
*
* <p><strong>Enterprise Mapping Features:</strong></p>
* <ul>
* <li><strong>Calculated Fields:</strong> Automatic total value computation (price × quantity)</li>
* <li><strong>Relationship Handling:</strong> Safe supplier name extraction with null safety</li>
* <li><strong>Audit Field Preservation:</strong> Maintains creation timestamps and user tracking</li>
* <li><strong>Service Layer Integration:</strong> Designed for seamless service-controller mapping</li>
* </ul>
*
* <p><strong>Enterprise Architecture:</strong> This mapper serves as the transformation layer
* between persistence entities and API DTOs, enabling clean separation of concerns and
* supporting multiple presentation formats while maintaining data integrity.</p>
*/
public final class InventoryItemMapper {
/**
* Private constructor to prevent instantiation of utility class.
*
* @throws UnsupportedOperationException if instantiation is attempted
*/
private InventoryItemMapper() {
throw new UnsupportedOperationException("Utility class - no instances allowed");
}
/**
* Transforms an inventory item entity to a data transfer object with computed fields.
*
* <p><strong>Enterprise Transformation Logic:</strong></p>
* <ul>
* <li><strong>Total Value Calculation:</strong> Computes price × quantity automatically</li>
* <li><strong>Supplier Name Resolution:</strong> Safely extracts supplier name with null checks</li>
* <li><strong>Entity Integrity:</strong> Preserves all entity fields including audit metadata</li>
* <li><strong>API Readiness:</strong> Returns DTO optimized for client consumption</li>
* </ul>
*
* <p><strong>Business Rules:</strong> The total value calculation uses BigDecimal precision
* to ensure financial accuracy for inventory valuation reports and analytics.</p>
*
* @param item the inventory entity from persistence layer, must not be null
* @return DTO with computed fields for API responses and frontend consumption
* @implNote Uses builder pattern for null safety and performance optimization
*/
public static InventoryItemDTO toDTO(InventoryItem item) {
if (item == null) {
return null;
}
// Calculate total value with null safety and financial precision
BigDecimal totalValue = calculateTotalValue(item.getPrice(), item.getQuantity());
// Resolve supplier name with null safety
String supplierName = resolveSupplierName(item.getSupplier());
return InventoryItemDTO.builder()
.id(item.getId())
.name(item.getName())
.quantity(item.getQuantity())
.price(item.getPrice())
.totalValue(totalValue)
.supplierId(item.getSupplierId())
.supplierName(supplierName)
.minimumQuantity(item.getMinimumQuantity())
.createdBy(item.getCreatedBy())
.createdAt(item.getCreatedAt())
.build();
}
/**
* Transforms a data transfer object back to an inventory item entity for persistence.
*
* <p><strong>Persistence Preparation Logic:</strong></p>
* <ul>
* <li><strong>Entity Reconstruction:</strong> Maps all DTO fields to entity properties</li>
* <li><strong>Persistence Context:</strong> Prepares entity for JPA persistence operations</li>
* <li><strong>Audit Field Support:</strong> Preserves creation metadata for entity tracking</li>
* <li><strong>Server Authoritative:</strong> Ignores computed fields like totalValue</li>
* </ul>
*
* <p><strong>Design Note:</strong> This method is primarily used for update operations
* and test data preparation. The supplier relationship is handled separately through
* the service layer to maintain referential integrity.</p>
*
* @param dto the data transfer object from API requests, must not be null
* @return entity ready for persistence layer operations and database storage
* @implNote Builder pattern ensures immutability and validation during entity creation
*/
public static InventoryItem toEntity(InventoryItemDTO dto) {
if (dto == null) {
return null;
}
return InventoryItem.builder()
.id(dto.getId())
.name(dto.getName())
.quantity(dto.getQuantity())
.price(dto.getPrice())
.supplierId(dto.getSupplierId())
.minimumQuantity(dto.getMinimumQuantity())
.createdBy(dto.getCreatedBy()) // will be overwritten in service if null
.createdAt(dto.getCreatedAt()) // PrePersist covers nulls
.build();
}
/**
* Calculates total value with financial precision and null safety.
*
* <p><strong>Business Rule:</strong> Total value = price × quantity using BigDecimal
* for financial accuracy. Returns zero for null inputs to prevent calculation errors.</p>
*
* @param price the item price (may be null)
* @param quantity the item quantity (may be null)
* @return calculated total value or BigDecimal.ZERO for null inputs
*/
private static BigDecimal calculateTotalValue(BigDecimal price, Integer quantity) {
if (price == null || quantity == null) {
return BigDecimal.ZERO;
}
return price.multiply(BigDecimal.valueOf(quantity));
}
/**
* Resolves supplier name with null safety for relationship handling.
*
* <p><strong>Relationship Safety:</strong> Safely navigates through supplier
* relationship to extract name, returning null for missing associations.</p>
*
* @param supplier the supplier entity (may be null)
* @return supplier name or null if supplier is null
*/
private static String resolveSupplierName(com.smartsupplypro.inventory.model.Supplier supplier) {
return supplier != null ? supplier.getName() : null;
}
}