org.broadleafcommerce.core.inventory.service.InventoryService Maven / Gradle / Ivy
/*
* #%L
* BroadleafCommerce Framework
* %%
* Copyright (C) 2009 - 2014 Broadleaf Commerce
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.broadleafcommerce.core.inventory.service;
import org.broadleafcommerce.core.catalog.domain.Sku;
import org.broadleafcommerce.core.inventory.service.type.InventoryType;
import java.util.Collection;
import java.util.Map;
/**
* This basic inventory service checks and adjusts the current inventory of a sku. All Skus will be considered
* generally unavailable from an inventory perspective if {@link Sku#isAvaliable()} returns false or if {@link Sku#isActive()}
* returns false.
*
* Skus with an InventoryType of null or 'ALWAYS_AVAILABLE' will be considered undefined from an inventory perspective, and will generally
* be considered available. However, a request for available quantities of Skus with a null or 'ALWAYS_AVAILABLE' inventory type will
* return null (as the {@link Sku} is available but no inventory strategy is defined).
*
* @author Kelly Tisdell
* @author Phillip Verheyden (phillipuniverse)
*/
public interface InventoryService {
/**
* Retrieves the quantity available for a given sku. May return null if no inventory is maintained
* for the given sku when Sku.getInventoryType() == null
* or the {@link InventoryType} of the given sku is {@link InventoryType#ALWAYS_AVAILABLE}. Effectively, if the quantity returned is null, inventory is
* undefined, which most likely means it is available. However, rather than returning an arbitrary integer values (like Integer.MAX_VALUE),
* which has specific meaning, we return null as this can be interpreted by the client to mean whatever they define it as (including
* infinitely available), which is the most likely scenario.
*
* In practice, this is a convenience method to wrap {@link #retrieveQuantitiesAvailable(Collection)}
*
* @param
* @return null if there is no inventory strategy defined (meaning, {@link Sku#getInventoryType()} is null or
* {@link InventoryType#ALWAYS_AVAILABLE}). Otherwise, this returns the quantity of the {@link Sku}
*/
public Integer retrieveQuantityAvailable(Sku sku);
/**
* Retrieves the quantity available for a given sku. May return null if no inventory is maintained
* for the given sku when Sku.getInventoryType() == null
* or the {@link InventoryType} of the given sku is {@link InventoryType#ALWAYS_AVAILABLE}. Effectively, if the quantity returned is null, inventory is
* undefined, which most likely means it is available. However, rather than returning an arbitrary integer values (like Integer.MAX_VALUE),
* which has specific meaning, we return null as this can be interpreted by the client to mean whatever they define it as (including
* infinitely available), which is the most likely scenario.
*
* @param skus the set of {@link Sku}s to return inventory for
* @return a map of the given set of skus to the quantity as represented in the inventory system. The {@link Map#keySet()}
* is the same collection of given skus
* @see {@link #retrieveQuantityAvailable(Sku)}
*/
public Map retrieveQuantitiesAvailable(Collection skus);
/**
* Indicates whether the given quantity is available for the particular skuId. The result will be
* true if Sku.getInventoryType() == null or not Sku.getInventoryType().equals(InventoryType.ALWAYS_AVAILABLE).
*
* The result will be false if the Sku is inactive, if the Sku.getAvaialable() == false, if the quantity
* field is null, or if the quantity requested exceeds the quantity available.
*
* @param sku the {@link Sku} to see if enough quantity is available
* @param quantity the quantity to check for the given sku
* @return true if there is available quantity
*/
public boolean isAvailable(Sku sku, int quantity);
/**
* Without worrying about quantities, just checks to see if the given Sku is available. A {@link Sku} is
* generally available if any of these is true:
*
* - {@link Sku#getInventoryType()} is null
* - {@link Sku#getInventoryType()} is anything but {@link InventoryType#UNAVAILABLE}
* The now-deprecated {@link Sku#isAvailable()} is true or null
*
*
* This will return true if {@link Sku#getInventoryType()} is {@link InventoryType#CHECK_QUANTITY}
* @param sku the {@link Sku} whose availability is being checked
* @return true or false according to the rules above
*/
public boolean checkBasicAvailablility(Sku sku);
/**
* Attempts to decrement inventory if it is available. If the Sku is marked as {@link InventoryType#ALWAYS_AVAILABLE}
* then this will be a no-op.
*
* This method is a convenience method to wrap {@link #decrementInventory(Map)}
*
* @param sku the {@link Sku} to decrement inventory from
* @param quantity the quantity to take inventory from
* @throws InventoryUnavailableException if there is not enough of the given quantity for the given sku
* @throws IllegalArgumentException if the given quantity is not greater than zero
*/
public void decrementInventory(Sku sku, int quantity) throws InventoryUnavailableException;
/**
* Attempts to decrement inventory for a map of Skus and quantities
*
* Quantities must be greater than zero or an IllegalArgumentException will be thrown.
*
* If any of the given {@link Sku}s inventory type is not {@link InventoryType#CHECK_QUANTITY} then this
* is a no-op and nothing actually happens
*
* @param skuQuantities a map from a {@link Sku} to the quantity attempting to decrement
* @throws InventoryUnavailableException if there is not enough inventory to decrement from any of the given skus or
* if {@link #checkBasicAvailablility(Sku)} returns false
* @throws IllegalArgumentException if any of the quantities of the given skus are less than zero
*/
public void decrementInventory(Map skuQuantities) throws InventoryUnavailableException;
/**
* Attempts to increment inventory. Quantity must be greater than zero or an IllegalArgumentException will be thrown.
*
* This is a convenience method to wrap {@link #incrementInventory(Map)}
*
* @param sku the {@link Sku} whose inventory should be incremented
* @param quantity greater than zero
* @throws IllegalArgumentException if quantity is less than zero or {@link #retrieveQuantityAvailable(Sku)} for
* the given sku returns null
* @see {@link #incrementInventory(Map)}
*/
public void incrementInventory(Sku sku, int quantity);
/**
* Attempts to increment inventory for a map of Skus and quantities.
*
* All must not be null and must be greater than zero or an IllegalArgumentException will be thrown.
*
* If any of the given {@link Sku}s inventory type is not {@link InventoryType#CHECK_QUANTITY} then this
* is a no-op and nothing actually happens
*
* @param skuQuantities the map of a {@link Sku} to the quantity that should be incremented
* @throws IllegalArgumentException if any of the quantities in the map values are null or less than zero, or if
* {@link #retrieveQuantityAvailable(Sku)} for the {@link Sku}s in the map is null
*/
public void incrementInventory(Map skuQuantities);
}