Árvore de páginas

Index

 

Customization of Events

The customization of events is performed by creating scripts in the "JavaScript" scripting language. The implementation code of each script is stored in database and does not require the use of any other files, like for example, "custom.p".

The customization of events for Fluig are created by the administrator from Fluig Studio. In the Fluig project, right click the folder  events  and then  New -> Fluig Global Event  as shown in the figure below.

Figure 1 - Event creation - Fluig Studio.


Then simply enter the Server and the Name of the Event that will be added. A screen for editing the event opens, as in the following image:

Figure 2 - Event creation - Fluig Studio.


You can also note that the .js file has been added to the project's  events  folder.

 

Fluig allows you to use execution log in the customization of events. Through the global variable "log", you can get feedback of the execution of each event. There are four log levels, they are:

  • ERROR:  presentation of errors.
  • DEBUG:  debug execution.
  • WARN:  inform possible execution problem.
  • INFO:  presentation of messages.

 

The presentation of each of the log types is conditioned to the application server configuration. For example, in JBoss®, by default, messages of the info and warn type are displayed on the server console and the debug and error type are displayed in the log file. Following is an example of log in script use:

            log.info ("Testing the log info");

There would be at the server console, the "Testing the log info" message.


Attention

Icon

Most events have WKUser to identify the user. This one by using the substitute function, where a user can substitute another, will always return the user that is currently using the system.

Example: Ana set Bruno as her substitute, Bruno accesses the system and makes an action on behalf of Ana. The system will return user code Bruno in the events that use WKUser.

 

Available Events

Following, the events available in Fluig will be detailed.

AddDocumentConvertionExt

This event enables you to customize document conversion performed by Fluig. More information about it can be found in the  Document Converters guide.

 

DisplayCentralTasks

This event is triggered before task central is displayed. Through it you can insert, change, or remove the links from task central. The event receives as parameter a LinkedHashMap with links available at task central.

Example adding a custom link at the end of the items of task central:

function displayCentralTasks (links){
links.put("Fluig","http://www.fluig.com");
}

 

Examples changing the display order of the links and adding three new ones, one at the beginning and two at the end:

function displayCentralTasks (links){
	var _links = new java.util.LinkedHashMap();
	_links.put("Fluig","http://www.fluig.com");                                     
    var it = links.keySet().iterator();
    while (it.hasNext()) {           
       var key = it.next();
       _links.put(key, links.get(key));
	}             
	_links.put("Fluig - DEV" ,"http://dev.fluig.com");
	_links.put("Google","http://www.google.com.br/search?sourceid=chrome&ie=UTF-8&q=" + getValue("WKUser"));
	links.clear();
	links.putAll(_links);
}

 

Some information about the user and the company have been made available, but only for query through the getValue method.

WKUser

User code

WKCompany

Company number

