Dynamic Assistant¶
As opposed to standard assistants, the dynamic nature allows for defining the steps using procedures. The steps must be defined as structures and a method can be set which will be executed when saving a given step.
assistant Survey using SurveyAnswerSet {
label = "Sample Survey";
savemode = OnFinish;
input(Param1);
init command {
execute {
}
}
steps {
dynamic GenerateSurveySetUp(Param1);
final step {
list SurveyAnswerList using SurveyAnswerSet {
filter = [SurveyId = Param1];
}
}
}
finish command {
execute {
}
}
}
Usage¶
- In the projection include fragment
FndDynamicAssistantSDK
; - With the
dynamic
keyword, define a function that returns the set-up procedure. This should be a structure of typeFndDynamicAssistantSetUp
. - This structure has 3 attributes that you may provide procedure names as text.
InitMetaFunction
- return the list of initialization commandsStepsMetaFunction
- return the list of stepsFinishMetaFunction
- return the list of finish commands- Steps should be returned from a procedure as a list of
FndDynamicAssistantStep
structures. - The
SaveAction
attribute of a step should point to a procedure that gets called when the step is completed. This procedure should return a structure of typeFndDynamicNextStep
which should give information about what the next step should be. - Commands should be returned as a list of
FndDynamicCommandDef
structures to be used during init/finish. Currently ‘set’, ‘alert’ and ‘action’ are supported.
Getting the Steps¶
Dynamic Assistant need to know its Steps. You need to implement a function which returns an Array of Structures of type “FndDynamicAssistantStep”. it’s an array because each structure instance defines a single step. So, the array contains declaration of each step.
This Structure Contains many Attributes. All you need to do in your function implementation (plsql) is query the dynamic instance you need use and loop through each item in it and fill the Structure. (for example, for survey it’s survey Questions you need to loop through and fill the structure attributes with)
The FndDynamicAssistantStep Structure attributes are as follows. Note that you don’t need to fill all attributes for all steps
Attribute | Description |
---|---|
Label | Step label |
StepLabel | Label shown in the Assistant Progress indicator (default label) |
Entity | Entity Used |
Description | Description of Step |
Name | Name used for the client group |
Datatype | Data Type of the entity attribute for which data is collected |
ControlType | Type of visual Control to be used for the entity attribute (default text control ) |
MultiLine | Should the Control support Multiline (default false) |
BindAttribute | Entity attribute to which control is bound |
BindAttributeLabel | Label to show for the Entity Attribute (default attribute name) |
SaveAction Action | method used to save the data in each step |
SaveActionParameters | Parameters for the save action: supports interpolation. Ex. (QuestionId:${QuestionId},SurveyId:${SurveyId},Answer:${Answer}) |
ProjectionName | Name of the Projection |
DefaultValue | Any default value to be used in the step (initial default values) |
Required | True if it’s a mandatory attribute |
Enumeration | Enumeration to be used in the step |
Reference | Lov Reference to be used in the step |
Visible | If a step is visible (default true) |
Enabled | If a step is enabled (default true) |
RemarkNeeded | If a remark attribute is needed for the step |
RemarkAttribute | Entity attribute to which remark is bound to |
RemarkAttributeLabel | Label of the remark (default attribute name of remark attribute) |
TerminateAllowed | If termination is allowed at this step (default false – survey specific) |
DynamicLovOptions | Options Available for check box group control (survey specific) |
Init and Finish Commands¶
As In normal assistants init and finish commands are supported in Dynamic assistants. It supports statically defined ones as well as dynamically defined ones.
Statically defined commands can be specified in the usual way for assistants. If you define dynamic ones (supports only alert and set operations for now) then they will be executed after static ones.
Defining dynamic commands is similar to defining steps. Implement a function which return an array of “FndDynamicCommandDef” structure
FndDynamicCommandDef structure¶
Attribute | Description |
---|---|
Method | 'Set' / 'alert' |
ArgName | value/ msg |
ArgValue | Argument value /alert message |
Result | not supported in dynamic |
Assign | Attribute to assign value to |
Next | not supported in dynamic |
Saving at each step¶
Dynamic assistant works by saving at each step. It’s so because in most cases we need collect values to same attribute at each step. And we may be working with many records. So, we should define an action to save values in our projection. And at each step’s “saveAction” attribute, specify that method. Then at the end of each step (when pressing ‘nex’t) framework calls that action along with the bind parameters. For different steps, we can use different save actions. (if different parameter types are needed etc)
Dynamic assistant allows to skip certain steps (even go back to an earlier step). For that to happen the save action should return the next step. Also if there is a default values to the next step that too needs to be sent, this is done again using a structure.“FndDynamicNextStep”
Attribute | Description |
---|---|
NextStep | Next step number |
DefaultValue | Default value of the next step |
TerminateInfo | True if the can terminate the (survey specific) |
Limitations¶
- Same limitations for standard assistants apply.
- The user cannot finish the dynamic assistant mid-way. A workaround is that the developers provide a terminating question.
Finish Command customization¶
In the finish command there are options for a customizable icon, label and finish message, and can be used as follows
finish command {
label = "Click to Finish";
icon = "calculator";
message = "Are you sure that this is what you want to do?";
execute {
...
}
}
Supported Assistant Properties¶
- init
- finish command
- cancel command
- label
- savemode
- steps
Supported Steps¶
- dynamic
- final step
- cancelled step
Example¶
Projection¶
layer Core;
description "Put some useful description here ...";
category Users;
include fragment FndDynamicAssistantSDK;
----------------------------- MAIN ENTRY POINTS -----------------------------
entityset SurveySet for TstSurvey;
entityset SurveyAnswerSet for TstSurveyAnswer;
entityset SurveyQuestionSet for TstSurveyQuestion;
------------------------------ ENTITY DETAILS -------------------------------
virtual TstSurvey {
attribute SurveyId Text;
attribute SurveyName Text;
attribute Description Text;
}
virtual TstSurveyQuestion {
attribute SurveyId Text;
attribute QuestionId Number;
attribute QuestionNo Number;
attribute Question Text;
}
virtual TstSurveyAnswer {
attribute SurveyId Text;
attribute QuestionId Number;
attribute Answer Text;
}
action PostAnswerWithResult Structure(FndDynamicNextStep) {
initialcheck none;
parameter SurveyId Text;
parameter QuestionId Text;
parameter Answer Text {
required = [false];
}
}
function GenerateSurveySteps List<Structure(FndDynamicAssistStep)> {
parameter SurveyId Text;
}
function GenerateSurveySetUp Structure(FndDynamicAssistSetup) {
parameter SurveyId Text;
}
function GenerateInitCommands List<Structure(FndDynamicCommandDef)> {
parameter SurveyId Text;
}
function GenerateFinishCommands List<Structure(FndDynamicCommandDef)> {
parameter SurveyId Text;
}
PLSQL¶
layer Core;
FUNCTION Generate_Survey_Steps___(
survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Assist_Step_Arr
IS
arr_ Fnd_Dynamic_Assist_Step_Arr := Fnd_Dynamic_Assist_Step_Arr();
steps_ Fnd_Dynamic_Assist_Step_Rec;
step_idx_ NUMBER;
CURSOR questions IS
select * from ${PROJECTION}_TST_SURVEY_QUESTION_VRT t where t.survey_id = survey_id_ order by t.question_no;
BEGIN
step_idx_ := 1;
FOR rec_ IN questions LOOP
steps_ := Generate_Step_Structure___(rec_, arr_, step_idx_);
step_idx_ := step_idx_ + 1;
END LOOP;
RETURN arr_;
END Generate_Survey_Steps___;
FUNCTION Generate_Step_Structure___(
q_record_ IN ${PROJECTION}_TST_SURVEY_QUESTION_VRT%ROWTYPE,
arr_ IN OUT Fnd_Dynamic_Assist_Step_Arr,
step_idx_ IN OUT NUMBER) RETURN Fnd_Dynamic_Assist_Step_Rec
IS
steps_ Fnd_Dynamic_Assist_Step_Rec;
BEGIN
steps_.label := q_record_.question;
steps_.step_label := 'Q-' || q_record_.question_no;
steps_.entity := 'TstSurveyAnswer';
steps_.description := q_record_.question;
steps_.name := 'Answer';
steps_.default_value := 'QuestionId:' || q_record_.question_no || ',SurveyId:' || q_record_.survey_id;
steps_.datatype := 'Text';
steps_.save_action := 'PostAnswerWithResult';
steps_.save_action_parameters := 'QuestionId:${QuestionId},SurveyId:${SurveyId},Answer:${Answer}';
steps_.bind_attribute := 'Answer';
steps_.bind_attribute_label := 'My Answer'; -- seriol no/ part no any label can be given
steps_.projection_name := 'Survey';
steps_.visible := TRUE;
IF(q_record_.question_no = 1) THEN
steps_.enabled := TRUE;
ELSE
steps_.enabled := FALSE;
END IF;
arr_.extend;
arr_(step_idx_) := steps_;
RETURN steps_;
END Generate_Step_Structure___;
FUNCTION Post_Answer_With_Result___ (
survey_id_ IN VARCHAR2,
question_id_ IN VARCHAR2,
answer_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Next_Step_Rec
IS
next_step_ Fnd_Dynamic_Next_Step_Rec;
BEGIN
INSERT INTO ${PROJECTION}_TST_SURVEY_ANSWER_VRT
(objkey, survey_id, question_id, answer, obj_created_by)
VALUES
(sys_guid(), survey_id_, question_id_, answer_, Fnd_Session_API.Get_Fnd_User());
next_step_.next_step := to_number(question_id_) + 1;
RETURN next_step_;
END Post_Answer_With_Result___;
FUNCTION Generate_Survey_Set_Up___(
survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Assist_Setup_Rec
IS
survey_rec_ Fnd_Dynamic_Assist_Setup_Rec;
BEGIN
SELECT survey_name, description INTO survey_rec_.label, survey_rec_.description
FROM ${PROJECTION}_TST_SURVEY_VRT
WHERE survey_id = survey_id_;
survey_rec_.entity := 'TstSurveyAnswer';
survey_rec_.init_meta_function := 'GenerateInitCommands(SurveyId=''${Param1}'')';
survey_rec_.steps_meta_function := 'GenerateSurveySteps(SurveyId=''${Param1}'')';
survey_rec_.finish_Meta_function := 'GenerateFinishCommands(SurveyId=''${Param1}'')';
SELECT count(*) INTO survey_rec_.number_of_steps FROM ${PROJECTION}_TST_SURVEY_QUESTION_VRT WHERE survey_id = survey_id_;
RETURN survey_rec_;
END Generate_Survey_Set_Up___;
FUNCTION Get_Question_Count(
survey_id_ IN VARCHAR2 ) RETURN NUMBER
IS
count_ Number;
BEGIN
SELECT count(*) INTO count_ FROM ${PROJECTION}_TST_SURVEY_QUESTION_VRT WHERE survey_id = survey_id_;
RETURN count_;
END;
FUNCTION Generate_Init_Commands___(
survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Command_Def_Arr
IS
init_command_arr_ Fnd_Dynamic_Command_Def_Arr := Fnd_Dynamic_Command_Def_Arr();
init_cmd_ Fnd_Dynamic_Command_Def_Rec;
init_cmd2_ Fnd_Dynamic_Command_Def_Rec;
BEGIN
init_command_arr_.extend();
init_cmd_.method := 'set';
init_cmd_.assign := 'SurveyId';
init_cmd_.arg_name := 'value';
init_cmd_.arg_value := survey_id_;
init_command_arr_(1) := init_cmd_;
init_command_arr_.extend();
init_cmd2_.method := 'alert';
init_cmd2_.arg_name := 'msg';
init_cmd2_.arg_value := 'Survey starts';
init_command_arr_(2) := init_cmd2_;
RETURN init_command_arr_;
END Generate_Init_Commands___;
FUNCTION Generate_Finish_Commands___(
survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Command_Def_Arr
IS
init_command_arr_ Fnd_Dynamic_Command_Def_Arr := Fnd_Dynamic_Command_Def_Arr();
init_cmd_ Fnd_Dynamic_Command_Def_Rec;
BEGIN
init_command_arr_.extend();
init_cmd_.method := 'alert';
init_cmd_.arg_name := 'msg';
init_cmd_.arg_value := 'Survey finished';
init_command_arr_(1) := init_cmd_;
RETURN init_command_arr_;
END Generate_Finish_Commands___;