Advanced Picklist - Resource Reservations

Version 1

    This will cover how to establish an internal web service that allows for the creation of a picklist with enhanced constraint abilities.



    This application utilizes the CMBD as a repository of items that can be reserved. Typically focused on traditional CIs (phones, scanners, etc.), it could easily be extended to accommodate additional CI types such as rooms for a room reservation application.


    CI is extended to add a new field ‘Reservable’. This allows a subset of CIs of any given type to be made available for reservation and loan.


    To reserve a given CI, a new business object called ‘Reservation’ is added to the system. The reservation will be linked to the CI, and will track the requestor by linking to the CI contact.


    These two additions work in concert in a request offering. The user will select the type of item they want from the available list of reservable CIs. They then pick the start and end date of the reservation desired.


    The system will then calculate the available, reservable, CIs for that period and present them as a dropdown selection.


    The user will select the device they wish to reserve and submit the request. The workflow for this request will then add a reservation record for the CI in question.


    • Filtering is done by availability, reservable flag, and CI type only
    • No accounting is done for the period between reservation completion and being available for the next reservation. If time is needed after an item is returned, this should be accounted for in the reservation period.
    • No accounting is done for holidays or other non-working hours to prevent reservation attempts.
    • Only one item can be reserved per request. This is to ensure that conflicts can be resolved.
    • This does mechanism does not account for simultaneous reservations. If two or more reservations for the same equipment are made at the same time, a manual resolution process will need to be initiated in the workflow.
    • CI names should be unique if they are reservable
    • The number of CIs available for any given type should not exceed 500, as they will appear in a pick list.
    • Additional details about the device selected are not presented to the user, the name of the CI should be sufficient to select the correct device.
    • The reservation records could be configured into a calendar format using the built in Calendar feature of HEAT.
    • CI could be extended to show a reservations tab that shows current or previous records of reservations of the equipment. The tab could be hidden if the reservable flag is not set.

    Optional features

    • The reservation records could be configured into a calendar format using the built in Calendar feature of HEAT.
    • CI could be extended to show a reservations tab that shows current or previous records of reservations of the equipment. The tab could be hidden if the reservable flag is not set.


    Technical Detail

    1. Base CI object needs a new boolean 'Reservable' - This will track which CIs can be reserved. You may have to create a quick action that sets this flag on the desired items after it has been created.


    2. Two new business objects need to be created

         a. "Reservation"

              This is a normal business object

              Has a relationship to Contact and CI



         b. "ReservableResources"

                  This is an External Business object. Make sure that you are marking external when building the object.


    3. With the objects created, you can add the external web service for the external object.


    Add a new External BO Integration


    Select the Object you just created:


    Paste in the code (You can edit it at this point to meet your business needs):


    //Return set of resources - this will hold the values to push to the picklist

    function possibleresource(name, ciType, startDate, endDate)


    this.Name = name;

    this.CIType = ciType;

    this.StartDate = startDate;

    this.EndDate = endDate;



    //Set parameters from request offering (based on the constraints) into the local variables


    var startRequestTimeStr = HeatContext.Arguments.StartDate[0];

    var endRequestTimeStr = HeatContext.Arguments.EndDate[0];

    var ciTypeStr = HeatContext.Arguments.CIType[0];


    //Data call to get a list of all CIs that can be reserved and of a set type

    var resources = Search('CI#').Where({Reservable: true, CIType: ciTypeStr });


    //calculate the start and end times into local variables from strings

    var startRequestTime = Math.round(new Date(startRequestTimeStr).getTime()/1000);

    var endRequestTime = Math.round(new Date(endRequestTimeStr).getTime()/1000);


    console.debug(startRequestTimeStr + " as " + startRequestTime + " to " + endRequestTime + " requested");


    //initialize the var

    var result = [];

    //Start to iterate over the list of resources (based on type)

    while (resources.MoveNext()) {

    console.debug("resource named " + resources.Current.Fields['Name']);

    //not reserved by default

    var reserved = false;

    //datacall to get a list of reservations already in the system.

    var reservations = Search('Reservation#').Where({Resource: resources.Current.Fields['Name']});

    //iterate over the list of current reservations to see if the Ci is already reserved

    while (reservations.MoveNext()) {

    var startReservationTime = Math.round(reservations.Current.Fields['StartTime'].getTime()/1000);

    var endReservationTime = Math.round(reservations.Current.Fields['EndTime'].getTime()/1000);

    console.debug("validating reservation for " + resources.Current.Fields['Name']);

    console.debug(" at " + startRequestTime + " " + endReservationTime + " " + startReservationTime + " " + endRequestTime);

    //Logic to check if resource is already reserved

    if ( startRequestTime <= endReservationTime && startReservationTime <= endRequestTime) {

    //item is reserved, mark it

    reserved = true;



    //item is not reserved, add it to the picklist

    if (!reserved) {

    console.debug("resource free = " + resources.Current.Fields['Name']);

    //push the value

    result.push(new possibleresource(resources.Current.Fields['Name'],ciTypeStr, startRequestTimeStr,endRequestTimeStr));




    if (!!HeatContext.PickList){SetReturnData(result);};


    Save and publish the code.


    Pick List


    Constraints are used to pass the arguments into the web service script.


    Request Offering:

    Type of Equipment is a combo box, driven by the CI Type pick list. Could be changed to a different pick list if a narrower list of just reservable items is desired.

    Resource Requested uses the “Available Resources” pick list.

    It passes the constraints start, return and type to the script so the results can be appropriately constrained to available resources. (ones where there is no overlapping reservation record).




    The workflow of the request offering adds a new Reservation object. This fills the values of the reservation, and links the employee. As the CI recID is not known at this time, a triggered business rule exists on the reservation, so that when a new reservation is created, if no CI is linked, it will do a search and link to attach the relevant CI based on Name being the same as the reservation.


    Reservation# Triggered business rule:




    Access point show no items as they are not marked as reservable


    Phones have been marked as reservable, they appear in the list




    You can't select it again in the same timeframe: