Displaying attachments on list view

LRobinson
Giga Contributor

I have added the "has attachment" field to my Incident form, and created the BR (from the wiki) to update the field to "true" when an attachment is added to an incident.   Although it works fine when I add an attachment to an Incident, I am having two problems with the script:

1. If I delete (remove) the attachment, the field doesn't change to "false" (unchecked).

2. I want all incidents with attachments to show "true" so that we can sort on this field, and it currently is only working when I add the attachment and update.

 

I've tried multiple modifications (with weak javascript skills) and have had no luck.   This is the BR on the sys_attachment table, run "after" insert or delete:

 

checkAttachment();

 

function checkAttachment(){

      // if inserting then the task has an attachment

      if (current.operation() == 'insert' || current.hasAttachments()) {

              hasAttachment('true');

      }

 

      // if deleting attachment check for other attachments

        if (current.operation() == 'delete') {

              //var timeNow3 = new GlideDateTime();

                  //gs.log('has_attachment br: gliderecord query start date time is: ' + //timeNow3.getNumericValue(),'jwtest');

              var attachCount = new GlideAggregate('sys_attachment');

              attachCount.addQuery('table_sys_id',current.sys_id);

              attachCount.addAggregate('COUNT');

              attachCount.query();

           

              var numAttachments = '0';

              // if no other attachments task does not have attachment

              if (attachCount.next()) {

                      numAttachments = attachCount.getAggregate("COUNT");

                      if (numAttachments > 0){

                              hasAttachment = 'true';

                      }

              }

              else {

                      hasAttachment = 'false';

              }

              //var timeNow4= new GlideDateTime();

                  //gs.log('has_attachment br: gliderecord query start date time is: ' + //timeNow4.getNumericValue(),'jwtest');    

      }

}

 

function hasAttachment(answer) {

      var inc = new GlideRecord('incident');

      inc.addQuery('sys_id',current.table_sys_id);

      inc.query();

 

      if(inc.next()) {

              inc.u_has_attachment = answer;

              inc.autoSysFields(false); //Don't set the lastUpdatedTime or the Simultaneous Update Alert will likely get triggered

              inc.setWorkflow(false); //Don't allow other business rules to run, otherwise multiple notifications will likely be sent

              inc.update();

      }

}

1 ACCEPTED SOLUTION

LRobinson
Giga Contributor

Hi,


I have created this solution to update the new "u_has_attachments" field on existing active records with attachments:



var rec = new GlideRecord('incident');


  rec.addActiveQuery();


  rec.query();



  while(rec.next()){


      if(rec.hasAttachments()){


          rec.u_has_attachments = 'true';  


          } else {  


          rec.u_has_attachments = 'false';  


          }  


    rec.setWorkflow(false);  


    rec.autoSysFields(false);


    gs.log("Incident: " + rec.getDisplayValue() + " has attachments");  


    rec.update();  


}  



I ran this from scripts-background and it updates the "u_has_attachment" field on the Incident record so that "true" or "false" displays as required in listview (or reports), and can then be used for sorting or filtering.


I modified the script you provided using the wiki "hasAttachments" script (GlideRecord - ServiceNow Wiki) to find this solution.


View solution in original post

19 REPLIES 19

Slava Savitsky
Giga Sage

You are saying yout BR is running on Attachments table. In this case, current refers to the attachment itself, not the corresponding incident record. So I do not quite understand what this condition is for because normally attachments do not have attachments:



... || current.hasAttachments()



Similarly, when you are processing a delete, I think you should be using current.table_sys_id instead of current.sys_id in the following piece of code:



attachCount.addQuery('table_sys_id',current.sys_id);



Otherwise, you are referring to the sys_id of the attachment itself.



Finally, when you get the count of attachments, you assign true or false value to the hasAttachment variable instead of calling the hasAttachment() function defined below.



If you fix these inconsistencies, your script will look similar to this:



checkAttachment();

