DBA Data[Home] [Help]

PACKAGE BODY: APPS.IEC_CPN_RLSE_STTGY_PVT

Source


1 PACKAGE BODY IEC_CPN_RLSE_STTGY_PVT AS
2 /* $Header: IECVCRLB.pls 115.55 2004/05/18 19:38:15 minwang ship $ */
3 
4 G_CAMPAIGN_ID NUMBER;
5 G_SERVER_ID NUMBER;
6 G_SOURCE_ID CONSTANT  NUMBER := -1;
7 -- Sub-Program Unit Declarations
8 
9 -- Check if a cpn is active..
10 PROCEDURE Log
11    ( p_method        IN VARCHAR2
12    , p_sub_method    IN VARCHAR2
13    , p_activity      IN VARCHAR2
14    , p_sql_code      IN NUMBER
15    , p_sql_errm      IN VARCHAR2)
16 IS
17    l_error_msg VARCHAR2(2048);
18 BEGIN
19 
20    IEC_OCS_LOG_PVT.LOG_INTERNAL_PLSQL_ERROR
21       ( 'IEC_CPN_RLSE_STTGY_PVT'
22       , p_method
23       , p_sub_method
24       , p_activity
25       , p_sql_code
26       , p_sql_errm
27       , l_error_msg
28       );
29 
30 END Log;
31 
32 
33 
34 PROCEDURE GET_UNAVAILABLE_REASON
35   (P_LIST_ID                     IN            NUMBER
36   ,X_CALLBACK_AVAILABLE_COUNT    IN OUT NOCOPY NUMBER
37   ,X_AVAILABLE_COUNT             IN OUT NOCOPY NUMBER
38   ,X_CALLBACK_CHECKED_OUT_COUNT  IN OUT NOCOPY NUMBER
39   ,X_CHECKED_OUT_COUNT           IN OUT NOCOPY NUMBER
40   ,X_CALENDAR_COUNT              IN OUT NOCOPY NUMBER
41   ,X_CALLBACK_CALENDAR_COUNT     IN OUT NOCOPY NUMBER
42   ,X_INACTIVE_COUNT              IN OUT NOCOPY NUMBER
43   ,X_CALLBACK_RESTRICT_COUNT     IN OUT NOCOPY NUMBER
44   )
45 AS
46 
47   L_CALLABLE_FLAG IEC_G_MKTG_ITEM_CC_TZS.CALLABLE_FLAG%TYPE;
48   L_STILL_CALLABLE BINARY_INTEGER;
49   L_CALLBACK_FLAG IEC_G_RETURN_ENTRIES.CALLBACK_FLAG%TYPE;
50   L_CHECKED_OUT_FLAG IEC_G_RETURN_ENTRIES.RECORD_OUT_FLAG%TYPE;
51   L_CALLBACK_EXPIRATION BINARY_INTEGER;
52   L_STATUS_CODE IEC_G_LIST_SUBSETS.STATUS_CODE%TYPE;
53   L_GROUP_COUNT NUMBER;
54 
55   L_CALLBACK_AVAILABLE_COUNT NUMBER := 0;
56   L_AVAILABLE_COUNT NUMBER := 0;
57   L_CALLBACK_CHECKED_OUT_COUNT NUMBER := 0;
58   L_CHECKED_OUT_COUNT NUMBER := 0;
59   L_CALENDAR_COUNT NUMBER := 0;
60   L_CALLBACK_CALENDAR_COUNT NUMBER := 0;
61   L_CALLBACK_RESTRICT_COUNT NUMBER := 0;
62   L_INACTIVE_COUNT NUMBER := 0;
63 
64 
65   CURSOR l_count_cursor(L_LIST_ID NUMBER) IS
66     select b.callable_flag
67     , decode(sign(nvl(b.last_callable_time, SYSDATE) - SYSDATE), 0, 0, 1, 1, 0)
68     , a.callback_flag
69     , decode(sign(nvl(NEXT_CALL_TIME, SYSDATE) - SYSDATE), 0, 0, 1, 1, 0)
70     , a.record_out_flag
71     , c.status_code
72     , count(*)
73     from iec_g_return_entries a
74     , iec_g_mktg_item_Cc_tzs b
75     , iec_g_list_subsets c
76     where a.list_header_id = L_LIST_ID
77     and a.list_header_id = c.list_header_id
78     and a.itm_cc_Tz_id = b.itm_cc_tz_id
79     and a.do_not_use_Flag = 'N'
80     group by b.callable_flag
81     , decode(sign(nvl(b.last_callable_time, SYSDATE) - SYSDATE), 0, 0, 1, 1, 0)
82     , a.callback_flag
83     , decode(sign(nvl(NEXT_CALL_TIME, SYSDATE) - SYSDATE), 0, 0, 1, 1, 0)
84     , a.record_out_flag
85     , c.status_code;
86 
87 BEGIN
88 
89   BEGIN
90     OPEN l_count_cursor(P_LIST_ID);
91 
92     LOOP
93 
94        FETCH l_count_cursor
95          INTO L_CALLABLE_FLAG
96          ,    L_STILL_CALLABLE
97          ,    L_CALLBACK_FLAG
98          ,    L_CALLBACK_EXPIRATION
99          ,    L_CHECKED_OUT_FLAG
100          ,    L_STATUS_CODE
101          ,    L_GROUP_COUNT;
102 
103        EXIT WHEN l_count_cursor%NOTFOUND;
104 
105 
106        ----------------------------------------------------------------
107        -- If the group belongs to an inactive subset then all of the
108        -- entries are inactive.
109        ----------------------------------------------------------------
110        IF (L_STATUS_CODE <> 'ACTIVE')
111        THEN
112           L_INACTIVE_COUNT := L_INACTIVE_COUNT + L_GROUP_COUNT;
113 
114        ----------------------------------------------------------------
115        -- This is a callback so count against the callback totals.
116        ----------------------------------------------------------------
117        ELSIF (L_CALLBACK_FLAG <> 'N')
118        THEN
119 
120           ----------------------------------------------------------------
121           -- These entries are currently checked out.
122           ----------------------------------------------------------------
123           IF (L_CHECKED_OUT_FLAG = 'Y')
124           THEN
125              L_CALLBACK_CHECKED_OUT_COUNT := L_CALLBACK_CHECKED_OUT_COUNT + L_GROUP_COUNT;
126 
127           ELSIF (L_CALLABLE_FLAG <> 'Y' OR L_STILL_CALLABLE = 0)
128           THEN
129 
130              L_CALLBACK_CALENDAR_COUNT := L_CALLBACK_CALENDAR_COUNT + L_GROUP_COUNT;
131 
132           ELSIF (L_CALLBACK_EXPIRATION = 1)
133           THEN
134              L_CALLBACK_RESTRICT_COUNT := L_CALLBACK_RESTRICT_COUNT + L_GROUP_COUNT;
135           ELSE
136 
137              L_CALLBACK_AVAILABLE_COUNT := L_CALLBACK_AVAILABLE_COUNT + L_GROUP_COUNT;
138 
139           END IF;
140        ----------------------------------------------------------------
141        -- This is not a callback so count against the non-callback totals.
142        ----------------------------------------------------------------
143        ELSE
144 
145           ----------------------------------------------------------------
146           -- These entries are currently checked out.
147           ----------------------------------------------------------------
148           IF (L_CHECKED_OUT_FLAG = 'Y')
149           THEN
150              L_CHECKED_OUT_COUNT := L_CHECKED_OUT_COUNT + L_GROUP_COUNT;
151 
152           ELSIF (L_CALLABLE_FLAG <> 'Y' OR L_STILL_CALLABLE = 0)
153           THEN
154 
155              L_CALENDAR_COUNT := L_CALENDAR_COUNT + L_GROUP_COUNT;
156 
157           ELSE
158 
159              L_AVAILABLE_COUNT := L_AVAILABLE_COUNT + L_GROUP_COUNT;
160 
161           END IF;
162 
163        END IF;
164 
165     END LOOP;
166 
167 
168     CLOSE l_count_cursor;
169 
170     X_CALLBACK_AVAILABLE_COUNT := L_CALLBACK_AVAILABLE_COUNT ;
171     X_AVAILABLE_COUNT := L_AVAILABLE_COUNT ;
172     X_CALLBACK_CHECKED_OUT_COUNT := L_CALLBACK_CHECKED_OUT_COUNT ;
173     X_CHECKED_OUT_COUNT := L_CHECKED_OUT_COUNT ;
174     X_CALENDAR_COUNT := L_CALENDAR_COUNT ;
175     X_CALLBACK_CALENDAR_COUNT := L_CALLBACK_CALENDAR_COUNT ;
176     X_INACTIVE_COUNT := L_INACTIVE_COUNT ;
177 
178 
179   EXCEPTION
180    WHEN NO_DATA_FOUND THEN
181      RETURN;
182    WHEN OTHERS THEN
183      RAISE;
184   END;
185 
186 EXCEPTION
187    WHEN OTHERS THEN
188       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
189 END GET_UNAVAILABLE_REASON;
190 
191 
192 PROCEDURE IS_SCHEDULE_ACTIVE
193   (P_SCHEDULE_ID    IN            NUMBER
194   ,X_ACTIVE         IN OUT NOCOPY VARCHAR2
195   )
196   AS
197   l_schedule_id NUMBER;
198 BEGIN
199 
200   -- Return success for now..
201   X_ACTIVE := FND_API.G_RET_STS_ERROR;
202 
203   Begin
204         EXECUTE IMMEDIATE 'select unique SCHEDULE_ID ' ||
205                           ' from  IEC_G_EXECUTING_LISTS_V ' ||
206                           ' where  SCHEDULE_ID = :1 '
207                           INTO l_schedule_id
208                           USING P_SCHEDULE_ID;
209 
210           X_ACTIVE := FND_API.G_RET_STS_SUCCESS;
211 
212   Exception
213    when NO_DATA_FOUND then
214      return;
215   End;
216 
217 END IS_SCHEDULE_ACTIVE;
218 
219 
220 -- Update subset release strategy info
221 
222 PROCEDURE UPDATE_SUBSET_RT_INFO
223   (P_CAMPAIGN_ID    IN            NUMBER
224   ,P_LIST_HEADER_ID IN            NUMBER
225   ,P_SUBSET_ID      IN            NUMBER
226   ,P_QUANTUM        IN            NUMBER
227   ,P_QUOTA          IN            NUMBER
228   ,P_QUOTA_RESET    IN            DATE
229   ,P_USE_FLAG       IN            VARCHAR2
230   ,X_RESULT         IN OUT NOCOPY VARCHAR2
231   )
232 AS
233   PRAGMA AUTONOMOUS_TRANSACTION;
234 
235 BEGIN
236 
237   EXECUTE IMMEDIATE 'update iec_g_subset_rt_info ' ||
238                     'set working_quantum = :1 ' ||
239                     ',   use_flag = :2 ' ||
240                     ',   working_quota = :3 ' ||
241                     ',   quota_reset_time = :4 ' ||
242                     ',   last_update_date = SYSDATE ' ||
243                     'where list_subset_id = :5 '
244          USING P_QUANTUM
245          ,     P_USE_FLAG
246          ,     P_QUOTA
247          ,     P_QUOTA_RESET
248          ,     P_SUBSET_ID;
249 
250   X_RESULT := FND_API.G_RET_STS_SUCCESS;
251   commit;
252 
253 END UPDATE_SUBSET_RT_INFO;
254 
255 PROCEDURE CHECK_OUT_ENTRIES
256   (P_SERVER_ID      IN  NUMBER
257   ,P_RETURNS_ID_TAB IN  SYSTEM.NUMBER_TBL_TYPE
258   )
259   AS
260 
261    ----------------------------------------------------------------
262    -- Bulk Update to check the entries out of AMS_LIST_ENTRIES.
263    -- At first don't specify unique index.
264    ----------------------------------------------------------------
265    BEGIN
266 
267    FORALL j IN P_RETURNS_ID_TAB.FIRST..P_RETURNS_ID_TAB.LAST
268       UPDATE IEC_G_RETURN_ENTRIES
269       SET    RECORD_OUT_FLAG = 'Y'
270       ,      CHECKOUT_ACTION_ID = P_SERVER_ID
271       ,      RECORD_RELEASE_TIME = SYSDATE
272       ,      LAST_UPDATE_DATE = SYSDATE
273       WHERE  RETURNS_ID = P_RETURNS_ID_TAB(j);
274 
275 EXCEPTION
276    WHEN OTHERS THEN
277       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
278 END CHECK_OUT_ENTRIES;
279 
280 PROCEDURE GET_CUST_CALLBACKS
281   (P_SERVER_ID              IN            NUMBER
282   ,P_CAMPAIGN_ID            IN            NUMBER
283   ,P_SCHEDULE_ID            IN            NUMBER
284   ,P_LIST_ID                IN            NUMBER
285   ,P_VIEW_NAME              IN            VARCHAR2
286   ,P_RLSE_CTRL_ALG_ID       IN            NUMBER
287   ,X_RETURNS_ID_TAB            OUT NOCOPY SYSTEM.NUMBER_TBL_TYPE
288   ,X_RETURN_CODE            IN OUT NOCOPY VARCHAR2
289   )
290   AS
291   CURSOR l_callback_query_cursor(L_LIST_ID NUMBER) IS
292                         select
293                         d.list_entry_id,
294                         d.returns_id,
295                         c.priority
296                         from iec_g_return_entries d
297                         ,    iec_g_list_subsets c
298                         where     itm_cc_tz_id in
299                         ( select itm_cc_tz_id
300                           from  iec_g_mktg_item_cc_tzs
301                           where subset_id in
302                           ( select a.list_Subset_id
303                             from iec_g_list_Subsets a
304                             ,    iec_g_subset_rt_info b
305                             where a.list_header_id = L_LIST_ID
306                             and   a.list_subset_id = b.list_subset_id
307                             and   b.working_quota > 0
308                             and   b.status_code = 'ACTIVE')
309                           and     nvl(callable_flag, 'Y') <> 'N'
310                           and     last_callable_time > sysdate)
311                         and     nvl( callback_flag, 'N') = 'C'
312                         and     nvl( contact_point_index, 0) > 0
313                         and     nvl( record_out_flag, 'N') = 'N'
314                         and     nvl( do_not_use_flag, 'N') = 'N'
315                         and     pulled_subset_id is null
316                         and     sysdate > NEXT_CALL_TIME
317                         and     d.subset_id = c.list_subset_id
318                         order by c.priority;
319   l_record_id NUMBER(15);
320   l_index BINARY_INTEGER := 0;
321   l_callback_count BINARY_INTEGER := 0;
322   l_returns_id_tab SYSTEM.NUMBER_TBL_TYPE;
323 
324   l_list_entry_id IEC_G_RETURN_ENTRIES.LIST_ENTRY_ID%TYPE;
325   l_subset_priority IEC_G_LIST_SUBSETS.PRIORITY%TYPE;
326   l_returns_id IEC_G_RETURN_ENTRIES.RETURNS_ID%TYPE;
327   l_callable_flag VARCHAR2(1);
328   l_return_code VARCHAR2(1);
329   l_error_code NUMBER;
330 
331 BEGIN
332    ---------------------------------------------------------
333    -- Initialize the status string to send back to success.
334    ---------------------------------------------------------
335     X_RETURN_CODE := FND_API.G_RET_STS_SUCCESS;
336 
337     l_returns_id_tab := SYSTEM.NUMBER_TBL_TYPE();
338 
339    ---------------------------------------------------------
340    -- Check to see if the campaign is locked.
341    ---------------------------------------------------------
342     IEC_COMMON_UTIL_PVT.LOCK_SCHEDULE( P_SOURCE_ID => G_SOURCE_ID
343                                      , P_SCHED_ID => P_SCHEDULE_ID
344                                      , P_SERVER_ID => P_SERVER_ID
345                                      , P_LOCK_ATTEMPTS => 1
346                                      , P_ATTEMPT_INTERVAL => 0
347                                      , X_SUCCESS_FLAG => l_return_code);
348 
349     IF( l_return_code <> 'Y' )
350     THEN
351       X_RETURN_CODE := SCHEDULE_IS_LOCKED;
352       return;
353     END IF;
354 
355     l_index := l_returns_id_tab.COUNT;
356 
357    -------------------------------------------------------------------
358    -- First get the customer specified callbacks.  We return all of
359    -- these regardless of amount.
360    -------------------------------------------------------------------
361     OPEN l_callback_query_cursor(P_LIST_ID);
362 
363     LOOP
364 
365        FETCH l_callback_query_cursor
366        INTO l_list_entry_id
367        ,    l_returns_id
368        ,    l_subset_priority;
369 
370        EXIT WHEN l_callback_query_cursor%NOTFOUND;
371 
372        -------------------------------------------------------------------
373        -- Check DNC and Record Filter before adding this entry to
374        -- the list.
375        -------------------------------------------------------------------
376        IEC_DNC_PVT.IS_CALLABLE( G_SOURCE_ID
377                                 , P_VIEW_NAME
378                                 , l_list_entry_id
379                                 , P_LIST_ID
380                                 , l_returns_id
381                                 , l_callable_flag);
382 
383        IF (l_callable_flag = 'Y')
384        THEN
385 
386           -- Check for record filter
387           IF (p_rlse_ctrl_alg_id > 0)
388           THEN
389              IEC_RECORD_FILTER_PVT.Apply_RecordFilter( l_list_entry_id
390                                                      , p_list_id
391                                                      , l_returns_id
392                                                      , p_rlse_ctrl_alg_id
393                                                      , p_view_name
394                                                      , l_callable_flag);
395           END IF;
396 
397           IF (l_callable_flag = 'Y')
398           THEN
399              l_callback_count := l_callback_count + 1;
400              l_index := l_index + 1;
401              l_returns_id_tab.EXTEND(1);
402              l_returns_id_tab(l_index) := l_returns_id;
403           END IF;
404 
405        END IF;
406 
407     END LOOP;
408 
409     IF (l_returns_id_tab.COUNT > 0)
410     THEN
411 
412        CHECK_OUT_ENTRIES( P_SERVER_ID
413                         , l_returns_id_tab);
414        X_RETURNS_ID_TAB := l_returns_id_tab;
415 
416     ELSE
417        X_RETURN_CODE := SCHEDULE_IS_EMPTY;
418     END IF;
419 
420     CLOSE l_callback_query_cursor;
421 
422     -- UNLOCK THE CAMPAIGN
423     IEC_COMMON_UTIL_PVT.UNLOCK_SCHEDULE( P_SOURCE_ID => G_SOURCE_ID
424                                        , P_SCHED_ID => P_SCHEDULE_ID
425                                        , P_SERVER_ID => P_SERVER_ID
429 EXCEPTION
426                                        , X_SUCCESS_FLAG => l_return_code);
427 
428     RETURN;
430    WHEN no_data_found THEN
431 
432       IF l_callback_query_cursor%ISOPEN
433       THEN
434          CLOSE l_callback_query_cursor;
435       END IF;
436        return;
437    WHEN OTHERS THEN
438       L_ERROR_CODE := SQLCODE;
439       IF l_callback_query_cursor%ISOPEN
440       THEN
441          CLOSE l_callback_query_cursor;
442       END IF;
443 
444       raise_application_error
445         ( -20000
446          , 'SQLCODE: <' || L_ERROR_CODE || '> SQLMESSAGE <' || SQLERRM || '>'
447          ,TRUE
448         );
449 END GET_CUST_CALLBACKS;
450 
451 PROCEDURE GET_CALLBACKS
452   (P_SERVER_ID              IN            NUMBER
453   ,P_CAMPAIGN_ID            IN            NUMBER
454   ,P_SCHEDULE_ID            IN            NUMBER
455   ,P_LIST_ID                IN            NUMBER
456   ,P_COUNT                  IN            NUMBER
457   ,P_VIEW_NAME              IN            VARCHAR2
458   ,P_RLSE_CTRL_ALG_ID       IN            NUMBER
459   ,X_RETURNS_ID_TAB            OUT NOCOPY SYSTEM.NUMBER_TBL_TYPE
460   ,X_RETURN_CODE            IN OUT NOCOPY VARCHAR2
461   )
462   AS
463 
464   CURSOR l_callback_query_cursor(L_LIST_ID NUMBER) IS
465                         select
466                         d.list_entry_id,
467                         d.returns_id,
468                         c.priority
469                         from iec_g_return_entries d
470                         ,    iec_g_list_subsets c
471                         where     itm_cc_tz_id in
472                         ( select itm_cc_tz_id
473                           from  iec_g_mktg_item_cc_tzs
474                           where subset_id in
475                           ( select a.list_Subset_id
476                             from iec_g_list_Subsets a
477                             ,    iec_g_subset_rt_info b
478                             where a.list_header_id = L_LIST_ID
479                             and   a.list_subset_id = b.list_subset_id
480                             and   b.working_quota > 0
481                             and   b.status_code = 'ACTIVE')
482                           and     nvl(callable_flag, 'Y') <> 'N'
483                           and     last_callable_time > sysdate)
484                         and     nvl( callback_flag, 'N') = 'Y'
485                         and     nvl( contact_point_index, 0) > 0
486                         and     nvl( record_out_flag, 'N') = 'N'
487                         and     nvl( do_not_use_flag, 'N') = 'N'
488                         and     pulled_subset_id is null
489                         and     sysdate > NEXT_CALL_TIME
490                         and     d.subset_id = c.list_subset_id
491                         order by c.priority;
492 
493   l_record_id NUMBER(15);
494   l_index BINARY_INTEGER := 0;
495   l_callback_count BINARY_INTEGER := 0;
496   l_returns_id_tab SYSTEM.NUMBER_TBL_TYPE := SYSTEM.NUMBER_TBL_TYPE();
497 
498   l_list_entry_id IEC_G_RETURN_ENTRIES.LIST_ENTRY_ID%TYPE;
499   l_subset_priority IEC_G_LIST_SUBSETS.PRIORITY%TYPE;
500   l_returns_id IEC_G_RETURN_ENTRIES.RETURNS_ID%TYPE;
501   l_callable_flag VARCHAR2(1);
502   l_return_code VARCHAR2(1);
503   l_error_code NUMBER;
504 
505 BEGIN
506 
507    ---------------------------------------------------------
508    -- Initialize the status string to send back to success.
509    ---------------------------------------------------------
510     X_RETURN_CODE := FND_API.G_RET_STS_SUCCESS;
511 
512    ---------------------------------------------------------
513    -- Check to see if the campaign is locked.
514    ---------------------------------------------------------
515     IEC_COMMON_UTIL_PVT.LOCK_SCHEDULE( P_SOURCE_ID => G_SOURCE_ID
516                                      , P_SCHED_ID => P_SCHEDULE_ID
517                                      , P_SERVER_ID => P_SERVER_ID
518                                      , P_LOCK_ATTEMPTS => 1
519                                      , P_ATTEMPT_INTERVAL => 0
520                                      , X_SUCCESS_FLAG => l_return_code);
521 
522     IF( l_return_code <> 'Y' )
523     THEN
524       X_RETURN_CODE := SCHEDULE_IS_LOCKED;
525       return;
526     END IF;
527 
528     l_index := l_returns_id_tab.COUNT;
529 
530     IF (P_COUNT > 0)
531     THEN
532        OPEN l_callback_query_cursor(P_LIST_ID);
533 
534        LOOP
535 
536           FETCH l_callback_query_cursor
537           INTO l_list_entry_id
538           ,    l_returns_id
539           ,    l_subset_priority;
540 
541           EXIT WHEN l_callback_query_cursor%NOTFOUND;
542 
543           -------------------------------------------------------------------
544           -- Check DNC and Record Filter before adding this entry to
545           -- the list.
546           -------------------------------------------------------------------
547           IEC_DNC_PVT.IS_CALLABLE( G_SOURCE_ID
548                                  , P_VIEW_NAME
549                                  , l_list_entry_id
550                                  , P_LIST_ID
551                                  , l_returns_id
552                                  , l_callable_flag);
553 
554           IF (l_callable_flag = 'Y')
555           THEN
556 
560                 IEC_RECORD_FILTER_PVT.Apply_RecordFilter( l_list_entry_id
557              -- Check for record filter
558              IF (p_rlse_ctrl_alg_id > 0)
559              THEN
561                                                         , p_list_id
562                                                         , l_returns_id
563                                                         , p_rlse_ctrl_alg_id
564                                                         , p_view_name
565                                                         , l_callable_flag);
566              END IF;
567 
568              IF (l_callable_flag = 'Y')
569              THEN
570                 l_callback_count := l_callback_count + 1;
571                 l_index := l_index + 1;
572                 l_returns_id_tab.EXTEND(1);
573                 l_returns_id_tab(l_index) := l_returns_id;
574              END IF;
575 
576           END IF;
577 
578           EXIT WHEN l_callback_count >= P_COUNT;
579 
580        END LOOP;
581 
582        IF (l_returns_id_tab.COUNT > 0)
583        THEN
584 
585           CHECK_OUT_ENTRIES( P_SERVER_ID
586                            , l_returns_id_tab);
587           X_RETURNS_ID_TAB := l_returns_id_tab;
588 
589        ELSE
590           X_RETURN_CODE := SCHEDULE_IS_EMPTY;
591        END IF;
592 
593     END IF;
594 
595     CLOSE l_callback_query_cursor;
596 
597     -- UNLOCK THE CAMPAIGN
598     IEC_COMMON_UTIL_PVT.UNLOCK_SCHEDULE( P_SOURCE_ID => G_SOURCE_ID
599                                        , P_SCHED_ID => P_SCHEDULE_ID
600                                        , P_SERVER_ID => P_SERVER_ID
601                                        , X_SUCCESS_FLAG => l_return_code);
602 
603 
604     RETURN;
605 EXCEPTION
606    WHEN no_data_found THEN
607 
608       IF l_callback_query_cursor%ISOPEN
609       THEN
610          CLOSE l_callback_query_cursor;
611       END IF;
612        return;
613    WHEN OTHERS THEN
614       L_ERROR_CODE := SQLCODE;
615       IF l_callback_query_cursor%ISOPEN
616       THEN
617          CLOSE l_callback_query_cursor;
618       END IF;
619       raise_application_error
620         ( -20000
621          , 'SQLCODE: <' || L_ERROR_CODE || '> SQLMESSAGE <' || SQLERRM || '>'
622          ,TRUE
623         );
624 END GET_CALLBACKS;
625 
626 -- Get a working subset
627 PROCEDURE GET_SUBSET_ENTRIES
628   (P_CAMPAIGN_ID       IN            NUMBER
629   ,P_LIST_HEADER_ID    IN            NUMBER
630   ,P_SUBSET_ID         IN            NUMBER
631   ,P_COUNT             IN            NUMBER
632   ,P_RLSE_CTRL_ALG_ID  IN            IEC_G_EXECUTING_LISTS_V.RELEASE_CONTROL_ALG_ID%TYPE
633   ,P_VIEW_NAME         IN            VARCHAR2
634   ,X_RETURN_CODE       IN OUT NOCOPY VARCHAR2
635   ,X_RETURNS_ID_TAB    IN OUT NOCOPY SYSTEM.NUMBER_TBL_TYPE
636   )
637   AS
638 
639   CURSOR l_entry_query_cursor(L_SUBSET_ID NUMBER) IS
640                         select /*+ index ( iec_g_return_entries, iec_g_return_entries_n8 ) */ list_entry_id,
641                         returns_id
642                         from iec_g_return_entries
643                         where   itm_cc_tz_id in
644                         ( select itm_cc_tz_id
645                           from  iec_g_mktg_item_cc_tzs
646                           where subset_id  = L_SUBSET_ID
647                           and     nvl(callable_flag, 'Y') <> 'N'
648                           and     last_callable_time > sysdate)
649                         and     nvl( callback_flag, 'N') = 'N'
650                         and     nvl( contact_point_index, 0) > 0
651                         and     nvl( record_out_flag, 'N') = 'N'
652                         and     nvl( do_not_use_flag, 'N') = 'N'
653                         and     pulled_subset_id is null
654                         order by record_release_time asc;
655 
656   l_record_id NUMBER := 0;
657   l_list_entry_id NUMBER := 0;
658   l_returns_id NUMBER := 0;
659   l_entry_count BINARY_INTEGER := 0;
660   l_callable_flag VARCHAR2(1);
661   l_index NUMBER;
662 
663 BEGIN
664 
665    -- Init defaults -
666    X_RETURN_CODE := FND_API.G_RET_STS_SUCCESS;
667    l_index := X_RETURNS_ID_TAB.COUNT;
668 
669    OPEN l_entry_query_cursor(P_SUBSET_ID);
670 
671    -------------------------------------------------------------------
672    -- Need to change this to fetch one-by-one and apply the dnc and
673    -- record filter.
674    -------------------------------------------------------------------
675     LOOP
676 
677        FETCH l_entry_query_cursor
678        INTO l_list_entry_id
679        ,    l_returns_id;
680 
681        EXIT WHEN l_entry_query_cursor%NOTFOUND;
682 
683        -------------------------------------------------------------------
684        -- Check DNC and Record Filter before adding this entry to
685        -- the list.
686        -------------------------------------------------------------------
687        IEC_DNC_PVT.IS_CALLABLE( G_SOURCE_ID
688                                 , P_VIEW_NAME
689                                 , l_list_entry_id
690                                 , P_LIST_HEADER_ID
691                                 , l_returns_id
692                                 , l_callable_flag);
693 
694        IF (l_callable_flag = 'Y')
695        THEN
696 
700              IEC_RECORD_FILTER_PVT.Apply_RecordFilter( l_list_entry_id
697           -- Check for record filter
698           IF (p_rlse_ctrl_alg_id > 0)
699           THEN
701                                                      , p_list_header_id
702                                                      , l_returns_id
703                                                      , p_rlse_ctrl_alg_id
704                                                      , p_view_name
705                                                      , l_callable_flag);
706           END IF;
707 
708           IF (l_callable_flag = 'Y')
709           THEN
710              l_entry_count := l_entry_count + 1;
711              l_index := l_index + 1;
712              X_RETURNS_ID_TAB.EXTEND(1);
713              X_RETURNS_ID_TAB(l_index) := l_returns_id;
714           END IF;
715 
716        END IF;
717 
718 
719        EXIT WHEN l_entry_count >= P_COUNT;
720 
721     END LOOP;
722 
723     CLOSE l_entry_query_cursor;
724 
725     return;
726 EXCEPTION
727    WHEN no_data_found then
728        return;
729 END GET_SUBSET_ENTRIES;
730 
731 PROCEDURE GET_SCHED_ENTRIES
732   (P_CAMPAIGN_ID       IN            NUMBER
733   ,P_SCHED_ID          IN            NUMBER
734   ,P_LIST_HEADER_ID    IN            NUMBER
735   ,P_COUNT             IN            NUMBER
736   ,P_VIEW_NAME         IN            VARCHAR2
737   ,P_RLSE_CTRL_ALG_ID  IN            NUMBER
738   ,X_RETURN_CODE       IN OUT NOCOPY VARCHAR2
739   ,X_RETURNS_ID_TAB    IN OUT NOCOPY SYSTEM.NUMBER_TBL_TYPE
740   )
741   AS
742 
743   l_subset_priority_tbl     SUBSET_PRIORITY;
744   l_subset_id_tbl           SUBSET_ID;
745   l_working_quantum_tbl     WORKING_QUANTUM;
746   l_working_quota_tbl       WORKING_QUOTA;
747   l_quantum_tbl             QUANTUM;
748   l_quota_tbl               QUOTA;
749   l_quota_reset_time_tbl    QUOTA_RESET_TIME;
750   l_quota_reset_tbl         QUOTA_RESET;
751   l_use_flag_tbl            USE_FLAG;
752   l_release_strategy_tbl    RELEASE_STRATEGY;
753   l_subset_updated_tbl      FLAG_COLLECTION;
754   l_subset_empty_tbl        FLAG_COLLECTION;
755   l_entries_released_tbl    QUOTA;
756 
757   l_reg_returns_id_tab      SYSTEM.NUMBER_TBL_TYPE := SYSTEM.NUMBER_TBL_TYPE();
758 
759   l_has_records NUMBER(1);
760 
761   l_fetch_records NUMBER(10) := 0;
762 
763   l_list_count NUMBER := 0;
764   l_subset_count NUMBER := 0;
765   l_callback_count NUMBER := 0;
766 
767   l_record_id NUMBER(15);
768   l_entry_index NUMBER := 0;
769 
770   -------------------------------------------------------------------
771   -- Physical index is used to store the start of the subsets that
772   -- are assigned the current priority in the subset collection.
773   -------------------------------------------------------------------
774   l_priority_start_index BINARY_INTEGER := 0;
775 
776   -------------------------------------------------------------------
777   -- Physical index is used to store the end of the subsets that
778   -- are assigned the current priority in the subset collection.
779   -------------------------------------------------------------------
780   l_priority_end_index BINARY_INTEGER := 0;
781 
782   -------------------------------------------------------------------
783   -- Logical index is used to store the subset that had the token
784   -- at the start of the routine for the subsets that
785   -- are assigned the current priority in the subset collection.
786   -------------------------------------------------------------------
787   l_priority_logical_index BINARY_INTEGER := 0;
788   l_priority_current_index BINARY_INTEGER := 0;
789 
790   l_subset_index BINARY_INTEGER := 0;
791 
792   l_current_priority BINARY_INTEGER := 0;
793   l_current_priority_count BINARY_INTEGER := 0;
794 
795   l_additional_entries_in_pri BOOLEAN := FALSE;
796   l_additional_entries_in_list BOOLEAN := FALSE;
797   l_restriction_encountered BOOLEAN := FALSE;
798   l_disregard_restriction BOOLEAN := FALSE;
799   l_priority_transition BOOLEAN := TRUE;
800   l_subset_transition BOOLEAN := FALSE;
801   l_priority_token_found BOOLEAN := FALSE;
802 
803 BEGIN
804   l_has_records := -1;
805 
806    -- Init defaults -
807    X_RETURN_CODE := FND_API.G_RET_STS_SUCCESS;
808    l_list_count := P_COUNT;
809    l_entry_index := X_RETURNS_ID_TAB.COUNT;
810 
811    -------------------------------------------------------------------
812    -- Get the subsets for the highest priority.
813    -------------------------------------------------------------------
814    SELECT a.list_subset_id
815    ,      a.priority
816    ,      a.release_strategy
817    ,      b.working_quantum
818    ,      b.working_quota
819    ,      a.quota
820    ,      a.quantum
821    ,      b.quota_reset_time
822    ,      b.use_flag
823    ,      a.quota_reset
824    BULK COLLECT INTO l_subset_id_tbl
825    ,                 l_subset_priority_tbl
826    ,                 l_release_strategy_tbl
827    ,                 l_working_quantum_tbl
828    ,                 l_working_quota_tbl
829    ,                 l_quota_tbl
830    ,                 l_quantum_tbl
831    ,                 l_quota_reset_time_tbl
832    ,                 l_use_flag_tbl
833    ,                 l_quota_reset_tbl
834    FROM iec_g_list_subsets a
835    ,    iec_g_subset_rt_info b
839    AND   b.callable_flag = 'Y'
836    WHERE a.list_header_id = P_LIST_HEADER_ID
837    AND   a.list_subset_id = b.list_subset_id
838    AND   b.valid_flag = 'Y'
840    AND   b.STATUS_CODE = 'ACTIVE'
841    ORDER BY a.priority, a.list_subset_id;
842 
843    -------------------------------------------------------------------
844    -- Create two more collections for storing information on each
845    -- subset as to whether it was updated and if it contains
846    -- callable records.
847    -------------------------------------------------------------------
848    FOR j in 1 .. l_subset_id_tbl.COUNT
849    LOOP
850       l_subset_updated_tbl(j) := 'Y';
851       l_subset_empty_tbl(j) := 'N';
852       l_entries_released_tbl(j) := 0;
853    END LOOP;
854 
855    -------------------------------------------------------------------
856    -- While we still have entries to fulfill.
857    -------------------------------------------------------------------
858    WHILE l_list_count > 0
859    LOOP
860       -------------------------------------------------------------------
861       -- Initialize the collection used to retrieve subset entries.
862       -------------------------------------------------------------------
863       l_reg_returns_id_tab.DELETE;
864 
865       -------------------------------------------------------------------
866       -- If we have switched priorities then we need to locate the
867       -- subset that currently owns the token to start fetching records
868       -- from for that priority.  If none of the subsets owns the token
869       -- then pick the first one.  We also will locate the index in
870       -- the collection that marks the final subset with this priority
871       -- and get a count of how many subsets are in this priority.
872       -------------------------------------------------------------------
873       IF l_priority_transition = TRUE
874       THEN
875 
876          l_priority_transition := FALSE;
877          l_priority_token_found := FALSE;
878 
879          -------------------------------------------------------------------
880          -- Check to ensure that the current priority is not the last
881          -- priority in the collection.
882          -------------------------------------------------------------------
883          IF l_priority_end_index >= l_subset_priority_tbl.COUNT
884          THEN
885 
886             -------------------------------------------------------------------
887             -- Since the routine has been thru the entire collection of priorities
888             -- assigned to this list and we didn't come across any subsets that
889             -- still had entries then just return with what we have.
890             -------------------------------------------------------------------
891             IF l_additional_entries_in_list = FALSE
892             THEN
893 
894                -------------------------------------------------------------------
895                -- If this list is set for quota and some subsets were turned off
896                -- due to quota restrictions then remove restrictions and try
897                -- again.
898                -------------------------------------------------------------------
899                IF l_restriction_encountered = TRUE
900                THEN
901                   l_additional_entries_in_pri := FALSE;
902                   l_additional_entries_in_list := FALSE;
903                   l_restriction_encountered := FALSE;
904                   l_disregard_restriction := TRUE;
905                   l_priority_end_index := 0;
906                ELSE
907                   EXIT;
908                END IF;
909 
910             -------------------------------------------------------------------
911             -- If there are still entries in the list then return to the first priority and
912             -- reinitialize the list_index, additional_entries_in_pri, and
913             -- priority_index variable.  We might need to set the working quantum
914             -- here if we change to the next list.  Also need to look at the use
915             -- flag (the priority token).
916             -------------------------------------------------------------------
917             ELSE
918                l_additional_entries_in_pri := FALSE;
919                l_additional_entries_in_list := FALSE;
920                l_priority_end_index := 0;
921             END IF;
922 
923          END IF;
924 
925          -------------------------------------------------------------------
926          -- Reinitialize the priority indexes.
927          -------------------------------------------------------------------
928          l_priority_start_index := l_priority_end_index + 1;
929          l_priority_end_index := 0;
930          l_priority_logical_index := l_priority_start_index;
931          l_priority_current_index := l_priority_start_index;
932          l_current_priority := l_subset_priority_tbl(l_priority_start_index);
933          l_current_priority_count := 1;
934 
935          -------------------------------------------------------------------
936          -- Continue looping thru collection until we locate the last
937          -- subset in the collection that belongs to this priority.
938          -------------------------------------------------------------------
939          WHILE l_priority_end_index = 0
940          LOOP
941 
942             -------------------------------------------------------------------
943             -- Found the subset in the priority has the token so continue
947             THEN
944             -- on and set the priority transition flag to FALSE.
945             -------------------------------------------------------------------
946             IF l_use_flag_tbl(l_priority_current_index) = 'Y'
948                l_priority_logical_index := l_priority_current_index;
949                l_priority_token_found := TRUE;
950             END IF;
951 
952             -------------------------------------------------------------------
953             -- If the current index is equal to the last entry in the collection
954             -- then we can assume that we have checked all of the subsets in
955             -- this priority and make the appropriate assignments for
956             -- this priority.
957             -------------------------------------------------------------------
958             IF l_priority_current_index < l_subset_priority_tbl.COUNT
959             THEN
960 
961                -------------------------------------------------------------------
962                -- If the priority on the next subset in the collection indicates
963                -- that it is belongs to the same priority as the previous subset
964                -- then increment the subset index.
965                -------------------------------------------------------------------
966                IF l_subset_priority_tbl(l_priority_current_index + 1) = l_current_priority
967                THEN
968                   l_priority_current_index := l_priority_current_index + 1;
969                   l_current_priority_count := l_current_priority_count + 1;
970 
971                -------------------------------------------------------------------
972                -- If the priority on the next subset in the collection indicates
973                -- that it belongs to a different priority as the previous subset
974                -- then give the token to the first subset in priority.
975                -------------------------------------------------------------------
976                ELSE
977                   IF l_priority_token_found = FALSE
978                   THEN
979                      l_subset_index := l_priority_start_index;
980                      l_use_flag_tbl(l_priority_start_index) := 'Y';
981                   ELSE
982                      l_subset_index := l_priority_logical_index;
983                      l_use_flag_tbl(l_priority_logical_index) := 'Y';
984                   END IF;
985                   l_priority_end_index := l_priority_current_index;
986                END IF;
987 
988             -------------------------------------------------------------------
989             -- If there are no more subsets to check then
990             -- set the end index for this priority.
991             -------------------------------------------------------------------
992             ELSE
993                l_subset_index := l_priority_logical_index;
994                l_use_flag_tbl(l_priority_logical_index) := 'Y';
995                l_priority_end_index := l_priority_current_index;
996             END IF;
997 
998          END LOOP;
999 
1000       END IF;  -- Priority transition conditional
1001 
1002       -------------------------------------------------------------------
1003       -- If this subset has already been visited and determined that no
1004       -- entries could be fetched from it, then don't try again.
1005       -------------------------------------------------------------------
1006       IF l_subset_empty_tbl(l_subset_index) = 'N'
1007       THEN
1008 
1009          -------------------------------------------------------------------
1010          -- If quantum strategy then use working quantum only.
1011          -------------------------------------------------------------------
1012          IF l_release_strategy_tbl(l_subset_index) = QUANTUM_RLSE_STTGY
1013          THEN
1014 
1015             -------------------------------------------------------------------
1016             -- Determines the number to try and retrieve.  If there is only
1017             -- one subset in this priority then try to fulfill the number
1018             -- requested on this list using just the single subset.  Otherwise
1019             -- if requested is greater than working quantum on current subset
1020             -- then retrieve current subset otherwise return requested.
1021             -------------------------------------------------------------------
1022             IF l_current_priority_count = 1
1023             THEN
1024                l_subset_count := l_list_count;
1025             ELSE
1026                IF l_working_quantum_tbl(l_subset_index) < l_list_count
1027                THEN
1028                   l_subset_count := l_working_quantum_tbl(l_subset_index);
1029                ELSE
1030                   l_subset_count := l_list_count;
1031                END IF;
1032             END IF;
1033          -------------------------------------------------------------------
1034          -- If quota strategy then check working quota as well.
1035          -------------------------------------------------------------------
1036          ELSIF l_release_strategy_tbl(l_subset_index) = QUOTA_RLSE_STTGY
1037          THEN
1038 
1039             -------------------------------------------------------------------
1040             -- First check to see if the quota reset time has been reached.  If
1041             -- it has we then need to update the quota reset time to the next
1042             -- time.
1043             -------------------------------------------------------------------
1047                IF (l_quota_reset_time_tbl(l_subset_index) + (l_quota_reset_tbl(l_subset_index) / 1440)) > SYSDATE
1044             IF l_quota_reset_time_tbl(l_subset_index) <= SYSDATE
1045             THEN
1046                l_working_quota_tbl(l_subset_index) := l_quota_tbl(l_subset_index);
1048                THEN
1049                   l_quota_reset_time_tbl(l_subset_index) := l_quota_reset_time_tbl(l_subset_index) + (l_quota_reset_tbl(l_subset_index) / 1440);
1050                ELSE
1051                   l_quota_reset_time_tbl(l_subset_index) := SYSDATE + (l_quota_reset_tbl(l_subset_index) / 1440);
1052                END IF;
1053             END IF;
1054 
1055             -------------------------------------------------------------------
1056             -- The quota on this subset has been reached but the reset time has
1057             -- not expired therefore we move on to the next subset.  This disregards
1058             -- priorities.  The only reason we would pull from this subset at
1059             -- this time is if there are no other subsets that have quota left.
1060             -------------------------------------------------------------------
1061             IF (l_working_quota_tbl(l_subset_index) = 0 OR l_entries_released_tbl(l_subset_index) >= l_working_quota_tbl(l_subset_index))
1062                AND l_disregard_restriction = FALSE
1063             THEN
1064                l_restriction_encountered := TRUE;
1065                l_subset_count := 0;
1066 
1067             ELSE
1068 
1069                -------------------------------------------------------------------
1070                -- If the quota is greater than zero then we release according to
1071                -- the quantum.  This could cause some issues with quota release
1072                -- strategy because the dial server now could contain 100 entries
1073                -- from this list even though the quota only is 1.  If the one
1074                -- is reached then currently we have no means to flush out the
1075                -- entries that are currently in the dial server.
1076                -------------------------------------------------------------------
1077 
1078                -------------------------------------------------------------------
1079                -- This strategy will only release maximum the remaining quota number
1080                -- of entries or the remaining quantum which ever is smaller.
1081                -------------------------------------------------------------------
1082                IF l_working_quota_tbl(l_subset_index) < l_list_count AND l_disregard_restriction = FALSE
1083                THEN
1084                   IF l_working_quantum_tbl(l_subset_index) < l_working_quota_tbl(l_subset_index)
1085                   THEN
1086                      l_subset_count := l_working_quantum_tbl(l_subset_index);
1087                   ELSE
1088                      l_subset_count := l_working_quota_tbl(l_subset_index);
1089                   END IF;
1090                ELSE
1091                   IF l_current_priority_count = 1
1092                   THEN
1093                      l_subset_count := l_list_count;
1094                   ELSE
1095                      IF l_working_quantum_tbl(l_subset_index) < l_list_count
1096                      THEN
1097                         l_subset_count := l_working_quantum_tbl(l_subset_index);
1098                      ELSE
1099                         l_subset_count := l_list_count;
1100                      END IF;
1101                   END IF;
1102                END IF;
1103             END IF;
1104          END IF;
1105 
1106          IF l_subset_count > 0
1107          THEN
1108             get_subset_entries( P_CAMPAIGN_ID => P_CAMPAIGN_ID
1109                               , P_LIST_HEADER_ID => P_LIST_HEADER_ID
1110                               , P_SUBSET_ID => l_subset_id_tbl(l_subset_index)
1111                               , P_COUNT => l_subset_count
1112                               , P_RLSE_CTRL_ALG_ID  => P_RLSE_CTRL_ALG_ID
1113                               , P_VIEW_NAME => P_VIEW_NAME
1114                               , X_RETURN_CODE => X_RETURN_CODE
1115                               , X_RETURNS_ID_TAB => l_reg_RETURNS_ID_TAB );
1116 
1117             IF ( X_RETURN_CODE <> FND_API.G_RET_STS_SUCCESS )
1118             THEN
1119                exit;
1120             END IF;
1121 
1122             -------------------------------------------------------------------
1123             -- If entries are returned then add the returned entries to
1124             -- the collection returned for the schedule as a whole.
1125             -------------------------------------------------------------------
1126             IF (l_reg_returns_id_tab.COUNT > 0)
1127             THEN
1128 
1129                IF (X_RETURNS_ID_TAB.COUNT = 0)
1130                THEN
1131                   l_entry_index := 0;
1132                ELSE
1133                   l_entry_index := X_RETURNS_ID_TAB.COUNT;
1134                END IF;
1135 
1136                FOR M in l_reg_returns_id_tab.FIRST .. l_reg_returns_id_tab.LAST
1137                LOOP
1138                   l_entry_index := l_entry_index + 1;
1139                   X_RETURNS_ID_TAB.EXTEND(1);
1140                   X_RETURNS_ID_TAB(l_entry_index) := l_reg_returns_id_tab(M);
1141                END LOOP;
1142 
1143                CHECK_OUT_ENTRIES( G_SERVER_ID
1144                                 , l_reg_returns_id_tab);
1145 
1146                l_entries_released_tbl(l_subset_index) := l_entries_released_tbl(l_subset_index) + l_reg_returns_id_tab.COUNT;
1147 
1148             END IF;  -- IF ENTRIES WERE RETURNED
1149 
1153             -- time.  Determine if the process needs to continue to the next
1150             -------------------------------------------------------------------
1151             -- If the number returned is less then the number requested then
1152             -- the subset has no more callable records to contribute at this
1154             -- subset or not.
1155             -------------------------------------------------------------------
1156             IF (l_reg_returns_id_tab.COUNT < l_subset_count)
1157             THEN
1158                l_subset_transition := TRUE;
1159                l_subset_empty_tbl(l_subset_index) := 'Y';
1160             ELSE
1161                l_subset_empty_tbl(l_subset_index) := 'N';
1162                l_additional_entries_in_pri := TRUE;
1163                l_additional_entries_in_list := TRUE;
1164                IF l_reg_returns_id_tab.COUNT < l_list_count
1165                THEN
1166                   l_subset_transition := TRUE;
1167                ELSE
1168                   IF l_working_quantum_tbl(l_subset_index) <= l_reg_returns_id_tab.COUNT
1169                   THEN
1170                      l_subset_transition := TRUE;
1171                   END IF;
1172                END IF;
1173             END IF;
1174 
1175             l_list_count := l_list_count - l_reg_returns_id_tab.COUNT;
1176 
1177          ELSE
1178             l_subset_transition := TRUE;
1179          END IF; -- IF SUBSET COUNT > 0
1180       ELSE
1181          l_subset_transition := TRUE;
1182       END IF;  -- IF SUBSET EMPTY CONDITIONAL.
1183 
1184       -------------------------------------------------------------------
1185       -- The next section determines if the next subset to attempt to
1186       -- retrieve entries from is assigned the same priority as the
1187       -- current subset.
1188       -------------------------------------------------------------------
1189       IF l_subset_index = l_priority_end_index
1190       THEN
1191          l_priority_current_index := l_priority_start_index;
1192       ELSE
1193          l_priority_current_index := l_subset_index + 1;
1194       END IF;
1195 
1196       -------------------------------------------------------------------
1197       -- We have gone thru all of the subsets for this priority once.
1198       -------------------------------------------------------------------
1199       IF l_priority_current_index =  l_priority_logical_index
1200       THEN
1201 
1202          -------------------------------------------------------------------
1203          -- We have alredy went thru the priority once so reset the fetch
1204          -- token as well as the additional entries in priority flag.
1205          -------------------------------------------------------------------
1206          IF l_subset_Transition = TRUE
1207          THEN
1208             l_working_quantum_tbl(l_subset_index) := l_quantum_tbl(l_subset_index);
1209             l_use_flag_tbl(l_subset_index) := 'N';
1210             l_use_flag_tbl(l_priority_current_index) := 'Y';
1211          ELSE
1212             l_working_quantum_tbl(l_subset_index) := l_working_quantum_tbl(l_subset_index) - l_reg_returns_id_tab.COUNT;
1213          END IF;
1214 
1215          -------------------------------------------------------------------
1216          -- If there are additional entries in the current priority then
1217          -- stay with this priority otherwise move to the next priority.
1218          -------------------------------------------------------------------
1219          IF l_additional_entries_in_pri = TRUE
1220          THEN
1221             l_subset_index := l_priority_logical_index;
1222             l_priority_transition := FALSE;
1223          ELSE
1224             l_subset_index := l_priority_end_index;
1225             l_priority_transition := TRUE;
1226          END IF;
1227          l_additional_entries_in_pri := FALSE;
1228 
1229       -------------------------------------------------------------------
1230       -- Haven't gone thru the priority so move to next subset in
1231       -- priority.
1232       -------------------------------------------------------------------
1233       ELSE
1234          l_priority_transition := FALSE;
1235          IF l_subset_Transition = TRUE
1236          THEN
1237             l_working_quantum_tbl(l_subset_index) := l_quantum_tbl(l_subset_index);
1238             l_use_flag_tbl(l_subset_index) := 'N';
1239             l_use_flag_tbl(l_priority_current_index) := 'Y';
1240          ELSE
1241             l_working_quantum_tbl(l_subset_index) := l_working_quantum_tbl(l_subset_index) - l_reg_returns_id_tab.COUNT;
1242          END IF;
1243          l_subset_index := l_priority_current_index;
1244       END IF;
1245 
1246       l_subset_transition := FALSE;
1247 
1248    END LOOP;         -- list loop
1249 
1250    -------------------------------------------------------------------
1251    -- Loop thru the subsets and update rt info when necessary.
1252    -------------------------------------------------------------------
1253    FOR j in 1 .. l_subset_id_tbl.COUNT
1254    LOOP
1255       IF l_subset_updated_tbl(j) = 'Y'
1256       THEN
1257          UPDATE_SUBSET_RT_INFO( P_CAMPAIGN_ID    => P_CAMPAIGN_ID
1258                               , P_LIST_HEADER_ID => P_LIST_HEADER_ID
1259                               , P_SUBSET_ID      => l_subset_id_tbl(j)
1260                               , P_QUANTUM        => l_working_quantum_tbl(j)
1261                               , P_QUOTA          => l_working_quota_tbl(j)
1262                               , P_QUOTA_RESET    => l_quota_reset_time_tbl(j)
1266    END LOOP;
1263                               , P_USE_FLAG       => l_use_flag_tbl(j)
1264                               , X_RESULT         => X_RETURN_CODE);
1265       END IF;
1267 
1268 EXCEPTION
1269    WHEN no_data_found then
1270        return;
1271 END GET_SCHED_ENTRIES;
1272 
1273 -- Get the records.
1274 PROCEDURE GET_RECORDS
1275   (P_SERVER_ID        IN            NUMBER
1276   ,P_CAMPAIGN_ID      IN            NUMBER
1277   ,P_SCHED_ID         IN            NUMBER
1278   ,P_TARGET_GROUP_ID  IN            NUMBER
1279   ,P_COUNT            IN            NUMBER
1280   ,P_VIEW_NAME        IN            VARCHAR2
1281   ,P_RLSE_CTRL_ALG_ID IN            NUMBER
1282   ,X_CACHE_RECORDS       OUT NOCOPY SYSTEM.NUMBER_TBL_TYPE
1283   ,X_RETURN_CODE         OUT NOCOPY VARCHAR2
1284   )
1285   AS
1286 
1287   l_result_code varchar2( 1 );
1288   l_count NUMBER := 0;
1289   l_returns_id_tab SYSTEM.NUMBER_TBL_TYPE := SYSTEM.NUMBER_TBL_TYPE();
1290   l_return_code VARCHAR2(1);
1291   L_CALLBACK_AVAILABLE_COUNT NUMBER := 0;
1292   L_AVAILABLE_COUNT NUMBER := 0;
1293   L_CALLBACK_CHECKED_OUT_COUNT NUMBER := 0;
1294   L_CHECKED_OUT_COUNT NUMBER := 0;
1295   L_CALENDAR_COUNT NUMBER := 0;
1296   L_CALLBACK_CALENDAR_COUNT NUMBER := 0;
1297   L_INACTIVE_COUNT NUMBER := 0;
1298   L_CALLBACK_RESTRICT_COUNT NUMBER := 0;
1299   L_ERROR_CODE NUMBER := 0;
1300 
1301 BEGIN
1302     G_CAMPAIGN_ID := P_CAMPAIGN_ID;
1303     G_SERVER_ID := P_SERVER_ID;
1304 
1305   ---------------------------------------------------------
1306   -- Initialize the status string to send back to success.
1307   ---------------------------------------------------------
1308   X_RETURN_CODE := FND_API.G_RET_STS_SUCCESS;
1309 
1310   ---------------------------------------------------------
1311   -- Make sure all parameters are passed in.
1312   ---------------------------------------------------------
1313   IF( ( P_SERVER_ID is null )
1314     OR( P_CAMPAIGN_ID is null )
1315     OR( P_SCHED_ID is null )
1316     OR( P_TARGET_GROUP_ID is null )
1317     OR( P_COUNT is null )
1318     OR( P_VIEW_NAME is null)
1319     )
1320   THEN
1321     raise_application_error
1322       ( -20000
1323        , 'P_SERVER_ID , P_CAMPAIGN_ID cannot be null.'
1324          || 'Values sent are Server id (' || P_SERVER_ID || ')'
1325          || ' Campaign id (' || P_CAMPAIGN_ID || ')'
1326          || ' Count (' || P_COUNT || ')'
1327        ,TRUE
1328       );
1329   END IF;
1330 
1331   ---------------------------------------------------------
1332   -- Check to make sure the campaign is active.
1333   ---------------------------------------------------------
1334   IS_SCHEDULE_ACTIVE( P_SCHED_ID
1335                     , l_return_code );
1336 
1337   IF( l_return_code <> FND_API.G_RET_STS_SUCCESS )
1338   THEN
1339     X_RETURN_CODE := SCHEDULE_IS_NOT_ACTIVE;
1340     return;
1341   END IF;
1342 
1343   ---------------------------------------------------------
1344   -- Check to see if the campaign is locked.
1345   ---------------------------------------------------------
1346   IEC_COMMON_UTIL_PVT.LOCK_SCHEDULE( P_SOURCE_ID => G_SOURCE_ID
1347                                    , P_SCHED_ID => P_SCHED_ID
1348                                    , P_SERVER_ID => P_SERVER_ID
1349                                    , P_LOCK_ATTEMPTS => 1
1350                                    , P_ATTEMPT_INTERVAL => 0
1351                                    , X_SUCCESS_FLAG => l_return_code);
1352 
1353   IF( l_return_code <> 'Y' )
1354   THEN
1355     X_RETURN_CODE := SCHEDULE_IS_LOCKED;
1356     return;
1357   END IF;
1358 
1359   ---------------------------------------------------------
1360   -- Move the desired customer count to a local variable.
1361   ---------------------------------------------------------
1362   l_count := P_COUNT;
1363 
1364   ---------------------------------------------------------
1365   -- Procedure to return the entries for this schedule.
1366   ---------------------------------------------------------
1367   GET_SCHED_ENTRIES( P_CAMPAIGN_ID      => P_CAMPAIGN_ID
1368                    , P_SCHED_ID         => P_SCHED_ID
1369                    , P_LIST_HEADER_ID   => P_TARGET_GROUP_ID
1370                    , P_COUNT            => l_COUNT
1371                    , P_VIEW_NAME        => P_VIEW_NAME
1372                    , P_RLSE_CTRL_ALG_ID => P_RLSE_CTRL_ALG_ID
1373                    , X_RETURN_CODE      => l_result_code
1374                    , X_RETURNS_ID_TAB   => l_returns_id_tab );
1375 
1376     if( l_result_code <> FND_API.G_RET_STS_SUCCESS )
1377     then
1378        IEC_COMMON_UTIL_PVT.UNLOCK_SCHEDULE( P_SOURCE_ID    => G_SOURCE_ID
1379                                           , P_SCHED_ID     => P_SCHED_ID
1380                                           , P_SERVER_ID    => P_SERVER_ID
1381                                           , X_SUCCESS_FLAG => l_return_code);
1382        X_RETURN_CODE := SCHEDULE_INTERNAL_ERROR;
1383        return;
1384     end if;
1385 
1386     if( l_returns_id_tab.count <= 0 )
1387     then
1388        IEC_COMMON_UTIL_PVT.UNLOCK_SCHEDULE( P_SOURCE_ID => G_SOURCE_ID
1389                                           , P_SCHED_ID => P_SCHED_ID
1390                                           , P_SERVER_ID => P_SERVER_ID
1391                                           , X_SUCCESS_FLAG => l_return_code);
1392 
1393        ---------------------------------------------------------
1394        -- At this point try to determine why we could
1398        -- (3) All are checked out.
1395        -- not get any more entries:
1396        -- (1) Have all of the customers been serviced?
1397        -- (2) Calendar issue.
1399        ---------------------------------------------------------
1400        GET_UNAVAILABLE_REASON
1401          (P_LIST_ID                     => P_TARGET_GROUP_ID
1402          ,X_CALLBACK_AVAILABLE_COUNT    => L_CALLBACK_AVAILABLE_COUNT
1403          ,X_AVAILABLE_COUNT             => L_AVAILABLE_COUNT
1404          ,X_CALLBACK_CHECKED_OUT_COUNT  => L_CALLBACK_CHECKED_OUT_COUNT
1405          ,X_CHECKED_OUT_COUNT           => L_CHECKED_OUT_COUNT
1406          ,X_CALENDAR_COUNT              => L_CALENDAR_COUNT
1407          ,X_CALLBACK_CALENDAR_COUNT     => L_CALLBACK_CALENDAR_COUNT
1408          ,X_INACTIVE_COUNT              => L_INACTIVE_COUNT
1409          ,X_CALLBACK_RESTRICT_COUNT     => L_CALLBACK_RESTRICT_COUNT);
1410 
1411        ---------------------------------------------------------
1412        -- This means that there are no records currently available
1413        -- so we will try to give a detailed reason why.
1414        ---------------------------------------------------------
1415        IF (L_AVAILABLE_COUNT = 0 AND L_CALLBACK_AVAILABLE_COUNT = 0)
1416        THEN
1417 
1418           ---------------------------------------------------------
1419           -- Unless we can find any other reason, the schedule
1420           -- is thought to be exhausted.
1421           ---------------------------------------------------------
1422           X_RETURN_CODE := SCHEDULE_IS_EMPTY;
1423 
1424           ---------------------------------------------------------
1425           -- Check to see if there are entries already checked out.
1426           ---------------------------------------------------------
1427           IF (L_CALLBACK_CHECKED_OUT_COUNT > 0 OR L_CHECKED_OUT_COUNT > 0)
1428           THEN
1429              X_RETURN_CODE := SCHEDULE_ALL_CHECKED_OUT;
1430           END IF;
1431 
1432           ---------------------------------------------------------
1433           -- Check to see if there are calendar restrictions.
1434           ---------------------------------------------------------
1435           IF (L_CALLBACK_CALENDAR_COUNT > 0 OR L_CALENDAR_COUNT > 0)
1436           THEN
1437 
1438              IF (X_RETURN_CODE = SCHEDULE_ALL_CHECKED_OUT)
1439              THEN
1440                 X_RETURN_CODE := SCHEDULE_CALENDAR_OUT;
1441              ELSE
1442                 X_RETURN_CODE := SCHEDULE_CALENDAR_RESTRICTION;
1443              END IF;
1444           END IF;
1445 
1446           ---------------------------------------------------------
1447           -- Check to see if there are callback restrictions.
1448           ---------------------------------------------------------
1449           IF (L_CALLBACK_RESTRICT_COUNT > 0 )
1450           THEN
1451 
1452              IF (X_RETURN_CODE = SCHEDULE_ALL_CHECKED_OUT)
1453              THEN
1454                 X_RETURN_CODE := SCHEDULE_CALLBACK_OUT;
1455              ELSIF  (X_RETURN_CODE = SCHEDULE_CALENDAR_RESTRICTION)
1456              THEN
1457                 X_RETURN_CODE := SCHEDULE_CALENDAR_CALLBACK;
1458              ELSIF  (X_RETURN_CODE = SCHEDULE_CALENDAR_OUT)
1459              THEN
1460                 X_RETURN_CODE := SCHEDULE_CALENDAR_CALLBACK_OUT;
1461              ELSE
1462                 X_RETURN_CODE := SCHEDULE_CALLBACK_EXPIRATION;
1463              END IF;
1464           END IF;
1465 
1466        END IF;
1467 
1468        RETURN;
1469     end if;
1470 
1471     -- UNLOCK THE CAMPAIGN
1472     IEC_COMMON_UTIL_PVT.UNLOCK_SCHEDULE( P_SOURCE_ID => G_SOURCE_ID
1473                                        , P_SCHED_ID => P_SCHED_ID
1474                                        , P_SERVER_ID => P_SERVER_ID
1475                                        , X_SUCCESS_FLAG => l_return_code);
1476 
1477     X_CACHE_RECORDS := l_returns_id_tab;
1478 
1479     return;
1480 EXCEPTION
1481    WHEN OTHERS THEN
1482 
1483     L_ERROR_CODE := SQLCODE;
1484     Log( 'GET_RECORDS'
1485        , 'UNKNOWN'
1486        , 'Retrieving records for campaign ' || p_campaign_id
1487        , SQLCODE
1488        , SQLERRM);
1489 
1490 
1491     raise_application_error
1492       ( -20000
1493        , 'SQLCODE: <' || L_ERROR_CODE || '> SQLMESSAGE <' || SQLERRM || '>'
1494        ,TRUE
1495       );
1496 
1497    RAISE;
1498 
1499 END GET_RECORDS;
1500 
1501 END IEC_CPN_RLSE_STTGY_PVT;