Welcome to Community Week 2025! Join us to learn, connect, and be recognized as we celebrate the spirit of Community and the power of AI. Get the details  

Service Offerings in Service Portal

Sascha1
Mega Contributor

Hello Everyone,

is there an easy way to display the Service Offerings of a Service in the Service Catalog of the Service Portal?

For instance I have a Business Service "Bond Trading" with the Service Offerings "Bond Trading NY" and "Bond Trading London"

In the backend Service Catalog it looks just the way I expect it to be in the Service Portal as well:

find_real_file.png

In the Service Portal this is just an empty Catalog Item:

find_real_file.png

Is there an easy OOB way to display the Service Offerings the same way in the Service Portal?

Thanks in advance!

Sascha

7 REPLIES 7

erik_brostrom
Mega Guru

To my knowledge there  is not a OOB SP widget/page to support the Service offerings / service portfolio functionality. This would require a customized effort to create the widgets to display as desired, etc.

I'd recommend putting in a and enhancement with HI.

Alok Kumar2
Tera Expert

Hi,

I had one such requirement in the past where I ended up creating a new widget for it on portal.

You can use the below code for you widget:

HTML:

<div  class="panel " ng-if="data.flag">
  <div class="panel-heading bg-primary" >{{data.business_service}}</div>
  <div class="row">
  <div class="panel-body" >
    <div class="col-md-6">
      <h4 class="head">In Scope</h4>
    <ul ng-repeat="scope in data.inScope track by $index">
    	<li>{{scope}}</li>
    </ul>
    </div>
    <div class="col-md-6">
      <h4 class="head">Out of Scope</h4> 
      <ul ng-repeat="scope in data.outScope track by $index">
    	<li>{{scope}}</li>
    </ul>
    </div>   
  </div>
  </div>
  <div class="row">
    <div class="panel-body" >
       <h4 class="head">Service Offerings</h4>
  <div class="col-md-3" ng-repeat="of in data.offerings track by $index" class="catalog_specs_card">
     
    <div class="catalog_specs_detail">
      <ul>
         <h5 class="head">{{of.name}}</h5> 
        <li><label>Location: </label>{{of.location}}</li>
        <li><Label>Manager: </Label>
          {{of.manager}}
        </li>
        <li><Label>Operational Status: </Label>{{of.oprtn}}</li>
        <li><label>Tech Support: </label>
          {{of.tech_contact}}
        </li>
         <h4 >Commitments</h4> 
        <div class="commitment">
        <div ng-repeat="l in of.comList track by $index">
          <img width="16" height="16" src="images/outputmsg_success.gifx" /> {{l}}
        </div>
        </div>
      </ul>  
    </div></div>
    
  </div>
  </div>
  </div>
   

Server Script:

(function() {
  /* populate the 'data' object */
  /* e.g., data.table = $sp.getValue('table'); */
	/**Custom widget to display the Service Portfolio Details**/
	/**Author@Alok Kumar**/
	var bsm= '';
	data.inScope= [];
	data.outScope=  [];
	data.commitments= [];
	data.offerings= [];
	data.of_com_list= [];
	data.flag = false;
	var sys = $sp.getParameter('sys_id');
	var g= new GlideRecord('sc_cat_item_service');
	g.addQuery('sys_id',sys);
	g.query();
	while(g.next()){
		data.flag= true;
		bsm=g.getValue('cmdb_ci_service');
		data.business_service= g.getDisplayValue('cmdb_ci_service');
		var sc= new GlideRecord('service_in_scope');
		sc.addEncodedQuery('cmdb_ci_service='+bsm);
		sc.query();
		while(sc.next()){
			data.inScope.push(sc.getDisplayValue('service_scope'));
		}
	var os =new GlideRecord('service_out_scope');
	os.addEncodedQuery('cmdb_ci_service='+bsm);
	os.query();
	while(os.next()){
		data.outScope.push(os.getDisplayValue('service_scope'));
	}
}	
	var com = new GlideRecord('service_offering');
	com.addEncodedQuery('parent='+bsm);
	com.query();
	while(com.next()){
		data.ofr_name= com.getDisplayValue('name');
		var so= {};
		so.name= com.getDisplayValue('name');
		so.location= com.getDisplayValue('location');
		so.manager= com.getDisplayValue('managed_by');
		so.oprtn= com.getDisplayValue('operational_status');
		so.tech_contact= com.getDisplayValue('technical_contact');
		data.offerings.push(so);
		var of_com =new GlideRecord('service_offering_commitment');
		of_com.addEncodedQuery('service_offering='+com.getValue('sys_id'));
		of_com.orderBy('order');
		of_com.query();
		var ar= [];
		while(of_com.next()){
			//console.log(of_com.service_commitment.availability)
			ar.push(of_com.getDisplayValue('service_commitment'));
			//data.of_com_list.push(of_com.getDisplayValue('service_commitment'));
			//so.comList.push(of_com.getDisplayValue('service_commitment'));
		}
		so.comList= ar;
	}
	
})();

 CSS:

.shift-left{
padding-left: 2%;
}
.catalog_specs_card{
    background-color: #f6f6f6;
    width: 18.25em;
    border: 1px solid #CCC;min-height: 420px;
    float: left;
    margin: 6px;
    margin-top: 12px;
    padding: 0;
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
}
.catalog_specs_detail {
    background-color: #FFF;
    padding: 4px;
}
.commitment{
max-height: 200px;
  overflow: auto;
}
.head{
 background-color: #f6f6f6;
}

You can add this widget to your sc_cat_item page or create a new page and link your service offering item to that page and the widget there as we did in our case!

It eventually looks something like this:

find_real_file.png

Note:Please mark it correct or helpful if it works!! 

 

Hi Alok,

I appreciate this is an old post but it is really good!

Can you just tell me how I can actually present my data from the server script into the front end widget? I seem to be having trouble writing the code within the HTML.

Thank you 🙂

Hi Keith,

Sorry for replying late on this, not sure you still have the issue.

If you had used the same code that i just wrote above, it should have surely worked. You can paste your code in the comments then i can try to investigate further on it.

 

Thanks,

Alok