DBA Data[Home] [Help]

PACKAGE BODY: APPS.PER_BG_NUMBERING_METHOD_PKG

Source


1 PACKAGE BODY PER_BG_NUMBERING_METHOD_PKG AS
2 /* $Header: pebgnuma.pkb 120.1 2009/12/22 06:31:55 skura ship $ */
3 --
4 -- Package Variables
5 --
6    g_X_EMPprofileset       boolean;
7    g_X_APLprofileset       boolean;
8    g_X_CWKprofileset       boolean;
9 --
10    g_debug                 boolean      := hr_utility.debug_enabled;
11    g_pkg_name              varchar2(30) := 'per_bg_numbering_method_pkg';
12    g_max_person_number     number       := 999999999999999999999999999999;
13    g_max_global_person_num number       := 999999999999999999999999999;
14    --
15    -- Enh 2931775
16    g_emp_sequence_name   varchar2(30) := 'PER_GLOBAL_EMP_NUM_S';
17    g_apl_sequence_name   varchar2(30) := 'PER_GLOBAL_APL_NUM_S';
18    g_cwk_sequence_name   varchar2(30) := 'PER_GLOBAL_CWK_NUM_S';
19    --
20    g_xbg_EMPNum_profile  varchar2(30) := 'PER_GLOBAL_EMP_NUM';
21    g_xbg_APLNum_profile  varchar2(30) := 'PER_GLOBAL_APL_NUM';
22    g_xbg_CWKNum_profile  varchar2(30) := 'PER_GLOBAL_CWK_NUM';
23    --
24    g_bg_context_name     varchar2(30) := 'Business Group Information';
25    g_automatic_method    varchar2(1)  := 'A';
26 --
27    g_EMP_Num_FF_cached    boolean := FALSE;
28    g_EMP_Num_FF_ID_cache  ff_formulas_f.formula_name%TYPE := null;
29    --
30    g_APL_Num_FF_cached    boolean := FALSE;
31    g_APL_Num_FF_ID_cache  ff_formulas_f.formula_name%TYPE := null;
32    --
33    g_CWK_Num_FF_cached    boolean := FALSE;
34    g_CWK_Num_FF_ID_cache  ff_formulas_f.formula_name%TYPE := null;
35 
36 --
37 -- ---------------------------------------------------------------------------+
38 -- Local Procedures
39 -- ---------------------------------------------------------------------------+
40 -- Write_Log: writes messages to the LOG file generated by Concurrent Mg.
41 -- ---------------------------------------------------------------------------+
42 PROCEDURE Write_Log
43          ( p_message varchar2 ) IS
44 --
45    c_proc_name varchar2(100) := g_pkg_name||'.write_log';
46 BEGIN
47    FND_FILE.PUT_LINE(FND_FILE.LOG,p_message);
48 
49 EXCEPTION
50       WHEN OTHERS THEN
51          --
52          -- Exception raised whilst writing the log file...
53          --
54          hr_utility.set_location(c_proc_name,1000);
55          FND_FILE.PUT_LINE(FND_FILE.LOG,SQLERRM);
56          RAISE;
57 END Write_Log;
58 -- ---------------------------------------------------------------------------+
59 -- ---------------------------------------------------------------------------+
60 -- Get_Max_applicant_number: - Applicants -
61 --  Returns the maximum numeric value being used in a business group.
62 -- ---------------------------------------------------------------------------+
63 FUNCTION get_max_applicant_number
64              (p_business_group_id IN per_all_people.business_group_id%TYPE)
65     RETURN NUMBER IS
66   --
67   TYPE l_applicant_number_type IS TABLE OF per_all_people_f.applicant_number%TYPE
68        INDEX BY BINARY_INTEGER;
69   --
70   l_applicant_number_tab l_applicant_number_type;
71   l_max_applicant_number NUMBER := 0;
72   --
73   cursor csr_applicants is
74         select applicant_number
75         from   per_all_people_f
76         where  business_group_id = p_business_group_id
77         and    applicant_number is not null;
78   --
79 BEGIN
80   OPEN csr_applicants;
81   LOOP
82     -- bulk collect 500 rows at a time
83     FETCH csr_applicants BULK COLLECT INTO l_applicant_number_tab LIMIT 500;
84     -- loop through each element
85     FOR i IN l_applicant_number_tab.FIRST..l_applicant_number_tab.LAST LOOP
86       BEGIN
87         -- perform a number conversion and then max comparison
88         -- if this fails because the applicant_number contains alpha chars
89         -- then the VALUE_ERROR exception will be raised and handled
90         IF TO_NUMBER(l_applicant_number_tab(i)) > l_max_applicant_number THEN
91           -- conversion succeeded, store new max number
92          if(instr(upper(l_applicant_number_tab(i)),'E') = 0 ) then  --Added for bug9178149
93           l_max_applicant_number := TO_NUMBER(l_applicant_number_tab(i));
94          end if;
95         END IF;
96       EXCEPTION
97         WHEN VALUE_ERROR THEN
98           -- conversion error, applicant number must contain an alpha char so ignore
99           NULL;
100       END;
101     END LOOP;
102     EXIT WHEN csr_applicants%NOTFOUND;
103   END LOOP;
104   CLOSE csr_applicants;
105   RETURN(l_max_applicant_number);
106 EXCEPTION
107   WHEN OTHERS THEN
108     -- this exception is most probably raised from a VALUE_ERROR when
109     -- l_applicant_number_tab.FIRST fails due to a fetch returning no
110     -- rows.
111     -- close the cursor if its open
112     IF csr_applicants%ISOPEN THEN
113       CLOSE csr_applicants;
114     END IF;
115     RETURN(l_max_applicant_number);
116 END get_max_applicant_number;
117 -- ---------------------------------------------------------------------------+
118 -- ---------------------------------------------------------------------------+
119 -- Get_Max_employee_number: - Employees -
120 --  Returns the maximum numeric value being used in a business group.
121 -- ---------------------------------------------------------------------------+
122 --
123 FUNCTION get_max_employee_number
124      (p_business_group_id IN per_all_people.business_group_id%TYPE)
125     RETURN NUMBER IS
126   --
127   TYPE l_employee_number_type IS TABLE OF per_all_people_f.employee_number%TYPE
128        INDEX BY BINARY_INTEGER;
129   --
130   l_employee_number_tab l_employee_number_type;
131   l_max_employee_number NUMBER := 0;
132   --
133   cursor csr_employees is
134         select employee_number
135         from   per_all_people_f
136         where  business_group_id = p_business_group_id
137         and    employee_number is not null;
138   --
139 BEGIN
140   OPEN csr_employees;
141   LOOP
142     -- bulk collect 500 rows at a time
143     FETCH csr_employees BULK COLLECT INTO l_employee_number_tab LIMIT 500;
144     -- loop through each element
145     FOR i IN l_employee_number_tab.FIRST..l_employee_number_tab.LAST LOOP
146       BEGIN
147         -- perform a number conversion and then max comparison
148         -- if this fails because the employee_number contains alpha chars
149         -- then the VALUE_ERROR exception will be raised and handled
150         --
151         IF TO_NUMBER(l_employee_number_tab(i)) > l_max_employee_number THEN
152           -- conversion succeeded, store new max number
153          if(instr(upper(l_employee_number_tab(i)),'E') = 0 ) then --Added for bug9178149
154             l_max_employee_number := TO_NUMBER(l_employee_number_tab(i));
155          end if;
156         END IF;
157       EXCEPTION
158         WHEN VALUE_ERROR THEN
159           -- conversion error, employee number must contain an alpha char so ignore
160           NULL;
161       END;
162     END LOOP;
163     EXIT WHEN csr_employees%NOTFOUND;
164   END LOOP;
165   CLOSE csr_employees;
166   RETURN(l_max_employee_number);
167 EXCEPTION
168   WHEN OTHERS THEN
169     -- this exception is most probably raised from a VALUE_ERROR when
170     -- l_employee_number_tab.FIRST fails due to a fetch returning no
171     -- rows.
172     -- close the cursor if its open
173     IF csr_employees%ISOPEN THEN
174       CLOSE csr_employees;
175     END IF;
176     RETURN(l_max_employee_number);
177 END get_max_employee_number;
178 -- ---------------------------------------------------------------------------+
179 -- ---------------------------------------------------------------------------+
180 -- Get_Max_CWK_number: - Contingent Workers -
181 --  Returns the maximum numeric value being used in a business group.
182 -- ---------------------------------------------------------------------------+
183 --
184 FUNCTION get_max_cwk_number
185      (p_business_group_id IN per_all_people.business_group_id%TYPE)
186     RETURN NUMBER IS
187   --
188   TYPE l_cwk_number_type IS TABLE OF per_all_people_f.npw_number%TYPE
189        INDEX BY BINARY_INTEGER;
190   --
191   l_cwk_number_tab l_cwk_number_type;
192   l_max_cwk_number NUMBER := 0;
193   --
194   cursor csr_cwk is
195         select npw_number
196         from   per_all_people_f
197         where  business_group_id = p_business_group_id
198         and    npw_number is not null;
199   --
200 BEGIN
201   OPEN csr_cwk;
202   LOOP
203     -- bulk collect 500 rows at a time
204     FETCH csr_cwk BULK COLLECT INTO l_cwk_number_tab LIMIT 500;
205     -- loop through each element
206     FOR i IN l_cwk_number_tab.FIRST..l_cwk_number_tab.LAST LOOP
207       BEGIN
208         -- perform a number conversion and then max comparison
209         -- if this fails because the npw_number contains alpha chars
210         -- then the VALUE_ERROR exception will be raised and handled
211         --
212         IF TO_NUMBER(l_cwk_number_tab(i)) > l_max_cwk_number THEN
213           -- conversion succeeded, store new max number
214           if(instr(upper(l_cwk_number_tab(i)),'E') = 0 ) then  --Added for bug9178149
215           l_max_cwk_number := TO_NUMBER(l_cwk_number_tab(i));
216           end if;
217         END IF;
218       EXCEPTION
219         WHEN VALUE_ERROR THEN
220           -- conversion error, cwk number must contain an alpha char so ignore
221           NULL;
222       END;
223     END LOOP;
224     EXIT WHEN csr_cwk%NOTFOUND;
225   END LOOP;
226   CLOSE csr_cwk;
227   RETURN(l_max_cwk_number);
228 EXCEPTION
229   WHEN OTHERS THEN
230     -- this exception is most probably raised from a VALUE_ERROR when
231     -- l_employee_number_tab.FIRST fails due to a fetch returning no
232     -- rows.
233     -- close the cursor if its open
234     IF csr_cwk%ISOPEN THEN
235       CLOSE csr_cwk;
236     END IF;
237     RETURN(l_max_cwk_number);
238 END get_max_cwk_number;
239 -- ---------------------------------------------------------------------------+
240 -- ---------------------------------------------------------------------------+
241 PROCEDURE convert_to_auto_gen_method
242     (errbuf              OUT nocopy varchar2
243     ,retcode             OUT nocopy number
244     ,p_business_group_id IN  number
245     ,p_person_type       IN  varchar2
246     ) IS
247 --
248 --  Local variables
249 --
250    c_proc_name         varchar2(100) := g_pkg_name||'.convert_to_auto_gen_method';
251 
252    e_ResourceBusy      EXCEPTION;
253       PRAGMA EXCEPTION_INIT(e_ResourceBusy, -54);
254 
255    TYPE t_bgRecord IS RECORD
256     (
257       org_id            HR_ORGANIZATION_INFORMATION.Organization_id%TYPE,
258       emp_method        HR_ORGANIZATION_INFORMATION.Org_information2%TYPE,
259       apl_method        HR_ORGANIZATION_INFORMATION.Org_information3%TYPE,
260       cwk_method        HR_ORGANIZATION_INFORMATION.Org_information16%TYPE
261     );
262 
263    l_max_num_found     number        := 0;
264    l_message           varchar2(200) := null;
265    l_rows_updated      number;
266    l_continue_flag     boolean := FALSE;
267    l_use_sequence      boolean := FALSE;
268 
269 
270    l_organization_id   per_all_people_f.business_group_id%TYPE;
271    l_rec_per_bg_groups t_bgRecord;
272 --
273 -- Returns the current method of number generation
274 --
275    cursor csr_method(cp_bg_id per_all_people.business_group_id%TYPE) is
276       SELECT organization_id, Org_information2, Org_information3, Org_information16
277         from  hr_organization_information
278        where organization_id = cp_bg_id
279          and ORG_INFORMATION_CONTEXT  = g_bg_context_name
280       FOR UPDATE of Org_information3          -- method_of_generation_apl_num
281                   , Org_information2          -- method_of_generation_emp_num
282                   , Org_information16 NOWAIT; -- method_of_generation_cwk_num
283 --
284 -- Returns next value stored per person type
285 --
286    cursor csr_next_value(cp_bg_id per_all_people.business_group_id%TYPE
287                  ,cp_person_type  per_person_types.system_person_type%TYPE) is
288       SELECT business_group_id
289         from per_number_generation_controls
290        where business_group_id   = cp_bg_id
291          and type = cp_person_type
292       FOR UPDATE of next_value NOWAIT;
293 --
294 --
295 BEGIN
296    --hr_utility.trace_on(null,'oracle');
297 
298    hr_utility.set_location('Entering: '||c_proc_name,1);
299    hr_utility.trace('Parameters:');
300    hr_utility.trace('  business_group_id = '||to_char(p_business_group_id));
301    hr_utility.trace('  person type       = '||p_person_type);
302 
303    --
304    BEGIN
305        -- Lock per_all_people_f to ensure person records are not created/updated/deleted
306        --
307        hr_utility.set_location(c_proc_name,2);
308        l_rows_updated    := 0;
309        l_organization_id := p_business_group_id;
310        l_use_sequence    := Global_person_numbering(p_person_type);
311 
312        LOCK TABLE per_all_people_f
313         IN EXCLUSIVE MODE NOWAIT;
314        --
315        open csr_method(p_business_group_id);
316        fetch csr_method into l_rec_per_bg_groups;
317 
318        if csr_method%FOUND then
319 
320           hr_utility.set_location(c_proc_name,5);
321           if l_use_sequence then
322              l_continue_flag := TRUE;
323              hr_utility.set_location(c_proc_name,7);
324           else
325              open csr_next_value(p_business_group_id, p_person_type);
326              fetch csr_next_value into l_organization_id;
327              l_continue_flag := csr_next_value%FOUND;
328           end if;
329 
330           if l_continue_flag then
331 
332              hr_utility.set_location(c_proc_name,10);
333              -- -------------------------------------------------------------+
334              --                     Processing Applicants                    +
335              -- -------------------------------------------------------------+
336              if p_person_type = 'APL' then
337 
338                hr_utility.set_location(c_proc_name,12);
339                l_max_num_found := get_max_applicant_number(p_business_group_id);
340 
341                UPDATE HR_ORGANIZATION_INFORMATION
342                   SET Org_information3 = g_automatic_method  -- method_of_generation_apl_num
343                 WHERE organization_id = l_organization_id
344                   AND ORG_INFORMATION_CONTEXT  = g_bg_context_name;
345 
346                hr_utility.set_location(c_proc_name,14);
347                l_rows_updated := SQL%ROWCOUNT;
348 
349              -- -------------------------------------------------------------+
350              --                     Processing Employees                     +
351              -- -------------------------------------------------------------+
352              elsif p_person_type = 'EMP' then
353 
354                hr_utility.set_location(c_proc_name,16);
355                -- needs to check whether CWK method = 'Based on Employee'
356                -- if yes, then need to greatest(empno, cwkno)
357                --
358                if l_rec_per_bg_groups.cwk_method = 'E' then
359                   hr_utility.set_location(c_proc_name,17);
360 
361                   l_max_num_found := greatest(get_max_employee_number(p_business_group_id)
362                                              ,get_max_cwk_number(p_business_group_id));
363                else
364                   l_max_num_found := get_max_employee_number(p_business_group_id);
365                end if;
366 
367                UPDATE HR_ORGANIZATION_INFORMATION
368                   SET Org_information2 = g_automatic_method  -- method_of_generation_emp_num
369                 WHERE organization_id = l_organization_id
370                   AND ORG_INFORMATION_CONTEXT  = g_bg_context_name;
371 
372                hr_utility.set_location(c_proc_name,18);
373                l_rows_updated := SQL%ROWCOUNT;
374              -- -------------------------------------------------------------+
375              --           Processing Contingent Workers                      +
376              -- -------------------------------------------------------------+
377              elsif p_person_type = 'CWK' then
378 
379                hr_utility.set_location(c_proc_name,20);
380                -- needs to check whether CWK method = 'Based on Employee'
381                -- if yes, then need to greatest(empno, cwkno)
382                --
383                if l_rec_per_bg_groups.cwk_method = 'E' then
384                   hr_utility.set_location(c_proc_name,21);
385 
386                   l_max_num_found := greatest(get_max_employee_number(p_business_group_id)
387                                              ,get_max_cwk_number(p_business_group_id));
388                else
389                   l_max_num_found := get_max_cwk_number(p_business_group_id);
390                end if;
391 
392                UPDATE HR_ORGANIZATION_INFORMATION
393                   SET Org_information16 = g_automatic_method  -- method_of_generation_cwk_num
394                 WHERE organization_id = l_organization_id
395                   AND ORG_INFORMATION_CONTEXT  = g_bg_context_name;
396 
397                hr_utility.set_location(c_proc_name,22);
398                l_rows_updated := SQL%ROWCOUNT;
399              end if;
400              -- -------------------------------------------------------------+
401              --                   Update NEXT VALUE                          +
402              -- -------------------------------------------------------------+
403              if (l_max_num_found + 1 > g_max_person_number)
404                 or (l_use_sequence and l_max_num_found > g_max_global_person_num)
405              then
406 
407                 hr_utility.set_message(800,'PER_289925_MAX_VALUE');
408                 hr_utility.raise_error;
409              else
410                 if l_rows_updated > 0 and l_max_num_found is not null then
411                     hr_utility.set_location(c_proc_name,24);
412 
413                     if l_use_sequence then
414                        -- alter sequence
415                        hr_utility.set_location(c_proc_name,25);
416                        set_global_sequence(p_person_type,l_max_num_found);
417                     else
418                        hr_utility.set_location(c_proc_name,26);
419                        UPDATE per_number_generation_controls
420                           SET next_value = l_max_num_found + 1
421                        WHERE business_group_id = l_organization_id
422                          and type = p_person_type;
423                        if csr_next_value%ISOPEN then
424                           close csr_next_value;
425                        end if;
426                     end if;
427                 end if;
428              end if;
429 
430              hr_utility.set_location(c_proc_name,27);
431 
432           end if; -- continue flag?
433 
434        end if; -- csr_method cursor
435        --
436        hr_utility.set_location(c_proc_name,28);
437        hr_utility.trace(' MAX value found = '||to_char(l_max_num_found));
438        --
439        close csr_method;
440    EXCEPTION
441       when TIMEOUT_ON_RESOURCE OR e_ResourceBusy then
442          hr_utility.set_location(c_proc_name,29);
443          -- The required resources are used by some other process.
444 
445          hr_utility.set_message(800,'PER_289849_RESOURCE_BUSY');
446          hr_utility.raise_error;
447 
448    END; -- Lock table
449    hr_utility.set_location('Leaving: '||c_proc_name,35);
450    --hr_utility.trace_off;
451 
452 END convert_to_auto_gen_method;
453 -- -------------------------------------------------------------------------- +
454 -- -------------------------------------------------------------------------- +
455 -- SET_GLOBAL_SEQUENCE:                                                       |
456 -- Alters the global sequence for a specific person type based on last        |
457 -- number parameter.                                                          |
458 -- -------------------------------------------------------------------------- +
459 PROCEDURE SET_GLOBAL_SEQUENCE(p_person_type IN varchar2
460                              ,p_last_number IN NUMBER)
461    IS
462    PRAGMA AUTONOMOUS_TRANSACTION;
463    -- this is required since DDL commands execute implicit commits
464    -- if for some reason, this procedure fails the calling procedure
465    -- should be rolled back.
466    --
467    l_max_number      number;
468    c_proc_name       varchar2(100) := g_pkg_name||'.set_global_sequence';
469    l_seq_owner       varchar2(30);
470    l_seq_name        varchar2(30);
471    l_seq_increment   number;
472    l_string          varchar2(1000);
473    l_PrevSettings    varchar2(1000);
474    l_mynextval       number;
475    l_currval         number;
476    l_seq_last        number;
477    l_cache_size      number;
478    l_min_value       number;
479    l_max_value       number;
480    l_cycleflag       varchar2(1);
481    l_cache_arg       varchar2(100);
482    l_alterflag       number := 0;
483   -- 3385104 start
484    l_status    varchar2(50);
485    l_industry  varchar2(50);
486    l_owner     varchar2(50);
487    l_ret       boolean := FND_INSTALLATION.GET_APP_INFO ('PER', l_status,
488                                                       l_industry, l_owner);
489   --3385104 end
490    --
491    cursor csr_seq_details(cp_seq_name varchar2) IS
492         SELECT sequence_owner, last_number, cache_size,
493              min_value, max_value, cycle_flag
494         FROM all_sequences
495         WHERE sequence_name = cp_seq_name
496           and sequence_owner = l_owner;
497  -- added owner condition for fix of bug 3385104
498 --
499 BEGIN -- main set_global_sequence
500    if g_debug then
501       hr_utility.trace('Entering :'||c_proc_name);
502    end if;
503    -- -------------------------------------------+
504    -- get the sequence name based on person type |
505    -- -------------------------------------------+
506    if p_person_type = 'EMP' then
507       l_seq_name := g_emp_sequence_name;
508    elsif p_person_type = 'APL' then
509       l_seq_name := g_apl_sequence_name;
510    elsif p_person_type = 'CWK' then
511       l_seq_name := g_cwk_sequence_name;
512    end if;
513    -- ---------------------------------------+
514    -- get current sequence details           |
515    -- ---------------------------------------+
516    open csr_seq_details(l_seq_name);
517    fetch csr_seq_details into l_seq_owner, l_seq_last, l_cache_size
518                             , l_min_value, l_max_value, l_cycleflag;
519    close csr_seq_details;
520    -- ----------------------------------------+
521    -- set details regarding original settings |
522    -- ----------------------------------------+
523    IF (l_cache_size = 0) THEN
524       l_cache_arg := ' ';
525    ELSE
526       l_cache_arg := ' CACHE ' || l_cache_size;
527    END IF;
528    --
529    --
530    l_PrevSettings := 'ALTER SEQUENCE ' || l_seq_owner || '.' || l_seq_name
531                     || ' INCREMENT BY 1 ' ||
532                     l_cache_arg || ' MAXVALUE ' || to_char(l_max_value)
533                     || ' MINVALUE ' || to_char(l_min_value);
534    -- -----------------------------------------------------------+
535    -- get current value from sequence to calculate the increment |
536    -- -----------------------------------------------------------+
537    l_mynextval := 0;
538    l_currval   := 0;
539    l_string := 'SELECT ' || l_seq_owner || '.' || l_seq_name ||
540               '.NEXTVAL FROM sys.dual';
541 
542    EXECUTE IMMEDIATE l_string INTO l_mynextval;
543 
544    l_mynextval := l_mynextval - 1;
545    l_currval   := l_mynextval;     -- store this value in case of a rollback
546    --
547    if g_debug then
548       hr_utility.trace('Current Value = '||to_char(l_mynextval));
549    end if;
550    -- ---------------------------------------+
551    -- calculate the increment                |
552    -- ---------------------------------------+
553    if l_mynextval < p_last_number then
554        l_alterflag := l_alterflag + 1;
555 
556        l_seq_increment := p_last_number - l_mynextval -1;
557        --
558        if g_debug then
559           hr_utility.trace('Altering sequence increment to ' || l_seq_increment);
560        end if;
561        --
562        l_string := 'ALTER SEQUENCE ' || l_seq_owner || '.' || l_seq_name
563                    || ' INCREMENT BY ' ||
564                    l_seq_increment ||
565                    ' NOCACHE NOMAXVALUE';
566 
567        EXECUTE IMMEDIATE l_string;
568        -- -----------------------------------------------------+
569        -- force the update of the sequence into the new range  |
570        -- -----------------------------------------------------+
571        if g_debug then
572           hr_utility.trace('Forcing sequence increment');
573        end if;
574        --
575        l_string := 'SELECT ' || l_seq_owner || '.' || l_seq_name ||
576                   '.nextval FROM sys.dual';
577 
578        EXECUTE IMMEDIATE l_string INTO l_mynextval;
579        l_alterflag := l_alterflag + 1;
580        -- ---------------------------------------+
581        -- return sequence to previous settings   |
582        -- ---------------------------------------+
583        if g_debug then
584           hr_utility.trace('Reseting sequence increment');
585        end if;
586 
587        EXECUTE IMMEDIATE l_PrevSettings;
588        l_alterflag := l_alterflag + 1;
589        --
590    end if; -- l_mynextval < p_last_number
591    if g_debug then
592       hr_utility.trace('Leaving : '||c_proc_name);
593    end if;
594 EXCEPTION
595    when others then
596    --
597    -- Rollback sequence changes
598    --
599    if l_alterflag > 1 and l_mynextval > 0 and l_currval > 0 then
600        l_seq_increment := l_currval - l_mynextval;
601        l_string := 'ALTER SEQUENCE ' || l_seq_owner || '.' || l_seq_name
602                    || ' INCREMENT BY ' ||
603                    l_seq_increment || ' NOCACHE ';
604 
605        EXECUTE IMMEDIATE l_string;
606        --
607        l_string := 'SELECT ' || l_seq_owner || '.' || l_seq_name ||
608                   '.nextval FROM sys.dual';
609 
610        EXECUTE IMMEDIATE l_string INTO l_mynextval;
611        -- return to previous settings
612        EXECUTE IMMEDIATE l_PrevSettings;
613        if g_debug then
614           hr_utility.trace('Leaving: sequence rollback done =>'||c_proc_name);
615        end if;
616    end if;
617    --
618    --
619    RAISE;
620 END SET_GLOBAL_SEQUENCE;
621 -- -------------------------------------------------------------------------- +
622 -- -------------------------------------------------------------------------- +
623 -- CONVERT_TO_GLOBAL_SEQUENCE: - this is run as a Conc. Request -             |
624 -- Enables the global sequence for a specific person type.                    |
625 -- This sequence will be use to generate person numbers and will be shared    |
626 -- among all business groups.                                                 |
627 -- -------------------------------------------------------------------------- +
628 PROCEDURE convert_to_global_sequence
629     (errbuf              OUT nocopy varchar2
630     ,retcode             OUT nocopy number
631     ,p_person_type       IN  varchar2
632     ) IS
633 
634    l_max_number      number;
635    c_proc_name       varchar2(100) := g_pkg_name||'.convert_to_global_sequence';
636    --
637    l_message         varchar2(2000);
638    l_success         boolean := FALSE;
639    l_session_date    date;
640    --
641    e_ResourceBusy      EXCEPTION;
642       PRAGMA EXCEPTION_INIT(e_ResourceBusy, -54);
643    e_ProfileUpdFailed  EXCEPTION;
644    e_SeqError          EXCEPTION;
645    --
646    cursor csr_max_emp_num(cp_person_type varchar2) is
647        select max(next_value)
648         from per_number_generation_controls png
649             ,hr_organization_information    hoi
650         where png.business_group_id = hoi.organization_id
651           and hoi.ORG_INFORMATION_CONTEXT  = g_bg_context_name
652           and hoi.Org_information2 = g_automatic_method
653           and png.type = cp_person_type;
654 
655    cursor csr_max_apl_num(cp_person_type varchar2) is
656        select max(next_value)
657         from per_number_generation_controls png
658             ,hr_organization_information    hoi
659         where png.business_group_id = hoi.organization_id
660           and hoi.ORG_INFORMATION_CONTEXT  = g_bg_context_name
661           and hoi.Org_information3 = g_automatic_method
662           and png.type = cp_person_type;
663 
664    cursor csr_max_cwk_num(cp_person_type varchar2) is
665        select max(next_value)
666         from per_number_generation_controls png
667             ,hr_organization_information    hoi
668         where png.business_group_id = hoi.organization_id
669           and hoi.ORG_INFORMATION_CONTEXT  = g_bg_context_name
670           and hoi.Org_information16 = g_automatic_method
671           and png.type = cp_person_type;
672    --
673 BEGIN
674    l_session_date := HR_GENERAL.Effective_Date;
675 
676    if Global_person_numbering(p_person_type) then
677       --
678       --  profile option is already set
679       --
680       hr_utility.set_message(800,'PER_289182_GLOBALNUM_SET');
681       l_message := fnd_message.get();
682 
683       Write_Log(l_message);
684       retcode := 1;  -- raise warning
685    else
686        l_max_number := 1;
687        if g_debug then
688           hr_utility.set_location('Entering: '||c_proc_name,1);
689        end if;
690        -- Lock per_all_people_f to ensure person records are not created/updated/deleted
691        --
692        LOCK TABLE per_all_people_f
693         IN EXCLUSIVE MODE NOWAIT;
694        --
695        -- altering profile option
696        --
697        if p_person_type = 'EMP' then
698           if not fnd_profile.save(g_xbg_EMPNum_profile,'Y','SITE') then
699              RAISE e_ProfileUpdFailed;
700           end if;
701           open csr_max_emp_num(p_person_type);
702           fetch csr_max_emp_num into l_max_number;
703           close csr_max_emp_num;
704 
705        elsif p_person_type = 'APL' then
706           if not fnd_profile.save(g_xbg_APLNum_profile,'Y','SITE') then
707              RAISE e_ProfileUpdFailed;
708           end if;
709           open csr_max_apl_num(p_person_type);
710           fetch csr_max_apl_num into l_max_number;
711           close csr_max_apl_num;
712 
713        elsif p_person_type = 'CWK' then
714           if not fnd_profile.save(g_xbg_CWKNum_profile,'Y','SITE') then
715              RAISE e_ProfileUpdFailed;
716           end if;
717           open csr_max_cwk_num(p_person_type);
718           fetch csr_max_cwk_num into l_max_number;
719           close csr_max_cwk_num;
720 
721        end if; -- person types
722        --
723        -- ------------------------------------------------------------------- +
724        --                     Alter the sequence                              |
725        -- ------------------------------------------------------------------- +
726        -- Sequence is altered based on next_value.
727        ---
728        Set_Global_Sequence(p_person_type, l_max_number);
729       --
730       if Get_PersonNumber_Formula(p_person_type,l_session_date) is not null then
731       --
732       --  custom algorithm is enabled
733       --
734          hr_utility.set_message(800,'PER_449102_NUMGEN_FF_SET');
735          l_message := fnd_message.get();
736 
737          Write_Log(l_message);
738          retcode := 1;  -- raise warning
739       end if;
740    end if; -- profile option set?
741    if g_debug then
742       hr_utility.set_location('Leaving: '||c_proc_name,35);
743    end if;
744    --
745 EXCEPTION
746   when TIMEOUT_ON_RESOURCE OR e_ResourceBusy then
747      if g_debug then
748         hr_utility.set_location(c_proc_name,29);
749      end if;
750      -- The required resources are used by some other process.
751 
752      hr_utility.set_message(800,'PER_289849_RESOURCE_BUSY');
753      hr_utility.raise_error;
754 
755   when e_ProfileUpdFailed then
756 
757      hr_utility.set_message(800,'PER_289181_SEQUENCE_FAIL'); -- change message
758      hr_utility.raise_error;
759 
760 END convert_to_global_sequence;
761 -- ---------------------------------------------------------------------------+
762 --  Global_person_numbering:                                                  |
763 -- This function returns TRUE when "global person numbering" profile          |
764 -- option for a particular person type is set to "yes".                       |
765 -- If this profile option is set, then the global sequence is being used      |
766 -- to generate automatic person numbers.                                      |
767 -- ---------------------------------------------------------------------------+
768 FUNCTION Global_person_numbering(p_person_type IN varchar2)
769   RETURN BOOLEAN IS
770 
771    l_value varchar2(100);
772    l_defined boolean;
773    l_result  boolean;
774    --
775    -- FND_PROFILE.get_specific is required to read from the database
776    -- in case Conc. Program that changes profile value already ran.
777    -- The value is cached once the profile value is set to 'Y';
778    -- FND_PROFILE.value is not used because it reads from cache thus existing
779    -- forms sessions will get old values.
780    --
781 BEGIN
782    l_result := FALSE;
783    if p_person_type = 'EMP' then
784      if g_X_EMPprofileset is null then
785            --
786            FND_PROFILE.get_specific(name_z    => g_xbg_EMPNum_profile
787                                    ,val_z     => l_value
788                                    ,defined_z => l_defined);
789           if l_defined and nvl(l_value,'N')= 'Y' then
790              g_X_EMPprofileset := TRUE;
791              l_result := TRUE;
792           end if;
793      else
794         return(g_X_EMPprofileset);
795      end if;
796    --
797    -- Applicants
798    --
799    elsif p_person_type = 'APL' then
800      if g_X_APLprofileset is null then
801            --
802            FND_PROFILE.get_specific(name_z    => g_xbg_APLNum_profile
803                                    ,val_z     => l_value
804                                    ,defined_z => l_defined);
805           if l_defined and nvl(l_value,'N')= 'Y' then
806              g_X_APLprofileset := TRUE;
807              l_result := TRUE;
808           end if;
809      else
810         return(g_X_APLprofileset);
811      end if;
812    --
813    -- Contingent Workers
814    --
815    elsif p_person_type = 'CWK' then
816      if g_X_CWKprofileset is null then
817            --
818            FND_PROFILE.get_specific(name_z    => g_xbg_CWKNum_profile
819                                    ,val_z     => l_value
820                                    ,defined_z => l_defined);
821           if l_defined and nvl(l_value,'N')= 'Y' then
822              g_X_CWKprofileset := TRUE;
823              l_result := TRUE;
824           end if;
825      else
826         return(g_X_CWKprofileset);
827      end if;
828 
829    else
830       l_result := FALSE;
831    end if;
832    return(l_result);
833 
834 END Global_person_numbering;
835 --
836 -- ---------------------------------------------------------------------------+
837 -- ---------------------------------------------------------------------------+
838 FUNCTION GetGlobalPersonNum(p_person_type IN varchar2)
839   RETURN number IS
840   l_next_value number;
841   c_proc_name  varchar2(100) := g_pkg_name||'.GetGlobalPersonNum';
842 BEGIN
843    l_next_value := null;
844    if p_person_type = 'EMP' then
845       select PER_GLOBAL_EMP_NUM_S.NEXTVAL
846         into l_next_value
847         from dual;
848    elsif p_person_type = 'APL' then
849       select PER_GLOBAL_APL_NUM_S.NEXTVAL
850         into l_next_value
851         from dual;
852 
853    elsif p_person_type = 'CWK' then
854       select PER_GLOBAL_CWK_NUM_S.NEXTVAL
855         into l_next_value
856         from dual;
857 
858    end if;
859    if g_debug then
860       hr_utility.set_location(c_proc_name,20);
861    end if;
862    return (l_next_value);
863 END GetGlobalPersonNum;
864 --
865 -- --------------------------------------------------------------------- +
866 -- Name:    Get_PersonNumber_Formula
867 -- Purpose: Retrieves the fast formula id defined for person number
868 --          generation.
869 -- Returns: formula id is successful, null otherwise.
870 -- --------------------------------------------------------------------- +
871 FUNCTION Get_PersonNumber_Formula(p_person_type    varchar2
872                                  ,p_effective_date date)
873   RETURN number IS
874    --
875    l_formula_id number;
876    l_formula_name ff_formulas_f.formula_name%TYPE;
877    e_NoFormula exception;
878    --
879 BEGIN
880     l_formula_id := null;
881     begin
882         if p_person_type = 'EMP' then
883               l_formula_name := 'EMP_NUMBER_GENERATION';
884         elsif p_person_type = 'APL' then
885            l_formula_name := 'APL_NUMBER_GENERATION';
886         elsif p_person_type = 'CWK' then
887            l_formula_name := 'CWK_NUMBER_GENERATION';
888         else
889            raise e_NoFormula;
890         end if;
891         --
892        select ff.formula_id
893        into   l_formula_id
897                                        -- we ignore the Legislation Code
894        from   ff_formulas_f ff
895        where  ff.formula_name = l_formula_name
896        and    ff.business_group_id = 0 -- global FF defined in Setup BG
898        and    p_effective_date between ff.effective_start_date and
899                                        ff.effective_end_date;
900     exception
901 
902     	    when no_data_found or e_NoFormula then
903 
904     	       l_formula_id := null;
905     end;
906     return (l_formula_id);
907 --
908 END Get_PersonNumber_Formula;
909 -- --------------------------------------------------------------------- +
910 -- Name:    Execute_Get_Person_Number_FF
911 -- Purpose: Execute fast formula in order to generate next person number.
912 -- Returns: Next person number
913 -- --------------------------------------------------------------------- +
914 FUNCTION EXECUTE_GET_PERSON_NUMBER_FF(
915           p_formula_id        number
916          ,p_effective_date    date
917          ,p_business_group_id number
918          ,p_person_type       varchar2
919          ,p_legislation_code  varchar2
920          ,p_person_id         number
921          ,p_person_number     varchar2
922          ,p_party_id          number
923          ,p_date_of_birth     date
924          ,p_start_date        date
925          ,p_national_id       per_all_people_f.national_identifier%TYPE)
926    RETURN VARCHAR2 IS
927 
928   l_proc varchar2(100) := g_pkg_name||'.execute_get_person_number_ff';
929   l_inputs               ff_exec.inputs_t;
930   l_outputs              ff_exec.outputs_t;
931   l_user_message         varchar2(1) := 'N';
932   l_invalid_message      fnd_new_messages.message_text%TYPE;
933   l_person_number        varchar2(30);
934   e_WrongParameters      exception;
935 BEGIN
936     hr_utility.set_location('Entering: '||l_proc,1);
937     --
938     -- Initalize the formula.
939     --
940     ff_exec.init_formula
941       (p_formula_id     => p_formula_id
942       ,p_effective_date => p_effective_date
943       ,p_inputs         => l_inputs
944       ,p_outputs        => l_outputs);
945 
946     hr_utility.set_location(l_proc, 45);
947 
948     --
949     -- Assign the inputs.
950     --
951     for i_input in l_inputs.first..l_inputs.last
952     loop
953 
954       if l_inputs(i_input).name    = 'BUSINESS_GROUP_ID' then
955          l_inputs(i_input).value  := p_business_group_id;
956       elsif l_inputs(i_input).name = 'LEGISLATION_CODE' then
957          l_inputs(i_input).value  := p_legislation_code;
958       elsif l_inputs(i_input).name = 'PERSON_TYPE' then
959          l_inputs(i_input).value  := p_person_type;
960       elsif l_inputs(i_input).name = 'PERSON_ID' then
961          l_inputs(i_input).value  := p_person_id;
962       elsif l_inputs(i_input).name = 'PERSON_NUMBER' then
963          l_inputs(i_input).value  := p_person_number;
964       elsif l_inputs(i_input).name = 'PARTY_ID' then
965          l_inputs(i_input).value  := p_party_id;
966       elsif l_inputs(i_input).name = 'DATE_OF_BIRTH' then
967          l_inputs(i_input).value  := fnd_date.date_to_canonical(p_date_of_birth);
968       elsif l_inputs(i_input).name = 'START_DATE' then
969          l_inputs(i_input).value  := fnd_date.date_to_canonical(p_start_date);
970       elsif l_inputs(i_input).name = 'NATIONAL_ID' then
971          l_inputs(i_input).value  := p_national_id;
972 
973       else
974          hr_utility.trace('2020 name = '||l_inputs(i_input).name);
975          raise e_WrongParameters;
976       end if;
977     end loop;
978     hr_utility.set_location(l_proc,50);
979     --
980     -- Run the formula.
981     --
982     ff_exec.run_formula(l_inputs, l_outputs);
983     --
984     -- Assign the outputs.
985     --
986     for i_output in l_outputs.first..l_outputs.last
987     loop
988       if l_outputs(i_output).name = 'NEXT_NUMBER' then
989 
990         if l_outputs(i_output).value = 'FAILED' then
991           l_user_message := 'Y';
992         else
993             l_person_number := l_outputs(i_output).value;
994         end if;
995 
996       elsif l_outputs(i_output).name = 'INVALID_MSG' then
997            --
998            -- Here any customer-defined messages are set and
999            -- raised after this loop.
1000            --
1001            l_invalid_message := l_outputs(i_output).value;
1002       else
1003         raise e_WrongParameters;
1004       end if;
1005 
1006     end loop;
1007     --
1008     -- If the Fast Formula raises a user-defined error message,
1009     -- raise the error back to the user. Here the message is
1010     -- truncated to 30 characters because that is the limit
1011     -- in the calling program.
1012     --
1013     if l_user_message = 'Y' then
1014       hr_utility.set_message(800, substr(l_invalid_message, 1, 30));
1015       hr_utility.raise_error;
1016     end if;
1017 
1018     hr_utility.set_location(l_proc,55);
1019 
1020     return l_person_number;
1021 
1022 exception
1023 
1024   when e_WrongParameters then
1025     --
1026     -- The inputs / outputs of the Fast Formula are incorrect
1027     -- so raise an error.
1028     --
1029     hr_utility.set_message(800,'HR_449943_BAD_FF_DEFINITION');
1030     hr_utility.raise_error;
1031 
1032 END EXECUTE_GET_PERSON_NUMBER_FF;
1033 --
1034 --
1035 END PER_BG_NUMBERING_METHOD_PKG;