Let us consider a use case: You need to check if the line quantities are greater than 100 for all records selected in the order summary form before booking them. How would we go about approaching this: 1. We need to check the event that fires when order booking is done. 2. We need to get a list of all records selected for booking as part of the multi select 3. We need to process all records when the event fires by calling custom code. This functionality can be achieved through code in CUSTOM.pll. 1. The event in question in the order organizer form is OM_PRE_ACTION_EVENT if (event_name = 'OM_PRE_ACTION_EVENT') then --fnd_message.debug(name_in('PARAMETER.ACTIONS')); if (form_name = 'OEXOEORD' and block_name = 'ORDERS_SUMMARY' and name_in('PARAMETER.ACTIONS')= 'BOOK_ORDER' ) then xx_custom_package.event(event_name,block_name); end if; end if; 2. To get the list of records use the following procedure. The input parameter is the block name(LINES_SUMMARY/ORDER_SUMMARY etc) The out variables are l_record_ids(comma delimited list of record ids, count of record ids PROCEDURE get_selected_ids(block_name IN VARCHAR2, l_record_ids OUT VARCHAR2, count_selected OUT NUMBER) IS rec_grp_count NUMBER; rg_id recordgroup; separator VARCHAR2(1) := ','; record_group_name VARCHAR2(60); BEGIN --message('Block_name='||Block_name); record_group_name := block_name || '_rg'; count_selected := get_group_row_count(block_name || '_MULTI'); IF (count_selected = 0) THEN l_record_ids := NULL; count_selected := 0; ELSE rg_id := find_group(record_group_name); IF id_null(rg_id) THEN fnd_message.debug('record_group doesnot exist'); RAISE form_trigger_failure; END IF; rec_grp_count := get_group_row_count(rg_id); IF rec_grp_count != count_selected THEN fnd_message.debug('sanity check failed: record group count and selected count different'); app_multi.event('DESELECT_ALL', block_name); IF NOT id_null(rg_id) THEN delete_group(record_group_name); END IF; RAISE form_trigger_failure; END IF; FOR j IN 1 .. rec_grp_count LOOP IF j = 1 THEN l_record_ids := get_group_char_cell(record_group_name || '.ID1', j); ELSE l_record_ids := l_record_ids || separator || get_group_char_cell(record_group_name || '.Id1', j); END IF; END LOOP; END IF; END get_selected_ids; The flow of code within OM for one such flow is: OE_ACTIONS_LIST.Actions_Button('WHEN-BUTTON-PRESSED') -> OE_SET_ACTIONS_LIST.Set_Actions_List(Name_In('SYSTEM.CURSOR_BLOCK')) -> action_type:=show_lov('ACTIONS') -> Set_Lov_Property('ACTIONS', GROUP_NAME,'DYNAMIC_ACTIONS_LIST')-> OE_SO_MASSCHANGE.get_selected_ids( name_in('SYSTEM.CURSOR_BLOCK'), l_selection_type, l_sel_rec_tbl, l_count_selected, l_multi_OU)-> OE_MASSCHANGE.Get_Selected_ids(l_block_name, l_record_ids, l_count_selected); |