function checkAttachment() {
      if (current.operation() == 'insert')
              hasAttachment('true');

      if (current.operation() == 'delete') {
              var attachCount = new GlideAggregate('sys_attachment');
              attachCount.addQuery('table_sys_id', current.table_sys_id);
              attachCount.addAggregate('COUNT');
              attachCount.query();


              var numAttachments = 0;


              if (attachCount.next()) {
                      numAttachments = attachCount.getAggregate('COUNT');
                      if (numAttachments > 0)
                              hasAttachment('true');
              } else {
                      hasAttachment('false');
              }
      }
}

function hasAttachment(answer) {
      var inc = new GlideRecord('incident');
      inc.addQuery('sys_id', current.table_sys_id);
      inc.query();

      if(inc.next()) {
              inc.u_has_attachment = answer;
              inc.autoSysFields(false);
              inc.setWorkflow(false);
              inc.update();
      }
}



By the way, I noticed you were assigning string values of 'true' and 'false' to u_has_attachment field? Is it a string field?


Hi, thank you for the help.   The field is boolean - True/False.   I tried your modifications, but the functionality remains the same.


The field is still "true" if I delete/remove the attachment, and the listview does not update to show "true" for all current records with attachments.   The only thing working properly is when I add an attachment and update, then the field updates to "true".  


DrewW
Mega Sage
Mega Sage

This is the code we did almost 4 years ago and as far as I am aware we have had no issues with it.




//This BR is used to mark a task as having attachments or not so


//that a paper clip can be displayed on the list view in the number field.



if(current.operation() == 'insert' || current.operation() == 'update'){


    hasAttachments();


} else if(current.operation() == 'delete'){


    verifyAttachments();


}



function hasAttachments(){


    var at = new GlideRecord(current.table_name);


    at.addQuery('sys_id', current.table_sys_id);


    at.query();


    if(at.next()){


          if(at.u_has_attachments != 'true'){


                at.u_has_attachments = 'true';


                at.update();


          }


    }


}



function verifyAttachments(){


    var at = new GlideRecord('sys_attachment');


    at.addQuery('table_sys_id', current.table_sys_id);


    at.addQuery('table_name', current.table_name);


    at.query();


    if(at.next()){


    } else {


          var tsk = new GlideRecord(current.table_name);


          tsk.addQuery('sys_id', current.table_sys_id);


          tsk.query();


          while(tsk.next()){


                tsk.u_has_attachments = 'false';


                tsk.update();


          }


    }


}



LRobinson
Giga Contributor

Thank you!


That one works great when I add or delete attachments.


I am still working on updating existing records using this background script that looks like it should work, however it is only identifying the records with attachments, not updating as required:


  1. //get all task tables for an instance  
  2. var tu = new TableUtils("task");  
  3. var tables = tu.getAllExtensions();  
  4.  
  5. //get task related attachments  
  6. var gr = new GlideAggregate("sys_attachment");  
  7. gr.addQuery("table_name", "IN", tables); //query for table_name IN tables array  
  8. //group by table name and id  
  9. gr.groupBy("table_name");  
  10. gr.groupBy("table_sys_id"); //group by task sys_id so we don't process multiple attachments for a single task  
  11. gr.query();  
  12.  
  13. while (gr.next()) {  
  14.       //process each unique attachment task  
  15.       var table = gr.table_name;  
  16.       var id = gr.table_sys_id;  
  17.        
  18.       //get task record  
  19.       var task = new GlideRecord("task");  
  20.       if (task.get(id)) {  
  21.               //we have a valid task record  
  22.               if (!task.u_has_attachments) {  
  23.                       //only update if it's not already set  
  24.                       task.u_has_attachments = true;  
  25.                       task.setWorkflow(false);  
  26.                       task.autoSysFields(false);  
  27.                       gs.log("TASK: " + task.getDisplayValue() + " has attachments");  
  28.                       //just log for now to test  
  29.                       task.update();   //uncomment to actually update the record  
  30.               }  
  31.       }  
  32. }