Example
function displayCentralTasks (links){
log.info("User: “ + getValue("WKUser"));
}

 

DisplayCustomMetadata

This event is triggered before the customized fields of a document are displayed, both at post and editing. Through it you can suggest the initial values for document metadata customized fields. The event receives a reference to the customized fields as parameter.

Example
function displayCustomMetadata(fields){
}

In the context of this event, the variable fields can be used to query or modify the values of the customized fields in a document. It does not allow adding new fields.

To add new fields to a document, there are several possible ways.

  • By inheritance from the parent folder.
  • In the Customized Fields registration, by selecting the option  Show in all documents  or the default way.
  • Through the WebService CustomFieldsService.
  • When editing the document metadata, by the user.

 

To query the value of a customized field in this event, use fields.getValue, passing as parameter the desired field code. Returning "null", if the field is not available for this document.

Example
function displayCustomMetadata(fields){
	log.info("Value of Field 1: “ + fields.getValue("campo1"));
}


For editing, use fields.setValue, passing as parameter first the field name, then the value.

Example
function displayCustomMetadata(fields){
	fields.setValue("field1","Value for Field 1");
}

 

 

In addition to the values of the customized fields, we provide some document information that is being created or edited, however only for query through the getValue method.

WKUser

User code

WKCompany

Company number

WKNumParentDocument

Parent folder number

WKDocumentType

Document type

WKPrivateDocument

If the document is being published in the private folder (true/false)

Example
function displayCustomMetadata(fields){
	log.info("User: “ + getValue("WKUser"));
}

 

ValidateCustomMetadata

This event is triggered before saving the values of the document customized fields, both at post and editing. Through it you can change or validate the customized field values of document metadada. The event receives a reference to the customized fields as parameter.

Example
function validateCustomMetadata(fields){
}


In the context of this event, the variable fields can be used to query or modify the values of the customized fields in a document. It does not allow adding new fields.

To add new fields in a document, there are several possible ways.

  • By inheritance from the parent folder.
  • In the Customized Fields registration, by selecting the option  Show in all documents  or the default way.
  • Through the WebService CustomFieldsService.
  • When editing the document metadata, by the user.

 

To query the value of a customized field in this event, use fields.getValue, passing as parameter the desired field code. Returning "null", if the field is not available for this document.

Example
function validateCustomMetadata (fields){
	log.info("Value of Field 1: “ + fields.getValue("campo1"));
}

 

For editing, use fields.setValue, passing as parameter first the field name, then the value.

Example
function validateCustomMetadata (fields){
	fields.setValue("field1","Value for Field 1");
}

 

In addition to the customized field values, we provide some information about the document that is being created or edited, but only for query through the getValue method.

WKUser

User code

WKCompany

Company number

WKNumParentDocument

Parent folder number

WKDocumentType

Document type

WKDocumentTypeId Document type ID

WKPrivateDocument

If the document is being published in the private folder (true/false)

WKNumAcess

Number of accesses

WKComments

Document comments

WKAuthor

Document author code

WKCreateDate

Document creation date

WKDescription

Document description

WKNumDocument

Document number

WKNumVersion

Document version number

WKExpirationDate

Document expiration date

WKExpires

Document expires? (true/false)

WKFileSize

Document size in bytes

WKKeyWord

Document keywords

WKVolume

Document volume

WKSubject

Subject related to the document

Example
function validateCustomMetadata (fields){
	log.info("User: “ + getValue("WKUser "));
}

 

The exceptions can be handled using the command throw.

This command returns a message to the user when they try to save the document.

Example
function validateCustomMetadata (fields){
	if( fields.getValue("campo1") == “Area 1”){
   		throw "EXCEPTION HANDLING";
	}
}

 

 

BeforeDocumentPublisher

Used when customized validation must be done in the document post/editing screen properties, before saving it to the database. Among all the document posting/editing screen properties, the custom fields will not be handled, because there is already an event that handles this situation.

Example
function beforeDocumentPublisher(){
}

 

Some properties are made available regarding the document that is being created or edited, but only for query through the getValue method.

 

Property

Description

Type

WKDocument

Document Object

DocumentDto

WKSubject

Document Subject Description

String

WKListApprover

Document Approver List

List<ApproverDto>

WKListSecurity

List with document security

List <DocumentSecurityConfigDto>

WKListRelatedDocument

List with documents related to the document

List< RelatedDocumentDto>

WKState

Action status: PUBLISH or MODIFY

String

WKUser

Logged in user

String

WKCompany

Company Code

int

Note

Icon

The Dto objects will be explained in the chapter "Objects used in the events"


The product returns  null  when it is necessary to pick up one of the properties of the document that does not exist.

For example: Not all posted documents have an approver, thus the variable  WKListApprover  will only have information when there really are approvers in the post.

Example
function beforeDocumentPublisher(){
               
                var doc = getValue("WKDocument");
                var subject = getValue("WKSubject");
                var listApprover = getValue("WKListApprover");
                var listSeg = getValue("WKListSecurity");
                var listRelated = getValue("WKListRelatedDocument");
                var state = getValue("WKState");
                var user = getValue("WKUser");
                var company = getValue("WKCompany");

                log.info("Logged in User: " + user);

                log.info("Company: " + company);
               
                log.info("Document number: "+ doc.getDocumentId() + " - Version: "+ doc.getVersion());
               
                if(listApprover!=null){
                    for(j = 0; j < listApprover.size(); j++) {           
                        if (listApprover.get(j).getColleagueId().equals("adm")){
                            throw "The adm user cannot be the document approver";
                        }
                    }
                }

                if(listSeg != null){
                    for(j = 0; j < listSeg.size(); j++) {     
                        if (listSeg.get(j).getAttributionValue().equals("cvd")){
                            throw "The cvd user cannot be in document security";
                        }
                    }
                }

                if( listRelated != null){
                    log.info("The following documents are related to these documents: ");
                        for(j = 0; j < listRelated.size(); j++) {          
                            log.info("Document no.: "+ listRelated.get(j).getRelatedDocumentId());
                        }
                }
                log.info("Subject: " + subject);
                log.info("Status: " + state);
}

 

AfterDocumentPublisher

Used when you need to handle customization of the document posting/editing screen properties after saving it to the database. Among all of the document posting/editing screen properties, the custom fields will not be handled.

Example
function afterDocumentPublisher(){
}

The properties retrieved through the getValue() method are the same of the  beforeDocumentPublisher  events and the form of handing the properties can be seen in the example of the  beforeDocumentPublisher event.

 

BeforeDocumentViewer

Used when customized validation must be done prior to viewing a document.

Example
function beforeDocumentViewer (){
}

 

Some properties are made available regarding the document that is being viewed, but only for query through the getValue method.

Property

Description

Type

WKDocument

Document Object

DocumentDto

WKUser

Logged in user.

String

WKCompany

Company Code

int

Note

Icon

The  Dto  objects will be explained in the chapter "Objects used in the events".

Example
function beforeDocumentViewer(){

                var doc = getValue("WKDocument");
                var company = getValue("WKCompany");
                var ds
               
                try {
                               var c1 = DatasetFactory.createConstraint(                                                                                                                                                                                                                                                    "allocatedDocumentPK.companyId", company, company, ConstraintType.MUST);
                               var c2 = DatasetFactory.createConstraint( "allocatedDocumentPK.sourceDocument", doc.getDocumentId(), doc.getDocumentId(), ConstraintType.MUST);
                               var c3 = DatasetFactory.createConstraint( "allocatedDocumentPK.sourceVersion", doc.getVersion(), doc.getVersion(), ConstraintType.MUST);
                               var c4 = DatasetFactory.createConstraint("active", "true","true", ConstraintType.MUST);
                                var constraints = new Array(c1, c2, c3, c4);
                               ds = DatasetFactory.getDataset("allocatedDocument", null, constraints, null);

                }catch (e) {
                               log.error("Error trying to recover the document in CheckOut: " + e.message);
                }

                if(ds!=null && ds.rowsCount>0){       
                               throw  "This document is in Check Out and cannot be viewed. The document " + ds.getValue(0,"allocatedDocumentPK.destinationDocument") + " was generated and is under the responsibility of the user with registration "+ ds.getValue(0,"colleagueId");
                }
}

 

AfterSaveCard

Used when creating/saving the data of a form record through Document Browsing or through Workflow transactions, if you wish to save the form record data in an external format. For example, when creating the form record, send the data to a Webservice of another product.

 

Example
function afterSaveCard(companyId, formId, cardId, versionId, cardData){
}

 

With parameters:

Property

Description

Type

companyId

Company Code

int

formId

Form Code

int

cardId

Form Record Code

int

versionId Form Record Version int
cardData Form Record Data Hashmap <String, String>
Example
function afterSaveCard(companyId, formId, cardId, versionId, cardData){ 
	var custom = ServiceManager.getService("CustomCard"); 
	var serviceHelper = custom.getBean(); 
	var serviceLocator = serviceHelper.instantiate("com.totvs.technology.webdesk.forms.service.custom.CustomCardServiceLocator"); 
	var service = serviceLocator.getCustomCardPort();
 
	var ar = new Array(); 
	var it = cardData.keySet().iterator(); 
	while (it.hasNext()) { 
		var key = it.next(); 
		var field1 = serviceHelper.instantiate("com.totvs.technology.webdesk.forms.service.custom.CardKeyValue"); 
		
		field1.setKey(key); 
			field1.setValue( cardData.get(key)); 
		log.info('>' + key + ': ' + cardData.get(key)); 
 
		ar.push(field1); 
	} 
 
	var resultArr = serviceHelper.instantiate("com.totvs.technology.webdesk.forms.service.custom.CardKeyValueArray"); 
	resultArr.setItem(ar); 
	service.create(companyId, formId, cardId, versionId, resultArr); 
}

 

AfterDeleteCard

Used as a supplement to the afterSaveCard event. It is called whenever a form or a form record is deleted from the bin.

 

Example
function afterSaveCard(companyId, formId, cardId, versionId, cardData){
}

 

With parameters:

Property

Description

Type

companyId

Company Code

int

cardId

Form Record Code

int

Example
function afterDeleteCard(companyId,cardId){ 
	var custom = ServiceManager.getService("CustomCard"); 
	var serviceHelper = custom.getBean();
 
	var serviceLocator = serviceHelper.instantiate("com.totvs.technology.webdesk.forms.service.custom.CustomCardServiceLocator"); 
 
	var service = serviceLocator.getCustomCardPort(); 
 
	log.info("########## loaded the CustomCard service"); 
	service.deleteCard(companyId, cardId); 
}

 

BeforeWatchContent

Used when following some content from which record you wish to retrieve information and use it before the "follow" action. For example, to follow a document,you can retrieve its information and use it in a dataset.

 

Example
function beforeWatchContent(companyId, watchDTO){
}

 

With parameters:

Property

Description

Type

companyId

Company Code

int

watchDTO

Record data

WatchDTO

Example
function beforeWatchContent(companyId, watchDTO){
	if(watchDTO.getSocialWatchType() == "DOCUMENT"){
		var objClass = "com.totvs.technology.social.document.6";
		var objClass = watchDTO.getObjectClass();
		var patt = new RegExp( /\d+/) ; 
		var documentId = patt.exec(objClass) ;
		var documentVersion = watchDTO.getObjectId();
		var doc = getValue("WKDocument"); 
		var company = companyId; 
		var ds ;
		try { 
			var c1 = DatasetFactory.createConstraint( "allocatedDocumentPK.companyId", company, company, ConstraintType.MUST); 
			var c2 = DatasetFactory.createConstraint("allocatedDocumentPK.sourceDocument",documentId,documentId, ConstraintType.MUST); 
			var c3 = DatasetFactory.createConstraint("allocatedDocumentPK.sourceVersion", documentVersion,documentVersion, ConstraintType.MUST); 
			var c4 = DatasetFactory.createConstraint("active", "true","true",ConstraintType.MUST); 
			var constraints = new Array(c1, c2, c3, c4); 
			
			ds = DatasetFactory.getDataset("allocatedDocument", null, constraints, null); 
		}catch (e) {
			log.error("Error trying to recover the document in CheckOut: " + e.message); 
		} 
	 
		if(ds!=null && ds.rowsCount>0){ 
		 throw  "Your notification request was rejected because the document is in checkout." ; 
		}
	}
}

 

AfterWatchContent

Used when following some content from which record you wish to retrieve information and use it after the "follow" action. For example, when following a post, it is possible to retrieve its information and use it to inform the user about the post author.

 

Example
function afterWatchContent(companyId, watchDTO){	
}

 

With parameters:

Property

Description

Type

companyId

Company Code

int

watchDTO

Record data

WatchDTO

Example
function afterWatchContent(companyId, watchDTO){
	if(watchDTO.getSocialWatchType() == "POST"){
		throw "The user "+watchDTO.getUserAlias()+" will be notified about the post " + watchDTO.getText() + " of author " + watchDTO.getPostAuthor() ;
	}
}

 

BeforeUnwatchContent

Used when you stop following some content from which record you wish to retrieve information and use it before the "stop following" action. For example, when trying to stop following a community, you can decide if the user can stop following it.

 

Example
function beforeUnwatchContent(companyId, watchDTO){
}

 

With parameters:

Property

Description

Type

companyId

Company Code

int

watchDTO

Record data

WatchDTO

Example
function beforeUnwatchContent(companyId, watchDTO){
	if(watchDTO.getSocialWatchType() == "COMMUNITY"){
		
		throw "You cannot stop being notified about the community " + watchDTO.getDescription() ;
	}
}

 

AfterUnwatchContent

Used when you stop following some content from which record you wish to retrieve information and use it after the "stop following" action. For example, to stop following a post, you can retrieve its information and inform the user that this post has many followers.

 

Example
function afterUnwatchContent(companyId, watchDTO){
}

 

With parameters:

Property

Description

Type

companyId

Company Code

int

watchDTO

Record data

WatchDTO

Example
function afterUnwatchContent(companyId, watchDTO){
	if(watchDTO.getSocialWatchType() == "POST" && watchDTO.getNumberWatchers() < 3 ){
		log.erro("The post   \"" + watchDTO.getText() + "\" of author " + watchDTO.getPostAuthor() + " is no longer polemic" )
	}
}

 

OnNotify

To interfere with sending a Fluig default email, the onNotify global event should be used, which is triggered when any of the Fluig emails are sent. In this event, changes can be made, such as adding other email recipients, modifying the values of parameters used in the email template, etc.

Following is an example of how to implement this event:

function onNotify(subject, receivers, template, params) {
    if (template.match("TPLDOCUMENT_APPROVAL_PENDING") != null) {
        receivers.add("[email protected]");
    }
}

Attention

Icon

Starting with Fluig version 1.3.3, it is recommended to validate the template using template == "TPLDOCUMENT_APPROVAL_PENDINGinstead of the match() function, thus avoiding redundancies in customization, since match() can return as valid for more than one template in cases like TPLNEW_TASK and TPLNEW_TASK_POOL_GROUP.

 

 

The onNotify event is available in the global event list. When you select this event in the list of available events, the above function signature will already be populated automatically. This event provides the following parameters:

Parameter Description
subject Is the email subject. Changing this variable will result in all users receiving the email with the new subject configured. Example of use: subject.add("SUBJECT");
receivers List of email recipients. You can also add other emails from users who are not part of the process. You can also add emails from users who are not registered in Fluig, if you need to notify a person that does not have access to the system.
template Allows you to validate the type of email that is being sent (for example, template of a document under approval, expiring document, and so on). Based on this variable, we can distinguish which emails we want to customize. It is recommended to always check the template code in order to avoid changes in other types of email that do not need customization.
params It is a data map that allows changing/adding parameters to be provided in the email. The name of the parameters provided in this map must be the same as those used within the template file.

 

In the example presented above, it is being validated if the template is the "TPLDOCUMENT_APPROVAL_PENDING" (which corresponds to the document pending approval). If so, a new email will be added to the list of recipients. That is, besides the person responsible for the approval, another person will be notified, receiving a copy of the email. Since the template code is being validated, the other email types will not be affected.

The templates can be queried within the volume directory, in: <VOLUME>\templates\tplmail. If you need to add some parameter to the default email, the templates can be edited directly in this directory.

 

 

Important

Icon
  • The global event onNotify has variable bind to access log, datasetManager, DatasetFactory, DatasetBuilder, ConstraintType and ServiceManager.
  • It is recommended to check the list of parameters (params) received before using them, as they vary according to the template used.
  • When a workflow has onNotify event, the global onNotify event is ignored for those process emails.
  • It is essential to validate through the code of the template before any implementation, because ALL emails will go through this customization when the event is logged.

 

Objects used in events

There are some objects provided by the product that are used in events. In the next sessions they will be explained, as well as their methods and their returns.

 

DocumentDto

This object represents the document and its properties. There is more information about it in the table below:

 

Function

Function Description

Return Type

getDocumentId()

Returns the document number.

int

getVersion()

Returns the document version number.

int

getCompanyId()

Returns the code of the company in which the document was published.

Int

getUUID()

Returns the UUID (Universal Unique Identifier) of the document.

String

getDocumentTypeId()

Returns the type of the physical file, if it returns blank or null, it is because this type is not known to Fluig.

String

getLanguageId()

Returns the language code of the document.

String

getIconId()

Returns the icon code of the document.

int

getTopicId()

Returns the subject code of the document.

int

getColleagueId()

Returns the registration of the user who created the document.

String

getDocumentDescription()

Returns the document description.

String

getAdditionalComments()

Returns the additional comments of the document.

String

getPhisicalFile()

Returns the physical path where the document is stored.

String

getCreateDate()

Returns the creation date.

java.util.Date

getApprovedDate()

Returns the Approval date.

java.util.Date

getLastModifiedDate()

Returns the Date of the last modification.

java.util.Date

getDocumentType()

Returns the type of document, where:

0 to Root folder

1 to Folder

2 is Normal document

3 is External document

4 to Card index

5 to Card

7 to Workflow Attachment

8 to New Content

9 to Application

10 to Report

portal to Site

portalPage to Site Page

String

getExpirationDate()

Returns the expiration date.

java.util.Date

getParentDocumentId()

Returns the number of the parent Folder/Card Index

int

getRelatedFiles()

String with the name of the main physical file and attachments.

String

getActiveVersion()

Returns if the version is active.

boolean

getVersionDescription()

Returns the version description.

String

getDownloadEnabled()

Returns if the document allows Download

boolean

getApproved()

Returns if the document is under approval.

boolean

getValidationStartDate()

Returns data from which the document can be viewed.

java.util.Date

getPublisherId()

Returns the registration of the user who published the document.

String

getCardDescription()

Returns the description of the card for document of type 5.

String

getDocumentPropertyNumber()

Returns the card index that was used as the basis for creating the card, so it only has a value when the document is of type 5 (card).

int

getDocumentPropertyVersion()

Returns the version of the card index in which the card was created.

int

getPrivateDocument()

Returns if the document/folder is under the private folder.

boolean

getPrivateColleagueId()

If it is a private document, returns the user registration where this document is allocated.

String

getIndexed()

Returns if the document has already been indexed.

boolean

getPriority()

Returns the priority of the document.

int

getUserNotify()

Returns if it notifies users who have this subject of interest.

boolean

getExpires()

Returns if the document has expired.

boolean

getVolumeId()

Returns the volume where the document has been posted, if blank it uses the parent volume.

String

getInheritSecurity()

Returns if it inherits security from parent.

boolean

getUpdateIsoProperties()

Returns if it updates the properties of the controlled copy.

boolean

getLastModifiedTime()

Returns the time of the last modification in milliseconds.

String

getDeleted()

Returns if the document is in the bin.

boolean

getDatasetName()

Returns the dataset document, if the document is a card index.

String

getKeyWord()

Returns the keywords of the document. Each word is separated by a comma.

String

getImutable()

Returns if the version/review is unmodifiable.

boolean

getDraft()

Returns if the document is being edited, for document of "new Content" type.

boolean

getInternalVisualizer()

Returns if it uses internal viewer.

boolean

getPhysicalFileSize()

Returns the physical size of the main document and attachments.

float

Example
var doc = getValue("WKDocument");
log.info("Document number: "+ doc.getDocumentId() + " - Version: "+ doc.getVersion());

 

ApproverDto

This object represents the approvers and their properties. There is more information about it in the table below:

 

Function

Function Description

Return Type

getDocumentId()

Returns the document number.

int

getVersion()

Returns the document version number.

int

getCompanyId()

Returns the code of the company in which the document was published.

Int

getColleagueId()

Returns the user registration or the group code that is approving this document. It is possible to know if it will return a user or a group by type of approval.

String

getApproverType()

Returns the type of approval, where:

0 for User

1 to Group

int

getLevelId()

Returns the level of approval, in the case of approval levels.

int

Example
var listApprover = getValue("WKListApprover");
	if(listApprover!=null){
    	for(j = 0; j < listApprover.size(); j++) {           
       	 if (listApprover.get(j).getColleagueId().equals("adm")){
            throw "The adm user cannot be the document approver";
        }
    }
}

        

DocumentSecurityConfigDto

This object represents the security of a document and its properties, in the table below there is more information about it:

  

Function

Function Description

Return Type

getDocumentId()

Returns the document number.

int

getVersion()

Returns the document version number.

int

getCompanyId()

Returns the code of the company in which the document was published.

Int

getAttributionValue()

Returns the registration of a user or the code of the group that is in the security of this document. It is possible to know if it will return a user or a group by type of security.

Note: Returns blank when the type is all users.

String

getAttributionType()

Returns the type of security, where:

1 for User;

2 to Group;

3 to All Users.

int

getPermission()

Returns if it is a permission.

Note: If it is not a permission, it is a constraint.

boolean

getShowContent()

Returns if it lists the content.

boolean

getSecurityLevel()

Returns in the permission/restriction level, where:

-1 to no permission/restriction (denies access);

0 to Reading;

1 to Writing;

2 to Modification;

3 to Total.

int

getSequence()

Returns the permission/restriction string.

int

getSecurityVersion()

Returns if it uses this version security in the other ones.

boolean

Example
var listSeg = getValue("WKListSecurity");
if(listSeg != null){
    for(j = 0; j < listSeg.size(); j++) {     
        if (listSeg.get(j).getAttributionValue().equals("cvd")){
            throw "The cvd user cannot be in document security";
        }
    }
}

 

RelatedDocumentDto

This object represents the related document and its properties. There is more information about it in the table below:

 

Function

Function Description

Return Type

getDocumentId()

Returns the document number.

int

getVersion()

Returns the document version number.

int

getCompanyId()

Returns the code of the company in which the document was published.

int

getRelatedDocumentId()

Returns the number of the document that is related to the posted document.

int

Example
var listRelated = getValue("WKListRelatedDocument");
	if( listRelated != null){
   	 log.info("The following documents are related to these documents: ");
     for(j = 0; j < listRelated.size(); j++) {          
        log.info("Document no.: "+ listRelated.get(j).getRelatedDocumentId());
     }
}

 

WatchDTO

This object represents the notifications of following comments and its properties. There is more information about it in the table below:

 

Function

Function Description

Return Type

getEntityId()

Returns the code of the Content.

String

getUserId()

Returns the user code.

String

getUserAlias()

Returns the user alias.

String

getSociableId() Returns the sociable code. String
getCreationDate() Returns the creation date. String
getLastUpdateDate() Returns the date of the last update. String
getNumberComments() Returns the number of comments. String
getNumberLikes() Returns the number of supports. String
getNumberShares() Returns the number of shares. String
getNumberWatchers() Returns the number of follows. String
getNumberDenouncements() Returns the number of reports. String
getSocialWatchType() Returns the type (social) String
getPostAuthor() Returns the content author. String
getTags() Returns the tags. String
getText() Returns the text. String
getDescription() Returns the description. String
getObjectClass() Returns the class of the object. String
getObjectId() Returns the objectId. String

getThumbURL()

Returns the thumb url.

String


Customization of JMS Events

Fluig has JMS event customization, allowing you to create audit procedures on the basis of information provided by the product. JMS (Java Message Service) is a Java™ API that provides an asynchronous connection between applications through messaging.

The product triggers two types of customizable JMS messages, wdkDocument  and  wdkAbstract.

The  wdkDocument  will be triggered when Fluig documents are handled, for the application to receive the message with the information from the document, the class has to extend the MessageListener and have the following line:

@MessageDriven(mappedName = "custom/DocumentListener", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/wdkDocument")})

 

The return object will be a MapMessage which will contain the following parameters:

  • event (String): Provides the type of event that was performed with the document, as shown in the table below:

Event

Description

PUBLISH

A new document posted.

MODIFY

Document is modified

DELETE

Document is deleted from the database.

SENDRECYCLE

Document is sent to bin.

DELETEFOLDER

A folder is deleted from the database.

EXTERNALCONVERTION

Document with custom conversion.

CONVERTIONLONGTERM

Document converted to long term.

MOVE

One or more documents or folders have been moved from one folder to another.

RESTORERECYCLE

Restores documents and folders from the Bin.

 

  • companyId (Integer): Code of the company in which the document was handled.
  • colleagueId (String): User who performed the action.
  • documentId (Integer): Code of the document that experienced the action.
  • version (Integer): Document version number.
  • lhasCreatedDocument (Boolean): Reports if document was created.
  • IhasIncreasedVersion (Boolean): Reports if the version was incremented.
  • changedApproval (Boolean): Reports if the approver has been modified.
  • document (byte[ ]): Array of bytes with the document and its properties.

 

Example
import java.util.Enumeration;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(mappedName = "custom/DocumentListener", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/wdkDocument")
})

public class DocumentListenerMessageBean implements MessageListener {

    @Override
    public void onMessage(Message message) {
        try {
            System.out.println("========Document Listener========");
            System.out.println("Message received: " + message.getJMSMessageID());
            if (message instanceof MapMessage) {
                MapMessage mm = (MapMessage) message;
                @SuppressWarnings("unchecked")
                Enumeration<String> es = mm.getMapNames();
                while (es.hasMoreElements()) {
                    String prop = es.nextElement();
                    System.out.println(prop + ": " + mm.getObject(prop));
                }
            }
            System.out.println("========End of Document Listener========");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

The  wdkAbstract  will be triggered when some Fluig objects are handled, according to the table below:

 

Object

Description

DB Table

Icon

Icon

ICON

Topic

Subject

TOPIC

Shortcut

Menu Security

MENU_ICON

LogAccess

Access Log

LOG_ACCESS

ColleagueReplacement

Substitute

COLAB_SUBSTTO

Application

Application

APLICATIVO

ProgressLib

Progress Environment

AMBIEN_PROGRESS

GlobalCalendar

Holiday

CALEND_GLOBAL

Term

Term

TERM

Synonym

Synonym

SYNONYM

DocumentType

Document Type

TIPO_DOCUMENTO

Volume

Volume

VOL_FISIC

AttributionMecanism

Assignment Mechanism

MECAN_ATRIBUIC

EmailTemplate

Email Template

TEMPLATE_EMAIL

CustomizedDatasetBuilder

Dataset

SERV_DATASET

DataService

Services

SERV_DADOS

CustomFields

Customized Fields

CAMPO_CUSTOM

UserGraphicSetings

Dashboard

CONFIGUR_GRAF_USUAR

Watermark

Watermark

MARCA_DAGUA

WebLayout

Layout

WEBLAYOUT

Adapter

Adapters

ADAPTER

 

For the application to receive the message with the information of these objects, the class has to extend the MessageListener and have the following line:

@MessageDriven(mappedName = "custom/DocumentListener", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/wdkAbstract")})

 

The return object will be a MapMessage which will contain the following parameters:

  • event (String): Provides the type of event that was performed with the object, as shown in the table below:

Event

Description

CREATE

A new object was created.

UPDATE

An object was modified

DELETE

An object was deleted from the database.

 

  • userId (String): User who performed the action.
  • entity (String): The object entity that is being handled, according to the object table that has already been presented above.
  • mapNewVersion (byte[ ]): Array of bytes of a HashMap < String, Object > with the property of the object.
  • mapPreviousVersion (byte[ ]): Array of bytes of a HashMap < String, Object> with the property of the object before the change.

 

Note

Icon

This map has no objects when the event is CREATE and DELETE.

 

To transform the Array of bytes received in the message in a HashMap, just use the function below:

 private Map<String, Object> decoderMap(byte[] array) {
    
        if(array.length>0){
            ByteArrayInputStream bos = new ByteArrayInputStream(array);
            ObjectInputStream p = new ObjectInputStream(bos);
            Object docObject = p.readObject();
            try{
                Map<String, Object> map = (Map<String, Object>) docObject;
                return map;
            }catch(java.lang.ClassCastException e){
                e.printStackTrace();
            }
        }                   
        return null;
    }
Example
 package com.totvs.fluig.custom.dm;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(mappedName = "custom/DocumentListener", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/wdkAbstract")
})
public class AbstractListenerMessageBean implements MessageListener {
    @Override
    public void onMessage(Message message) {
        try {
            System.out.println("==============Abstract Listener====================");
            System.out.println("Message received: " + message.getJMSMessageID());
            if (message instanceof MapMessage) {
                MapMessage mm = (MapMessage) message;
                @SuppressWarnings("unchecked")
                Enumeration<String> es = mm.getMapNames();
                while (es.hasMoreElements()) {
                    String prop = es.nextElement();
                    System.out.println(prop + ": " + mm.getObject(prop));
                    if(prop.equalsIgnoreCase("mapNewVersion")
                            || prop.equalsIgnoreCase("mapOldVersion")){
                        Map<String, Object> m = decoderMap(mm.getBytes(prop));
                        Iterator it = m.entrySet().iterator();
                        while (it.hasNext()) {
                            Map.Entry e = (Map.Entry)it.next();
                            System.out.println(prop + " - " + e.getKey() + ": " + e.getValue());
                        }
                    }
                }
            }
            System.out.println("==========End of Abstract Listener===============");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
      
    private Map<String, Object> decoderMap(byte[] array) throws IOException, ClassNotFoundException{
        if(array.length>0){
            ByteArrayInputStream bos = new ByteArrayInputStream(array);
            ObjectInputStream p = new ObjectInputStream(bos);
            Object docObject = p.readObject();
            try{
                Map<String, Object> map = (Map<String, Object>) docObject;
                return map;
            }catch(java.lang.ClassCastException e){
                e.printStackTrace();
            }
        }                   
        return null;
    }

}