Documentation Home

Inventory Notifications

Customers (both registered and anonymous) can subscribe to inventory notifications via the InventoryNotificationService. This allows you to email the customer when an item has come back in stock via the processNotification method. Out of the box, this well send a very basic email to the customer via the template from a blAdvancedInventoryNotificationEmail bean of type EmailInfo. The available context objects added by default are 'notification' representing the current notification, as well as 'sku' and 'customer', both gleaned from the notification being processed.

There is also an example job class that you can use to process these notifications. The below example sets up a Quartz job to run at 2am every morning:

<bean id="inventoryAvailabilityNotificationJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject">
        <bean class="com.broadleafcommerce.inventory.advanced.notification.service.InventoryNotificationJob" />
    </property>
    <property name="targetMethod" value="execute" />
</bean>

<bean id="inventoryAvailabilityNotificationTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="inventoryAvailabilityNotificationJobDetail" />
    <property name="cronExpression" value="0 0 2 * * *" />
</bean>

The InventoryNotificationJob will then send an email when there is at least 1 item for the Sku.

If you need to customize the way in which notifications are processed, rather than overriding this entire job itself you might instead override the InventoryNotificationService process method.

There is also a controller, [com/broadleafcommerce/inventory/advanced/web/controller/BroadleafInventoryNotificationController.java]. This controller does not have any @RequestMapping annotations on it out of the box, but you can easily subclass and provide them yourself. For example:

@Controller
public class InventoryNotificationController extends BroadleafInventoryNotificationController {

    @Override
    @RequestMapping(value = "/inventory/notification/{skuId}", method = RequestMethod.GET)
    public String getNotificationForm(HttpServletRequest request, HttpServletResponse response, Model model,
            @PathVariable(value = "skuId") Long skuId) {
        return super.getNotificationForm(request, response, model, skuId);
    }

    /**
     * Creates a new {@link InventoryNotification}
     */
    @Override
    @RequestMapping(value = "/inventory/notification", method = RequestMethod.POST)
    public @ResponseBody Map<String, Object> addNotification(HttpServletRequest request, HttpServletResponse response, Model model,
            @RequestParam(value = "skuId") Long skuId,
            @RequestParam(value = "email") String email) {
        return super.addNotification(request, response, model, skuId, email);
    }
}

If you are starting from the demo site, the following Javascript will respond to a button click and pop up a form to submit your email address to be notified:

$(function(){

    var modalAccountOptions = {
        maxWidth    : 200,
        maxHeight   : 600,
        minHeight   : 150,
        fitToView   : false,
        width       : '100%',
        height      : '100%',
        autoSize    : true,
        closeClick  : false,
        topRatio    : 0,
        openEffect  : 'none',
        closeEffect : 'none'
    };

    // Bind all links with class 'create-review' to open the review modal
    $('body').on('click', 'a.inventoryNotification', function() {
        BLC.ajax({url: $(this).attr('href')}, function(data) {
            var extendedOptions = $.extend({
                afterShow: function() {
                    $('.simplemodal-wrap').find('form:first').find('input:first').focus();
                    return true;
                }
            }, modalAccountOptions);
            $.modal(data, extendedOptions);
        });
        return false;
    });

    $('body').on('click','.simplemodal-wrap input.subscribe_button', function() {
        var $form = $(this).closest("form");
        BLC.ajax({url: $form.attr('action'), 
                type: "POST",
                data: $form.serialize()
            }, function(responseData) {
                if (responseData.success) {
                    $.modal.close();
                    HC.showNotification("Successfully subscribed to inventory notifications");
                }
            }
        );
        return false;
    });     

});

The controller also assumes that you have a template that corresponds to the path catalog/partials/inventoryNotification for the notification form. An example template implementation for this form:

<div id="notification">
    <blc:form th:object="${reviewForm}" th:action="@{'/inventory/notification'}" method="POST">
        <div class="form30">
            <label for="email">Email:</label>
            <input class="field30" type="text" name="email" />
            <input type="hidden" name="skuId" th:value="${skuId}" />
        </div>
        <div class="button_container">
            <input class="subscribe_button big red" type="submit" value="Subscribe"/>
        </div>
    </blc:form>
</div>

Additional Reading