Thứ Năm, 15 tháng 9, 2016

Call java from PL/SQL

1. Create file java

public class Hello
{
  public static String world()
  {
    return "Hello world";
  }
}

2. Complier file java 


Javac Hello.java

3. Loadjava to database 


C:\app\shbadmin\product\11.2.0\client_1\BIN>loadjava -r -user xxx@xxx d:
\Hello.class


4.Create function database 


 CREATE OR REPLACE FUNCTION helloworld RETURN VARCHAR2 AS
 LANGUAGE JAVA NAME 'Hello.world () return java.lang.String';

5 . Result:


select helloworld() from dual;


Note: Version javac and loadjava the same if different  error : \

java.lang.UnsupportedClassVersionError




Displaying Related Cases in ICM 5.2 

I described how you could use the Case List widget to display a list of "Related Cases"; cases that are somehow related to the case you are currently looking at.
This has been a pretty popular solution customization so I thought it was about time I updated it for ICM 5.2.x.






The use case here is that you want to display a list of related cases on a work details page that is used to process a task step for a particular case. You can easily modify the first bit if your Case List happens to be on another page (eg. payload.caseEditable.
  • Add a case list widget to your Work Details page
  • Use the wiring settings to disable the Select Case broadcast event. This ensures the case list does not interfere with other page widgets like the Case Infomation
  • Add a Script Adapter widget to the hidden page area
  • Enter the following script in the Script Adapter
  • Wire the inbound event of the Script adapter from the Page Container's "send Work Item" event
  • We use a broadcast event in our script so no need to wire the outbound event
var solution = this.solution;
var params = {};
var self = this;

/* This is good practice. Makes reusing scripts much easier */
var prefix = solution.prefix;

params.ObjectStore = solution.getTargetOS().id;

var custID = payload.workItemEditable.propertiesCollection[prefix+"_CustomerID"].value;
console.log ("Customer ID: ",custID);

var caseObj = payload.workItemEditable.icmWorkItem.caseObject;

/^ The following call ensures that the case data is loaded before we go try and get the case ID */

caseObj.retrieveCachedAttributes(function(caseObject) {
    var caseID = caseObject.caseIdentifier;
    console.log ("Case ID: ",caseID);

    /* Find all of these */
var criterion1 = new ecm.model.SearchCriterion({"id": prefix+"_CustomerID", 
"name" : "Customer ID", 
        "selectedOperator": "STARTSWITH", "defaultOperator": "STARTSWITH",
 "dataType": "xs:string"});
    criterion1.value = custID ;
    criterion1.defaultValue = custID ;
    criterion1.setValues( [custID]);

    /* But omit this one */
    var criterion2 = new ecm.model.SearchCriterion({"id": "cmAcmCaseIdentifier", "name" : "Title",
 "anded": true,
 "selectedOperator": "NOTEQUAL", "defaultOperator": "NOTEQUAL", 
"dataType": "xs:string"});
    criterion2.value = caseID;
    criterion2.defaultValue = caseID;
    criterion2.setValues( [caseID]);

    params.criterions = [criterion1, criterion2];
    params.CaseType = ""; /* all case types */
    params.solution = solution;

    var searchPayload = new icm.util.SearchPayload();
    searchPayload.setModel(params);

    searchPayload.getSearchPayload(function(payload) {
        self.onBroadcastEvent("icm.SearchCases", payload);
    });
});






 

Thứ Tư, 14 tháng 9, 2016

How to add a document as both work item attachment and case document

 


Sometime, when add an attachment from your local desktop, you may want to also add the attachment document as case document. This function can be implemented by replacing the attachment page widget's 'Add Document From Local System' action button by an event action and a script adapter.
With this function, in a work detail page, when add attachment, it allows the user to more easily file the new document into the case folder, without requiring the user to navigate to the case folder.
Configuration steps:
1. Replace the 'Add Document From Local File System' action inside the attachment widget with a Script Action EventAction.
2. Configure the EventAction
   2.1 Set the action label as "Add Document From Local File System"
   2.2 Set the event name as "icm.AddDocToBothCaseAndAttachment"
   2.3 Set the Enable this event action as
    var attachment = this.getActionContext("Attachment");
    if (attachment && attachment.length > 0) {
       attachment = attachment[0];
    }
 
   if ((attachment && (attachment.get("readOnly") == true)) || (!attachment)){
     return false;
   }else{
    return true;
   }
3. Put the script below into a script adapter inside work detail page. Disable the outbound event of the script adaptor.
4. Wiring the page container "icm.SendWorkItem" event to script adaptor's incoming event.
5. Wiring the attachment widget "icm.AddDocToBothCaseAndAttachment" event to script adaptor's inbound event.
6. Wiring the script adaptor outbound event to attachment page widget "icm.AddAttachment" event.
7. Optional, put a case document in the page to observe the case document updates.
 
Usage:
1. Open work item in work detail page, select a attachment in attachment widget.
2. Click on the "Add Document From Local File System" action button.
3. In the add document dialog, select a local document to add.
Script:
var self = this;
 
/*Wire to page container icm.SendWorkItem event, retrieve the workitem related case.*/
if (payload.eventName == "icm.SendWorkItem") {
    self.workItemEdt = payload.workItemEditable;
    self.workItemEdt.retrieveStep(function() {
        self.caze = self.workItemEdt.getCase();
    });
}
 
/*Wire to event action on attachment, which published the user configured event icm.AddDocToBothCaseAndAttachment*/
if (payload.eventName == "icm.AddDocToBothCaseAndAttachment") {
    /*Get the selected attachment sent from event action*/
    self.attachment = payload.Attachment;
 
    /*Callback to add case document as attachment*/
    var _addToAttachment = function(contentItem) {
        self.onPublishEvent("icm.SendEventPayload", {
            "attachmentName": self.attachment.id,
            "documents": [contentItem]
        });
    };
 
    /*retrieve the case folder, make it as the parent folder of the add document dialog*/
    self.caze.retrieveCaseFolder(function() {
        var parentFolder = self.caze.getCaseFolder();
        require(["ecm/widget/dialog/AddContentItemDialog"], function(AddContentItemDialog) {
            /*Create the add document dialog*/
            self.addContentItemDialog = new AddContentItemDialog();
            var contentItemGeneralPane = self.addContentItemDialog.addContentItemGeneralPane;
 
            /*Show the add document dialog*/
            self.addContentItemDialog.show(parentFolder.repository, parentFolder, true, false, _addToAttachment, null, false, null, true);
 
            /*Enable folder select in save in*/
            contentItemGeneralPane.folderSelector.setDisabled(false);
        });
    });
 
}

Customize the Get Next feature in ICM 5.2

Author:      Yan Fen Guo (gyfguo@cn.ibm.com), ICM Case Client QA tester;
                   Xiao Ji Tian (tianxj@cn.ibm.com), ICM Case Client developer.
Automatically “Get Next” is a common feature in business process, IBM Case Manager (ICM) as an application which can conveniently unites content, process and people, certainly it has this feature to provide flexible process controls, this blog entry will show you how “Get Next” works in ICM 5.2 and how to customize it to get next without showing the work items list.

Difference between ICM 5.1.1 and ICM 5.2
Assume you open a work item which is not the first one in In-basket, in ICM 5.1.1, after all the following work item has been processed, it can go back to the first one to process the rest; But from ICM 5.2, if a case worker doesn’t choose the first one to start, we think he doesn’t want to process the first one, so “Get Next” won’t go back to work items which are above the one just he opened. This means in ICM 5.2, “Get Next” will only handle the work items which are sequenced following the one you opened, after all done, even there are still some work items in In-basket (which above the one you opened),  it will pop up a dialog says no more work items to deal with.

Enable Get Next feature in ICM 5.2
By default, get next feature is not enabled; this means when you complete a current work item, it will automatically close the work detail page. There are two ways to enable get next by the following steps:
1. Open Work Details page in Page Designer.
2. Open Edit Setting window of work item toolbar, switch to Toolbarstab.
3. The first way is to double click to edit “Complete” button, you should be able to see the selection “Automatically get the next work item”. If you select it, every time a case worker clicks Complete button in Work Detail page during runtime, it will automatically retrieve the next work item until all the following work items in In-basket has been processed.
4. Another way is to add a separate “Open Next Work Item” action.

In this way, it will add a check box with label “Get Next” to work item toolbar. If you mark “Automatically get the next work item” when adding this action, the checkbox will be selected by default, and vice versa.

The second way is suggested since it more intuition, and you can decide whether to get next in runtime, not to speak this setting can overwrite the setting in “Complete” button.
Other notable features about Get Next
1. Get Next won’t deal with locked work item which is locked by other users, but if the next work item is locked by current user himself, it will directly open the work item in edit mode.
2. Get Next will always open the next work item in current work detail page, even the next work item is from different task type with different work detail page.

Customize Get Next feature to support the push-only mode
By default, you will see all the work item list and can choose anyone to process, but under some circumstance, user is expected not to see the whole list, every time he login the application, there is only one work item displays and he can only process by sequence. This is push-only mode, like custom service in bank or insurance company. Customer supporters are not expected to choose a favorite custom to service; they just service for any custom the system push to them.
To achieve this, first, we need to hidden In-basket, which can be easily done by hidden default Work page.
Open target solution, switch to Roles tab, click to open target role, then on Pages tab, remove Work page.
            


Second, we need to customize the Work Detail page to retrieve the first work item when work details page loaded. This can be done by the following steps:
1. Open Work Details page in Page Designer.
2. Add a Script Adapter widget to page then click the little black triangle on the top right, select Hide Widget to hide it. Open hidden area, you can see the hidden widget you just added. There is another default Script Adatper1 by default, ignore it since we won’t use it.

3. Click the Edit Settings icon on the Script Adapter widget and insert the script below into the JavaScript text area.
var self = this;
var role = self.role;
require(["icm/model/WorkItem","icm/util/WorkItemHandler"],function(WorkItem, WorkItemHandler){
        role.retrieveWorklists(function(inbaskets){
                if(inbaskets.length > 0){ /*if there are multiple In-baskets*/
                        var inbasket = inbaskets[0]; /*we choose the first one, this should be first role's In-basket*/
                        inbasket.retrieveWorkItems(function(resultSet){
                                var items = resultSet.getItems();  /*fetch the work items in this In-basket*/
                                if(items.length >0){  /*if there are multiple work items*/
                                   var first = items[0];  /*get the first one*/
                                   first = WorkItem.fromWorkItem(first);  /*this is to change an ICN work item to the format of ICM work item*/
                                   var workItemHandler = newWorkItemHandler(self);  /*open it*/
                   workItemHandler.handleCurrentPageWorkItem(first);  /*process the next first work item*/                                 
                                }
                        });
                }
        });
});
4. Open the Wire Events window and select Script Adapter, wire Page Container widget to send Page Opened event to Script Adapter.


Until now we’ve done the configuration, to use it, we need to open the work detail page directly when login ICM. Add these two properties“&page=CmAcmSTEP_DEFAULT_PAGE&pageType=StepPage” to the URL link you get by testing the solution from Case Builder. Like:http://ICMServer:PortNumber/navigator/?desktop=icm&feature=Cases&tos=%TOS%&solution=%Prefix%&page=CmAcmSTEP_DEFAULT_PAGE&pageType=StepPage.

When opening the link, it looks like the picture as below. No Work page and In-basket shown, and directly displays a work item.


Select Get Next checkbox and process the work item, it will automatically push next work item, when all done, the dialog “There are no more work items to be processed in this in-basket or the work item that you handled is at the end of this in-basket.” displays.


Summary
This blog entry introduces Get Next feature in ICM 5.2 and give an example on how to customize it to push only mode, hope this can give you as a reference when you using this feature.

Thứ Ba, 13 tháng 9, 2016

Sample data json for inbasket dynamic filler

var json = {
  "queueName":"DY_R1",
  //inbasket queue name
  "inbasketName":"R1",
  //inbasket name
  "hideFilterUI":true,
  // true will hide the inbasket filter
  "queryFilter":"(DY_Company = :A) OR (DY_Company = :A AND DY_LOC = :A) AND (DY_Int > :A)"
  //Please see PE Java API doc(VWWorkBasket class,fetchFilteredBatch function,
  //queryFilter parameter) to construct the parameter
  "queryFields": [
   {
     "name": "DY_Company",
     //filter field symbolic name
     "type": "xs:string",
     // filter field type
     "value":["ABC","XYZ"]
     // Array represents OR condition. The expression only supports equal operator.
    // When the filter operator is Equal, that mean "value=="ABC" OR value==XYZ"
    // If the filter field is a choice list type, value need to be input by choice item value
    // If the filter field is case type, value need to be input by case type id.
   },
   {
     "name": "DY_LOC",
     "type": "xs:string",
     "value":"Beijing"
   },
   {
     "name": "DY_Int",
     "type": "xs:integer",
     "value":2
   }
  ],
  "hideLockedByOther":true
  // true will hide the work items locked by other.
 };

How to filter in-basket base on service responce

var data= {};   
    data = {
                                                                    "queueName":"ONL_DVKD",
                                                                    "inbasketName":"DVKD",
                                                                    "hideFilterUI":false,
                                                                    "queryFilter":"(ONL_Pos_cd like :A)",
                                                                    "queryFields":[
                                                                    {
                                                                    "name":"ONL_Pos_cd",
                                                                    "type":"xs:string",
                                                                    "value":"*"
                                                                    }
                                                                    ],
                                                                    "hideLockedByOther":"true"
                                                                    };
                                                                   
                                                                   
require(
        [ "icm/base/Constants",
                "icm/model/properties/controller/ControllerManager",
                "ecm/model/Request" ],
        function(Constants, ControllerManager, Request)
        {
                                               
                                    var params = {};
                                    params.repositoryId = "icmcmtos";
                                    params.repositoryType = "p8";
                                    params.queryType = "CM_UserInfo";
                                    params.CM_UserName = ecm.model.desktop.userId;

                                    Request
                                            .invokePluginService
                                            (
                                                    "ICMCustomPlugin",
                                                    "QueryDocumentService",
                                                    {
                                                        requestParams : params,
                                                        requestCompleteCallback : function(
                                                                response)
                                                        {
                                                            console
                                                                    .log(
                                                                            "response: ",
                                                                            response);
                                                            userPoscode = response.CM_Poscode;
                                                           
                                                            console
                                                                    .log(
                                                                            "userPoscode: ",
                                                                            userPoscode[0]
                                                                        );
                                                            tmpposcode=userPoscode[0];       
                                                           
                                                            if (tmpposcode==="110000" || tmpposcode === undefined ||tmpposcode === "")
                                                            {
                                                            console
                                                                    .log(
                                                                            "hoi so: ",tmpposcode
                                                                        );   
                                                            data.queryFields[0].value = "%";
                                                            }
                                                            else
                                                            {
                                                                if (tmpposcode.substr(4,6)==="00")
                                                                {
                                                                    console
                                                                    .log(
                                                                            "chi nhanh: ",tmpposcode.substr(0,4)
                                                                        );   
                                                                data.queryFields[0].value = tmpposcode.substr(0,4) + "%";   
                                                                }
                                                                else
                                                                {
                                                                    console
                                                                    .log(
                                                                            "pgd: ",tmpposcode
                                                                        );   
                                                                data.queryFields[0].value = tmpposcode;       
                                                                }       
                                                            }
                                                        }
                                                    }
                                            );
                                       
                                                                                                                               
        }
    );
   
 var model = icm.model.InbasketDynamicFilter.fromJSON(data);
        var modelArray = [];
        modelArray.push(model);
console
                                                                    .log(
                                                                            "model_bug: ",
                                                                            model
                                                                        );
        return {"dynamicFilters":modelArray};

 

 

Thứ Năm, 8 tháng 9, 2016

Adds an in-basket dynamic filter

This customization scenario adds an in-basket dynamic filter. The in-basket
widget loads when the dynamic filter is received so that the results that are
shown in the in-basket widget already are filtered to the case worker.
Complete the following steps:
1. From Case Manager Builder, open Page Designer on the Work page.
2. Drag the Script Adapter widget from the widget palette area to the main layout
area.
3. Wire the Script Adapter widget to the Page Container widget under the
Incoming Events section by setting the following values:
– Source widget: Page Container
– Outgoing event: Page Activated
– Incoming event: Receive event payload
Click Add Wireto add this wiring setting.
4. Wire the Script Adapter widget to the Page Container widget under the
Outgoing Events section by setting the following values:
– Outgoing Event: Send event payload
– Target widget: In-baskets
– Incoming event: Apply filter
Click Add Wireto add this wiring setting.
5. Validate that the In-basket widget is wired appropriately.
6. Click the Edit Settings icon for the Script Adapter widget and paste the script
that is shown in Example 11-8 on page 438 into the JavaScript text area. The
following script grabs the current user name and constructs variables to pass
to the icm.model.InbasketDynamicFilter.fromJSON(data);function to
perform the dynamic filter.
Note:The script that is shown in Example 11-8 on page 438 is specific to
the Customer Complaints solution. Make sure to create a case property for
the Customer Complaints solution that is called AssignedToUser. The
in-basket dynamic filter searches on this case property and matches it to
the user name, which is case-sensitive.
======code=========

var myUser = ecm.model.desktop.userDisplayName;
var data = {
"queueName":"CC_Specialist",
"inbasketName":"Specialist",
"hideFilterUI":false,
"queryFilter":"(CC_AssignedToUser = :A)",
"queryFields":[
{
"name":"CC_AssignedToUser",
"type":"xs:string",
"value":"*"
}
],
"hideLockedByOther":"true"
};
data.queryFields[0].value = myUser;
var model = icm.model.InbasketDynamicFilter.fromJSON(data);
console.log(model);
var modelArray = [];
modelArray.push(model);
return {"dynamicFilters":modelArray};