Automated Document Processing & Numbering

With Module Suite, it is very easy to set up a process that allows automatic control of document numbering in order to add a unique and traceable reference to the document. It is possible to create numerous types of numbering structures using prefixes, suffixes and attribute constants combined with sequential numbering.

In this recipe, Module Suite has been used to intercept the creation of new documents within a specific space, to generate the necessary unique IDs, and to apply this information within the metadata and name of the new document. Additional information can also be extracted from the document itself, when available. Here, we are extracting information such as the document title and author from MS Office documents and storing it as metadata in the system.

The sample metadata fields included in the “Controlled Document” category we will be using are the following:

  • Doc ID
  • Title
  • Author
  • Owner
  • Status
  • Department

In order to automate the process, we will bind our business logic to a Content Script Synchronous Event Callback, associated to a “ChildNodeCreate” event: this means that, whenever a new object is created within the predefined space, our logic will be executed.

Let’s have a look at what the script could look like:

def newNode = asCSNode(newNodeID) // In ChildNodeCreate events, this allows us to intercept the new node.

if( newNode.subtype == 144 ){ // we are only interested in documents

    // Get current user performing the operation
    def currentUser = users.current
    
    // Get the next value for a database sequence, used to rename the document and set the metadata 'Doc ID'
    def seq = 0
    try{
        seq = sql.runSQL("SELECT NEXT VALUE FOR Z_ADNRecipeSequence sequence").rows[0].sequence
    }catch(e) {
        log.error("Could not retrieve sequence Z_ADNRecipeSequence", e)
    }

    def docName    = "DOC-" + "${seq}".padLeft(6, '0') // Define the document name using the DB sequence (eg. DOC000123)
    def title      = newNode.name
    def author     = ""
    def owner      = currentUser.ID
    def status     = "Draft"
    def department = currentUser.departmentGroup.name


    // Get properties of docx/xlsx document using the APIs docx and xlsx. 
    // ( "Title" and "Creator" properties of the Office document )
    switch( newNode.mimeType ){

        case "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : // docx document
        
            def wordDocProperties = docx.loadWordDoc(newNode).listProperties()
            title  = wordDocProperties.title
            author = wordDocProperties.creator
            break

        case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" :  // xlsx document
        
            def excelProperties = xlsx.loadSpreadsheet(newNode).listProperties()
            title  = excelProperties.title
            author = excelProperties.creator
            break

        default :  // generic document (PDF, etc)
            
            author = currentUser.displayName  
 
            // Filename minus extension
            if (newNode.name.indexOf(".") > 0){
                title = newNode.name.substring(0, newNode.name.lastIndexOf("."))  
            }
    }

    // Assign automatic metadata
    
    if(newNode."Controlled Document"){

        newNode."Controlled Document"."Doc ID"     = docName
        newNode."Controlled Document"."Title"      = title
        newNode."Controlled Document"."Author"     = author
        newNode."Controlled Document"."Owner"      = owner
        newNode."Controlled Document"."Status"     = status
        newNode."Controlled Document"."Department" = department

        newNode.update()
    }

    // Rename document
    newNode.rename(docName)

}