FUNCTION ZBW_SFLI001_DS. *"---------------------------------------------------------------------- *"*"Local interface: *" IMPORTING *" VALUE(I_REQUNR) TYPE SRSC_S_IF_SIMPLE-REQUNR *" VALUE(I_DSOURCE) TYPE SRSC_S_IF_SIMPLE-DSOURCE OPTIONAL *" VALUE(I_MAXSIZE) TYPE SRSC_S_IF_SIMPLE-MAXSIZE OPTIONAL *" VALUE(I_INITFLAG) TYPE SRSC_S_IF_SIMPLE-INITFLAG OPTIONAL *" VALUE(I_READ_ONLY) TYPE SRSC_S_IF_SIMPLE-READONLY OPTIONAL *" TABLES *" I_T_SELECT TYPE SRSC_S_IF_SIMPLE-T_SELECT OPTIONAL *" I_T_FIELDS TYPE SRSC_S_IF_SIMPLE-T_FIELDS OPTIONAL *" E_T_DATA STRUCTURE ZBW_SFLI001_DS OPTIONAL *" EXCEPTIONS *" NO_MORE_DATA *" ERROR_PASSED_TO_MESS_HANDLER *"---------------------------------------------------------------------- ************************************************************************ * Date: 7/28/2005 * Author: David Eady * * This code is an example of providing data to a generic extractor * based on a function module. * * Our generic extractor uses the ZBW_SFLI001_DS table as its extract * structure. The ZCALWEEK and ZCLASS fields will have selections * enabled in the generic extractor. * * this structure will be used to decode selections passed from the * extractor DATA: l_s_select TYPE SRSC_S_SELECT. * The following static variables are populated in the first call * (the initialization call) to the extractor and then are used in * subsequent calls. * the S_S_IF structure is used to hold incoming parameters. STATICS: s_s_if TYPE SRSC_S_IF_SIMPLE, * a simple counter s_counter_datapakid LIKE SY-TABIX, * a database cursor that will read and return records s_cursor TYPE CURSOR. * Select ranges * When the function module is called for the first time the * I_T_SELECT table holds any selections from the infopackage. * We will extract those selections and store them in these * ranges. We will then use these ranges to limit the amount * of data returned to BW. RANGES: l_r_zcalweek FOR ZBW_SFLI001_DS-ZCALWEEK, l_r_zclass FOR ZBW_SFLI001_DS-ZCLASS. * The extractor will have a selection for calendar week but the * data is stored in the SBOOK table by calendar day. We'll include * logic later in the function module to take the incoming calendar * week selections and create calendar day selections. We'll put * those calendar day selections in this range and then use it * to limit the amount of data coming from SBOOK. RANGES: l_r_fldate FOR SBOOK-FLDATE. * Helper variable if we need to loop on week ranges DATA: zweek LIKE ZBW_SFLI001_DS-ZCALWEEK. * Helper internal table to hold SBOOK records that match our * selections DATA: zsbook LIKE SBOOK OCCURS 0 WITH HEADER LINE. * Helper internal table to hold SFLIGHT records that match our * selections DATA: zsflight LIKE SFLIGHT OCCURS 0 WITH HEADER LINE. * Helper internal table to accumulate data from SBOOK DATA: zitab LIKE ZBW_SFLI001_DS OCCURS 0 WITH HEADER LINE. * Now we are getting into the real logic of the function module. * The function module is called several times; once for an * initialization and then several more times (once for each data * packet) until the function module signals that there is no * more data available. * The I_INITFLAG is an IMPORT parameter that indicates if this * is the first call. If so, validate the datasource and put * away the other initialization fields into static variables * for use in later calls. IF I_INITFLAG = SBIWA_C_FLAG_ON. "Step (A) * This should never happen, but just in case. CASE I_DSOURCE. WHEN 'ZBW_SFLI001_DS'. WHEN OTHERS. IF 1 = 2. MESSAGE E009(R3). ENDIF. LOG_WRITE 'E' "message type 'R3' "message class '009' "message number I_DSOURCE "message variable 1 ' '. "message variable 2 RAISE ERROR_PASSED_TO_MESS_HANDLER. ENDCASE. * Make a static copy of the selection field ranges APPEND LINES OF I_T_SELECT TO s_s_if-t_select. "Step (B) * This grabs a copy of the IMPORT parameters into static variables. * These static variables can be used in later calls to the function * module. s_s_if-requnr = I_REQUNR. "Step (B) s_s_if-dsource = I_DSOURCE. "Step (B) s_s_if-maxsize = I_MAXSIZE. "Step (B) * The I_T_FIELDS table holds the fields that the extractor is * expecting. You can use this field list to minimize the * fields read from database tables. APPEND LINES OF I_T_FIELDS TO s_s_if-t_fields. "Step (B) ELSE. "Initialization mode or data extraction ? * This batch of code is for later calls into the function module * (to gather and return data). * If we haven't returned any data packets yet (this is the first * function module call asking for data packets), then gather up * the necessary data. IF s_counter_datapakid = 0. "Step (C) "Begin of Step (D) * In the initialization call we copied the incoming I_T_SELECT * table (which holds infopackage selections) into the S_S_IF * static variable. Now interrogate those selections to create * ranges that will be used to restrict the database records read. * We know (because we defined the extractor) that the only two fields * that can have selections are ZCALWEEK and ZCLASS. LOOP AT s_s_if-t_select INTO l_s_select WHERE FIELDNM = 'ZCALWEEK'. MOVE-CORRESPONDING l_s_select TO l_r_zcalweek. APPEND l_r_zcalweek. ENDLOOP. LOOP AT s_s_if-t_select INTO l_s_select WHERE FIELDNM = 'ZCLASS'. MOVE-CORRESPONDING l_s_select TO l_r_zclass. APPEND l_r_zclass. ENDLOOP. * The generic extractor has selections on calendar week, but our data * (in the SBOOK table) is captured by flight date. So we need to * take our calendar week selections and convert them into flight * date selections. * The ZCALWEEK range could be a single week, it could be a range * of weeks, or it could be several of both. LOOP AT l_r_zcalweek. * handle either single values (EQ) or ranges (BT) CASE l_r_zcalweek-option. WHEN 'EQ'. * convert the low value to a date range CALL FUNCTION 'WEEK_GET_FIRST_DAY' EXPORTING WEEK = l_r_zcalweek-low IMPORTING DATE = l_r_fldate-low EXCEPTIONS WEEK_INVALID = 1 OTHERS = 2. l_r_fldate-high = l_r_fldate-low + 7. l_r_fldate-sign = 'I'. l_r_fldate-option = 'BT'. APPEND l_r_fldate. when 'BT'. zweek = l_r_zcalweek-low. WHILE zweek <= l_r_zcalweek-high. * convert the low value to a date range CALL FUNCTION 'WEEK_GET_FIRST_DAY' EXPORTING WEEK = zweek IMPORTING DATE = l_r_fldate-low EXCEPTIONS WEEK_INVALID = 1 OTHERS = 2. l_r_fldate-high = l_r_fldate-low + 7. l_r_fldate-sign = 'I'. l_r_fldate-option = 'BT'. APPEND l_r_fldate. zweek = zweek + 1. ENDWHILE. ENDCASE. ENDLOOP. "End of Step (D) * Now it's time to gather the data and populate our ZBW_SFLI001_DS * table. But first let's make sure we don't have any residual data * already in the table for this same request identifier. * For example, if we use RSA3 to test the extractor, the request * identifier is always TEST. Let's make sure we don't have any * left over from previous tests. DELETE FROM ZBW_SFLI001_DS "Step (E) WHERE ZREQUNR = s_s_if-requnr. * Now lets go get data from the SBOOK table that meets our selection * criteria. SELECT * FROM SBOOK "Step (F) INTO TABLE zsbook WHERE fldate IN l_r_fldate AND class IN l_r_zclass. * Now get all matching SFLIGHT records (we need these to calculate * our expected revenue) SELECT * FROM SFLIGHT "Step (F) INTO TABLE zsflight FOR ALL ENTRIES IN zsbook WHERE carrid = zsbook-carrid AND connid = zsbook-connid AND fldate = zsbook-fldate. "Begin of Step (G) * now take the SBOOK records and build records to send back to BW LOOP AT zsbook. * set the request identifier zitab-zrequnr = s_s_if-requnr. * set the calendar week based on the flight date CALL FUNCTION 'DATE_GET_WEEK' EXPORTING DATE = zsbook-fldate IMPORTING WEEK = zitab-zcalweek EXCEPTIONS DATE_INVALID = 1 OTHERS = 2. * set class zitab-zclass = zsbook-class. * set total passengers zitab-ztotpass = 1. * accumulate revenue zitab-ztotrev = zsbook-loccuram. * look up the matching SFLIGHT record to get expected revenue READ TABLE zsflight WITH KEY carrid = zsbook-carrid connid = zsbook-connid fldate = zsbook-fldate. IF sy-subrc = 0. zitab-zexprev = zsflight-price. ELSE. zitab-zexprev = 0. ENDIF. * set currency key zitab-zcurrency = zsbook-loccurkey. * accumulate baggage weight zitab-ztotbagwt = zsbook-luggweight. * set baggage weight unit zitab-zwtunit = zsbook-wunit. * this will accumulate key figures that have the same characteristics COLLECT zitab. ENDLOOP. "End of Step (G) * finally, write the accumulated, summarized records to the database INSERT ZBW_SFLI001_DS FROM TABLE zitab. "Step (H) * open a database cursor to gather the data from the database * table and pass it back to BW. Here the S_S_IF-T_FIELDS * internal table (copied from the I_T_FIELDS internal table * passed to this function module by BW) is used to make sure we * only get the fields that BW actually needs. OPEN CURSOR WITH HOLD s_cursor FOR "Step (I) SELECT (S_S_IF-T_FIELDS) FROM ZBW_SFLI001_DS WHERE zrequnr = s_s_if-requnr. ENDIF. "First data package ? * This code actually returns a packet of data to BW. It gets the * next packet of data from our database table (using the cursor) * and puts the data into the E_T_DATA internal table. This * internal table is then handed back to BW as a packet of data. FETCH NEXT CURSOR s_cursor "Step (J) APPENDING CORRESPONDING FIELDS OF TABLE E_T_DATA PACKAGE SIZE S_S_IF-MAXSIZE. * If there is no more data, close the cursor, remove the data * from the ZBW_SFLI001_DS table (since we don't need it anymore) * and signal BW that there is no more data. IF SY-SUBRC <> 0. "Step (K) CLOSE CURSOR S_CURSOR. "Step (L) DELETE FROM zbw_sfli001_ds "Step (M) WHERE zrequnr = s_s_if-requnr. RAISE NO_MORE_DATA. "Step (N) ENDIF. * accumulate our packet counter s_counter_datapakid = s_counter_datapakid + 1. "Step (O) ENDIF. "Initialization mode or data extraction ? ENDFUNCTION.