1 package body PA_FP_ELEMENTS_PUB as
2 /* $Header: PAFPELPB.pls 120.4.12020000.3 2013/04/04 07:22:59 djambhek ship $ */
3
4 l_module_name VARCHAR2(100) := 'pa.plsql.pa_fp_elements_pub';
5 g_plsql_max_array_size NUMBER := 200;
6
7 /*==================================================================================================
8 REFRESH_FP_ELEMENTS: This procedure is used to refresh the existing FP Elements records i.e.
9 delete and recreate the FP Elements Records based on the Planning Levels passed to this procedure.
10
11 Bug :- 2920954 This is an existing api that has been modified to insert resource elements for the
12 default task elements based on the automatic resource selection parameter and resource planning
13 level for automatic resource selection. Currently only the defaul task elements are created based
14 on the input planning level and resource list id.
15 ==================================================================================================*/
16 P_PA_DEBUG_MODE varchar2(1) := NVL(FND_PROFILE.value('PA_DEBUG_MODE'), 'N');
17
18 PROCEDURE Refresh_FP_Elements (
19 p_proj_fp_options_id IN NUMBER
20 ,p_cost_planning_level IN VARCHAR2
21 ,p_revenue_planning_level IN VARCHAR2
22 ,p_all_planning_level IN VARCHAR2
23 ,p_cost_resource_list_id IN NUMBER
24 ,p_revenue_resource_list_id IN NUMBER
25 ,p_all_resource_list_id IN NUMBER
26 /*Bug :- 2920954 start of new parameters added for post fp-K one off patch */
27 ,p_select_cost_res_auto_flag IN pa_proj_fp_options.select_cost_res_auto_flag%TYPE
28 ,p_cost_res_planning_level IN pa_proj_fp_options.cost_res_planning_level%TYPE
29 ,p_select_rev_res_auto_flag IN pa_proj_fp_options.select_rev_res_auto_flag%TYPE
30 ,p_revenue_res_planning_level IN pa_proj_fp_options.revenue_res_planning_level%TYPE
31 ,p_select_all_res_auto_flag IN pa_proj_fp_options.select_all_res_auto_flag%TYPE
32 ,p_all_res_planning_level IN pa_proj_fp_options.all_res_planning_level%TYPE
33 /*Bug :- 2920954 end of new parameters added for post fp-K one off patch */
34 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
35 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
36 ,x_msg_data OUT NOCOPY VARCHAR2) is --File.Sql.39 bug 4440895
37
38 l_msg_count NUMBER := 0;
39 l_data VARCHAR2(2000);
40 l_msg_data VARCHAR2(2000);
41 l_msg_index_out NUMBER;
42 l_return_status VARCHAR2(2000);
43 l_debug_mode VARCHAR2(30);
44
45 BEGIN
46
47 FND_MSG_PUB.initialize;
48 IF P_PA_DEBUG_MODE = 'Y' THEN
49 pa_debug.init_err_stack('PA_FP_ELEMENTS_PUB.Refresh_FP_Elements');
50 END IF;
51 fnd_profile.get('pa_debug_MODE',l_debug_mode);
52 l_debug_mode := NVL(l_debug_mode, 'Y');
53 IF P_PA_DEBUG_MODE = 'Y' THEN
54 pa_debug.set_process('Refresh_FP_Elements: ' || 'PLSQL','LOG',l_debug_mode);
55 END IF;
56 x_msg_count := 0;
57
58 x_return_status := FND_API.G_RET_STS_SUCCESS;
59
60 IF (p_proj_fp_options_id IS NULL) THEN
61 pa_debug.g_err_stage := 'Err- Proj FP Options ID cannot be NULL.';
62 IF P_PA_DEBUG_MODE = 'Y' THEN
63 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
64 END IF;
65 x_return_status := FND_API.G_RET_STS_ERROR;
66 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
67 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
68 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
69 END IF;
70
71 /* Depending on the Planning Level, i.e 'COST', PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE or PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, delete the
72 fp_elements for the Proj_FP_Options_ID and then call the Insert_Default procedure
73 to insert into fp_elements. */
74
75 pa_debug.g_err_stage := 'Deleting records from pa_fp_elements and calling insert_Default';
76 IF P_PA_DEBUG_MODE = 'Y' THEN
77 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
78 END IF;
79
80 IF (p_cost_planning_level IS NOT NULL) THEN
81 pa_debug.g_err_stage := 'Deleting and inserting for Cost Planning Level';
82 IF P_PA_DEBUG_MODE = 'Y' THEN
83 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
84 END IF;
85 delete_elements(p_proj_fp_options_id => p_proj_fp_options_id
86 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST
87 ,p_element_level => PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK
88 ,x_return_status => x_return_status
89 ,x_msg_count => x_msg_count
90 ,x_msg_data => x_msg_data);
91
92 insert_default(p_proj_fp_options_id => p_proj_fp_options_id
93 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST
94 ,p_planning_level => p_cost_planning_level
95 ,p_resource_list_id => p_cost_resource_list_id
96 ,p_select_res_auto_flag => p_select_cost_res_auto_flag /* Bug 2920954*/
97 ,p_res_planning_level => p_cost_res_planning_level /* Bug 2920954*/
98 ,x_return_status => x_return_status
99 ,x_msg_count => x_msg_count
100 ,x_msg_data => x_msg_data);
101 END IF;
102
103 IF (p_revenue_planning_level IS NOT NULL) THEN
104 pa_debug.g_err_stage := 'Deleting and inserting for Revenue Planning Level';
105 IF P_PA_DEBUG_MODE = 'Y' THEN
106 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
107 END IF;
108 delete_elements(p_proj_fp_options_id => p_proj_fp_options_id
109 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE
110 ,p_element_level => PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK
111 ,x_return_status => x_return_status
112 ,x_msg_count => x_msg_count
113 ,x_msg_data => x_msg_data);
114
115 insert_default(p_proj_fp_options_id => p_proj_fp_options_id
116 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE
117 ,p_planning_level => p_revenue_planning_level
118 ,p_resource_list_id => p_revenue_resource_list_id
119 ,p_select_res_auto_flag => p_select_rev_res_auto_flag /* Bug 2920954*/
120 ,p_res_planning_level => p_revenue_res_planning_level /* Bug 2920954*/
121 ,x_return_status => x_return_status
122 ,x_msg_count => x_msg_count
123 ,x_msg_data => x_msg_data);
124 END IF;
125
126 IF (p_all_planning_level IS NOT NULL) THEN
127 pa_debug.g_err_stage := 'Deleting and inserting for All Planning Level';
128 IF P_PA_DEBUG_MODE = 'Y' THEN
129 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
130 END IF;
131 delete_elements(p_proj_fp_options_id => p_proj_fp_options_id
132 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL
133 ,p_element_level => PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK
134 ,x_return_status => x_return_status
135 ,x_msg_count => x_msg_count
136 ,x_msg_data => x_msg_data);
137
138 insert_default(p_proj_fp_options_id => p_proj_fp_options_id
139 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL
140 ,p_planning_level => p_all_planning_level
141 ,p_resource_list_id => p_all_resource_list_id
142 ,p_select_res_auto_flag => p_select_all_res_auto_flag /* Bug 2920954*/
143 ,p_res_planning_level => p_all_res_planning_level /* Bug 2920954*/
144 ,x_return_status => x_return_status
145 ,x_msg_count => x_msg_count
146 ,x_msg_data => x_msg_data);
147 END IF;
148
149 pa_debug.g_err_stage := 'End of Refresh_FP_Elements';
150 IF P_PA_DEBUG_MODE = 'Y' THEN
151 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
152 END IF;
153 pa_debug.reset_err_stack;
154
155 EXCEPTION
156 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
157 l_msg_count := FND_MSG_PUB.count_msg;
158 IF l_msg_count = 1 THEN
159 PA_INTERFACE_UTILS_PUB.get_messages
160 (p_encoded => FND_API.G_TRUE,
161 p_msg_index => 1,
162 p_msg_count => l_msg_count,
163 p_msg_data => l_msg_data,
164 p_data => l_data,
165 p_msg_index_out => l_msg_index_out);
166 x_msg_data := l_data;
167 x_msg_count := l_msg_count;
168 ELSE
169 x_msg_count := l_msg_count;
170 END IF;
171 pa_debug.reset_err_stack;
172 RAISE;
173 WHEN OTHERS THEN
174 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
175 x_msg_count := 1;
176 x_msg_data := SQLERRM;
177 FND_MSG_PUB.add_exc_msg
178 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.Refresh_FP_Elements'
179 ,p_procedure_name => pa_debug.G_Err_Stack );
180 IF P_PA_DEBUG_MODE = 'Y' THEN
181 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,SQLERRM,4);
182 pa_debug.write('Refresh_FP_Elements: ' || l_module_name,pa_debug.G_Err_Stack,4);
183 END IF;
184 pa_debug.reset_err_stack;
185
186 raise FND_API.G_EXC_UNEXPECTED_ERROR;
187 END Refresh_FP_Elements;
188
189 /*==================================================================================================
190 COPY_ELEMENTS: This procedure is used to copy FP Elements from the Source FP Option to the Target
191 FP OPtion.
192 -> If the Source FP Option is not passed (i.e. FP Elements are being created for a new FP
193 Option. In this case, details are got from the Parent of the Target FP Option, if not found, then
194 Defaults are inserted for the new Proj FP Option.
195 -> If the Source FP Option is passed, then details are got from the Source FP Option and inserted
196 for the Target FP Option.
197
198 Bug 2920954 :- This is an existing api that has been modified to include the resource selection and
199 resource planning level parameters to pa_fp_elements_pub.insert_default api. P_copy_mode has been
200 added as a parameter to this api. If copying elements for baselined version, only the elements with
201 plan amounts need to copied.
202
203 For bug 2976168. Copy the elements from excluded_elements table if the copy mode is not B
204 and only when the source exists
205 ==================================================================================================*/
206 PROCEDURE Copy_Elements (
207 p_from_proj_fp_options_id IN NUMBER
208 ,p_from_element_type IN VARCHAR2
209 ,p_to_proj_fp_options_id IN NUMBER
210 ,p_to_element_type IN VARCHAR2
211 ,p_to_resource_list_id IN NUMBER
212 ,p_copy_mode IN VARCHAR2 /* Bug 2920954 */
213 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
214 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
215 ,x_msg_data OUT NOCOPY VARCHAR2) is --File.Sql.39 bug 4440895
216
217 l_debug_mode VARCHAR2(30);
218 l_msg_count NUMBER := 0;
219 l_data VARCHAR2(2000);
220 l_msg_data VARCHAR2(2000);
221 l_msg_index_out NUMBER;
222 l_return_status VARCHAR2(2000);
223 l_stage NUMBER := 100;
224 l_par_fp_option_id pa_proj_fp_options.PROJ_FP_OPTIONS_ID%TYPE;
225 l_planning_level pa_proj_fp_options.ALL_FIN_PLAN_LEVEL_CODE%TYPE;
226 l_cost_planning_level pa_proj_fp_options.COST_FIN_PLAN_LEVEL_CODE%TYPE;
227 l_rev_planning_level pa_proj_fp_options.REVENUE_FIN_PLAN_LEVEL_CODE%TYPE;
228 l_from_proj_fp_option_id pa_proj_fp_options.PROJ_FP_OPTIONS_ID%TYPE;
229 l_from_element_type pa_fp_elements.ELEMENT_TYPE%TYPE;
230 l_to_fin_plan_type_id pa_proj_fp_options.FIN_PLAN_TYPE_ID%TYPE;
231 l_to_fin_plan_version_id pa_proj_fp_options.FIN_PLAN_VERSION_ID%TYPE;
232 l_to_project_id pa_projects.project_id%TYPE;
233 l_from_project_id pa_projects.project_id%TYPE;
234 l_element_level VARCHAR2(30) := PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK;
235
236 l_source_preference_code pa_proj_fp_options.FIN_PLAN_PREFERENCE_CODE%TYPE; /* M20-AUG */
237 l_target_preference_code pa_proj_fp_options.FIN_PLAN_PREFERENCE_CODE%TYPE; /* M20-AUG */
238 l_from_planning_level pa_proj_fp_options.ALL_FIN_PLAN_LEVEL_CODE%TYPE;
239 l_to_planning_level pa_proj_fp_options.ALL_FIN_PLAN_LEVEL_CODE%TYPE;
240 l_from_resource_list_id pa_proj_fp_options.ALL_RESOURCE_LIST_ID%TYPE;
241 l_to_resource_list_id pa_proj_fp_options.ALL_RESOURCE_LIST_ID%TYPE;
242
243 /* Start of Variables defined for the bug :- 2684766 */
244
245 l_all_fin_plan_level_code pa_proj_fp_options.all_fin_plan_level_code%TYPE;
246 l_cost_fin_plan_level_code pa_proj_fp_options.cost_fin_plan_level_code%TYPE;
247 l_revenue_fin_plan_level_code pa_proj_fp_options.revenue_fin_plan_level_code%TYPE;
248
249 /* End of Variables defined for the bug :- 2684766 */
250
251 /* start of variables defined for Bug 2920954*/
252 l_select_res_auto_flag PA_PROJ_FP_OPTIONS.select_cost_res_auto_flag%TYPE;
253 l_res_planning_level PA_PROJ_FP_OPTIONS.cost_res_planning_level%TYPE;
254 l_select_cost_res_auto_flag PA_PROJ_FP_OPTIONS.select_cost_res_auto_flag%TYPE;
255 l_cost_res_planning_level PA_PROJ_FP_OPTIONS.cost_res_planning_level%TYPE;
256 l_select_rev_res_auto_flag PA_PROJ_FP_OPTIONS.select_rev_res_auto_flag%TYPE;
257 l_revenue_res_planning_level PA_PROJ_FP_OPTIONS.revenue_res_planning_level%TYPE;
258 /* end of variables defined for Bug 2920954*/
259
260 BEGIN
261
262 FND_MSG_PUB.initialize;
263 IF P_PA_DEBUG_MODE = 'Y' THEN
264 pa_debug.init_err_stack('PA_FP_ELEMENTS_PUB.Copy_Elements');
265 END IF;
266 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
267 l_debug_mode := NVL(l_debug_mode, 'Y');
268 IF P_PA_DEBUG_MODE = 'Y' THEN
269 pa_debug.set_process('Copy_Elements: ' || 'PLSQL','LOG',l_debug_mode);
270 END IF;
271 x_msg_count := 0;
272
273 x_return_status := FND_API.G_RET_STS_SUCCESS;
274
275 IF (p_to_proj_fp_options_id IS NULL) THEN
276 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Target Proj FP Options ID is NULL.';
277 IF P_PA_DEBUG_MODE = 'Y' THEN
278 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
279 END IF;
280
281 x_return_status := FND_API.G_RET_STS_ERROR;
282 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
283 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
284 END IF;
285
286 IF (p_to_element_type IS NULL) THEN
287
288 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Target Element Type is NULL.';
289 IF P_PA_DEBUG_MODE = 'Y' THEN
290 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
291 END IF;
292 x_return_status := FND_API.G_RET_STS_ERROR;
293 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
294 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
295 END IF;
296
297 IF (p_from_proj_fp_options_id IS NOT NULL AND p_from_element_type IS NULL) THEN
298
299 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Source Element Type is NULL.';
300 IF P_PA_DEBUG_MODE = 'Y' THEN
301 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
302 END IF;
303 x_return_status := FND_API.G_RET_STS_ERROR;
304 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
305 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
306
307 END IF;
308
309 IF FND_MSG_PUB.count_msg > 0 THEN
310 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
311 END IF;
312
313 l_stage := 200;
314 IF (p_from_proj_fp_options_id IS NOT NULL) THEN
315 /* If the Source Proj FP Option is passed, then the records have to be copied
316 from pa_fp_elements for the Source FP Option and the Source Element Type. */
317 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Source Proj FP Option is passed.';
318 IF P_PA_DEBUG_MODE = 'Y' THEN
319 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
320 END IF;
321
322 l_from_proj_fp_option_id := p_from_proj_fp_options_id;
323 l_from_element_type := p_from_element_type;
324
325 ELSE
326 l_stage := 300;
327 /* If the Source FP Option is not passed, get the Parent FP Option ID */
328 l_par_fp_option_id := PA_PROJ_FP_OPTIONS_PUB.Get_Parent_FP_Option_ID(p_to_proj_fp_options_id);
329
330
331 IF (l_par_fp_option_id IS NOT NULL) THEN
332 /* Since Parent FP Option is found, records have to be copied from pa_fp_elements
333 for the Parent FP Option and the Target Element Type. */
334 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Parent FP Option is not null.';
335 IF P_PA_DEBUG_MODE = 'Y' THEN
336 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
337 END IF;
338
339 l_from_proj_fp_option_id := l_par_fp_option_id ;
340 -- l_from_element_type := p_to_element_type; /* M20-08: commented this */
341
342 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Got parent. l_from_proj_fp_option_id = '|| l_from_proj_fp_option_id ;
343 IF P_PA_DEBUG_MODE = 'Y' THEN
344 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
345 END IF;
346
347
348 /* M20-AUG changes start from here */
349 SELECT pfo_src.fin_plan_preference_code
350 ,pfo_target.fin_plan_preference_code
351 INTO l_source_preference_code
352 ,l_target_preference_code
353 FROM PA_PROJ_FP_OPTIONS pfo_src
354 ,PA_PROJ_FP_OPTIONS pfo_target
355 WHERE pfo_src.proj_fp_options_id = l_from_proj_fp_option_id
356 AND pfo_target.proj_fp_options_id = p_to_proj_fp_options_id;
357
358
359 IF l_source_preference_code = PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SEP THEN
360 /* this is true whenever parent is project level option. Can also be true when
361 version is created for cost and revenue separately plan type */
362 IF l_target_preference_code = PA_FP_CONSTANTS_PKG.G_PREF_COST_ONLY THEN
363 l_from_element_type := PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST;
364
365 ELSIF l_target_preference_code = PA_FP_CONSTANTS_PKG.G_PREF_REVENUE_ONLY THEN
366 l_from_element_type := PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE;
367
368 ELSIF l_target_preference_code = PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SAME THEN
369 l_from_element_type := PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST;
370
371 ELSIF l_target_preference_code = PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SEP THEN
372 /* this case occurres when adding a cost and revenue separately plan type to a project */
373 l_from_element_type := p_to_element_type;
374
375 END IF;
376 ELSE
377 /* adding a version to a plan type. In this case we dont need to do anything.
378 this is because when plan type is COST AND REVENUE SEPARATELY then case is already handled
379 when plan type is other than this than version and plan type preference code has to be
380 same. Hence set the from element type same as to element type */
381
382 l_from_element_type := p_to_element_type;
383
384 END IF;
385
386 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': from element type set = '|| l_from_element_type ;
387 IF P_PA_DEBUG_MODE = 'Y' THEN
388 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
389 END IF;
390
391
392 ELSE
393 /* Parent Proj Option ID not found, so Insert Default */
394 /* First delete the records from pa_fp_elements and then insert the Default
395 Values into PA_FP_Elements table. */
396
397 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Parent FP Option is null, hence insert_default.';
398 IF P_PA_DEBUG_MODE = 'Y' THEN
399 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
400 END IF;
401
402 Delete_Elements(p_proj_fp_options_id => p_to_proj_fp_options_id
403 ,p_element_type => p_to_element_type
404 ,p_element_level => PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK -- 'TASK' /* M20-08: changed to null */
405 ,x_return_status => x_return_status
406 ,x_msg_count => x_msg_count
407 ,x_msg_data => x_msg_data);
408
409 /* Insert Default values for the proj_fp_option_id, element_type and planning_level. */
410 IF (p_to_element_type = PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH) THEN
411 l_stage := 400;
412 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Inserting Default Values for Both - COST
413 and REVENUE.';
414 IF P_PA_DEBUG_MODE = 'Y' THEN
415 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
416 END IF;
417
418 /* Get the value of the Cost and Revenue Planning Level for the proj_fp_options_id
419 depending on the p_element_type value. */
420
421 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': getting planning level.';
422 IF P_PA_DEBUG_MODE = 'Y' THEN
423 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
424 END IF;
425
426 SELECT cost_fin_plan_level_code
427 ,revenue_fin_plan_level_code
428 ,select_cost_res_auto_flag /* Bug 2920954 */
429 ,cost_res_planning_level /* Bug 2920954 */
430 ,select_rev_res_auto_flag /* Bug 2920954 */
431 ,revenue_res_planning_level /* Bug 2920954 */
432 INTO l_cost_planning_level
433 ,l_rev_planning_level
434 ,l_select_cost_res_auto_flag /* Bug 2920954 */
435 ,l_cost_res_planning_level /* Bug 2920954 */
436 ,l_select_rev_res_auto_flag /* Bug 2920954 */
437 ,l_revenue_res_planning_level /* Bug 2920954 */
438 FROM pa_proj_fp_options
439 WHERE proj_fp_options_id = p_to_proj_fp_options_id;
440
441 /* Call Insert_Default twice, once with Element_Type as 'COST' and then as PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE
442 as the case of element_type being 'BOTH' is not handled in Insert_Default. */
443 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': calling insert default for cost.';
444 IF P_PA_DEBUG_MODE = 'Y' THEN
445 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
446 END IF;
447 Insert_Default(p_proj_fp_options_id => p_to_proj_fp_options_id
448 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST
449 ,p_planning_level => l_cost_planning_level
450 ,p_resource_list_id => p_to_resource_list_id
451 ,p_select_res_auto_flag => l_select_cost_res_auto_flag /* Bug 2920954 */
452 ,p_res_planning_level => l_cost_res_planning_level /* Bug 2920954 */
453 ,x_return_status => x_return_status
454 ,x_msg_count => x_msg_count
455 ,x_msg_data => x_msg_data);
456
457 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': calling insert default for revenue.';
458 IF P_PA_DEBUG_MODE = 'Y' THEN
459 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
460 END IF;
461
462 Insert_Default(p_proj_fp_options_id => p_to_proj_fp_options_id
463 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE
464 ,p_planning_level => l_rev_planning_level
465 ,p_resource_list_id => p_to_resource_list_id
466 ,p_select_res_auto_flag => l_select_rev_res_auto_flag /* Bug 2920954 */
467 ,p_res_planning_level => l_revenue_res_planning_level /* Bug 2920954 */
468 ,x_return_status => x_return_status
469 ,x_msg_count => x_msg_count
470 ,x_msg_data => x_msg_data);
471 ELSE
472 l_stage := 500;
473 /* Get the value of the Planning Level for the proj_fp_options_id depending on the
474 p_element_type value. */
475
476 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Inserting Default Values for either COST
477 OR REVENUE.';
478 IF P_PA_DEBUG_MODE = 'Y' THEN
479 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
480 END IF;
481
482 /* M20-AUG: replaced select with call to fin plan utils */
483
484 l_planning_level := PA_FIN_PLAN_UTILS.get_option_planning_level(p_to_proj_fp_options_id ,l_planning_level);
485
486 IF P_PA_DEBUG_MODE = 'Y' THEN
487 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': fetching auto res addition params from option.';
488 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
489 END IF;
490
491 /* Bug 2920954 start of changes */
492
493 SELECT decode(p_to_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, select_cost_res_auto_flag
494 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE,select_rev_res_auto_flag
495 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, select_all_res_auto_flag
496 ,NULL) select_res_auto_flag
497 ,decode(p_to_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, cost_res_planning_level
498 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE,revenue_res_planning_level
499 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, all_res_planning_level
500 ,NULL) res_planning_level
501 INTO l_select_res_auto_flag
502 ,l_res_planning_level
503 FROM pa_proj_fp_options
504 WHERE proj_fp_options_id = p_to_proj_fp_options_id;
505
506 /* Bug 2920954 end of changes */
507
508 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': calling insert default for element type.';
509 IF P_PA_DEBUG_MODE = 'Y' THEN
510 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
511 END IF;
512
513 Insert_Default(p_proj_fp_options_id => p_to_proj_fp_options_id
514 ,p_element_type => p_to_element_type
515 ,p_planning_level => l_planning_level
516 ,p_resource_list_id => p_to_resource_list_id
517 ,p_select_res_auto_flag => l_select_res_auto_flag /* Bug 2920954 */
518 ,p_res_planning_level => l_res_planning_level /* Bug 2920954 */
519 ,x_return_status => x_return_status
520 ,x_msg_count => x_msg_count
521 ,x_msg_data => x_msg_data);
522 END IF;
523 END IF;
524 END IF;
525
526 IF (l_from_proj_fp_option_id IS NOT NULL AND l_from_element_type IS NOT NULL) THEN
527 l_stage := 600;
528
529 /* Get the values of the Plan_Type_ID and Plan_Version_ID of the Target
530 FP Option to be used while inserting records into pa_fp_elements. */
531
532 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': getting info from to option id.';
533 IF P_PA_DEBUG_MODE = 'Y' THEN
534 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
535 END IF;
536
537 SELECT fin_plan_type_id, fin_plan_version_id,project_id,
538 DECODE(fin_plan_preference_code,
539 PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SAME, all_fin_plan_level_code,
540 PA_FP_CONSTANTS_PKG.G_PREF_COST_ONLY, cost_fin_plan_level_code,
541 PA_FP_CONSTANTS_PKG.G_PREF_REVENUE_ONLY, revenue_fin_plan_level_code) planning_level,
542 DECODE(fin_plan_preference_code,
543 PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SAME, all_resource_list_id,
544 PA_FP_CONSTANTS_PKG.G_PREF_COST_ONLY, cost_resource_list_id,
545 PA_FP_CONSTANTS_PKG.G_PREF_REVENUE_ONLY, revenue_resource_list_id) resource_list_id
546 INTO l_to_fin_plan_type_id, l_to_fin_plan_version_id,l_to_project_id, l_to_planning_level,
547 l_to_resource_list_id
548 FROM pa_proj_fp_options
549 WHERE proj_fp_options_id = p_to_proj_fp_options_id;
550
551
552 /*Get the project id of source fp options id */
553 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': getting project of source.';
554 IF P_PA_DEBUG_MODE = 'Y' THEN
555 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
556 END IF;
557
558 SELECT project_id,
559 DECODE(l_from_element_type,
560 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, all_fin_plan_level_code,
561 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, cost_fin_plan_level_code,
562 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, revenue_fin_plan_level_code) plan_type_planning_level,
563 DECODE(l_from_element_type,
564 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, all_resource_list_id,
565 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, cost_resource_list_id,
566 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, revenue_resource_list_id) plan_type_resource_list_id
567 INTO l_from_project_id, l_from_planning_level,l_from_resource_list_id
568 FROM pa_proj_fp_options
569 WHERE proj_fp_options_id = l_from_proj_fp_option_id;
570 /* WHERE proj_fp_options_id = p_from_proj_fp_options_id; manokuma -- UT fixed*/
571
572 /* Bug# 2676352 - Included the below check to catch such cases where copy elements is being called
573 with incompatible planning levels. This procedure needs to be changed for handling this */
574
575 IF (l_from_planning_level <> l_to_planning_level OR
576 l_from_resource_list_id <> l_to_resource_list_id) THEN
577
578 pa_debug.g_err_stage := 'Bug# 2684787: PA_FP_ELEMENTS_PUB.COPY_ELEMENTS being called with ' ||
579 'incompatible planning levels/resource list ids..';
580 IF P_PA_DEBUG_MODE = 'Y' THEN
581 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,4);
582 END IF;
583 pa_debug.g_err_stage := l_from_planning_level || ':' || l_to_planning_level || ':' ||
584 to_char(l_from_resource_list_id) || ':' || to_char(l_to_resource_list_id);
585 IF P_PA_DEBUG_MODE = 'Y' THEN
586 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,4);
587 END IF;
588 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
589 END IF;
590
591
592 /* Delete the records from pa_fp_elements for the Target Proj FP Option and Target Element Type
593 before inserting records into pa_fp_elements. */
594 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Deleting the Elements from FP Elements';
595 IF P_PA_DEBUG_MODE = 'Y' THEN
596 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
597 END IF;
598 Delete_Elements(p_proj_fp_options_id => p_to_proj_fp_options_id
599 ,p_element_type => p_to_element_type
600 ,p_element_level => PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK -- 'TASK'
601 ,x_return_status => x_return_status
602 ,x_msg_count => x_msg_count
603 ,x_msg_data => x_msg_data);
604
605 /* Get the records from pa_fp_elements for the Proj FP Option and the Element Type
606 and insert into PA_FP_ELEMENTS. */
607 l_stage :=700;
608
609 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Inserting records into PA_FP_ELEMENTS';
610 IF P_PA_DEBUG_MODE = 'Y' THEN
611 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
612 END IF;
613
614 -- IF source and target projects are same
615
616 IF l_from_project_id = l_to_project_id THEN
617
618 INSERT INTO pa_fp_elements
619 (PROJ_FP_ELEMENTS_ID
620 ,PROJ_FP_OPTIONS_ID
621 ,PROJECT_ID
622 ,FIN_PLAN_TYPE_ID
623 ,ELEMENT_TYPE
624 ,FIN_PLAN_VERSION_ID
625 ,TASK_ID
626 ,TOP_TASK_ID
627 ,RESOURCE_LIST_MEMBER_ID
628 ,TOP_TASK_PLANNING_LEVEL
629 ,RESOURCE_PLANNING_LEVEL
630 ,PLANNABLE_FLAG
631 ,RESOURCES_PLANNED_FOR_TASK
632 ,PLAN_AMOUNT_EXISTS_FLAG
633 ,TMP_PLANNABLE_FLAG
634 ,TMP_TOP_TASK_PLANNING_LEVEL
635 ,RECORD_VERSION_NUMBER
636 ,LAST_UPDATE_DATE
637 ,LAST_UPDATED_BY
638 ,CREATION_DATE
639 ,CREATED_BY
640 ,LAST_UPDATE_LOGIN)
641 SELECT pa_fp_elements_s.nextval
642 ,p_to_proj_fp_options_id
643 ,project_id
644 ,l_to_fin_plan_type_id
645 ,decode(p_to_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,p_to_element_type)
646 ,l_to_fin_plan_version_id
647 ,task_id
648 ,top_task_id
649 ,resource_list_member_id
650 ,top_task_planning_level
651 ,resource_planning_level
652 ,plannable_flag
653 ,resources_planned_for_task
654 ,NVL(plan_amount_exists_flag,'N') /* Bug 2966275 its better to store to as 'N' */
655 ,plannable_flag /* Same as plannable_flag */
656 ,top_task_planning_level /* Same as top_task_planning_level */
657 ,1
658 ,sysdate
659 ,fnd_global.user_id
660 ,sysdate
661 ,fnd_global.user_id
662 ,fnd_global.login_id
663 FROM pa_fp_elements
664 WHERE proj_fp_options_id = l_from_proj_fp_option_id
665 AND element_type = decode(l_from_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,l_from_element_type)
666 AND NVL(plan_amount_exists_flag,'N') = decode(p_copy_mode,PA_FP_CONSTANTS_PKG.G_BUDGET_STATUS_BASELINED,'Y',NVL(plan_amount_exists_flag,'N')); /* Bug 2920954 */
667
668 /* Bug 2966275 null handling is necessary for plan_amount_exists_flag as in someplaces its being populated as null */
669
670 ELSE --if projects are different then
671
672 IF P_PA_DEBUG_MODE = 'Y' THEN
673 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': projects are different.';
674 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
675 END IF;
676
677 INSERT INTO pa_fp_elements
678 (PROJ_FP_ELEMENTS_ID
679 ,PROJ_FP_OPTIONS_ID
680 ,PROJECT_ID
681 ,FIN_PLAN_TYPE_ID
682 ,ELEMENT_TYPE
683 ,FIN_PLAN_VERSION_ID
684 ,TASK_ID
685 ,TOP_TASK_ID
686 ,RESOURCE_LIST_MEMBER_ID
687 ,TOP_TASK_PLANNING_LEVEL
688 ,RESOURCE_PLANNING_LEVEL
689 ,PLANNABLE_FLAG
690 ,RESOURCES_PLANNED_FOR_TASK
691 ,PLAN_AMOUNT_EXISTS_FLAG
692 ,TMP_PLANNABLE_FLAG
693 ,TMP_TOP_TASK_PLANNING_LEVEL
694 ,RECORD_VERSION_NUMBER
695 ,LAST_UPDATE_DATE
696 ,LAST_UPDATED_BY
697 ,CREATION_DATE
698 ,CREATED_BY
699 ,LAST_UPDATE_LOGIN)
700 SELECT
701 pa_fp_elements_s.nextval
702 ,p_to_proj_fp_options_id
703 ,l_to_project_id
704 ,l_to_fin_plan_type_id
705 ,decode(p_to_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,p_to_element_type)
706 ,l_to_fin_plan_version_id
707 ,target_pt.task_id
708 ,target_pt.top_task_id
709 ,resource_list_member_id
710 ,top_task_planning_level
711 ,resource_planning_level
712 ,plannable_flag
713 ,resources_planned_for_task
714 ,NVL(plan_amount_exists_flag,'N') /* Bug 2966275 its better to store to as 'N' */
715 ,plannable_flag /* Same as plannable_flag */
716 ,top_task_planning_level /* Same as top_task_planning_level */
717 ,1
718 ,sysdate
719 ,fnd_global.user_id
720 ,sysdate
721 ,fnd_global.user_id
722 ,fnd_global.login_id
723 FROM pa_fp_elements fp,
724 pa_tasks source_pt,
725 pa_tasks target_pt
726 WHERE fp.proj_fp_options_id = l_from_proj_fp_option_id
727 AND fp.task_id = source_pt.task_id
728 AND source_pt.task_number = target_pt.task_number
729 AND target_pt.project_id = l_to_project_id
730 --AND source_pt.project_id = l_from_project_id /* Bug# 2688544 */ Commented for bug 2814165
731 AND element_type = decode(l_from_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,l_from_element_type);
732
733 /*** start of changes for bug :- 2684766 ***/
734 -- The above select just inserts the elements with task_id <> 0
735 -- We also need to copy elements having task_id = 0 as in the case of
736 -- project level planning for the fp option we have elements with task_id as 'zero'.
737
738 BEGIN
739 SELECT all_fin_plan_level_code
740 ,cost_fin_plan_level_code
741 ,revenue_fin_plan_level_code
742 INTO l_all_fin_plan_level_code
743 ,l_cost_fin_plan_level_code
744 ,l_revenue_fin_plan_level_code
745 FROM pa_proj_fp_options
746 WHERE proj_fp_options_id = l_from_proj_fp_option_id;
747
748 EXCEPTION
749 WHEN OTHERS THEN
750 IF P_PA_DEBUG_MODE = 'Y' THEN
751 pa_debug.g_err_stage := 'Error while fetching the fp option record of '||l_from_proj_fp_option_id;
752 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
753 END IF;
754 RAISE;
755 END;
756
757 -- If any of these have palnning level is populated as 'P' ie. project
758 -- it means for this fp option there are elemnts with task_id = 0
759 -- and they have to be copied.
760
761 IF (l_all_fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT) OR
762 (l_cost_fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT ) OR
763 (l_revenue_fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT )
764 THEN
765 INSERT INTO pa_fp_elements
766 (PROJ_FP_ELEMENTS_ID
767 ,PROJ_FP_OPTIONS_ID
768 ,PROJECT_ID
769 ,FIN_PLAN_TYPE_ID
770 ,ELEMENT_TYPE
771 ,FIN_PLAN_VERSION_ID
772 ,TASK_ID
773 ,TOP_TASK_ID
774 ,RESOURCE_LIST_MEMBER_ID
775 ,TOP_TASK_PLANNING_LEVEL
776 ,RESOURCE_PLANNING_LEVEL
777 ,PLANNABLE_FLAG
778 ,RESOURCES_PLANNED_FOR_TASK
779 ,PLAN_AMOUNT_EXISTS_FLAG
780 ,TMP_PLANNABLE_FLAG
781 ,TMP_TOP_TASK_PLANNING_LEVEL
782 ,RECORD_VERSION_NUMBER
783 ,LAST_UPDATE_DATE
784 ,LAST_UPDATED_BY
785 ,CREATION_DATE
786 ,CREATED_BY
787 ,LAST_UPDATE_LOGIN)
788 SELECT pa_fp_elements_s.nextval
789 ,p_to_proj_fp_options_id
790 ,l_to_project_id
791 ,l_to_fin_plan_type_id
792 ,decode(p_to_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,p_to_element_type)
793 ,l_to_fin_plan_version_id
794 ,fp.task_id
795 ,fp.top_task_id
796 ,resource_list_member_id
797 ,top_task_planning_level
798 ,resource_planning_level
799 ,plannable_flag
800 ,resources_planned_for_task
801 ,NVL(plan_amount_exists_flag,'N') /* Bug 2966275 its better to store to as 'N' */
802 ,plannable_flag /* Same as plannable_flag */
803 ,top_task_planning_level /* Same as top_task_planning_level */
804 ,1
805 ,sysdate
806 ,fnd_global.user_id
807 ,sysdate
808 ,fnd_global.user_id
809 ,fnd_global.login_id
810 FROM pa_fp_elements fp
811 WHERE fp.proj_fp_options_id = l_from_proj_fp_option_id
812 AND fp.task_id = 0
813 AND element_type = decode(l_from_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,l_from_element_type);
814
815 END IF;
816 /*** end of changes for bug :- 2684766 ***/
817
818 END IF; --project ids are different
819
820
821 END IF;
822
823 /* For bug 2976168. Copy the elements from excluded_elements table if the copy mode is not B
824 and only when the source exists */
825
826 IF nvl(p_copy_mode ,'-99') <> PA_FP_CONSTANTS_PKG.G_BUDGET_STATUS_BASELINED AND
827 l_from_proj_fp_option_id IS NOT NULL AND
828 l_from_element_type IS NOT NULL THEN
829
830 pa_debug.g_err_stage := TO_CHAR(l_stage)||': About to call Copy_Excluded_Elements';
831 IF P_PA_DEBUG_MODE = 'Y' THEN
832 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
833 END IF;
834
835 PA_FP_EXCLUDED_ELEMENTS_PUB.Copy_Excluded_Elements
836 ( p_from_proj_fp_options_id => l_from_proj_fp_option_id
837 ,p_from_element_type => l_from_element_type
838 ,p_to_proj_fp_options_id => p_to_proj_fp_options_id
839 ,p_to_element_type => p_to_element_type
840 ,x_return_status => x_return_status
841 ,x_msg_count => x_msg_count
842 ,x_msg_data => x_msg_data);
843
844 IF x_return_status<>FND_API.G_RET_STS_SUCCESS THEN
845 pa_debug.g_err_stage := TO_CHAR(l_stage)||'Copy_Excluded_Elements errored out '||x_msg_data;
846 IF P_PA_DEBUG_MODE = 'Y' THEN
847 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,5);
848 END IF;
849 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
850 END IF;
851 END IF;
852
853 pa_debug.g_err_stage := TO_CHAR(l_stage)||': End of Copy_Elements';
854 IF P_PA_DEBUG_MODE = 'Y' THEN
855 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
856 END IF;
857 pa_debug.reset_err_stack;
858
859 EXCEPTION
860 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
861 l_msg_count := FND_MSG_PUB.count_msg;
862 IF l_msg_count = 1 THEN
863 PA_INTERFACE_UTILS_PUB.get_messages
864 (p_encoded => FND_API.G_TRUE,
865 p_msg_index => 1,
866 p_msg_count => l_msg_count,
867 p_msg_data => l_msg_data,
868 p_data => l_data,
869 p_msg_index_out => l_msg_index_out);
870 x_msg_data := l_data;
871 x_msg_count := l_msg_count;
872 ELSE
873 x_msg_count := l_msg_count;
874 END IF;
875 pa_debug.reset_err_stack;
876 RAISE;
877 WHEN OTHERS THEN
878 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
879 x_msg_count := 1;
880 x_msg_data := SQLERRM;
881 FND_MSG_PUB.add_exc_msg
882 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.Copy_Elements'
883 ,p_procedure_name => pa_debug.G_Err_Stack );
884 IF P_PA_DEBUG_MODE = 'Y' THEN
885 pa_debug.write('Copy_Elements: ' || l_module_name,SQLERRM,4);
886 pa_debug.write('Copy_Elements: ' || l_module_name,pa_debug.G_Err_Stack,4);
887 END IF;
888 pa_debug.reset_err_stack;
889
890 raise FND_API.G_EXC_UNEXPECTED_ERROR;
891 END Copy_Elements;
892
893 /*==================================================================================================
894 INSERT_DEFAULT: This procedure is used to insert records into FP Elements. This procedure is
895 called from Copy_Elements and Refresh_FP_Elements.
896 -> The insertion of records is based on the Planning Level passed to this procedure. The planning
897 level coud be at Top and Lowest Task or only Top Tasks.
898 -> Two different cursors are created for this purpose, one for Top and Lowest Tasks and
899 one for only Top Tasks.
900
901 NOTE:- Input parameter p_res_planning_level refers to the resource planning level
902
903 Bug 2920954 :- This is an existing api that has been modified to insert resource elements for the
904 default task elements based on the i/p parameters for automatic resource selection and resource
905 planning level for automatic resource selection.
906 ==================================================================================================*/
907 PROCEDURE Insert_Default (
908 p_proj_fp_options_id IN NUMBER
909 ,p_element_type IN VARCHAR2
910 ,p_planning_level IN VARCHAR2
911 ,p_resource_list_id IN NUMBER
912 /* Bug 2920954 start of parameters added for post fp-K one off patch */
913 ,p_select_res_auto_flag IN pa_proj_fp_options.select_cost_res_auto_flag%TYPE
914 ,p_res_planning_level IN pa_proj_fp_options.cost_res_planning_level%TYPE
915 /* Bug 2920954 end of parameters added for post fp-K one off patch */
916 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
917 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
918 ,x_msg_data OUT NOCOPY VARCHAR2) is --File.Sql.39 bug 4440895
919
920 l_project_id pa_proj_fp_options.PROJECT_ID%TYPE;
921 l_fin_plan_type_id pa_proj_fp_options.FIN_PLAN_TYPE_ID%TYPE;
922 l_fin_plan_version_id pa_proj_fp_options.FIN_PLAN_VERSION_ID%TYPE;
923 l_msg_count NUMBER := 0;
924 l_data VARCHAR2(2000);
925 l_msg_data VARCHAR2(2000);
926 l_msg_index_out NUMBER;
927 l_return_status VARCHAR2(2000);
928 l_debug_mode VARCHAR2(30);
929 l_stage NUMBER := 100;
930 l_planning_level pa_proj_fp_options.ALL_FIN_PLAN_LEVEL_CODE%TYPE;
931 l_resource_list_id pa_proj_fp_options.ALL_RESOURCE_LIST_ID%TYPE;
932 -- Bug 2920954 l_res_planning_level pa_fp_elements.RESOURCE_PLANNING_LEVEL%TYPE;
933
934 /* start of variables defined for Bug 2920954*/
935 l_select_res_auto_flag pa_proj_fp_options.select_cost_res_auto_flag%TYPE;
936 l_res_planning_level pa_proj_fp_options.cost_res_planning_level%TYPE;
937 /*end of variables defined for Bug 2920954*/
938
939 l_resource_list_member_id CONSTANT pa_fp_elements.RESOURCE_LIST_MEMBER_ID%TYPE := 0;
940 l_task_planning_level_top CONSTANT pa_fp_elements.TOP_TASK_PLANNING_LEVEL%TYPE := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_TOP;
941 l_task_planning_level_low CONSTANT pa_fp_elements.TOP_TASK_PLANNING_LEVEL%TYPE
942 := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST;
943 l_res_planned_for_task CONSTANT pa_fp_elements.RESOURCES_PLANNED_FOR_TASK%TYPE := 'N';
944 l_plan_amt_exists_flag CONSTANT pa_fp_elements.PLAN_AMOUNT_EXISTS_FLAG%TYPE := 'N';
945
946 /* Bug 2586647*/
947 l_res_list_is_uncategorized PA_RESOURCE_LISTS_ALL_BG.UNCATEGORIZED_FLAG%TYPE;
948 l_is_resource_list_grouped VARCHAR2(1);
949 l_group_resource_type_id PA_RESOURCE_LISTS_ALL_BG.GROUP_RESOURCE_TYPE_ID%TYPE;
950
951 /* According to guidelines from Performance group
952 plsql table size should never exceed 200 */
953
954 l_plsql_max_array_size NUMBER := 200;
955 l_prev_txn_id NUMBER := NULL;
956 l_counter NUMBER; /* Used by plsql tables during their population */
957
958 TYPE l_task_id_tbl_typ IS TABLE OF
959 pa_tasks.TASK_ID%TYPE INDEX BY BINARY_INTEGER;
960 TYPE l_top_task_id_tbl_typ IS TABLE OF
961 pa_tasks.TOP_TASK_ID%TYPE INDEX BY BINARY_INTEGER;
962 TYPE l_top_plan_level_tbl_typ IS TABLE OF
963 PA_FP_ELEMENTS.TOP_TASK_PLANNING_LEVEL%TYPE INDEX BY BINARY_INTEGER;
964 TYPE l_plannable_flag_tbl_typ IS TABLE OF
965 PA_FP_ELEMENTS.PLANNABLE_FLAG%TYPE INDEX BY BINARY_INTEGER;
966
967 l_task_id_tbl l_task_id_tbl_typ ;
968 l_top_task_id_tbl l_top_task_id_tbl_typ ;
969 l_top_plan_level_tbl l_top_plan_level_tbl_typ;
970 l_plannable_flag_tbl l_plannable_flag_tbl_typ;
971 l_dummy_task_id_tbl pa_fp_elements_pub.l_task_id_tbl_typ;
972
973 /* Cursor for Top and Lowest Tasks */
974 /* M24-08: Modified this cursor as it was previously inserting top and lowest task with plannable
975 flag as 'N'
976 Now first union will select only those top tasks for which any lowest task exists.
977 Second union will select all Lowest and 'Top and Lowest' Tasks. If task id is same
978 as top and lowest task then planning level will be lowest else null
979 */
980 CURSOR top_low_tasks_cur(p_project_id NUMBER) is
981
982 /* Bug 3106741 for performance improvement Order By removed, UNION replaced with UNION ALL */
983 SELECT task_id task_id
984 ,top_task_id top_task_id
985 ,l_task_planning_level_low top_task_planning_level
986 ,'N' plannable_flag
987 FROM pa_tasks t1
988 WHERE project_id = p_project_id
989 AND task_id = top_task_id
990 AND exists (SELECT 'x'
991 FROM pa_tasks t2
992 WHERE t2.parent_task_id = t1.task_id)
993 UNION ALL -- bug 3106741 UNION
994 SELECT task_id task_id
995 ,top_task_id top_task_id
996 ,decode(task_id,top_task_id,l_task_planning_level_low,null) top_task_planning_level
997 ,'Y' plannable_flag
998 FROM pa_tasks t1
999 WHERE project_id = p_project_id
1000 AND not exists (SELECT 'x'
1001 FROM pa_tasks t2
1002 WHERE t2.parent_task_id = t1.task_id);
1003 -- AND task_id <> top_task_id
1004 /* ORDER BY task_id; Bug 3106741 */
1005
1006 /* Cursor for Top Tasks*/
1007 CURSOR top_tasks_cur(p_project_id NUMBER) is
1008 SELECT task_id task_id
1009 ,top_task_id top_task_id
1010 ,l_task_planning_level_top top_task_planning_level
1011 ,'Y' plannable_flag
1012 FROM pa_tasks
1013 WHERE project_id = p_project_id
1014 AND task_id = top_task_id;
1015
1016 BEGIN
1017
1018 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.Insert_Default');
1019 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
1020 l_debug_mode := NVL(l_debug_mode, 'Y');
1021 IF P_PA_DEBUG_MODE = 'Y' THEN
1022 pa_debug.set_process('Insert_Default: ' || 'PLSQL','LOG',l_debug_mode);
1023 END IF;
1024
1025 x_return_status := FND_API.G_RET_STS_SUCCESS;
1026
1027 /* Check for the input parameters not being NULL. */
1028 IF (p_proj_fp_options_id IS NULL) THEN
1029 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Proj FP Option ID cannot be NULL.';
1030 IF P_PA_DEBUG_MODE = 'Y' THEN
1031 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,5);
1032 END IF;
1033 IF (p_element_type IS NULL) THEN
1034 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Element Type cannot be NULL.';
1035 IF P_PA_DEBUG_MODE = 'Y' THEN
1036 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,5);
1037 END IF;
1038 END IF;
1039 x_return_status := FND_API.G_RET_STS_ERROR;
1040 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
1041 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
1042 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
1043 END IF;
1044
1045 l_stage :=200;
1046 /* If the Planning Level parameter is not passed, get the value of the planning level
1047 from the table pa_proj_fp_options depending on the Element_Type. */
1048
1049 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Getting the value of Planning Level.';
1050 IF P_PA_DEBUG_MODE = 'Y' THEN
1051 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1052 END IF;
1053
1054 IF (p_planning_level IS NOT NULL) THEN
1055 /* Planning Level is passed to the procedure, if Proj FP Option records
1056 have not been saved to the Database. */
1057 l_planning_level := p_planning_level;
1058 ELSE
1059
1060 l_planning_level := PA_FIN_PLAN_UTILS.GET_OPTION_PLANNING_LEVEL(p_proj_fp_options_id,p_element_type);
1061 /* M20-AUG replaced by call
1062 SELECT decode(p_element_type,'COST',cost_fin_plan_level_code,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE,revenue_fin_plan_level_code,
1063 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL,all_fin_plan_level_code,NULL)
1064 INTO l_planning_level
1065 FROM pa_proj_fp_options
1066 WHERE proj_fp_options_id = p_proj_fp_options_id;
1067 */
1068
1069 END IF;
1070
1071 l_stage := 300;
1072 /* If the Resouce List ID parameter is not passed, get the value of the resource list id
1073 from the table pa_proj_fp_options depending on the Element_Type. */
1074
1075 IF (p_resource_list_id IS NOT NULL) THEN
1076 /* Resource List ID is passed to the procedure, if Proj FP Option records
1077 have not been saved to the Database. */
1078 l_resource_list_id := p_resource_list_id;
1079 ELSE
1080 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Resource List ID not passed getting from option.';
1081 IF P_PA_DEBUG_MODE = 'Y' THEN
1082 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1083 END IF;
1084
1085 SELECT decode(p_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST,cost_resource_list_id
1086 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE,revenue_resource_list_id,
1087 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL,all_resource_list_id,NULL)
1088 INTO l_resource_list_id
1089 FROM pa_proj_fp_options
1090 WHERE proj_fp_options_id = p_proj_fp_options_id;
1091 END IF;
1092
1093 /* Bug 2920954 If the auto resource addition paramters aren't passed, get the values
1094 from the table pa_proj_fp_options depending on the Element_Type. */
1095
1096 IF (p_select_res_auto_flag IS NULL) AND (p_res_planning_level IS NULL)
1097 THEN
1098
1099 IF P_PA_DEBUG_MODE = 'Y' THEN
1100 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Auto res addition params not passed getting from option.';
1101 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1102 END IF;
1103
1104 SELECT decode(p_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, select_cost_res_auto_flag
1105 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE,select_rev_res_auto_flag
1106 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, select_all_res_auto_flag
1107 ,NULL) select_res_auto_flag
1108 ,decode(p_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, cost_res_planning_level
1109 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE,revenue_res_planning_level
1110 ,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, all_res_planning_level
1111 ,NULL) res_planning_level
1112 INTO l_select_res_auto_flag
1113 ,l_res_planning_level
1114 FROM pa_proj_fp_options
1115 WHERE proj_fp_options_id = p_proj_fp_options_id;
1116
1117 ELSE
1118
1119 /* The parameters are passed incase the changes arenot
1120 commited to the database yet. */
1121
1122 l_select_res_auto_flag := p_select_res_auto_flag;
1123 l_res_planning_level := p_res_planning_level ;
1124 END IF;
1125
1126 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': getting project id plan type id and plan version id from option.';
1127 IF P_PA_DEBUG_MODE = 'Y' THEN
1128 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1129 END IF;
1130
1131 SELECT project_id, fin_plan_type_id, fin_plan_version_id
1132 INTO l_project_id, l_fin_plan_type_id, l_fin_plan_version_id
1133 FROM pa_proj_fp_options
1134 WHERE proj_fp_options_id = p_proj_fp_options_id;
1135
1136 /* Get the value of the Resource Planning Level. The value is NULL if the resource_list_id of the
1137 element_type is Uncategorised, else it is "RESOURCE". */
1138 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': getting resource planning level from resource list.';
1139 IF P_PA_DEBUG_MODE = 'Y' THEN
1140 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1141 END IF;
1142
1143 /* SELECT decode(uncategorized_flag,'Y',NULL,PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R)
1144 INTO l_res_planning_level
1145 FROM pa_resource_lists_all_bg R1, pa_implementations_all I
1146 WHERE R1.resource_list_id = l_resource_list_id
1147 AND R1.business_group_id = I.business_group_id;
1148 */
1149
1150 /* Fix for 2586647. Commented the above select. Replaced with the following call. */
1151
1152 PA_FIN_PLAN_UTILS.GET_RESOURCE_LIST_INFO(
1153 P_RESOURCE_LIST_ID => l_resource_list_id,
1154 X_RES_LIST_IS_UNCATEGORIZED => l_res_list_is_uncategorized,
1155 X_IS_RESOURCE_LIST_GROUPED => l_is_resource_list_grouped,
1156 X_GROUP_RESOURCE_TYPE_ID => l_group_resource_type_id,
1157 X_RETURN_STATUS => x_return_status,
1158 X_MSG_COUNT => x_msg_count,
1159 X_MSG_DATA => x_msg_data
1160 );
1161
1162 /*
1163 If auto res selection is chosen, resource planning level for the task should be
1164 res_planning_level chosen on the plan_settings page.
1165 */
1166
1167 IF (l_select_res_auto_flag <> 'Y')
1168 THEN /* Bug 2920954 */
1169 IF l_res_list_is_uncategorized = 'N' THEN
1170 l_res_planning_level := PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R;
1171 ELSE
1172 l_res_planning_level := NULL;
1173 END IF;
1174 END IF; /* Bug 2920954 */
1175
1176 /* fix for 2586647 */
1177
1178
1179 l_stage := 400;
1180
1181
1182 /* The values that are inserted into the table PA_FP_ELEMENTS depending on the the planning level.
1183 The values of the columns task_id, top_task_id, top_task_planning_level, plannable_flag to be
1184 inserted into the table would depend on the Planning Level. */
1185
1186 --<Patchset M: B and F impact changes : AMG:>-- Bug # 3507156
1187 -- References to PA_FP_ELEMENTS table have been commented as records are no longer inserted in it
1188 --Comment START.
1189
1190 /*
1191 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Bulk Inserting records into PA_FP_Elements';
1192 IF P_PA_DEBUG_MODE = 'Y' THEN
1193 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,3);
1194 END IF;
1195 IF l_planning_level IN (PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_LOWEST,PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_M)
1196 THEN --Planning Level is Top and Lowest Task (OR) Lowest Task
1197 l_stage := 500;
1198 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Fetching records for Top and Lowest Tasks.';
1199 IF P_PA_DEBUG_MODE = 'Y' THEN
1200 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1201 END IF;
1202
1203 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': opening top and lowest task cur';
1204 IF P_PA_DEBUG_MODE = 'Y' THEN
1205 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,3);
1206 END IF;
1207
1208 OPEN top_low_tasks_cur(l_project_id);
1209 LOOP
1210 FETCH top_low_tasks_cur BULK COLLECT INTO
1211 l_task_id_tbl
1212 ,l_top_task_id_tbl
1213 ,l_top_plan_level_tbl
1214 ,l_plannable_flag_tbl
1215 LIMIT l_plsql_max_array_size;
1216
1217 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': fetched ' || sql%rowcount || ' records';
1218 IF P_PA_DEBUG_MODE = 'Y' THEN
1219 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,3);
1220 END IF;
1221
1222 IF nvl(l_task_id_tbl.last,0) >= 1 THEN -- only if something is fetched
1223
1224 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Inserting records for Top and Lowest Tasks.';
1225 IF P_PA_DEBUG_MODE = 'Y' THEN
1226 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,3);
1227 END IF;
1228
1229 FORALL i in l_task_id_tbl.first..l_task_id_tbl.last
1230 -- Bulk Insert records into PA_FP_ELEMENTS table for the details fetched
1231 -- from the above tables.
1232 INSERT INTO pa_fp_elements
1233 (PROJ_FP_ELEMENTS_ID
1234 ,PROJ_FP_OPTIONS_ID
1235 ,PROJECT_ID
1236 ,FIN_PLAN_TYPE_ID
1237 ,ELEMENT_TYPE
1238 ,FIN_PLAN_VERSION_ID
1239 ,TASK_ID
1240 ,TOP_TASK_ID
1241 ,RESOURCE_LIST_MEMBER_ID
1242 ,TOP_TASK_PLANNING_LEVEL
1243 ,RESOURCE_PLANNING_LEVEL
1244 ,PLANNABLE_FLAG
1245 ,RESOURCES_PLANNED_FOR_TASK
1246 ,PLAN_AMOUNT_EXISTS_FLAG
1247 ,TMP_PLANNABLE_FLAG
1248 ,TMP_TOP_TASK_PLANNING_LEVEL
1249 ,RECORD_VERSION_NUMBER
1250 ,LAST_UPDATE_DATE
1251 ,LAST_UPDATED_BY
1252 ,CREATION_DATE
1253 ,CREATED_BY
1254 ,LAST_UPDATE_LOGIN)
1255 VALUES
1256 (pa_fp_elements_s.nextval
1257 ,p_proj_fp_options_id
1258 ,l_project_id
1259 ,l_fin_plan_type_id
1260 ,p_element_type
1261 ,l_fin_plan_version_id
1262 ,l_task_id_tbl(i)
1263 ,l_top_task_id_tbl(i)
1264 ,l_resource_list_member_id
1265 ,l_top_plan_level_tbl(i)
1266 ,l_res_planning_level
1267 ,l_plannable_flag_tbl(i)
1268 ,l_res_planned_for_task
1269 ,l_plan_amt_exists_flag
1270 ,l_plannable_flag_tbl(i) -- Same as plannable_flag
1271 ,l_top_plan_level_tbl(i) -- Same as top_task_planning_level
1272 ,1
1273 ,sysdate
1274 ,fnd_global.user_id
1275 ,sysdate
1276 ,fnd_global.user_id
1277 ,fnd_global.login_id);
1278
1279 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': inserted ' || sql%rowcount || ' records';
1280 IF P_PA_DEBUG_MODE = 'Y' THEN
1281 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,3);
1282 END IF;
1283
1284
1285 END IF;
1286
1287 EXIT WHEN nvl(l_task_id_tbl.last,0) < l_plsql_max_array_size;
1288
1289 END LOOP;
1290 CLOSE top_low_tasks_cur;
1291
1292 ELSIF l_planning_level = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_TOP THEN -- Planning Level is Top Task
1293 l_stage := 600;
1294 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Fetching records for Top Tasks only.';
1295 IF P_PA_DEBUG_MODE = 'Y' THEN
1296 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,3);
1297 END IF;
1298
1299 OPEN top_tasks_cur(l_project_id);
1300 LOOP
1301 FETCH top_tasks_cur BULK COLLECT INTO
1302 l_task_id_tbl
1303 ,l_top_task_id_tbl
1304 ,l_top_plan_level_tbl
1305 ,l_plannable_flag_tbl
1306 LIMIT l_plsql_max_array_size;
1307
1308 IF nvl(l_task_id_tbl.last,0) >= 1 THEN -- only if something is fetched
1309 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Inserting records for Top Tasks only.';
1310 IF P_PA_DEBUG_MODE = 'Y' THEN
1311 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,3);
1312 END IF;
1313
1314 FORALL i in l_task_id_tbl.first..l_task_id_tbl.last
1315 -- Bulk Insert records into PA_FP_ELEMENTS table for the details fetched
1316 -- from the above tables.
1317 INSERT INTO pa_fp_elements
1318 (PROJ_FP_ELEMENTS_ID
1319 ,PROJ_FP_OPTIONS_ID
1320 ,PROJECT_ID
1321 ,FIN_PLAN_TYPE_ID
1322 ,ELEMENT_TYPE
1323 ,FIN_PLAN_VERSION_ID
1324 ,TASK_ID
1325 ,TOP_TASK_ID
1326 ,RESOURCE_LIST_MEMBER_ID
1327 ,TOP_TASK_PLANNING_LEVEL
1328 ,RESOURCE_PLANNING_LEVEL
1329 ,PLANNABLE_FLAG
1330 ,RESOURCES_PLANNED_FOR_TASK
1331 ,PLAN_AMOUNT_EXISTS_FLAG
1332 ,TMP_PLANNABLE_FLAG
1333 ,TMP_TOP_TASK_PLANNING_LEVEL
1334 ,RECORD_VERSION_NUMBER
1335 ,LAST_UPDATE_DATE
1336 ,LAST_UPDATED_BY
1337 ,CREATION_DATE
1338 ,CREATED_BY
1339 ,LAST_UPDATE_LOGIN)
1340 VALUES
1341 (pa_fp_elements_s.nextval
1342 ,p_proj_fp_options_id
1343 ,l_project_id
1344 ,l_fin_plan_type_id
1345 ,p_element_type
1346 ,l_fin_plan_version_id
1347 ,l_task_id_tbl(i)
1348 ,l_top_task_id_tbl(i)
1349 ,l_resource_list_member_id
1350 ,l_top_plan_level_tbl(i)
1351 ,l_res_planning_level
1352 ,l_plannable_flag_tbl(i)
1353 ,l_res_planned_for_task
1354 ,l_plan_amt_exists_flag
1355 ,l_plannable_flag_tbl(i) -- Same as plannable_flag
1356 ,l_top_plan_level_tbl(i) -- Same as top_task_planning_level
1357 ,1
1358 ,sysdate
1359 ,fnd_global.user_id
1360 ,sysdate
1361 ,fnd_global.user_id
1362 ,fnd_global.login_id);
1363
1364 END IF;
1365
1366 EXIT WHEN nvl(l_task_id_tbl.last,0) < l_plsql_max_array_size;
1367
1368 END LOOP;
1369 CLOSE top_tasks_cur;
1370
1371 ELSIF l_planning_level = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN -- Planning Level is Project
1372
1373 l_stage := 700;
1374
1375 -- No records will be inserted into pa_fp_elements if the Planning Level is 'Project'
1376
1377 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Nothing to be done for Planning Level at PROJECT';
1378 IF P_PA_DEBUG_MODE = 'Y' THEN
1379 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1380 END IF;
1381 NULL;
1382
1383 END IF; -- End of check for l_planning_level
1384
1385 */
1386 --<Patchset M: B and F impact changes : AMG:>-- Bug # 3507156
1387 --Comment END
1388
1389 /*
1390 Bug 2920954 If the automatic resource addition is chosen, resources need to be added for all the plannable tasks.
1391 Call add_resources_automatically api with entire option i/p as 'Y'
1392 */
1393
1394 IF l_select_res_auto_flag = 'Y'
1395 THEN
1396
1397 IF P_PA_DEBUG_MODE = 'Y' THEN
1398 pa_debug.g_err_stage := TO_CHAR(l_stage)||'Calling add_resources_automatically';
1399 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1400 END IF;
1401
1402 PA_FP_ELEMENTS_PUB.Add_resources_automatically
1403 ( p_proj_fp_options_id => p_proj_fp_options_id
1404 ,p_element_type => p_element_type
1405 ,p_fin_plan_level_code => l_planning_level
1406 ,p_resource_list_id => l_resource_list_id
1407 ,p_res_planning_level => l_res_planning_level
1408 ,p_entire_option => 'Y'
1409 ,p_element_task_id_tbl => l_dummy_task_id_tbl
1410 ,x_return_status => x_return_status
1411 ,x_msg_count => x_msg_count
1412 ,x_msg_data => x_msg_data
1413 );
1414 END IF;
1415
1416 pa_debug.g_err_stage := TO_CHAR(l_stage)||': End of Insert_Default';
1417 IF P_PA_DEBUG_MODE = 'Y' THEN
1418 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.g_err_stage,1);
1419 END IF;
1420 pa_debug.reset_err_stack;
1421
1422 EXCEPTION
1423 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
1424 l_msg_count := FND_MSG_PUB.count_msg;
1425 IF l_msg_count = 1 THEN
1426 PA_INTERFACE_UTILS_PUB.get_messages
1427 (p_encoded => FND_API.G_TRUE,
1428 p_msg_index => 1,
1429 p_msg_count => l_msg_count,
1430 p_msg_data => l_msg_data,
1431 p_data => l_data,
1432 p_msg_index_out => l_msg_index_out);
1433 x_msg_data := l_data;
1434 x_msg_count := l_msg_count;
1435 ELSE
1436 x_msg_count := l_msg_count;
1437 END IF;
1438 pa_debug.reset_err_stack;
1439 RAISE;
1440 WHEN OTHERS THEN
1441 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1442 x_msg_count := 1;
1443 x_msg_data := SQLERRM;
1444 FND_MSG_PUB.add_exc_msg
1445 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.Insert_Default'
1446 ,p_procedure_name => pa_debug.G_Err_Stack );
1447 IF P_PA_DEBUG_MODE = 'Y' THEN
1448 pa_debug.write('Insert_Default: ' || l_module_name,SQLERRM,4);
1449 pa_debug.write('Insert_Default: ' || l_module_name,pa_debug.G_Err_Stack,4);
1450 END IF;
1451 pa_debug.reset_err_stack;
1452
1453 raise FND_API.G_EXC_UNEXPECTED_ERROR;
1454 END Insert_Default;
1455
1456 /*==================================================================================================
1457 DELETE_ELEMENTS: This procedure is used to delete records from PA_FP_ELEMENTS table for a
1458 particular Proj FP Options ID depending on the Element Type and the Element Level.
1459 - If element_type is BOTH, delete both the cost and revenue planning elements.
1460 - If the element_level is 'TASK', then delete all the task elements and corresponding resources.
1461 - If the element_level is resource, delete on the resources for all the task elements
1462
1463 Bug 2976168. Delete from pa_fp_excluded_elements also
1464
1465 ==================================================================================================*/
1466 PROCEDURE Delete_Elements (
1467 p_proj_fp_options_id IN NUMBER
1468 ,p_element_type IN VARCHAR2 /* COST,REVENUE,ALL,BOTH */
1469 ,p_element_level IN VARCHAR2 /* TASK,RESOURCE */
1470 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
1471 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
1472 ,x_msg_data OUT NOCOPY VARCHAR2) is --File.Sql.39 bug 4440895
1473
1474 l_msg_count NUMBER := 0;
1475 l_data VARCHAR2(2000);
1476 l_msg_data VARCHAR2(2000);
1477 l_msg_index_out NUMBER;
1478 l_return_status VARCHAR2(2000);
1479 l_debug_mode VARCHAR2(30);
1480
1481 BEGIN
1482
1483 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.Delete_Elements');
1484 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
1485 l_debug_mode := NVL(l_debug_mode, 'Y');
1486 IF P_PA_DEBUG_MODE = 'Y' THEN
1487 pa_debug.set_process('Delete_Elements: ' || 'PLSQL','LOG',l_debug_mode);
1488 END IF;
1489
1490 x_return_status := FND_API.G_RET_STS_SUCCESS;
1491
1492 /* Delete the records from the table PA_FP_Elements based on the Element_Type and
1493 the Element_Level. If the Element_Type is 'BOTH' then both the COST and
1494 REVENUE Planning Elements have to be deleted. */
1495
1496 pa_debug.g_err_stage := 'Deleting Elements from PA_FP_Elements';
1497 IF P_PA_DEBUG_MODE = 'Y' THEN
1498 pa_debug.write('Delete_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
1499 END IF;
1500
1501 IF (p_element_level = PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK) THEN
1502
1503 /* If Element Level is 'TASK', then delete FP Elements with Level as 'TASK' */
1504
1505 pa_debug.g_err_stage := 'Deleting Elements for the Element Level as TASK';
1506 IF P_PA_DEBUG_MODE = 'Y' THEN
1507 pa_debug.write('Delete_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
1508 END IF;
1509
1510 DELETE FROM pa_fp_elements
1511 WHERE proj_fp_options_id = p_proj_fp_options_id
1512 AND element_type = decode(p_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,p_element_type)
1513 AND p_element_level = PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK ;
1514
1515 /* For bug 2976168. Delete from pa_fp_excluded_elements also */
1516
1517 DELETE FROM pa_fp_excluded_elements
1518 WHERE proj_fp_options_id = p_proj_fp_options_id
1519 AND element_type = decode(p_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,p_element_type)
1520 AND p_element_level = PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_TASK ;
1521
1522 ELSIF (p_element_level = PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_RESOURCE) THEN
1523
1524 /* If Element Level is 'RESOURCE', then delete FP Elements with Level as
1525 'RESOURCE' and where the resource_list_memeber_id is not 0 */
1526
1527 pa_debug.g_err_stage := 'Deleting Elements for the Element Level as RESOURCE';
1528 IF P_PA_DEBUG_MODE = 'Y' THEN
1529 pa_debug.write('Delete_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
1530 END IF;
1531
1532 DELETE FROM pa_fp_elements
1533 WHERE proj_fp_options_id = p_proj_fp_options_id
1534 AND element_type = decode(p_element_type,PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH,element_type,p_element_type)
1535 AND p_element_level = PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_RESOURCE
1536 AND resource_list_member_id <> 0;
1537 END IF;
1538
1539 pa_debug.g_err_stage := 'End of Delete_Elements';
1540 IF P_PA_DEBUG_MODE = 'Y' THEN
1541 pa_debug.write('Delete_Elements: ' || l_module_name,pa_debug.g_err_stage,1);
1542 END IF;
1543 pa_debug.reset_err_stack;
1544
1545 EXCEPTION
1546 WHEN OTHERS THEN
1547 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1548 x_msg_count := 1;
1549 x_msg_data := SQLERRM;
1550 FND_MSG_PUB.add_exc_msg
1551 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.Delete_Elements'
1552 ,p_procedure_name => pa_debug.G_Err_Stack );
1553 IF P_PA_DEBUG_MODE = 'Y' THEN
1554 pa_debug.write('Delete_Elements: ' || l_module_name,SQLERRM,4);
1555 pa_debug.write('Delete_Elements: ' || l_module_name,pa_debug.G_Err_Stack,4);
1556 END IF;
1557 pa_debug.reset_err_stack;
1558
1559 raise FND_API.G_EXC_UNEXPECTED_ERROR;
1560 END Delete_Elements;
1561
1562
1563 /*==================================================================================================
1564 DELETE_ELEMENT: This procedure is used to delete records from PA_FP_ELEMENTS table for a
1565 particular task_id and resource_list_member_id.
1566 If resource_list_member_id is populated then only resource level element will be deleted.
1567 Else if task_id is lowest task and its top task does not have any other tasks then the
1568 input task_id as well as its top task will be deleted.
1569 ==================================================================================================*/
1570 PROCEDURE Delete_Element (
1571 p_task_id IN NUMBER
1572 ,p_resource_list_member_id IN NUMBER
1573 ,p_budget_version_id IN NUMBER
1574 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
1575 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
1576 ,x_msg_data OUT NOCOPY VARCHAR2) is --File.Sql.39 bug 4440895
1577
1578 l_msg_count NUMBER := 0;
1579 l_data VARCHAR2(2000);
1580 l_msg_data VARCHAR2(2000);
1581 l_msg_index_out NUMBER;
1582 l_return_status VARCHAR2(2000);
1583 l_debug_mode VARCHAR2(30);
1584
1585 l_uncat_res_list_id pa_resource_lists.RESOURCE_LIST_ID%TYPE;
1586 l_uncat_res_list_mem_id pa_resource_list_members.RESOURCE_LIST_MEMBER_ID%TYPE;
1587 l_uncat_res_id pa_resource_list_members.RESOURCE_ID%TYPE;
1588 l_uncat_track_as_labor_flg pa_resource_assignments.TRACK_AS_LABOR_FLAG%TYPE;
1589 l_err_code NUMBER;
1590 l_err_stage VARCHAR2(100);
1591 l_err_stack VARCHAR2(1000);
1592
1593 l_resource_exists_flag VARCHAR2(1);
1594 l_proj_fp_options_id PA_PROJ_FP_OPTIONS.PROJ_FP_OPTIONS_ID%TYPE;
1595
1596 --Bug 2774779
1597 l_top_task_id pa_tasks.task_id%TYPE;
1598 l_row_update_count NUMBER;
1599
1600 BEGIN
1601
1602 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.Delete_Element');
1603 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
1604 l_debug_mode := NVL(l_debug_mode, 'Y');
1605 IF P_PA_DEBUG_MODE = 'Y' THEN
1606 pa_debug.set_process('Delete_Element: ' || 'PLSQL','LOG',l_debug_mode);
1607 END IF;
1608
1609 x_return_status := FND_API.G_RET_STS_SUCCESS;
1610
1611 pa_debug.g_err_stage := 'calling pa_get_resource.get_uncateg_resource_info';
1612 IF P_PA_DEBUG_MODE = 'Y' THEN
1613 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,1);
1614 END IF;
1615
1616 pa_get_resource.get_uncateg_resource_info(p_resource_list_id => l_uncat_res_list_id
1617 ,p_resource_list_member_id => l_uncat_res_list_mem_id
1618 ,p_resource_id => l_uncat_res_id
1619 ,p_track_as_labor_flag => l_uncat_track_as_labor_flg
1620 ,p_err_code => l_err_code
1621 ,p_err_stage => l_err_stage
1622 ,p_err_stack => l_err_stack);
1623
1624 SELECT proj_fp_options_id
1625 INTO l_proj_fp_options_id
1626 FROM pa_proj_fp_options pfo
1627 WHERE fin_plan_version_id = p_budget_version_id;
1628
1629 /* #2593264: The following condition was corrected from
1630 p_resource_list_member_id <> l_uncat_res_list_mem_id. */
1631
1632 IF (p_resource_list_member_id = l_uncat_res_list_mem_id) THEN
1633
1634 /* If its an uncategorized resource then task level record needs to be deleted.
1635 task level records in pa_fp_elements always have resource list member id as zero. */
1636
1637 pa_debug.g_err_stage := 'Deleting Elements for the task';
1638 IF P_PA_DEBUG_MODE = 'Y' THEN
1639 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,1);
1640 END IF;
1641
1642 DELETE FROM pa_fp_elements
1643 WHERE proj_fp_options_id = l_proj_fp_options_id
1644 AND task_id = p_task_id
1645 AND resource_list_member_id = 0
1646 RETURNING top_task_id into l_top_task_id; --Bug 2774779
1647
1648 --Bug 2774779 Maintain the plan amount exists flag for the top task record.
1649 --This update need not be issued if the planning level is top task(l_top_task_id = p_task_id)
1650 --as this record would have been deleted already.
1651
1652 IF l_top_task_id <> p_task_id THEN
1653
1654 update pa_fp_elements
1655 set plan_amount_exists_flag = 'N',
1656 record_version_number = record_version_number + 1,
1657 last_update_date = sysdate,
1658 last_updated_by = FND_GLOBAL.USER_ID,
1659 last_update_login = FND_GLOBAL.LOGIN_ID
1660 where proj_fp_options_id = l_proj_fp_options_id
1661 and task_id = l_top_task_id
1662 and not exists
1663 (
1664 select 1
1665 from pa_fp_elements
1666 where top_task_id = l_top_task_id
1667 and task_id <> l_top_task_id
1668 and proj_fp_options_id = l_proj_fp_options_id
1669 and nvl(plan_amount_exists_flag,'N') = 'Y'
1670 );
1671
1672 IF P_PA_DEBUG_MODE = 'Y' THEN
1673 pa_debug.g_err_stage := 'Number of rows updated for plan amount exists flag : '||sql%rowcount;
1674 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,3);
1675 END IF;
1676 END IF;
1677
1678 ELSE
1679
1680 /* If its a normal resource from a resource list then we need to delete the resource
1681 level element from fp elements. */
1682
1683 pa_debug.g_err_stage := 'Deleting Elements for the RESOURCE';
1684 IF P_PA_DEBUG_MODE = 'Y' THEN
1685 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,1);
1686 END IF;
1687
1688 DELETE FROM pa_fp_elements
1689 WHERE proj_fp_options_id = l_proj_fp_options_id -- included for Bug 3062798
1690 AND fin_plan_version_id = p_budget_version_id
1691 AND task_id = p_task_id
1692 AND resource_list_member_id = p_resource_list_member_id
1693 RETURNING top_task_id into l_top_task_id; --Bug 2774779
1694
1695 -- Bug 2774779
1696 -- Maintain the plan amount exists flag for the top task and lowest task elements.
1697 -- The following update also takes care of the situation where resource are planned for the
1698 -- Top Task and not the lowest task.
1699
1700 update pa_fp_elements
1701 set plan_amount_exists_flag = 'N',
1702 record_version_number = record_version_number + 1,
1703 last_update_date = sysdate,
1704 last_updated_by = FND_GLOBAL.USER_ID,
1705 last_update_login = FND_GLOBAL.LOGIN_ID
1706 where proj_fp_options_id = l_proj_fp_options_id
1707 and resource_list_member_id = 0
1708 and task_id = p_task_id
1709 and not exists
1710 (
1711 select 1
1712 from pa_fp_elements
1713 where task_id = p_task_id
1714 and proj_fp_options_id = l_proj_fp_options_id
1715 and resource_list_member_id <> 0
1716 and nvl(plan_amount_exists_flag,'N') = 'Y'
1717 );
1718
1719 l_row_update_count := sql%rowcount;
1720 IF P_PA_DEBUG_MODE = 'Y' THEN
1721 pa_debug.g_err_stage := 'Number of rows updated for plan amount exists flag : '|| l_row_update_count;
1722 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,3);
1723 END IF;
1724
1725
1726 IF p_task_id <> l_top_task_id and l_row_update_count > 0 then
1727
1728 update pa_fp_elements
1729 set plan_amount_exists_flag = 'N',
1730 record_version_number = record_version_number + 1,
1731 last_update_date = sysdate,
1732 last_updated_by = FND_GLOBAL.USER_ID,
1733 last_update_login = FND_GLOBAL.LOGIN_ID
1734 where proj_fp_options_id = l_proj_fp_options_id
1735 and resource_list_member_id = 0
1736 and task_id = l_top_task_id
1737 and not exists
1738 (
1739 select 1
1740 from pa_fp_elements
1741 where top_task_id = l_top_task_id
1742 and proj_fp_options_id = l_proj_fp_options_id
1743 and resource_list_member_id <> 0
1744 and nvl(plan_amount_exists_flag,'N') = 'Y'
1745 );
1746
1747 IF P_PA_DEBUG_MODE = 'Y' THEN
1748 pa_debug.g_err_stage := 'Number of rows updated for plan amount exists flag : '||sql%rowcount;
1749 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,3);
1750 END IF;
1751
1752 END IF;
1753
1754
1755 /* now need to set the resources_planned_for_task flag. In case the task has no more resources
1756 defined under it then set this to 'N'
1757 */
1758
1759 pa_debug.g_err_stage := 'Checking for more resources under the task';
1760 IF P_PA_DEBUG_MODE = 'Y' THEN
1761 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,1);
1762 END IF;
1763
1764 l_resource_exists_flag := 'N';
1765 BEGIN
1766 SELECT 'Y'
1767 INTO l_resource_exists_flag
1768 FROM dual
1769 WHERE exists (select 1
1770 from pa_fp_elements fp
1771 where proj_fp_options_id = l_proj_fp_options_id
1772 and fp.task_id = p_task_id
1773 and fp.resource_list_member_id <> 0);
1774 EXCEPTION
1775 WHEN NO_DATA_FOUND THEN
1776 l_resource_exists_flag := 'N';
1777 END;
1778
1779 IF l_resource_exists_flag = 'N' THEN
1780
1781 pa_debug.g_err_stage := 'setting resource planning level to N';
1782 IF P_PA_DEBUG_MODE = 'Y' THEN
1783 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,1);
1784 END IF;
1785
1786 UPDATE pa_fp_elements
1787 SET resources_planned_for_task = 'N',
1788 record_version_number = record_version_number + 1,
1789 last_update_date = sysdate,
1790 last_updated_by = FND_GLOBAL.USER_ID,
1791 last_update_login = FND_GLOBAL.LOGIN_ID
1792 WHERE proj_fp_options_id = l_proj_fp_options_id
1793 AND task_id = p_task_id
1794 AND resource_list_member_id = 0;
1795 END IF;
1796
1797 END IF;
1798
1799 pa_debug.g_err_stage := 'End of Delete_Elements';
1800 IF P_PA_DEBUG_MODE = 'Y' THEN
1801 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.g_err_stage,1);
1802 END IF;
1803 pa_debug.reset_err_stack;
1804
1805 EXCEPTION
1806 WHEN OTHERS THEN
1807 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1808 x_msg_count := 1;
1809 x_msg_data := SQLERRM;
1810 FND_MSG_PUB.add_exc_msg
1811 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.Delete_Element'
1812 ,p_procedure_name => pa_debug.G_Err_Stack );
1813 IF P_PA_DEBUG_MODE = 'Y' THEN
1814 pa_debug.write('Delete_Element: ' || l_module_name,SQLERRM,4);
1815 pa_debug.write('Delete_Element: ' || l_module_name,pa_debug.G_Err_Stack,4);
1816 END IF;
1817 pa_debug.reset_err_stack;
1818
1819 raise FND_API.G_EXC_UNEXPECTED_ERROR;
1820
1821 END Delete_Element;
1822
1823
1824 /*==================================================================================================
1825 This procedure inserts records into PA_FP_ELEMENTS in BULK
1826 ==================================================================================================*/
1827
1828
1829 PROCEDURE Insert_Bulk_Rows (
1830 p_proj_fp_options_id IN NUMBER
1831 ,p_project_id IN NUMBER
1832 ,p_fin_plan_type_id IN NUMBER
1833 ,p_element_type IN VARCHAR2
1834 ,p_plan_version_id IN NUMBER
1835 ,p_task_id_tbl IN l_task_id_tbl_typ
1836 ,p_top_task_id_tbl IN l_top_task_id_tbl_typ
1837 ,p_res_list_mem_id_tbl IN l_res_list_mem_id_tbl_typ
1838 ,p_task_planning_level_tbl IN l_task_planning_level_tbl_typ
1839 ,p_res_planning_level_tbl IN l_res_planning_level_tbl_typ
1840 ,p_plannable_flag_tbl IN l_plannable_flag_tbl_typ
1841 ,p_res_planned_for_task_tbl IN l_res_planned_for_task_tbl_typ
1842 ,p_planamount_exists_tbl IN l_planamount_exists_tbl_typ
1843 ,p_res_uncategorized_flag IN VARCHAR2
1844 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
1845 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
1846 ,x_msg_data OUT NOCOPY VARCHAR2 ) is --File.Sql.39 bug 4440895
1847
1848 l_stage NUMBER :=100;
1849 l_debug_mode VARCHAR2(10);
1850
1851 BEGIN
1852
1853 -- Set the error stack.
1854 pa_debug.set_err_stack('PA_FP_ELELEMNTS_PUB.Insert_Bulk_Rows');
1855
1856 -- Get the Debug mode into local variable and set it to 'Y' if its NULL
1857 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
1858 l_debug_mode := NVL(l_debug_mode, 'Y');
1859
1860 -- Initialize the return status to success
1861 x_return_status := FND_API.G_RET_STS_SUCCESS;
1862
1863 IF P_PA_DEBUG_MODE = 'Y' THEN
1864 pa_debug.set_process('Insert_Bulk_Rows: ' || 'PLSQL','LOG',l_debug_mode);
1865 END IF;
1866
1867 pa_debug.g_err_stage := TO_CHAR(l_stage)||':In PA_FP_ELELEMNTS_PUB.Insert_Bulk_Rows ';
1868 IF P_PA_DEBUG_MODE = 'Y' THEN
1869 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.g_err_stage,2);
1870 END IF;
1871
1872 /*
1873 * Bulk Insert records into PA_FP_ELEMENTS table for the records fetched
1874 * from cursor top_task_cur.
1875 */
1876 pa_debug.g_err_stage := TO_CHAR(l_stage)||': In Insert_Bulk_Rows';
1877 IF P_PA_DEBUG_MODE = 'Y' THEN
1878 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.g_err_stage,2);
1879 END IF;
1880
1881 pa_debug.g_err_stage := TO_CHAR(l_stage)||': Bulk inserting into PA_FP_ELEMENTS';
1882 IF P_PA_DEBUG_MODE = 'Y' THEN
1883 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.g_err_stage,2);
1884 END IF;
1885
1886 FORALL i in p_top_task_id_tbl.first..p_top_task_id_tbl.last
1887
1888 INSERT INTO pa_fp_elements
1889 (PROJ_FP_ELEMENTS_ID
1890 ,PROJ_FP_OPTIONS_ID
1891 ,PROJECT_ID
1892 ,FIN_PLAN_TYPE_ID
1893 ,ELEMENT_TYPE
1894 ,FIN_PLAN_VERSION_ID
1895 ,TASK_ID
1896 ,TOP_TASK_ID
1897 ,RESOURCE_LIST_MEMBER_ID
1898 ,TOP_TASK_PLANNING_LEVEL
1899 ,RESOURCE_PLANNING_LEVEL
1900 ,PLANNABLE_FLAG
1901 ,RESOURCES_PLANNED_FOR_TASK
1902 ,PLAN_AMOUNT_EXISTS_FLAG
1903 ,TMP_PLANNABLE_FLAG
1904 ,TMP_TOP_TASK_PLANNING_LEVEL
1905 ,RECORD_VERSION_NUMBER
1906 ,LAST_UPDATE_DATE
1907 ,LAST_UPDATED_BY
1908 ,CREATION_DATE
1909 ,CREATED_BY
1910 ,LAST_UPDATE_LOGIN)
1911 VALUES
1912 (pa_fp_elements_s.nextval
1913 ,p_proj_fp_options_id
1914 ,p_project_id
1915 ,p_fin_plan_type_id
1916 ,p_element_type
1917 ,p_plan_version_id
1918 ,p_task_id_tbl(i)
1919 ,p_top_task_id_tbl(i)
1920 ,decode(p_res_uncategorized_flag,'Y',0,p_res_list_mem_id_tbl(i))
1921 ,p_task_planning_level_tbl(i)
1922 ,p_res_planning_level_tbl(i)
1923 ,p_plannable_flag_tbl(i)
1924 ,p_res_planned_for_task_tbl(i)
1925 ,p_planamount_exists_tbl(i)
1926 ,p_plannable_flag_tbl(i)
1927 ,p_task_planning_level_tbl(i)
1928 ,1
1929 ,sysdate
1930 ,fnd_global.user_id
1931 ,sysdate
1932 ,fnd_global.user_id
1933 ,fnd_global.login_id);
1934
1935 pa_debug.reset_err_stack;
1936 EXCEPTION
1937 WHEN OTHERS THEN
1938 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1939 x_msg_count := 1;
1940 x_msg_data := SQLERRM;
1941 FND_MSG_PUB.add_exc_msg
1942 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.Insert_Bulk_Rows'
1943 ,p_procedure_name => pa_debug.G_Err_Stack );
1944 IF P_PA_DEBUG_MODE = 'Y' THEN
1945 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,SQLERRM,4);
1946 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.G_Err_Stack,4);
1947 END IF;
1948 pa_debug.reset_err_stack;
1949
1950 raise FND_API.G_EXC_UNEXPECTED_ERROR;
1951
1952 END Insert_Bulk_Rows;
1953
1954 /*==================================================================================================
1955 This procedure inserts records into PA_RESOURCE_ASSIGNMENTS in BULK
1956 ==================================================================================================*/
1957
1958 PROCEDURE Insert_Bulk_Rows_Res (
1959 p_project_id IN NUMBER
1960 ,p_plan_version_id IN NUMBER
1961 ,p_task_id_tbl IN l_task_id_tbl_typ
1962 ,p_res_list_mem_id_tbl IN l_res_list_mem_id_tbl_typ
1963 ,p_unit_of_measure_tbl IN l_unit_of_measure_tbl_typ
1964 ,p_track_as_labor_flag_tbl IN l_track_as_labor_flag_tbl_typ
1965 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
1966 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
1967 ,x_msg_data OUT NOCOPY VARCHAR2 ) is --File.Sql.39 bug 4440895
1968
1969 l_stage NUMBER :=100;
1970 l_debug_mode VARCHAR2(10);
1971
1972 BEGIN
1973
1974 -- Set the error stack.
1975 pa_debug.set_err_stack('PA_FP_ELELEMNTS_PUB.Insert_Bulk_Rows_Res');
1976
1977 -- Get the Debug mode into local variable and set it to 'Y' if its NULL
1978 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
1979 l_debug_mode := NVL(l_debug_mode, 'Y');
1980
1981 -- Initialize the return status to success
1982 x_return_status := FND_API.G_RET_STS_SUCCESS;
1983
1984 IF P_PA_DEBUG_MODE = 'Y' THEN
1985 pa_debug.set_process('Insert_Bulk_Rows: ' || 'PLSQL','LOG',l_debug_mode);
1986 END IF;
1987
1988 pa_debug.g_err_stage := TO_CHAR(l_stage)||':In PA_FP_ELELEMNTS_PUB.Insert_Bulk_Rows_Res ';
1989 IF P_PA_DEBUG_MODE = 'Y' THEN
1990 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.g_err_stage,2);
1991 END IF;
1992
1993
1994 /*
1995 * Bulk Insert records into PA_FP_ELEMENTS table for the records fetched
1996 * from cursor top_task_cur.
1997 */
1998 pa_debug.g_err_stage := TO_CHAR(l_stage)||': In Insert_Bulk_Rows_Res';
1999 IF P_PA_DEBUG_MODE = 'Y' THEN
2000 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.g_err_stage,2);
2001 END IF;
2002
2003 pa_debug.g_err_stage := TO_CHAR(l_stage)||': Bulk inserting into PA_RESOURCE_ASSIGNMENTS';
2004 IF P_PA_DEBUG_MODE = 'Y' THEN
2005 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.g_err_stage,2);
2006 END IF;
2007
2008 FORALL i in p_task_id_tbl.first..p_task_id_tbl.last
2009
2010 INSERT INTO pa_resource_assignments
2011 (RESOURCE_ASSIGNMENT_ID
2012 ,BUDGET_VERSION_ID
2013 ,PROJECT_ID
2014 ,TASK_ID
2015 ,RESOURCE_LIST_MEMBER_ID
2016 ,LAST_UPDATE_DATE
2017 ,LAST_UPDATED_BY
2018 ,CREATION_DATE
2019 ,CREATED_BY
2020 ,LAST_UPDATE_LOGIN
2021 ,UNIT_OF_MEASURE
2022 ,TRACK_AS_LABOR_FLAG
2023 ,PROJECT_ASSIGNMENT_ID
2024 ,RESOURCE_ASSIGNMENT_TYPE )
2025 VALUES
2026 (PA_RESOURCE_ASSIGNMENTS_S.NEXTVAL
2027 ,p_plan_version_id -- BUDGET_VERSION_ID
2028 ,p_project_id -- PROJECT_ID
2029 ,p_task_id_tbl(i) -- TASK_ID
2030 ,p_res_list_mem_id_tbl(i) -- RESOURCE_LIST_MEMBER_ID
2031 ,sysdate -- LAST_UPDATE_DATE
2032 ,fnd_global.user_id -- LAST_UPDATED_BY
2033 ,sysdate -- CREATION_DATE
2034 ,fnd_global.user_id -- CREATED_BY
2035 ,fnd_global.login_id -- LAST_UPDATE_LOGIN
2036 ,p_unit_of_measure_tbl(i) -- UNIT_OF_MEASURE
2037 ,p_track_as_labor_flag_tbl(i) -- TRACK_AS_LABOR_FLAG
2038 ,-1 -- PROJECT_ASSIGNMENT_ID
2039 ,PA_FP_CONSTANTS_PKG.G_USER_ENTERED) ; -- RESOURCE_ASSIGNMENT_TYPE
2040
2041 pa_debug.reset_err_stack;
2042
2043 EXCEPTION
2044 WHEN OTHERS THEN
2045 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2046 x_msg_count := 1;
2047 x_msg_data := SQLERRM;
2048 FND_MSG_PUB.add_exc_msg
2049 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.Insert_Bulk_Rows_Res'
2050 ,p_procedure_name => pa_debug.G_Err_Stack );
2051 IF P_PA_DEBUG_MODE = 'Y' THEN
2052 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,SQLERRM,4);
2053 pa_debug.write('Insert_Bulk_Rows: ' || l_module_name,pa_debug.G_Err_Stack,4);
2054 END IF;
2055 pa_debug.reset_err_stack;
2056
2057 raise FND_API.G_EXC_UNEXPECTED_ERROR;
2058
2059 END Insert_Bulk_Rows_Res;
2060
2061
2062 /*============================================================================
2063 This api makes use of PA_FP_ELEMENTS and enters only user_entered records
2064 if they aren't already present in PA_RESOURCE_ASSIGNMENTS. Uncategorised
2065 resource_list has been dealt separately, as in this case, we can avoid a
2066 table join with pa_resource_list_members.It also deals the case when
2067 planning level is project and resource_list is uncategorised, in which
2068 case the given version doesn't have a record in PA_FP_ELEMENTS.
2069
2070 Bug 2920954 - To create ras for a particular task and control deletion
2071 of resource assignments, p_task_id and p_res_del_req_flag parameters have
2072 been introduced.
2073 ============================================================================*/
2074
2075 PROCEDURE create_enterable_resources
2076 ( p_plan_version_id IN NUMBER
2077 ,p_task_id IN pa_tasks.task_id%TYPE /* Bug 2920954 */
2078 ,p_res_del_req_flag IN VARCHAR2 /* Bug 2920954 */
2079 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
2080 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
2081 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
2082 AS
2083
2084 l_msg_count NUMBER := 0;
2085 l_data VARCHAR2(2000);
2086 l_msg_data VARCHAR2(2000);
2087 l_error_msg_code VARCHAR2(30);
2088 l_msg_index_out NUMBER;
2089 l_return_status VARCHAR2(2000);
2090 l_debug_mode VARCHAR2(30);
2091
2092 l_max_fetch_size NUMBER := 200; -- limiting the max fetch size
2093
2094 l_resource_list_id PA_BUDGET_VERSIONS.RESOURCE_LIST_ID%TYPE;
2095 l_project_id PA_BUDGET_VERSIONS.PROJECT_ID%TYPE;
2096 l_uncat_flag PA_RESOURCE_LISTS.UNCATEGORIzED_FLAG%TYPE;
2097 l_fp_pref_code PA_PROJ_FP_OPTIONS.FIN_PLAN_PREFERENCE_CODE%TYPE;
2098 l_fp_level_code PA_PROJ_FP_OPTIONS.COST_FIN_PLAN_LEVEL_CODE%TYPE;
2099 l_proj_fp_options_id PA_PROJ_FP_OPTIONS.PROJ_FP_OPTIONS_ID%TYPE;
2100 l_uncat_rlmid PA_RESOURCE_ASSIGNMENTS.RESOURCE_LIST_MEMBER_ID%TYPE;
2101 l_track_as_labor_flag PA_RESOURCE_LIST_MEMBERS.TRACK_AS_LABOR_FLAG%TYPE;
2102 l_unit_of_measure PA_RESOURCE_ASSIGNMENTS.UNIT_OF_MEASURE%TYPE;
2103
2104 TYPE l_ra_id_tbl_typ IS TABLE OF
2105 PA_RESOURCE_ASSIGNMENTS.RESOURCE_ASSIGNMENT_ID%TYPE INDEX BY BINARY_INTEGER;
2106
2107 l_task_id_tbl l_task_id_tbl_typ;
2108 l_rlmid_tbl l_res_list_mem_id_tbl_typ;
2109 l_track_as_labor_flag_tbl l_track_as_labor_flag_tbl_typ;
2110 l_uom_tbl l_unit_of_measure_tbl_typ;
2111 l_ra_id_tbl l_ra_id_tbl_typ;
2112
2113 CURSOR l_cur_for_uncat_project_level IS
2114 SELECT 0 --task_id
2115 ,l_uncat_rlmid --resource_list_member_id
2116 ,l_track_as_labor_flag
2117 ,l_unit_of_measure /* Modified for bug #2586307. */
2118 FROM DUAL
2119 WHERE NOT EXISTS ( SELECT 'x'
2120 FROM pa_resource_assignments ra
2121 WHERE ra.budget_version_id = p_plan_version_id
2122 AND ra.task_id = 0
2123 AND ra.resource_list_member_id =
2124 l_uncat_rlmid);
2125
2126 CURSOR l_cur_for_uncat_task_level IS
2127 SELECT fp.task_id --task_id
2128 ,l_uncat_rlmid --resource_list_member_id
2129 ,l_track_as_labor_flag
2130 ,l_unit_of_measure /* Modified for bug #2586307. */
2131 FROM pa_fp_elements fp
2132 WHERE proj_fp_options_id = l_proj_fp_options_id /* included for bug 3062798*/
2133 AND fin_plan_version_id = p_plan_version_id
2134 AND plannable_flag = 'Y'
2135 AND fp.task_id = Nvl(p_task_id,fp.task_id) /* Bug 2920954 */
2136 AND NOT EXISTS ( SELECT 'x'
2137 FROM pa_resource_assignments ra
2138 WHERE ra.budget_version_id = fp.fin_plan_version_id
2139 AND ra.project_id = fp.project_id
2140 AND ra.task_id = fp.task_id
2141 AND ra.resource_list_member_id = l_uncat_rlmid);
2142
2143 CURSOR l_cur_for_cat_res_list IS
2144 SELECT fp.task_id
2145 ,fp.resource_list_member_id
2146 ,prlm.track_as_labor_flag
2147 ,decode(prlm.track_as_labor_flag,'Y',PA_FP_CONSTANTS_PKG.G_UNIT_OF_MEASURE_HOURS,
2148 'N',decode(pr.unit_of_measure,PA_FP_CONSTANTS_PKG.G_UNIT_OF_MEASURE_HOURS,NULL,pr.unit_of_measure)
2149 ) unit_of_measure /* Modified for bug #2586307 */
2150 FROM pa_fp_elements fp, pa_resource_list_members prlm, pa_resources pr
2151 WHERE proj_fp_options_id = l_proj_fp_options_id /* included for bug 3062798*/
2152 AND fin_plan_version_id = p_plan_version_id
2153 AND fp.resource_list_member_id <> 0 -- select only resource level records
2154 AND fp.plannable_flag = 'Y' --resource is plannable
2155 AND fp.resource_list_member_id = prlm.resource_list_member_id
2156 AND pr.resource_id = prlm.resource_id
2157 AND fp.task_id = Nvl(p_task_id,fp.task_id) /* Bug 2920954 */
2158 AND NOT EXISTS ( SELECT 'x'
2159 FROM pa_resource_assignments ra
2160 WHERE ra.budget_version_id = fp.fin_plan_version_id
2161 AND ra.project_id = fp.project_id
2162 AND ra.task_id = fp.task_id
2163 AND ra.resource_list_member_id =
2164 fp.resource_list_member_id);
2165
2166 /* Added for the bug #2615837 */
2167 CURSOR l_cur_for_res_del IS
2168 SELECT pra.resource_assignment_id
2169 FROM pa_resource_assignments pra
2170 WHERE pra.budget_version_id = p_plan_version_id
2171 AND resource_assignment_type = PA_FP_CONSTANTS_PKG.G_USER_ENTERED
2172 AND NOT EXISTS (SELECT 1
2173 FROM pa_fp_elements fpe
2174 WHERE proj_fp_options_id = l_proj_fp_options_id /* included for bug 3062798*/
2175 AND fpe.fin_plan_version_id = p_plan_version_id
2176 AND fpe.task_id = pra.task_id
2177 AND fpe.resource_list_member_id = decode(pra.resource_list_member_id,l_uncat_rlmid,
2178 0,pra.resource_list_member_id)
2179 );
2180 BEGIN
2181
2182 x_msg_count := 0;
2183 x_return_status := FND_API.G_RET_STS_SUCCESS;
2184 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.Create_Enterable_Resources');
2185 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
2186 l_debug_mode := NVL(l_debug_mode, 'Y');
2187 IF P_PA_DEBUG_MODE = 'Y' THEN
2188 pa_debug.set_process('create_enterable_resources: ' || 'PLSQL','LOG',l_debug_mode);
2189 END IF;
2190
2191
2192 -- Check for business rules violations
2193
2194 pa_debug.g_err_stage:= 'validating input parameters';
2195 IF P_PA_DEBUG_MODE = 'Y' THEN
2196 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2197 END IF;
2198
2199 --Check if plan version id is null
2200
2201 IF p_plan_version_id is NULL THEN
2202
2203 pa_debug.g_err_stage:= 'plan version id is null';
2204 IF P_PA_DEBUG_MODE = 'Y' THEN
2205 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,5);
2206 END IF;
2207
2208 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
2209 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
2210
2211 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
2212
2213 END IF;
2214
2215 pa_debug.g_err_stage:='fetching resource_list_id, project_id';
2216 IF P_PA_DEBUG_MODE = 'Y' THEN
2217 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2218 END IF;
2219
2220 SELECT resource_list_id
2221 ,project_id
2222 INTO l_resource_list_id
2223 ,l_project_id
2224 FROM pa_budget_versions
2225 WHERE budget_version_id = p_plan_version_id;
2226
2227 -- 3062798 fetch options_id and use in the cursors to
2228 -- avoid full table scan on pa_fp_elements
2229
2230 SELECT proj_fp_options_id
2231 INTO l_proj_fp_options_id
2232 FROM pa_proj_fp_options
2233 WHERE fin_plan_version_id = p_plan_version_id;
2234
2235 pa_debug.g_err_stage:='checking if resource list is uncategorised';
2236 IF P_PA_DEBUG_MODE = 'Y' THEN
2237 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2238 END IF;
2239
2240 SELECT NVL(uncategorized_flag,'N')
2241 INTO l_uncat_flag
2242 FROM pa_resource_lists
2243 WHERE resource_list_id = l_resource_list_id;
2244
2245
2246 /* Checking uncategorised flag to avoid a join with
2247 * pa_resource_list_members table if it is 'Y'
2248 */
2249
2250 IF l_uncat_flag = 'Y' THEN
2251
2252 -- Fetch resource_list_member_id and track_as_labor_flag and unit of measure
2253
2254 pa_debug.g_err_stage:='resource_list is uncategorised ';
2255 IF P_PA_DEBUG_MODE = 'Y' THEN
2256 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2257 END IF;
2258
2259 pa_debug.g_err_stage:=' fetching resource_list_member_id,track_as_labor_flag';
2260 IF P_PA_DEBUG_MODE = 'Y' THEN
2261 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2262 END IF;
2263
2264 DECLARE
2265 l_dummy_res_list_id PA_RESOURCE_LISTS_ALL_BG.resource_list_id%TYPE;
2266 BEGIN
2267
2268 PA_FIN_PLAN_UTILS.Get_Uncat_Resource_List_Info
2269 (x_resource_list_id => l_dummy_res_list_id
2270 ,x_resource_list_member_id => l_uncat_rlmid
2271 ,x_track_as_labor_flag => l_track_as_labor_flag
2272 ,x_unit_of_measure => l_unit_of_measure
2273 ,x_return_status => x_return_status
2274 ,x_msg_count => x_msg_count
2275 ,x_msg_data => x_msg_data);
2276
2277 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
2278 pa_debug.g_err_stage := 'Error while fetching uncat res list id info ...';
2279 IF P_PA_DEBUG_MODE = 'Y' THEN
2280 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,5);
2281 END IF;
2282 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
2283 END IF;
2284
2285 END;
2286
2287 END IF;
2288
2289
2290 pa_debug.g_err_stage:= 'parameter validation complete';
2291 IF P_PA_DEBUG_MODE = 'Y' THEN
2292 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2293 END IF;
2294
2295 --Fetching the finplan planning level
2296
2297 l_fp_level_code := pa_fin_plan_utils.get_fin_plan_level_code(
2298 p_fin_plan_version_id => p_plan_version_id);
2299
2300 /* #2615837: If the resources have been unchecked in the pages, then the elements are
2301 deleted from pa_fp_elements but not from resource_assignments. These records have
2302 to be deleted from pa_resource_assignments also else they will be once again
2303 available in the Edit Plan page. */
2304
2305 /* Should NOT be done when planning level is project and resource list is uncategorized
2306 as there needs to be one record existing in pa_resource_assignments for this case. */
2307
2308 /* Bug #2634979: Modified the logic of deleting records from pa_resource_assignments.
2309 If the Planning level is 'Project' and the resource list is uncategorized, then
2310 the records for the Plan Version ID have to be deleted except the project level
2311 records and the records with uncategorized resource list member id.
2312
2313 This will handle the case where the plannning level has been modified to 'Project',
2314 and the resource list has been changed to an uncategorized resource list.
2315 In this case the old records have to be deleted from resource assignments and new
2316 resource assignments need to be created after the new FP elements are define. */
2317
2318
2319 /* Bug 2920954 - Deletion of resource assignments would be done only if p_res_del_req_flag is Y */
2320
2321 IF p_res_del_req_flag = 'Y' THEN
2322
2323 IF (l_fp_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT AND
2324 l_uncat_flag = 'Y' ) THEN
2325
2326 pa_debug.g_err_stage:= 'Deleting resource assignments';
2327 IF P_PA_DEBUG_MODE = 'Y' THEN
2328 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2329 END IF;
2330
2331 DELETE FROM pa_resource_assignments
2332 WHERE budget_version_id = p_plan_version_id
2333 AND (task_id <> 0 or resource_list_member_id <> l_uncat_rlmid);
2334
2335 ELSE
2336
2337 /* In all other cases, records have to be deleted from pa_resource_assignments
2338 which do not exist in pa_fp_elements. */
2339
2340 pa_debug.g_err_stage:= 'fetching resource assignments that should be deleted';
2341 IF P_PA_DEBUG_MODE = 'Y' THEN
2342 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2343 END IF;
2344
2345 OPEN l_cur_for_res_del;
2346 pa_debug.g_err_stage:= 'Deleting records from Resource Assignments.';
2347 IF P_PA_DEBUG_MODE = 'Y' THEN
2348 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2349 END IF;
2350
2351 FETCH l_cur_for_res_del BULK COLLECT INTO
2352 l_ra_id_tbl;
2353
2354 pa_debug.g_err_stage := 'Fetched ' || sql%rowcount || ' records';
2355 IF P_PA_DEBUG_MODE = 'Y' THEN
2356 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2357 END IF;
2358
2359 IF (nvl(l_ra_id_tbl.last,0) > 0) THEN
2360
2361 FORALL i in l_ra_id_tbl.first..l_ra_id_tbl.last
2362
2363 DELETE FROM pa_resource_assignments
2364 WHERE resource_assignment_id = l_ra_id_tbl(i);
2365
2366 pa_debug.g_err_stage := 'Deleted ' || sql%rowcount || ' records';
2367 IF P_PA_DEBUG_MODE = 'Y' THEN
2368 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2369 END IF;
2370 END IF;
2371 CLOSE l_cur_for_res_del;
2372
2373 END IF;
2374
2375 END IF; /* Bug 2920954 - p_res_del_req_flag = 'Y' */
2376
2377 IF l_uncat_flag ='Y' THEN
2378
2379 IF l_fp_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
2380
2381 -- CASE:planning level 'project' and 'uncategorised resource_list'
2382
2383 pa_debug.g_err_stage:='project level planning and resource_list uncategorised';
2384 IF P_PA_DEBUG_MODE = 'Y' THEN
2385 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2386 END IF;
2387 pa_debug.g_err_stage:='opening l_cur_for_uncat_project_level';
2388 IF P_PA_DEBUG_MODE = 'Y' THEN
2389 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2390 END IF;
2391
2392 OPEN l_cur_for_uncat_project_level;
2393
2394 pa_debug.g_err_stage:= 'fetching cursor values and doing bulk insert';
2395 IF P_PA_DEBUG_MODE = 'Y' THEN
2396 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2397 END IF;
2398
2399 LOOP
2400
2401 FETCH l_cur_for_uncat_project_level BULK COLLECT INTO
2402 l_task_id_tbl
2403 ,l_rlmid_tbl
2404 ,l_track_as_labor_flag_tbl
2405 ,l_uom_tbl
2406 LIMIT l_max_fetch_size;
2407
2408 --Calling Bulk insert api
2409
2410 IF nvl(l_task_id_tbl.last,0) >= 1 THEN
2411 Insert_Bulk_Rows_Res(
2412 p_project_id =>l_project_id
2413 ,p_plan_version_id =>p_plan_version_id
2414 ,p_task_id_tbl =>l_task_id_tbl
2415 ,p_res_list_mem_id_tbl =>l_rlmid_tbl
2416 ,p_unit_of_measure_tbl =>l_uom_tbl
2417 ,p_track_as_labor_flag_tbl=>l_track_as_labor_flag_tbl
2418 ,x_return_status =>l_return_status
2419 ,x_msg_count =>l_msg_count
2420 ,x_msg_data =>l_msg_data );
2421 END IF;
2422
2423 -- Exit if fetch size is less than 200
2424
2425 EXIT WHEN NVL(l_task_id_tbl.last,0) < l_max_fetch_size;
2426
2427 END LOOP;
2428
2429 CLOSE l_cur_for_uncat_project_level;
2430
2431
2432 ELSIF l_fp_level_code <> PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
2433
2434 -- CASE: planning level 'task' and uncategorised resource_list
2435
2436 pa_debug.g_err_stage:='task level planning and Uncategorised resource_list';
2437 IF P_PA_DEBUG_MODE = 'Y' THEN
2438 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2439 END IF;
2440
2441 pa_debug.g_err_stage:='opening l_elements_cur';
2442 IF P_PA_DEBUG_MODE = 'Y' THEN
2443 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2444 END IF;
2445
2446 OPEN l_cur_for_uncat_task_level;
2447
2448 pa_debug.g_err_stage:= 'fetching cursor values and doing bulk insert';
2449 IF P_PA_DEBUG_MODE = 'Y' THEN
2450 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2451 END IF;
2452
2453 LOOP
2454
2455 FETCH l_cur_for_uncat_task_level BULK COLLECT INTO
2456 l_task_id_tbl
2457 ,l_rlmid_tbl
2458 ,l_track_as_labor_flag_tbl
2459 ,l_uom_tbl
2460 LIMIT l_max_fetch_size;
2461
2462 --Calling Bulk insert api
2463
2464 IF nvl(l_task_id_tbl.last,0) >= 1 THEN
2465 Insert_Bulk_Rows_Res(
2466 p_project_id =>l_project_id
2467 ,p_plan_version_id =>p_plan_version_id
2468 ,p_task_id_tbl =>l_task_id_tbl
2469 ,p_res_list_mem_id_tbl =>l_rlmid_tbl
2470 ,p_unit_of_measure_tbl =>l_uom_tbl
2471 ,p_track_as_labor_flag_tbl=>l_track_as_labor_flag_tbl
2472 ,x_return_status =>l_return_status
2473 ,x_msg_count =>l_msg_count
2474 ,x_msg_data =>l_msg_data );
2475 END IF;
2476
2477 -- Exit if fetch size is less than 200
2478
2479 EXIT WHEN NVL(l_task_id_tbl.last,0) < l_max_fetch_size;
2480
2481 END LOOP;
2482
2483 CLOSE l_cur_for_uncat_task_level;
2484
2485 END IF; -- l_fp_level_code
2486
2487 ELSIF l_uncat_flag = 'N' THEN
2488
2489 -- CASE: resource_list is categorised
2490
2491 pa_debug.g_err_stage:='Categorised resource_list';
2492 IF P_PA_DEBUG_MODE = 'Y' THEN
2493 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2494 END IF;
2495
2496 pa_debug.g_err_stage:='opening l_cur_for_cat_res_list';
2497 IF P_PA_DEBUG_MODE = 'Y' THEN
2498 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2499 END IF;
2500
2501 OPEN l_cur_for_cat_res_list;
2502
2503 pa_debug.g_err_stage:= 'fetching cursor values and doing bulk insert';
2504 IF P_PA_DEBUG_MODE = 'Y' THEN
2505 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2506 END IF;
2507
2508 LOOP
2509
2510 FETCH l_cur_for_cat_res_list BULK COLLECT INTO
2511 l_task_id_tbl
2512 ,l_rlmid_tbl
2513 ,l_track_as_labor_flag_tbl
2514 ,l_uom_tbl
2515 LIMIT l_max_fetch_size;
2516
2517 --Calling Bulk insert api
2518
2519 IF nvl(l_task_id_tbl.last,0) >= 1 THEN
2520 Insert_Bulk_Rows_Res(
2521 p_project_id =>l_project_id
2522 ,p_plan_version_id =>p_plan_version_id
2523 ,p_task_id_tbl =>l_task_id_tbl
2524 ,p_res_list_mem_id_tbl =>l_rlmid_tbl
2525 ,p_unit_of_measure_tbl =>l_uom_tbl
2526 ,p_track_as_labor_flag_tbl=>l_track_as_labor_flag_tbl
2527 ,x_return_status =>l_return_status
2528 ,x_msg_count =>l_msg_count
2529 ,x_msg_data =>l_msg_data );
2530 END IF;
2531
2532 -- Exit if fetch size is less than 200
2533
2534 EXIT WHEN NVL(l_task_id_tbl.last,0) < l_max_fetch_size;
2535
2536 END LOOP;
2537
2538 CLOSE l_cur_for_cat_res_list;
2539
2540 END IF; --l_uncat_flag
2541
2542 pa_debug.g_err_stage:= 'Exiting Create_Enterable_Resources';
2543 IF P_PA_DEBUG_MODE = 'Y' THEN
2544 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,3);
2545 END IF;
2546
2547 pa_debug.reset_err_stack;
2548
2549 EXCEPTION
2550
2551 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
2552
2553 l_msg_count := FND_MSG_PUB.count_msg;
2554 IF l_msg_count = 1 THEN
2555 PA_INTERFACE_UTILS_PUB.get_messages
2556 (p_encoded => FND_API.G_TRUE
2557 ,p_msg_index => 1
2558 ,p_msg_count => l_msg_count
2559 ,p_msg_data => l_msg_data
2560 ,p_data => l_data
2561 ,p_msg_index_out => l_msg_index_out);
2562 x_msg_data := l_data;
2563 x_msg_count := l_msg_count;
2564 ELSE
2565 x_msg_count := l_msg_count;
2566 END IF;
2567
2568 pa_debug.g_err_stage:= 'Invalid Arguments Passed';
2569 IF P_PA_DEBUG_MODE = 'Y' THEN
2570 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,5);
2571 END IF;
2572
2573 x_return_status := FND_API.G_RET_STS_ERROR;
2574 pa_debug.reset_err_stack;
2575 RAISE;
2576
2577 WHEN others THEN
2578
2579 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2580 x_msg_count := 1;
2581 x_msg_data := SQLERRM;
2582 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
2583 ,p_procedure_name => 'CREATE_ENTERABLE_RESOURCES');
2584 pa_debug.g_err_stage:= 'Unexpected Error'||SQLERRM;
2585 IF P_PA_DEBUG_MODE = 'Y' THEN
2586 pa_debug.write('create_enterable_resources: ' || l_module_name,pa_debug.g_err_stage,5);
2587 END IF;
2588 pa_debug.reset_err_stack;
2589 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2590
2591 END create_enterable_resources;
2592
2593 /*==================================================================================================
2594 get_element_id: This procedure is used from setup pages to get the element id in case an element
2595 is already available in database.
2596 ==================================================================================================*/
2597 FUNCTION get_element_id (
2598 p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
2599 ,p_element_type IN pa_fp_elements.element_type%TYPE
2600 ,p_task_id IN pa_tasks.task_id%TYPE
2601 ,p_resource_list_member_id IN pa_resource_list_members.resource_list_member_id%TYPE)
2602 RETURN pa_fp_elements.proj_fp_elements_id%TYPE
2603 IS
2604
2605 l_proj_fp_elements_id pa_fp_elements.proj_fp_elements_id%TYPE := -99;
2606 BEGIN
2607
2608 SELECT proj_fp_elements_id
2609 INTO l_proj_fp_elements_id
2610 FROM pa_fp_elements fpe
2611 WHERE fpe.proj_fp_options_id = p_proj_fp_options_id
2612 AND fpe.element_type = p_element_type
2613 AND fpe.task_id = p_task_id
2614 AND fpe.resource_list_member_id = p_resource_list_member_id;
2615
2616 RETURN l_proj_fp_elements_id;
2617
2618 EXCEPTION
2619 WHEN NO_DATA_FOUND THEN
2620 l_proj_fp_elements_id := -99;
2621 RETURN l_proj_fp_elements_id; /* when no data found then return -99 */
2622 WHEN OTHERS THEN
2623 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2624 END get_element_id;
2625
2626 /*==================================================================================================
2627 get_element_plannable_flag: This procedure is used from setup pages to get the plannable flag in
2628 case an element is already available in database.
2629 ==================================================================================================*/
2630 FUNCTION get_element_plannable_flag (
2631 p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
2632 ,p_element_type IN pa_fp_elements.element_type%TYPE
2633 ,p_task_id IN pa_tasks.task_id%TYPE
2634 ,p_resource_list_member_id IN pa_resource_list_members.resource_list_member_id%TYPE)
2635 RETURN pa_fp_elements.plannable_flag%TYPE
2636 IS
2637
2638 l_plannable_flag pa_fp_elements.plannable_flag%TYPE := 'N';
2639 BEGIN
2640
2641 SELECT plannable_flag
2642 INTO l_plannable_flag
2643 FROM pa_fp_elements fpe
2644 WHERE fpe.proj_fp_options_id = p_proj_fp_options_id
2645 AND fpe.element_type = p_element_type
2646 AND fpe.task_id = p_task_id
2647 AND fpe.resource_list_member_id = p_resource_list_member_id;
2648
2649 RETURN l_plannable_flag;
2650
2651 EXCEPTION
2652 WHEN NO_DATA_FOUND THEN
2653 l_plannable_flag := 'N';
2654 RETURN l_plannable_flag;
2655 WHEN OTHERS THEN
2656 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2657 END get_element_plannable_flag;
2658
2659 /*==================================================================================================
2660 get_plan_amount_exists_flag: This procedure is used from setup pages to get the plan amount exists
2661 in case an elementis already available in database.
2662 ==================================================================================================*/
2663 FUNCTION get_plan_amount_exists_flag (
2664 p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
2665 ,p_element_type IN pa_fp_elements.element_type%TYPE
2666 ,p_task_id IN pa_tasks.task_id%TYPE
2667 ,p_resource_list_member_id IN pa_resource_list_members.resource_list_member_id%TYPE)
2668 RETURN pa_fp_elements.plan_amount_exists_flag%TYPE
2669 IS
2670
2671 l_plan_amount_exists_flag pa_fp_elements.plan_amount_exists_flag%TYPE := 'N';
2672 BEGIN
2673
2674 SELECT plan_amount_exists_flag
2675 INTO l_plan_amount_exists_flag
2676 FROM pa_fp_elements fpe
2677 WHERE fpe.proj_fp_options_id = p_proj_fp_options_id
2678 AND fpe.element_type = p_element_type
2679 AND fpe.task_id = p_task_id
2680 AND fpe.resource_list_member_id = p_resource_list_member_id;
2681
2682 RETURN l_plan_amount_exists_flag;
2683
2684 EXCEPTION
2685 WHEN NO_DATA_FOUND THEN
2686 l_plan_amount_exists_flag := 'N';
2687 RETURN l_plan_amount_exists_flag;
2688 WHEN OTHERS THEN
2689 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2690 END get_plan_amount_exists_flag;
2691
2692 /*=======================================================================
2693 The following function returns resource_planning_level based upon the i/ps.
2694 ========================================================================*/
2695 FUNCTION get_resource_planning_level(
2696 p_parent_member_id IN pa_resource_list_members.parent_member_id%TYPE
2697 ,p_uncategorized_flag IN pa_resource_lists.uncategorized_flag%TYPE
2698 ,p_grouped_flag IN VARCHAR2)
2699 RETURN pa_fp_elements.resource_planning_level%TYPE IS
2700
2701 l_resource_planning_level pa_fp_elements.resource_planning_level%TYPE;
2702
2703 BEGIN
2704 IF p_uncategorized_flag = 'N' THEN
2705 IF p_grouped_flag = 'Y' THEN
2706
2707 IF p_parent_member_id IS NULL THEN
2708
2709 l_resource_planning_level := PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_G;
2710
2711 ELSE
2712 l_resource_planning_level := PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R;
2713
2714 END IF; --parent_member_id
2715
2716 ELSIF p_grouped_flag = 'N' THEN
2717
2718 l_resource_planning_level := PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R;
2719
2720 END IF; --p_grouped_flag
2721 ELSIF p_uncategorized_flag = 'Y' THEN
2722
2723 l_resource_planning_level := NULL;
2724
2725 END IF;
2726
2727 RETURN l_resource_planning_level;
2728 END get_resource_planning_level;
2729
2730 /*===================================================================
2731 The follwing procedure creates elements from the budget versions id
2732 passed for the fp options id passed. The starategy is
2733 1)First,create resource level elements
2734 2)Then, create task level elements which are plannable and present in
2735 pa_resource_assignments.
2736 3)Lastly,create top task level elements for the above included tasks
2737 if they aren't already created.
2738
2739 Bug:- 2634900, the cursors have been modified so that the api can be
2740 called mulitiple times and the next time the api is called only those
2741 elements that are not inserted already are chosen for insertion.
2742
2743 Bug :- 2625872, In the new budgets model,for a given task the user can
2744 plan either at resource level or resource group level butn't both.
2745 As this api is also being used to upgrade budget_versions from old model
2746 to new model, we should check if mixed resource planning level exists
2747 for the current budget version.
2748 ===================================================================*/
2749 PROCEDURE Create_elements_from_version(
2750 p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
2751 ,p_element_type IN pa_fp_elements.element_type%TYPE
2752 ,p_from_version_id IN pa_budget_versions.budget_version_id%TYPE
2753 ,p_resource_list_id IN pa_budget_versions.resource_list_id%TYPE
2754 ,x_mixed_resource_planned_flag OUT NOCOPY VARCHAR2 -- new parameter for Bug :- 2625872 --File.Sql.39 bug 4440895
2755 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
2756 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
2757 ,x_msg_data OUT NOCOPY VARCHAR2) IS --File.Sql.39 bug 4440895
2758
2759 l_return_status VARCHAR2(2000);
2760 l_msg_count NUMBER :=0;
2761 l_msg_data VARCHAR2(2000);
2762 l_data VARCHAR2(2000);
2763 l_msg_index_out NUMBER;
2764 l_debug_mode VARCHAR2(30);
2765
2766 l_plsql_max_array_size NUMBER := 200;
2767
2768 l_uncategorized_flag pa_resource_lists.uncategorized_flag%TYPE;
2769 l_grouped_flag VARCHAR2(1); --indicates if resource_list is grouped
2770 l_group_resource_type_id pa_resource_lists.group_resource_type_id%TYPE;
2771
2772 l_task_id_tbl l_task_id_tbl_typ;
2773 l_top_task_id_tbl l_top_task_id_tbl_typ;
2774 l_res_list_member_id_tbl l_res_list_mem_id_tbl_typ;
2775 l_top_task_planning_level_tbl l_task_planning_level_tbl_typ;
2776 l_res_planning_level_tbl l_res_planning_level_tbl_typ;
2777 l_plannable_flag_tbl l_plannable_flag_tbl_typ;
2778 l_res_planned_for_task_tbl l_res_planned_for_task_tbl_typ;
2779 l_plan_amount_exists_flag_tbl l_planamount_exists_tbl_typ;
2780
2781 ---- variables added for Bug :- 2625872 ----
2782
2783 TYPE l_resource_level_tbl_typ IS TABLE OF
2784 VARCHAR2(30) INDEX BY BINARY_INTEGER;
2785
2786 l_resource_level_tbl l_resource_level_tbl_typ;
2787 l_prev_res_level VARCHAR2(30);
2788 l_prev_task_id pa_tasks.task_id%TYPE;
2789
2790 -- The following exception would be raised if the budget version
2791 -- has mixed resource planning level
2792
2793 Mixed_Res_Plan_Level_Exc EXCEPTION;
2794
2795 ---- variables added for Bug :- 2625872 ----
2796
2797 CURSOR fp_options_cur(
2798 c_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
2799 ,c_element_type IN pa_fp_elements.element_type%TYPE) IS
2800 SELECT project_id
2801 ,fin_plan_type_id
2802 ,fin_plan_version_id
2803 ,PA_FIN_PLAN_UTILS.GET_OPTION_PLANNING_LEVEL(c_proj_fp_options_id,c_element_type) fin_plan_level_code
2804 FROM pa_proj_fp_options
2805 WHERE proj_fp_options_id = c_proj_fp_options_id;
2806
2807 fp_options_rec fp_options_cur%ROWTYPE;
2808
2809 -- The following cursor is opened for the case of project level planning and
2810 -- categorized resource list
2811
2812 CURSOR resources_for_proj_level_cur(
2813 c_from_version_id IN pa_budget_versions.budget_version_id%TYPE) IS
2814 SELECT 0 task_id
2815 ,0 top_task_id
2816 ,pra.resource_list_member_id resource_list_member_id
2817 ,NULL top_task_planning_level
2818 ,NULL resource_planning_level
2819 ,'Y' plannable_flag
2820 ,NULL resources_planned_for_task
2821 ,'Y' plan_amount_exists_flag
2822 ,DECODE(prlm.parent_member_id, NULL, 'G','R') resource_level -- Bug :- 2625872
2823 FROM pa_resource_assignments pra
2824 ,pa_resource_list_members prlm
2825 WHERE budget_version_id = c_from_version_id
2826 AND NVL(resource_assignment_type,PA_FP_CONSTANTS_PKG.G_USER_ENTERED) =
2827 PA_FP_CONSTANTS_PKG.G_USER_ENTERED
2828 AND prlm.resource_list_member_id = pra.resource_list_member_id
2829 AND NOT EXISTS(select 'x' from pa_fp_elements e
2830 where e.proj_fp_options_id = p_proj_fp_options_id
2831 and e.element_Type = p_element_Type
2832 and e.task_id = 0
2833 and e.resource_list_member_id = pra.resource_list_member_id);
2834
2835 -- The following cursor is opened for the case of task level planning and
2836 -- categorized resource list to fetch resource level records
2837
2838 CURSOR resources_for_task_level_cur(
2839 c_from_version_id IN pa_budget_versions.budget_version_id%TYPE) IS
2840 SELECT pra.task_id task_id
2841 ,pt.top_task_id top_task_id
2842 ,pra.resource_list_member_id resource_list_member_id
2843 ,NULL top_task_planning_level
2844 ,NULL resource_planning_level
2845 ,'Y' plannable_flag
2846 ,NULL resources_planned_for_task
2847 ,'Y' plan_amount_exists_flag
2848 ,DECODE(prlm.parent_member_id, NULL, 'G','R') resource_level -- Bug :- 2625872
2849 FROM pa_resource_assignments pra
2850 ,pa_tasks pt
2851 ,pa_resource_list_members prlm
2852 WHERE budget_version_id = c_from_version_id
2853 AND pt.task_id = pra.task_id
2854 AND NVL(resource_assignment_type,PA_FP_CONSTANTS_PKG.G_USER_ENTERED) =
2855 PA_FP_CONSTANTS_PKG.G_USER_ENTERED
2856 AND prlm.resource_list_member_id = pra.resource_list_member_id
2857 AND NOT EXISTS(select 'x' from pa_fp_elements e
2858 where e.proj_fp_options_id = p_proj_fp_options_id
2859 and e.element_Type = p_element_Type
2860 and e.task_id = pra.task_id
2861 and e.resource_list_member_id = pra.resource_list_member_id)
2862 ORDER BY pra.task_id ;
2863
2864 -- The following cursor is opened for the case of task level planning
2865 -- to fetch task level records irrespective of resource list categorized or not
2866
2867 /* Bug #2933875: In the below cursor for Top_Task_Planning_Level, added the check for
2868 Planning level as Top and Lowest (G_BUDGET_ENTRY_LEVEL_M). If the Planning level is
2869 Top and Lowest and the Task is also the Top task then the top_task_planning_level
2870 should be 'LOWEST' and not 'TOP' as it was getting defaulted earlier. */
2871
2872 /* Bug 3019572 : The fix done for bug 2933875 is incomplete. If budget planning level is
2873 'Top and Lowest' , top task planning level for a top task should be derived as follows:
2874
2875 if task has chidren
2876 Populate as 'Planned at Top Task'
2877 else
2878 Populate as 'Planned at Lowest Task'
2879 end if;
2880
2881 Note: Please note that top task planning level column needs to be populated for
2882 top task records only.
2883 */
2884
2885 CURSOR task_level_elements_cur(
2886 c_from_version_id IN pa_budget_versions.budget_version_id%TYPE) IS
2887 SELECT DISTINCT pra.task_id task_id
2888 ,pt.top_task_id top_task_id
2889 ,0 resource_list_member_id
2890 /* Bug 3019572
2891 ,DECODE(fp_options_rec.fin_plan_level_code,
2892 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_LOWEST, PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST,
2893 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_M, DECODE(pra.task_id, pt.top_task_id, PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST),
2894 DECODE(pra.task_id,pt.top_task_id,PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_TOP,
2895 PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST)) top_task_planning_level
2896 */
2897 ,DECODE(pra.task_id,
2898 pt.top_task_id,
2899 DECODE(fp_options_rec.fin_plan_level_code,
2900 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_LOWEST,
2901 PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST,
2902 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_TOP,
2903 PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_TOP,
2904 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_M,
2905 DECODE(pa_task_utils.check_child_exists(pra.task_id),
2906 1, PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_TOP,
2907 PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST)
2908 ),
2909 null
2910 ) top_task_planning_level
2911 ,get_resource_planning_level( prlm.parent_member_id
2912 ,l_uncategorized_flag
2913 ,l_grouped_flag ) resource_planning_level
2914 ,'Y' plannable_flag
2915 ,DECODE(l_uncategorized_flag,'Y',NULL,'Y') resources_planned_for_task
2916 ,'Y' plan_amount_exists_flag
2917 FROM pa_resource_assignments pra
2918 ,pa_tasks pt
2919 ,pa_resource_list_members prlm
2920 WHERE budget_version_id = c_from_version_id
2921 AND pt.task_id = pra.task_id
2922 AND prlm.resource_list_member_id = pra.resource_list_member_id
2923 AND NVL(resource_assignment_type,PA_FP_CONSTANTS_PKG.G_USER_ENTERED) = PA_FP_CONSTANTS_PKG.G_USER_ENTERED
2924 AND NOT EXISTS(select 'x' from pa_fp_elements e
2925 where e.proj_fp_options_id = p_proj_fp_options_id
2926 and e.element_Type = p_element_Type
2927 and e.task_id = pra.task_id
2928 and e.resource_list_member_id = 0);
2929
2930
2931 -- The following cursor is opened for the case of task level planning
2932 -- to insert top task level records for the task level records inserted using the above cursor
2933 -- irrespective of resource list categorized or not
2934
2935 CURSOR top_task_level_elements_cur(
2936 c_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE ) IS
2937 SELECT DISTINCT pt.top_task_id task_id
2938 ,pt.top_task_id top_task_id
2939 ,0 resource_list_member_id
2940 ,PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST top_task_planning_level
2941 ,NULL resource_planning_level
2942 ,'N' plannable_flag
2943 ,NULL resources_planned_for_task
2944 ,'Y' plan_amount_exists_flag
2945 FROM pa_fp_elements pfe
2946 ,pa_tasks pt
2947 WHERE pfe.proj_fp_options_id = c_proj_fp_options_id
2948 AND pfe.element_type = p_element_type
2949 AND pt.task_id = pfe.task_id
2950 AND pt.top_task_id <> pfe.task_id
2951 AND NOT EXISTS (SELECT 'x' -- not exists clause added for bug#2803724
2952 FROM pa_fp_elements e
2953 WHERE e.proj_fp_options_id = p_proj_fp_options_id
2954 AND e.element_Type = p_element_Type
2955 AND e.task_id = pt.top_task_id
2956 AND e.resource_list_member_id = 0 );
2957
2958 -- The following procedure calls insert bulk rows api
2959
2960 PROCEDURE Call_Insert_Bulk_Rows_Elements IS
2961 BEGIN
2962 PA_FP_ELEMENTS_PUB.Insert_Bulk_Rows (
2963 p_proj_fp_options_id => p_proj_fp_options_id
2964 ,p_project_id => fp_options_rec.project_id
2965 ,p_fin_plan_type_id => fp_options_rec.fin_plan_type_id
2966 ,p_element_type => p_element_type
2967 ,p_plan_version_id => fp_options_rec.fin_plan_version_id
2968 ,p_task_id_tbl => l_task_id_tbl
2969 ,p_top_task_id_tbl => l_top_task_id_tbl
2970 ,p_res_list_mem_id_tbl => l_res_list_member_id_tbl
2971 ,p_task_planning_level_tbl => l_top_task_planning_level_tbl
2972 ,p_res_planning_level_tbl => l_res_planning_level_tbl
2973 ,p_plannable_flag_tbl => l_plannable_flag_tbl
2974 ,p_res_planned_for_task_tbl => l_res_planned_for_task_tbl
2975 ,p_planamount_exists_tbl => l_plan_amount_exists_flag_tbl
2976 ,p_res_uncategorized_flag => NULL
2977 ,x_return_status => l_return_status
2978 ,x_msg_count => l_msg_count
2979 ,x_msg_data => l_msg_data);
2980
2981 END Call_Insert_Bulk_Rows_Elements;
2982
2983 BEGIN
2984
2985 x_msg_count := 0;
2986 x_return_status := FND_API.G_RET_STS_SUCCESS;
2987
2988 pa_debug.set_err_stack('Create_elements_from_version');
2989 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
2990 l_debug_mode := NVL(l_debug_mode, 'Y');
2991 pa_debug.set_process('PLSQL','LOG',l_debug_mode);
2992
2993 IF p_pa_debug_mode = 'Y' THEN
2994 pa_debug.g_err_stage := 'Entered Create_elements_from_version';
2995 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
2996 END IF;
2997
2998 -- Check for not null parameters
2999
3000 IF p_pa_debug_mode = 'Y' THEN
3001 pa_debug.g_err_stage := 'Checking for valid parameters:';
3002 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3003 END IF;
3004
3005 IF (p_proj_fp_options_id IS NULL) OR
3006 (p_element_type IS NULL) OR
3007 (p_from_version_id IS NULL) OR
3008 (p_resource_list_id IS NULL)
3009 THEN
3010 IF p_pa_debug_mode = 'Y' THEN
3011 pa_debug.g_err_stage := 'p_proj_fp_options_id = '||p_proj_fp_options_id;
3012 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3013 pa_debug.g_err_stage := 'p_element_type = '||p_element_type;
3014 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3015 pa_debug.g_err_stage := 'p_from_version_id = '||p_from_version_id;
3016 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3017 pa_debug.g_err_stage := 'p_resource_list_id = '||p_resource_list_id;
3018 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3019 END IF;
3020 PA_UTILS.ADD_MESSAGE(p_app_short_name=> 'PA',
3021 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
3022
3023 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3024
3025 END IF;
3026
3027 IF p_pa_debug_mode = 'Y' THEN
3028 pa_debug.g_err_stage := 'Parameter validation complete';
3029 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3030 pa_debug.g_err_stage := 'p_proj_fp_options_id = '||p_proj_fp_options_id;
3031 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3032 pa_debug.g_err_stage := 'p_from_version_id = '||p_from_version_id;
3033 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3034 pa_debug.g_err_stage := 'p_resource_list_id = '||p_resource_list_id;
3035 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3036 END IF;
3037
3038 --Get the required fp options info using p_proj_fp_options_id
3039
3040 OPEN fp_options_cur(p_proj_fp_options_id,p_element_type);
3041 FETCH fp_options_cur INTO fp_options_rec;
3042 CLOSE fp_options_cur;
3043
3044 --get resourcelist info regarding the categorization and grouping of resourcelist
3045
3046 pa_fin_plan_utils.get_resource_list_info(
3047 p_resource_list_id => p_resource_list_id
3048 ,x_res_list_is_uncategorized => l_uncategorized_flag
3049 ,x_is_resource_list_grouped => l_grouped_flag
3050 ,x_group_resource_type_id => l_group_resource_type_id
3051 ,x_return_status => l_return_status
3052 ,x_msg_count => l_msg_count
3053 ,x_msg_data => l_msg_data);
3054
3055 -- Initialising the varaibles used to check mixed resource planning level to NULL
3056
3057 l_prev_res_level := NULL;
3058 l_prev_task_id := NULL;
3059
3060 -- Setting the OUT varible to 'N' initially
3061
3062 x_mixed_resource_planned_flag := 'N';
3063
3064 IF (fp_options_rec.fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT) THEN
3065
3066 IF l_uncategorized_flag = 'N' THEN
3067
3068 -- Case:- project level planning and categorised resource list
3069
3070 --Fetch and insert resource level records into pa_fp_elements.
3071
3072 IF p_pa_debug_mode = 'Y' THEN
3073 pa_debug.g_err_stage := 'Opening resources_for_proj_level_cur';
3074 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3075 END IF;
3076
3077 OPEN resources_for_proj_level_cur(p_from_version_id);
3078 LOOP
3079 FETCH resources_for_proj_level_cur BULK COLLECT INTO
3080 l_task_id_tbl
3081 ,l_top_task_id_tbl
3082 ,l_res_list_member_id_tbl
3083 ,l_top_task_planning_level_tbl
3084 ,l_res_planning_level_tbl
3085 ,l_plannable_flag_tbl
3086 ,l_res_planned_for_task_tbl
3087 ,l_plan_amount_exists_flag_tbl
3088 ,l_resource_level_tbl -- Bug :- 2625872
3089 LIMIT l_plsql_max_array_size;
3090
3091 -- Check if mixed planning level exists for the fetched records
3092 IF NVL(l_resource_level_tbl.last,0) >= 1 THEN
3093
3094 FOR i IN l_resource_level_tbl.first .. l_resource_level_tbl.last
3095 LOOP
3096
3097 IF (l_prev_res_level IS NULL) THEN
3098
3099 -- we are at the first record, and so initialise
3100 -- l_prev_res_level with the current record
3101
3102 l_prev_res_level := l_resource_level_tbl(i);
3103
3104 ELSIF l_prev_res_level <> l_resource_level_tbl(i) THEN
3105
3106 -- for the current record, the resource planning level
3107 -- has changed from previous record and so return error
3108 RAISE Mixed_Res_Plan_Level_Exc;
3109 END IF;
3110 END LOOP;
3111 END IF;
3112 -- If there are no mixed resoruce planning level records insert elements
3113
3114 IF NVL(l_task_id_tbl.last,0) >= 1 THEN
3115 pa_debug.g_err_stage := 'Calling call_insert_bulk_rows_elements';
3116 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3117 Call_Insert_Bulk_Rows_Elements;
3118 END IF;
3119
3120 EXIT WHEN NVL(l_task_id_tbl.last,0) < l_plsql_max_array_size;
3121 END LOOP;
3122 CLOSE resources_for_proj_level_cur;
3123
3124 IF p_pa_debug_mode = 'Y' THEN
3125 pa_debug.g_err_stage := 'Closed resources_for_proj_level_cur';
3126 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3127 END IF;
3128
3129 END IF;
3130
3131 ELSE --task level planning
3132
3133 IF l_uncategorized_flag = 'N' THEN
3134
3135 --CASE :- task level planning and categorised resource list
3136 --Fetch and insert resource level records into pa_fp_elements.
3137
3138 IF p_pa_debug_mode = 'Y' THEN
3139 pa_debug.g_err_stage := 'Opening resources_for_task_level_cur';
3140 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3141 END IF;
3142
3143 OPEN resources_for_task_level_cur(p_from_version_id);
3144 LOOP
3145 FETCH resources_for_task_level_cur BULK COLLECT INTO
3146 l_task_id_tbl
3147 ,l_top_task_id_tbl
3148 ,l_res_list_member_id_tbl
3149 ,l_top_task_planning_level_tbl
3150 ,l_res_planning_level_tbl
3151 ,l_plannable_flag_tbl
3152 ,l_res_planned_for_task_tbl
3153 ,l_plan_amount_exists_flag_tbl
3154 ,l_resource_level_tbl -- Bug :- 2625872
3155 LIMIT l_plsql_max_array_size;
3156
3157 -- Check if mixed planning level exists for the fetched records
3158 IF NVL(l_task_id_tbl.last,0) >= 1 THEN
3159
3160 FOR i IN l_resource_level_tbl.first..l_resource_level_tbl.last
3161 LOOP
3162 IF l_prev_res_level IS NULL OR
3163 l_prev_task_id IS NULL OR
3164 l_prev_task_id <> l_task_id_tbl(i)
3165 THEN
3166
3167 IF p_pa_debug_mode = 'Y' THEN
3168 pa_debug.g_err_stage := 'previous task = '||l_prev_task_id;
3169 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3170 END IF;
3171
3172 -- we are at the first record fetched or the task has changed
3173 -- So initialise l_prev_res_level, l_prev_task_id with the
3174 -- current record
3175
3176 l_prev_res_level := l_resource_level_tbl(i);
3177 l_prev_task_id := l_task_id_tbl(i);
3178
3179 ELSIF l_prev_res_level <> l_resource_level_tbl(i) THEN
3180
3181 -- the task is same but resource planning level is different
3182 -- so raise mixed resource planning exception
3183 RAISE Mixed_Res_Plan_Level_Exc;
3184 END IF;
3185 END LOOP;
3186
3187 END IF;
3188
3189 -- If there are no mixed resoruce planning level records insert elements
3190
3191 IF NVL(l_task_id_tbl.last,0) >= 1 THEN
3192 Call_Insert_Bulk_Rows_Elements;
3193 END IF;
3194 EXIT WHEN NVL(l_task_id_tbl.last,0) < l_plsql_max_array_size;
3195 END LOOP;
3196 CLOSE resources_for_task_level_cur;
3197
3198 IF p_pa_debug_mode = 'Y' THEN
3199 pa_debug.g_err_stage := 'Closed resources_for_task_level_cur';
3200 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3201 END IF;
3202 END IF;
3203
3204 --Fetch and insert task level records into pa_fp_elements
3205
3206 IF p_pa_debug_mode = 'Y' THEN
3207 pa_debug.g_err_stage := 'Opening task_level_elements_cur';
3208 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3209 END IF;
3210
3211 OPEN task_level_elements_cur(p_from_version_id);
3212 LOOP
3213 FETCH task_level_elements_cur BULK COLLECT INTO
3214 l_task_id_tbl
3215 ,l_top_task_id_tbl
3216 ,l_res_list_member_id_tbl
3217 ,l_top_task_planning_level_tbl
3218 ,l_res_planning_level_tbl
3219 ,l_plannable_flag_tbl
3220 ,l_res_planned_for_task_tbl
3221 ,l_plan_amount_exists_flag_tbl
3222 LIMIT l_plsql_max_array_size;
3223
3224 IF NVL(l_task_id_tbl.last,0) >= 1 THEN
3225 Call_Insert_Bulk_Rows_Elements;
3226 END IF;
3227
3228 EXIT WHEN NVL(l_task_id_tbl.last,0) < l_plsql_max_array_size;
3229 END LOOP;
3230 CLOSE task_level_elements_cur;
3231
3232 --Fetch and insert top task level records if they aren't already inserted.
3233
3234 IF p_pa_debug_mode = 'Y' THEN
3235 pa_debug.g_err_stage := 'Closed task_level_elements_cur';
3236 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3237 pa_debug.g_err_stage := 'Opening top_task_level_elements_cur';
3238 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3239 END IF;
3240
3241 OPEN top_task_level_elements_cur(p_proj_fp_options_id);
3242 LOOP
3243 FETCH top_task_level_elements_cur BULK COLLECT INTO
3244 l_task_id_tbl
3245 ,l_top_task_id_tbl
3246 ,l_res_list_member_id_tbl
3247 ,l_top_task_planning_level_tbl
3248 ,l_res_planning_level_tbl
3249 ,l_plannable_flag_tbl
3250 ,l_res_planned_for_task_tbl
3251 ,l_plan_amount_exists_flag_tbl
3252 LIMIT l_plsql_max_array_size;
3253
3254 IF NVL(l_task_id_tbl.last,0) >= 1 THEN
3255 Call_Insert_Bulk_Rows_Elements;
3256 END IF;
3257
3258 EXIT WHEN NVL(l_task_id_tbl.last,0) < l_plsql_max_array_size;
3259 END LOOP;
3260 CLOSE top_task_level_elements_cur;
3261
3262 IF p_pa_debug_mode = 'Y' THEN
3263 pa_debug.g_err_stage := 'Closed top_task_level_elements_cur';
3264 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3265 END IF;
3266 END IF;
3267 IF p_pa_debug_mode = 'Y' THEN
3268 pa_debug.g_err_stage := 'Exiting Create_elements_from_version';
3269 pa_debug.write(l_module_name,pa_debug.g_err_stage,3);
3270 END IF;
3271 pa_debug.reset_err_stack;
3272 EXCEPTION
3273
3274 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
3275
3276 l_msg_count := FND_MSG_PUB.count_msg;
3277 IF l_msg_count = 1 THEN
3278 PA_INTERFACE_UTILS_PUB.get_messages
3279 (p_encoded => FND_API.G_TRUE
3280 ,p_msg_index => 1
3281 ,p_msg_count => l_msg_count
3282 ,p_msg_data => l_msg_data
3283 ,p_data => l_data
3284 ,p_msg_index_out => l_msg_index_out);
3285 x_msg_data := l_data;
3286 x_msg_count := l_msg_count;
3287 ELSE
3288 x_msg_count := l_msg_count;
3289 END IF;
3290 IF p_pa_debug_mode = 'Y' THEN
3291 pa_debug.g_err_stage:='Invalid Arguments Passed';
3292 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3293 END IF;
3294 x_return_status:= FND_API.G_RET_STS_ERROR;
3295 pa_debug.reset_err_stack;
3296 RAISE;
3297
3298 WHEN Mixed_Res_Plan_Level_Exc THEN
3299
3300 IF resources_for_proj_level_cur%ISOPEN THEN
3301 CLOSE resources_for_proj_level_cur;
3302 END IF;
3303 IF resources_for_task_level_cur%ISOPEN THEN
3304 CLOSE resources_for_task_level_cur;
3305 END IF;
3306
3307 x_mixed_resource_planned_flag := 'Y';
3308 x_return_status:= FND_API.G_RET_STS_ERROR;
3309 IF p_pa_debug_mode = 'Y' THEN
3310 pa_debug.g_err_stage:='Budget_Version '||p_from_version_id ||' has mixed planning level';
3311 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3312 END IF;
3313 pa_debug.reset_err_stack;
3314 RETURN;
3315
3316 WHEN Others THEN
3317
3318 IF resources_for_proj_level_cur%ISOPEN THEN
3319 CLOSE resources_for_proj_level_cur;
3320 END IF;
3321 IF resources_for_task_level_cur%ISOPEN THEN
3322 CLOSE resources_for_task_level_cur;
3323 END IF;
3324 IF task_level_elements_cur%ISOPEN THEN
3325 CLOSE task_level_elements_cur;
3326 END IF;
3327 IF top_task_level_elements_cur%ISOPEN THEN
3328 CLOSE top_task_level_elements_cur;
3329 END IF;
3330
3331 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3332 x_msg_count := 1;
3333 x_msg_data := SQLERRM;
3334 FND_MSG_PUB.add_exc_msg( p_pkg_name=> 'PA_FP_UPGRADE_PKG'
3335 ,p_procedure_name => 'Create_elements_from_version');
3336 IF p_pa_debug_mode = 'Y' THEN
3337 pa_debug.g_err_stage:='Unexpected Error'||SQLERRM;
3338 pa_debug.write(l_module_name,pa_debug.g_err_stage,5);
3339 END IF;
3340 pa_debug.reset_err_stack;
3341 RAISE;
3342 END Create_elements_from_version;
3343
3344 /*==================================================================================================
3345 refresh_res_list_changes: This procedure is used to delete resource elements from PA_FP_ELEMENTS
3346 table for a particular Proj FP Options ID depending on the Element Type when the resource list is
3347 changed in the plan settings page. After deleting the resource records, it sets the
3348 resource planning level for the task records to 'R' if the resource list is categorized or to NULL
3349 if it is not categorized
3350 Bug 2920954 :- This api has been modifed to insert resource elements for the already selected task
3351 or project elements based on the input resource list id and the automatic resource selection
3352 parameter and resource planning level for automatic resource selection
3353 ==================================================================================================*/
3354 PROCEDURE refresh_res_list_changes (
3355 p_proj_fp_options_id IN PA_PROJ_FP_OPTIONS.PROJ_FP_OPTIONS_ID%TYPE
3356 ,p_element_type IN PA_FP_ELEMENTS.ELEMENT_TYPE%TYPE /* COST,REVENUE,ALL,BOTH */
3357 ,p_cost_resource_list_id IN PA_PROJ_FP_OPTIONS.COST_RESOURCE_LIST_ID%TYPE
3358 ,p_rev_resource_list_id IN PA_PROJ_FP_OPTIONS.REVENUE_RESOURCE_LIST_ID%TYPE
3359 ,p_all_resource_list_id IN PA_PROJ_FP_OPTIONS.ALL_RESOURCE_LIST_ID%TYPE
3360 /* Bug 2920954 start of new parameters added for post fp-K one off patch */
3361 ,p_select_cost_res_auto_flag IN pa_proj_fp_options.select_cost_res_auto_flag%TYPE
3362 ,p_cost_res_planning_level IN pa_proj_fp_options.cost_res_planning_level%TYPE
3363 ,p_select_rev_res_auto_flag IN pa_proj_fp_options.select_rev_res_auto_flag%TYPE
3364 ,p_revenue_res_planning_level IN pa_proj_fp_options.revenue_res_planning_level%TYPE
3365 ,p_select_all_res_auto_flag IN pa_proj_fp_options.select_all_res_auto_flag%TYPE
3366 ,p_all_res_planning_level IN pa_proj_fp_options.all_res_planning_level%TYPE
3367 /* Bug 2920954 end of new parameters added for post fp-K one off patch */
3368 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
3369 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
3370 ,x_msg_data OUT NOCOPY VARCHAR2) is --File.Sql.39 bug 4440895
3371
3372 l_msg_count NUMBER := 0;
3373 l_data VARCHAR2(2000);
3374 l_msg_data VARCHAR2(2000);
3375 l_msg_index_out NUMBER;
3376 l_return_status VARCHAR2(2000);
3377 l_debug_mode VARCHAR2(30);
3378 l_res_list_is_uncategorized PA_RESOURCE_LISTS_ALL_BG.UNCATEGORIZED_FLAG%TYPE;
3379 l_is_resource_list_grouped VARCHAR2(1);
3380 l_group_resource_type_id PA_RESOURCE_LISTS_ALL_BG.GROUP_RESOURCE_TYPE_ID%TYPE;
3381 l_resource_list_id PA_PROJ_FP_OPTIONS.ALL_RESOURCE_LIST_ID%TYPE;
3382 l_res_planning_level PA_FP_ELEMENTS.RESOURCE_PLANNING_LEVEL%TYPE;
3383 l_fin_plan_level_code PA_PROJ_FP_OPTIONS.COST_FIN_PLAN_LEVEL_CODE%TYPE;
3384 l_stage NUMBER := 100;
3385
3386 l_dummy_task_id_tbl pa_fp_elements_pub.l_task_id_tbl_typ;
3387
3388 BEGIN
3389
3390 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.refresh_res_list_changes');
3391 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
3392 l_debug_mode := NVL(l_debug_mode, 'Y');
3393 IF P_PA_DEBUG_MODE = 'Y' THEN
3394 pa_debug.set_process('refresh_res_list_changes: ' || 'PLSQL','LOG',l_debug_mode);
3395 END IF;
3396
3397 x_return_status := FND_API.G_RET_STS_SUCCESS;
3398
3399 IF (p_proj_fp_options_id IS NULL) or (p_element_type IS NULL) THEN
3400
3401 IF P_PA_DEBUG_MODE = 'Y' THEN
3402 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Proj FP Options ID is .'
3403 || p_proj_fp_options_id ||': Err- Element Type is .' || p_element_type;
3404 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3405 END IF;
3406
3407 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3408 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
3409 x_return_status := FND_API.G_RET_STS_ERROR;
3410 ELSE
3411
3412 IF P_PA_DEBUG_MODE = 'Y' THEN
3413 pa_debug.g_err_stage := TO_CHAR(l_Stage)||'Input parameters are valid ';
3414 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3415 END IF;
3416
3417 END IF;
3418
3419
3420 IF FND_MSG_PUB.count_msg > 0 THEN
3421 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3422 END IF;
3423
3424
3425
3426 /* Delete the records from the table PA_FP_Elements based on the Element_Type and
3427 for Element level RESOURCE. */
3428
3429 pa_debug.g_err_stage := 'Deleting Elements from PA_FP_Elements';
3430 IF P_PA_DEBUG_MODE = 'Y' THEN
3431 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,3);
3432 END IF;
3433
3434 delete_elements(p_proj_fp_options_id => p_proj_fp_options_id
3435 ,p_element_type => p_element_type
3436 ,p_element_level => PA_FP_CONSTANTS_PKG.G_ELEMENT_LEVEL_RESOURCE
3437 ,x_return_status => x_return_status
3438 ,x_msg_count => x_msg_count
3439 ,x_msg_data => x_msg_data);
3440
3441 /* Depending upon the element type, if the resource list chosen is categorized
3442 then update the resource planning level for the task records to 'R'. If the
3443 resource list is not categorized make the resource planning level NULL */
3444
3445 IF (p_element_type =PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST OR
3446 p_element_type =PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH) THEN
3447
3448
3449 IF (p_cost_resource_list_id IS NULL) THEN
3450 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Cost Resource List Id is NULL.';
3451 IF P_PA_DEBUG_MODE = 'Y' THEN
3452 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3453 END IF;
3454
3455 x_return_status := FND_API.G_RET_STS_ERROR;
3456 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3457 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
3458 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3459 END IF;
3460
3461 IF P_PA_DEBUG_MODE = 'Y' THEN
3462 pa_debug.g_err_stage := 'Element Type is Cost ';
3463 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,3);
3464 END IF;
3465
3466 IF p_select_cost_res_auto_flag = 'Y'
3467 THEN /* Bug 2920954 */
3468 /* p_cost_res_planning_level should be either 'R'/'G' */
3469
3470 IF p_cost_res_planning_level NOT IN ('R','G')
3471 THEN
3472 IF P_PA_DEBUG_MODE = 'Y' THEN
3473 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Cost Auto Res Plan Level is Invalid';
3474 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3475 END IF;
3476
3477 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3478 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
3479 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3480 END IF;
3481
3482 l_fin_plan_level_code := PA_FIN_PLAN_UTILS.Get_option_planning_level(
3483 P_PROJ_FP_OPTIONS_ID => p_proj_fp_options_id,
3484 P_ELEMENT_TYPE => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST);
3485
3486 /* If automatic resource addition is enabled, call add_resources_automatically api for entire option */
3487
3488 PA_FP_ELEMENTS_PUB.Add_resources_automatically
3489 ( p_proj_fp_options_id => p_proj_fp_options_id
3490 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST
3491 ,p_fin_plan_level_code => l_fin_plan_level_code
3492 ,p_resource_list_id => p_cost_resource_list_id
3493 ,p_res_planning_level => p_cost_res_planning_level
3494 ,p_entire_option => 'Y'
3495 ,p_element_task_id_tbl => l_dummy_task_id_tbl
3496 ,x_return_status => x_return_status
3497 ,x_msg_count => x_msg_count
3498 ,x_msg_data => x_msg_data
3499 );
3500
3501 ELSE /* Bug 2920954 */
3502 PA_FIN_PLAN_UTILS.GET_RESOURCE_LIST_INFO(
3503 P_RESOURCE_LIST_ID => p_cost_resource_list_id,
3504 X_RES_LIST_IS_UNCATEGORIZED => l_res_list_is_uncategorized,
3505 X_IS_RESOURCE_LIST_GROUPED => l_is_resource_list_grouped,
3506 X_GROUP_RESOURCE_TYPE_ID => l_group_resource_type_id,
3507 X_RETURN_STATUS => x_return_status,
3508 X_MSG_COUNT => x_msg_count,
3509 X_MSG_DATA => x_msg_data
3510 );
3511 IF l_res_list_is_uncategorized = 'N' THEN
3512 l_res_planning_level := PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R;
3513 ELSE
3514 l_res_planning_level := NULL;
3515 END IF;
3516
3517
3518 pa_debug.g_err_stage := 'Resource Planning Level is '||l_res_planning_level;
3519 IF P_PA_DEBUG_MODE = 'Y' THEN
3520 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,3);
3521 END IF;
3522
3523 /*Added the condition resources_planned_for_task = 'N' for bug 2676456 so that
3524 the resource plannned for task column in planning elements page shows correct value
3525 */
3526
3527 UPDATE pa_fp_elements
3528 SET resource_planning_level = l_res_planning_level
3529 ,resources_planned_for_task = 'N'
3530 ,record_version_number = record_version_number + 1
3531 ,last_update_date = sysdate
3532 ,last_updated_by = FND_GLOBAL.USER_ID
3533 ,last_update_login = FND_GLOBAL.LOGIN_ID
3534 WHERE proj_fp_options_id = p_proj_fp_options_id
3535 AND element_type = PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST;
3536 END IF; /* Bug 2920954 */
3537 END IF;
3538
3539 IF (p_element_type =PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE OR
3540 p_element_type =PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_BOTH) THEN
3541
3542 IF (p_rev_resource_list_id IS NULL) THEN
3543 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Revenue Resource List Id is NULL.';
3544 IF P_PA_DEBUG_MODE = 'Y' THEN
3545 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3546 END IF;
3547
3548 x_return_status := FND_API.G_RET_STS_ERROR;
3549 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3550 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
3551 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3552 END IF;
3553
3554 pa_debug.g_err_stage := 'Element Type is REVENUE ';
3555 IF P_PA_DEBUG_MODE = 'Y' THEN
3556 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,3);
3557 END IF;
3558
3559 IF p_select_rev_res_auto_flag = 'Y'
3560 THEN /* Bug 2920954 */
3561 /* p_revenue_res_planning_level should be either 'R'/'G' */
3562
3563 IF p_revenue_res_planning_level NOT IN ('R','G')
3564 THEN
3565 IF P_PA_DEBUG_MODE = 'Y' THEN
3566 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- Revenue Auto Res Plan Level is Invalid';
3567 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3568 END IF;
3569
3570 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3571 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
3572 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3573 END IF;
3574
3575 l_fin_plan_level_code := PA_FIN_PLAN_UTILS.Get_option_planning_level(
3576 P_PROJ_FP_OPTIONS_ID => p_proj_fp_options_id,
3577 P_ELEMENT_TYPE => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE);
3578
3579 /* If automatic resource addition is enabled, call add_resources_automatically api for entire option */
3580
3581 PA_FP_ELEMENTS_PUB.Add_resources_automatically
3582 ( p_proj_fp_options_id => p_proj_fp_options_id
3583 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE
3584 ,p_fin_plan_level_code => l_fin_plan_level_code
3585 ,p_resource_list_id => p_rev_resource_list_id
3586 ,p_res_planning_level => p_revenue_res_planning_level
3587 ,p_entire_option => 'Y'
3588 ,p_element_task_id_tbl => l_dummy_task_id_tbl
3589 ,x_return_status => x_return_status
3590 ,x_msg_count => x_msg_count
3591 ,x_msg_data => x_msg_data
3592 );
3593 ELSE /* Bug 2920954 */
3594 PA_FIN_PLAN_UTILS.GET_RESOURCE_LIST_INFO(
3595 P_RESOURCE_LIST_ID => p_rev_resource_list_id,
3596 X_RES_LIST_IS_UNCATEGORIZED => l_res_list_is_uncategorized,
3597 X_IS_RESOURCE_LIST_GROUPED => l_is_resource_list_grouped,
3598 X_GROUP_RESOURCE_TYPE_ID => l_group_resource_type_id,
3599 X_RETURN_STATUS => x_return_status,
3600 X_MSG_COUNT => x_msg_count,
3601 X_MSG_DATA => x_msg_data
3602 );
3603 IF l_res_list_is_uncategorized = 'N' THEN
3604 l_res_planning_level := PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R;
3605 ELSE
3606 l_res_planning_level := NULL;
3607 END IF;
3608
3609 pa_debug.g_err_stage := 'Resource Planning Level is '||l_res_planning_level;
3610 IF P_PA_DEBUG_MODE = 'Y' THEN
3611 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,3);
3612 END IF;
3613
3614 UPDATE pa_fp_elements
3615 SET resource_planning_level = l_res_planning_level
3616 ,resources_planned_for_task = 'N' --for bug 2676456
3617 ,record_version_number = record_version_number + 1
3618 ,last_update_date = sysdate
3619 ,last_updated_by = FND_GLOBAL.USER_ID
3620 ,last_update_login = FND_GLOBAL.LOGIN_ID
3621 WHERE proj_fp_options_id = p_proj_fp_options_id
3622 AND element_type = PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE;
3623 END IF; /* Bug 2920954 */
3624
3625 END IF;
3626
3627 IF (p_element_type =PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL ) THEN
3628
3629 IF (p_all_resource_list_id IS NULL) THEN
3630 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- All Resource List Id is NULL.';
3631 IF P_PA_DEBUG_MODE = 'Y' THEN
3632 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3633 END IF;
3634
3635 x_return_status := FND_API.G_RET_STS_ERROR;
3636 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3637 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
3638 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3639 END IF;
3640
3641 pa_debug.g_err_stage := 'Element Type is ALL ';
3642 IF P_PA_DEBUG_MODE = 'Y' THEN
3643 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,3);
3644 END IF;
3645
3646 IF p_select_all_res_auto_flag = 'Y'
3647 THEN /* Bug 2920954 */
3648 /* p_all_res_planning_level should be either 'R'/'G' */
3649
3650 IF p_all_res_planning_level NOT IN ('R','G')
3651 THEN
3652 IF P_PA_DEBUG_MODE = 'Y' THEN
3653 pa_debug.g_err_stage := TO_CHAR(l_Stage)||': Err- All Auto Res Plan Level is Invalid';
3654 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,5);
3655 END IF;
3656
3657 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3658 p_msg_name => 'PA_FP_INV_PARAM_PASSED' );
3659 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3660 END IF;
3661
3662 l_fin_plan_level_code := PA_FIN_PLAN_UTILS.Get_option_planning_level(
3663 P_PROJ_FP_OPTIONS_ID => p_proj_fp_options_id,
3664 P_ELEMENT_TYPE => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL);
3665
3666 /* If automatic resource addition is enabled, call add_resources_automatically api for entire option */
3667
3668 PA_FP_ELEMENTS_PUB.Add_resources_automatically
3669 ( p_proj_fp_options_id => p_proj_fp_options_id
3670 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL
3671 ,p_fin_plan_level_code => l_fin_plan_level_code
3672 ,p_resource_list_id => p_all_resource_list_id
3673 ,p_res_planning_level => p_all_res_planning_level
3674 ,p_entire_option => 'Y'
3675 ,p_element_task_id_tbl => l_dummy_task_id_tbl
3676 ,x_return_status => x_return_status
3677 ,x_msg_count => x_msg_count
3678 ,x_msg_data => x_msg_data
3679 );
3680 ELSE /* Bug 2920954 */
3681 PA_FIN_PLAN_UTILS.GET_RESOURCE_LIST_INFO(
3682 P_RESOURCE_LIST_ID => p_all_resource_list_id,
3683 X_RES_LIST_IS_UNCATEGORIZED => l_res_list_is_uncategorized,
3684 X_IS_RESOURCE_LIST_GROUPED => l_is_resource_list_grouped,
3685 X_GROUP_RESOURCE_TYPE_ID => l_group_resource_type_id,
3686 X_RETURN_STATUS => x_return_status,
3687 X_MSG_COUNT => x_msg_count,
3688 X_MSG_DATA => x_msg_data
3689 );
3690 IF l_res_list_is_uncategorized = 'N' THEN
3691 l_res_planning_level := PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R;
3692 ELSE
3693 l_res_planning_level := NULL;
3694 END IF;
3695
3696 pa_debug.g_err_stage := 'Resource Planning Level is '||l_res_planning_level;
3697 IF P_PA_DEBUG_MODE = 'Y' THEN
3698 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.g_err_stage,3);
3699 END IF;
3700
3701 UPDATE pa_fp_elements
3702 SET resource_planning_level = l_res_planning_level
3703 ,resources_planned_for_task = 'N' --for bug 2676456
3704 ,record_version_number = record_version_number + 1
3705 ,last_update_date = sysdate
3706 ,last_updated_by = FND_GLOBAL.USER_ID
3707 ,last_update_login = FND_GLOBAL.LOGIN_ID
3708 WHERE proj_fp_options_id = p_proj_fp_options_id
3709 AND element_type = p_element_type;
3710 END IF; /* Bug 2920954 */
3711
3712 END IF;
3713 pa_debug.reset_err_stack;
3714
3715 EXCEPTION
3716 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
3717 l_msg_count := FND_MSG_PUB.count_msg;
3718 IF l_msg_count = 1 THEN
3719 PA_INTERFACE_UTILS_PUB.get_messages
3720 (p_encoded => FND_API.G_TRUE,
3721 p_msg_index => 1,
3722 p_msg_count => l_msg_count,
3723 p_msg_data => l_msg_data,
3724 p_data => l_data,
3725 p_msg_index_out => l_msg_index_out);
3726 x_msg_data := l_data;
3727 x_msg_count := l_msg_count;
3728 ELSE
3729 x_msg_count := l_msg_count;
3730 END IF;
3731 pa_debug.reset_err_stack;
3732 RETURN;
3733
3734 WHEN OTHERS THEN
3735 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3736 x_msg_count := 1;
3737 x_msg_data := SQLERRM;
3738 FND_MSG_PUB.add_exc_msg
3739 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB.refresh_res_list_changes'
3740 ,p_procedure_name => pa_debug.G_Err_Stack );
3741 IF P_PA_DEBUG_MODE = 'Y' THEN
3742 pa_debug.write('refresh_res_list_changes: ' || l_module_name,SQLERRM,4);
3743 pa_debug.write('refresh_res_list_changes: ' || l_module_name,pa_debug.G_Err_Stack,4);
3744 END IF;
3745 pa_debug.reset_err_stack;
3746
3747 raise FND_API.G_EXC_UNEXPECTED_ERROR;
3748 END refresh_res_list_changes;
3749
3750 /*
3751 This API creates resource assignments and elements for a budget version.
3752 The API expects that the necessary data(only) to create the above two are available in
3753 pa_fp_rollup_tmp table(task_id in system_reference1 and resource_list_member_id in
3754 system_reference2). The resource assignment id contains -1 if the RA id doesnot exist.
3755 */
3756 PROCEDURE CREATE_ASSGMT_FROM_ROLLUPTMP
3757 ( p_fin_plan_version_id IN pa_budget_versions.budget_version_id%TYPE
3758 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
3759 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
3760 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
3761
3762 AS
3763
3764 l_msg_count NUMBER := 0;
3765 l_data VARCHAR2(2000);
3766 l_msg_data VARCHAR2(2000);
3767 l_error_msg_code VARCHAR2(30);
3768 l_msg_index_out NUMBER;
3769 l_return_status VARCHAR2(1);
3770 l_debug_mode VARCHAR2(30);
3771
3772
3773 /* Bug 2677597 - introduced the following types and commented out the rest */
3774 l_task_id_tbl l_task_id_tbl_typ;
3775 l_res_list_mem_id_tbl l_res_list_mem_id_tbl_typ ;
3776 l_unit_of_measure_tbl l_unit_of_measure_tbl_typ ;
3777 l_track_as_labor_flag_tbl l_track_as_labor_flag_tbl_typ ;
3778
3779 --l_task_id_tbl pa_fp_rollup_pkg.l_task_id_tbl_typ;
3780 --l_res_list_mem_id_tbl pa_fp_rollup_pkg.l_res_list_mem_id_tbl_typ;
3781 --l_unit_of_measure_tbl pa_fp_rollup_pkg.l_unit_of_measure_tbl_typ;
3782 --l_track_as_labor_flag_tbl pa_fp_rollup_pkg.l_track_as_labor_flag_tbl_typ;
3783 --l_proj_raw_cost_tbl pa_fp_rollup_pkg.l_proj_raw_cost_tbl_typ;
3784 --l_proj_burdened_cost_tbl pa_fp_rollup_pkg.l_proj_burd_cost_tbl_typ;
3785 --l_proj_revenue_tbl pa_fp_rollup_pkg.l_proj_revenue_tbl_typ;
3786 --l_projfunc_raw_cost_tbl pa_fp_rollup_pkg.l_projfunc_raw_cost_tbl_typ;
3787 --l_projfunc_burd_cost_tbl pa_fp_rollup_pkg.l_projfunc_burd_cost_tbl_typ;
3788 --l_projfunc_revenue_tbl pa_fp_rollup_pkg.l_projfunc_revenue_tbl_typ;
3789 --l_quantity_tbl pa_fp_rollup_pkg.l_quantity_tbl_typ;
3790 /* Bug 2677597 - declaration change end */
3791
3792 l_project_id pa_projects_all.project_id%TYPE;
3793 l_fp_options_id pa_proj_fp_options.proj_fp_options_id%TYPE;
3794 l_element_type pa_fp_elements.element_type%TYPE;
3795 l_resource_list_id pa_budget_versions.resource_list_id%TYPE;
3796 l_mixed_resource_planned_flag VARCHAR2(1); -- Added for Bug:- 2625872
3797
3798 --Bug # 3507156 : Patchset M: B and F impact changes : AMG
3799 --Added some variables.
3800 l_context VARCHAR2(30);
3801 l_task_elem_version_id_tbl SYSTEM.PA_NUM_TBL_TYPE := SYSTEM.PA_NUM_TBL_TYPE();
3802 l_resource_list_member_id_tbl SYSTEM.PA_NUM_TBL_TYPE := SYSTEM.PA_NUM_TBL_TYPE();
3803 -- Added for CBS 16598322
3804 l_cbs_element_id_tbl SYSTEM.PA_NUM_TBL_TYPE := SYSTEM.PA_NUM_TBL_TYPE();
3805 l_rlm_id_tbl_tmp SYSTEM.PA_NUM_TBL_TYPE := SYSTEM.PA_NUM_TBL_TYPE();
3806 /*Bug # 3622551 --Added some parameters */
3807
3808 l_parent_structure_version_id pa_proj_element_versions.parent_structure_version_id%TYPE ;
3809 l_task_id_tmp_tbl SYSTEM.pa_num_tbl_type := SYSTEM.PA_NUM_TBL_TYPE();
3810
3811
3812 /*Bug # 3622551 -- Added a join to the cursor to get the value of wbs_element_version_id*/
3813 CURSOR res_assign_cur(c_version_id NUMBER
3814 ,c_parent_structure_version_id pa_proj_element_versions.parent_structure_version_id%TYPE) IS
3815 select distinct system_reference1 task_id
3816 ,system_reference2 resource_list_member_id
3817 ,system_reference3 CBS_ELEMENT_ID -- Added for CBS 16598322
3818 ,system_reference4 unit_of_measure
3819 ,system_reference5 track_as_labor_flag
3820 ,decode(rollup.system_reference1,0,0,pelm.element_version_id) wbs_element_version_id
3821 /* included null columns after UT */
3822 -- ,null proj_raw_cost /* Bug 2677597 */
3823 -- ,null proj_burdened_cost
3824 -- ,null proj_revenue
3825 -- ,null projfunc_raw_cost
3826 -- ,null projfunc_burd_cost
3827 -- ,null projfunc_revenue
3828 -- ,null quantity
3829 from pa_fp_rollup_tmp rollup
3830 ,pa_proj_element_versions pelm
3831 where not exists
3832 (
3833 select pra.resource_assignment_id
3834 from pa_resource_assignments pra
3835 where pra.task_id=rollup.system_reference1
3836 and pra.project_id = pelm.project_id --Bug #16297013
3837 and pra.resource_list_member_id = rollup.system_reference2
3838 and NVL(pra.cbs_element_id,-1) = NVL(rollup.system_reference3,-1) -- Added for CBS 16598322
3839 and pra.budget_version_id = c_version_id
3840 )
3841 and decode(rollup.system_reference1,0,c_parent_structure_version_id,rollup.system_reference1)
3842 = decode(rollup.system_reference1,0,pelm.element_version_id,pelm.proj_element_id) -- Bug 3655290
3843 and pelm.parent_structure_version_id = c_parent_structure_version_id
3844 order by task_id,resource_list_member_id;
3845
3846 --Bug # 3507156 : Patchset M: B and F impact changes : AMG
3847 --Added a curosr to get the value of plan_class_code
3848
3849 CURSOR get_context_csr IS
3850 SELECT pfp.plan_class_code FROM pa_fin_plan_types_b pfp,pa_budget_versions pbv
3851 WHERE pfp.FIN_PLAN_TYPE_ID = pbv.FIN_PLAN_TYPE_ID
3852 AND pbv.budget_version_id =p_fin_plan_version_id ;
3853
3854 BEGIN
3855
3856 x_msg_count := 0;
3857 x_return_status := FND_API.G_RET_STS_SUCCESS;
3858 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.CREATE_ASSGMT_FROM_ROLLUPTMP');
3859 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
3860 l_debug_mode := NVL(l_debug_mode, 'Y');
3861 IF P_PA_DEBUG_MODE = 'Y' THEN
3862 pa_debug.set_process('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || 'PLSQL','LOG',l_debug_mode);
3863 END IF;
3864
3865 -- Check for business rules violations
3866
3867 pa_debug.g_err_stage:= 'Validating input parameters';
3868 IF P_PA_DEBUG_MODE = 'Y' THEN
3869 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3870 END IF;
3871
3872 --Validate plan version id
3873
3874 IF (p_fin_plan_version_id IS NULL)
3875 THEN
3876
3877 pa_debug.g_err_stage:= 'fin_plan_version_id = '|| p_fin_plan_version_id;
3878 IF P_PA_DEBUG_MODE = 'Y' THEN
3879 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
3880 END IF;
3881
3882 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3883 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
3884
3885 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3886 END IF;
3887
3888 pa_debug.g_err_stage:= 'Obtain the relevant parameters for the version';
3889 IF P_PA_DEBUG_MODE = 'Y' THEN
3890 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3891 END IF;
3892
3893 BEGIN
3894 select opt.project_id,
3895 opt.proj_fp_options_id,
3896 pbv.version_type, -- Version type and element type are used interchangeably.
3897 pbv.resource_list_id
3898 into
3899 l_project_id
3900 ,l_fp_options_id
3901 ,l_element_type
3902 ,l_resource_list_id
3903 from pa_proj_fp_options opt,pa_budget_versions pbv
3904 where opt.fin_plan_version_id = pbv.budget_version_id
3905 and pbv.budget_version_id = p_fin_plan_version_id;
3906 EXCEPTION
3907 WHEN NO_DATA_FOUND THEN
3908 pa_debug.g_err_stage:= 'Could not get the details of the plan version option';
3909 IF P_PA_DEBUG_MODE = 'Y' THEN
3910 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3911 END IF;
3912 RAISE;
3913 END;
3914
3915 pa_debug.g_err_stage:= 'Create resource assignments - Bulk collect into the plsql tables';
3916 IF P_PA_DEBUG_MODE = 'Y' THEN
3917 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3918 END IF;
3919
3920 /*Bug # 3622551 -- Get the value of l_parent_structure_version_id */
3921 l_parent_structure_version_id := pa_project_structure_utils.get_fin_struc_ver_id(l_project_id);
3922
3923 OPEN res_assign_cur(p_fin_plan_version_id,l_parent_structure_version_id);
3924 LOOP
3925
3926 FETCH res_assign_cur
3927 BULK COLLECT INTO l_task_id_tbl
3928 ,l_resource_list_member_id_tbl
3929 ,l_cbs_element_id_tbl --- Added for CBS 16598322
3930 ,l_unit_of_measure_tbl
3931 ,l_track_as_labor_flag_tbl
3932 ,l_task_elem_version_id_tbl
3933 -- ,l_proj_raw_cost_tbl /* Bug 2677597 */
3934 -- ,l_proj_burdened_cost_tbl
3935 -- ,l_proj_revenue_tbl
3936 -- ,l_projfunc_raw_cost_tbl
3937 -- ,l_projfunc_burd_cost_tbl
3938 -- ,l_projfunc_revenue_tbl
3939 -- ,l_quantity_tbl
3940 LIMIT g_plsql_max_array_size;
3941
3942 pa_debug.g_err_stage:= 'Create resource assignments - Call the API';
3943 IF P_PA_DEBUG_MODE = 'Y' THEN
3944 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3945 END IF;
3946
3947 -- getting the context
3948 OPEN get_context_csr ;
3949 FETCH get_context_csr INTO l_context ;
3950 CLOSE get_context_csr ;
3951
3952 IF(nvl(l_task_id_tbl.last,0) > 0) THEN
3953 /* Bug 4200168: calling add_planning_transactions with p_one_to_one_mapping as Y
3954 * and discarding the earlier logic to pass the cartesian product for task_id and rlm_id
3955 */
3956 pa_fp_planning_transaction_pub.add_planning_transactions
3957 (
3958 p_context => l_context
3959 ,p_one_to_one_mapping_flag => 'Y' /*Bug 4200168*/
3960 ,p_calling_module => 'CREATE_VERSION' -- Bug 3655290
3961 ,p_project_id => l_project_id
3962 ,p_budget_version_id => p_fin_plan_version_id
3963 ,p_task_elem_version_id_tbl => l_task_elem_version_id_tbl
3964 ,p_resource_list_member_id_tbl => l_resource_list_member_id_tbl
3965 ,p_cbs_element_id_tbl => l_cbs_element_id_tbl -- Added for CBS 16598322
3966 ,x_return_status => x_return_status
3967 ,x_msg_count => x_msg_count
3968 ,x_msg_data => x_msg_data
3969 );
3970
3971 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
3972 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3973 END IF;
3974
3975 END IF;
3976 EXIT WHEN nvl(l_task_id_tbl.last,0) < g_plsql_max_array_size;
3977 END LOOP;
3978
3979 --Update the roll up tmp table with the newly created resource assignment id.
3980 update pa_fp_rollup_tmp rollup
3981 set resource_assignment_id =
3982 (
3983 select resource_assignment_id
3984 from pa_resource_assignments ra
3985 where ra.budget_version_id = p_fin_plan_version_id
3986 and ra.task_id = rollup.system_reference1
3987 and ra.resource_list_member_id = rollup.system_reference2
3988 and NVL(ra.cbs_element_id,-1) = NVL(rollup.system_reference3,-1)
3989 and ra.resource_assignment_id IS NOT NULL
3990 );
3991 pa_debug.g_err_stage:= 'No of records updated in rollup tmp-> ' || sql%rowcount;
3992 IF P_PA_DEBUG_MODE = 'Y' THEN
3993 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3994 END IF;
3995
3996
3997 EXCEPTION
3998
3999 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
4000
4001 x_return_status := FND_API.G_RET_STS_ERROR;
4002 l_msg_count := FND_MSG_PUB.count_msg;
4003 IF l_msg_count = 1 THEN
4004 PA_INTERFACE_UTILS_PUB.get_messages
4005 (p_encoded => FND_API.G_TRUE
4006 ,p_msg_index => 1
4007 ,p_msg_count => l_msg_count
4008 ,p_msg_data => l_msg_data
4009 ,p_data => l_data
4010 ,p_msg_index_out => l_msg_index_out);
4011 x_msg_data := l_data;
4012 x_msg_count := l_msg_count;
4013 ELSE
4014 x_msg_count := l_msg_count;
4015 END IF;
4016
4017 pa_debug.g_err_stage:= 'Invalid Arguments Passed';
4018 IF P_PA_DEBUG_MODE = 'Y' THEN
4019 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4020 END IF;
4021 pa_debug.reset_err_stack;
4022 RAISE;
4023
4024 WHEN others THEN
4025
4026 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4027 x_msg_count := 1;
4028 x_msg_data := SQLERRM;
4029 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
4030 ,p_procedure_name => 'CREATE_ASSGMT_FROM_ROLLUPTMP');
4031 pa_debug.g_err_stage:= 'Unexpected Error'||SQLERRM;
4032 IF P_PA_DEBUG_MODE = 'Y' THEN
4033 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4034 END IF;
4035 pa_debug.reset_err_stack;
4036 RAISE;
4037
4038 END CREATE_ASSGMT_FROM_ROLLUPTMP;
4039
4040 /*==============================================================================
4041 This is a private api called from Create_CI_Resource_Assignments api for
4042 insertion of a record into PA_RESOURCE_ASSIGNMENTS package.
4043 ===============================================================================*/
4044
4045 PROCEDURE Insert_Resource_Assignment(
4046 p_project_id IN pa_resource_assignments.project_id%TYPE
4047 ,p_budget_version_id IN pa_resource_assignments.budget_version_id%TYPE
4048 ,p_task_id IN pa_resource_assignments.task_id%TYPE
4049 ,p_resource_list_member_id IN pa_resource_assignments.resource_list_member_id%TYPE
4050 ,p_unit_of_measure IN pa_resource_assignments.unit_of_measure%TYPE
4051 ,p_track_as_labor_flag IN pa_resource_assignments.track_as_labor_flag%TYPE )
4052 AS
4053
4054 l_row_id rowid;
4055 l_return_status VARCHAR2(30);
4056 l_resource_assignment_id pa_resource_assignments.resource_assignment_id%TYPE;
4057
4058 BEGIN
4059
4060 PA_FP_RESOURCE_ASSIGNMENTS_PKG.Insert_Row
4061 ( px_resource_assignment_id => l_resource_assignment_id
4062 ,p_budget_version_id => p_budget_version_id
4063 ,p_project_id => p_project_id
4064 ,p_task_id => p_task_id
4065 ,p_resource_list_member_id => p_resource_list_member_id
4066 ,p_unit_of_measure => p_unit_of_measure
4067 ,p_track_as_labor_flag => p_track_as_labor_flag
4068 ,p_standard_bill_rate => NULL
4069 ,p_average_bill_rate => NULL
4070 ,p_average_cost_rate => NULL
4071 ,p_project_assignment_id => -1
4072 ,p_plan_error_code => NULL
4073 ,p_total_plan_revenue => NULL
4074 ,p_total_plan_raw_cost => NULL
4075 ,p_total_plan_burdened_cost => NULL
4076 ,p_total_plan_quantity => NULL
4077 ,p_average_discount_percentage => NULL
4078 ,p_total_borrowed_revenue => NULL
4079 ,p_total_tp_revenue_in => NULL
4080 ,p_total_tp_revenue_out => NULL
4081 ,p_total_revenue_adj => NULL
4082 ,p_total_lent_resource_cost => NULL
4083 ,p_total_tp_cost_in => NULL
4084 ,p_total_tp_cost_out => NULL
4085 ,p_total_cost_adj => NULL
4086 ,p_total_unassigned_time_cost => NULL
4087 ,p_total_utilization_percent => NULL
4088 ,p_total_utilization_hours => NULL
4089 ,p_total_utilization_adj => NULL
4090 ,p_total_capacity => NULL
4091 ,p_total_head_count => NULL
4092 ,p_total_head_count_adj => NULL
4093 ,p_resource_assignment_type => PA_FP_CONSTANTS_PKG.G_USER_ENTERED
4094 ,p_total_project_raw_cost => NULL
4095 ,p_total_project_burdened_cost => NULL
4096 ,p_total_project_revenue => NULL
4097 ,p_parent_assignment_id => NULL
4098 ,x_row_id => l_row_id
4099 ,x_return_status => l_return_status);
4100
4101 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4102 pa_debug.g_err_stage:= 'Exception while inserting a row into pa_resource_assignments;';
4103 IF P_PA_DEBUG_MODE = 'Y' THEN
4104 pa_debug.write('Insert_Resource_Assignment: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4105 END IF;
4106 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4107 END IF;
4108 END Insert_Resource_Assignment;
4109
4110 /*==============================================================================
4111 This api is called to create resource assignments during creation of CI budget
4112 version for a given impacted task id.
4113 ===============================================================================*/
4114
4115 --
4116 -- 01-JUL-2003 jwhite - Bug 2989874
4117 -- For Create_CI_Resource_Assignment,
4118 -- default ci from the current working version.
4119
4120 -- 12-APR-2004 dbora FP.M Changes
4121 -- 13-MAY-2004 rravipat Bug 3615617
4122 -- Create_res_task_maps api specification has changed
4123 -- target resource list member id should be derived and
4124 -- passed to the api
4125
4126 PROCEDURE Create_CI_Resource_Assignments
4127 ( p_project_id IN pa_budget_versions.project_id%TYPE
4128 ,p_budget_version_id IN pa_budget_versions.budget_version_id%TYPE
4129 ,p_version_type IN pa_budget_versions.version_type%TYPE
4130 ,p_impacted_task_id IN pa_resource_assignments.task_id%TYPE
4131 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
4132 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
4133 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
4134 AS
4135
4136 l_msg_count NUMBER := 0;
4137 l_data VARCHAR2(2000);
4138 l_msg_data VARCHAR2(2000);
4139 l_error_msg_code VARCHAR2(30);
4140 l_msg_index_out NUMBER;
4141 l_return_status VARCHAR2(2000);
4142 l_debug_mode VARCHAR2(30);
4143
4144 l_err_code NUMBER;
4145 l_err_stage VARCHAR2(100);
4146 l_err_stack VARCHAR2(1000);
4147
4148 l_no_of_records_processed NUMBER;
4149 l_count NUMBER;
4150
4151 l_fin_plan_type_id pa_proj_fp_options.fin_plan_type_id%TYPE;
4152
4153 -- Bug Fix: 4569365. Removed MRC code.
4154 -- l_calling_context pa_mrc_finplan.g_calling_module%TYPE;
4155 l_calling_context VARCHAR2(30);
4156
4157 l_ci_apprv_cw_bv_id pa_budget_versions.budget_version_id%TYPE :=NULL;
4158 l_plan_version_planning_level pa_proj_fp_options.all_fin_plan_level_code%TYPE;
4159
4160 /* PL/SQL table types to be passed to create_res_task_map */
4161
4162 l_src_ra_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4163 l_src_elem_ver_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4164 l_targ_elem_ver_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4165 l_targ_proj_assmt_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4166 l_planning_start_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4167 l_planning_end_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4168 l_schedule_start_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4169 l_schedule_end_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4170 l_targ_rlm_id_tbl SYSTEM.PA_NUM_TBL_TYPE; -- bug 3615617
4171
4172 /* The existing cursors were replaced by the following cursors to get the resource assignments
4173 * for the impacted task, or its childrens or its parent's childrens as the case may be
4174 */
4175
4176 CURSOR impacted_task_cur(c_impacted_task_id pa_tasks.task_id%TYPE) IS
4177 SELECT parent_task_id,
4178 top_task_id
4179 FROM pa_tasks
4180 WHERE task_id = c_impacted_task_id;
4181
4182 impacted_task_rec impacted_task_cur%ROWTYPE;
4183
4184 CURSOR cur_elements_for_project IS
4185 SELECT pra.resource_assignment_id,
4186 pra.wbs_element_version_id, -- This column is selected so that it can be passed, to create_res_task_maps. One for source and one for target.
4187 pra.wbs_element_version_id, -- This would be null for budgets and forecasts!
4188 pra.project_assignment_id, -- This would be -1 for Budgets and Forecasts
4189 pra.planning_start_date,
4190 pra.planning_end_date,
4191 pra.schedule_start_date,
4192 pra.schedule_end_date,
4193 pra.resource_list_member_id -- Bug 3615617
4194 FROM pa_resource_assignments pra
4195 WHERE pra.budget_version_id = l_ci_apprv_cw_bv_id;
4196
4197 CURSOR cur_elements_for_task (c_task_id pa_tasks.task_id%TYPE) IS
4198 SELECT pra.resource_assignment_id,
4199 pra.wbs_element_version_id, -- This column is selected so that it can be passed, to create_res_task_maps. One for source and one for target.
4200 pra.wbs_element_version_id, -- This would be null for budgets and forecasts!
4201 pra.project_assignment_id, -- This would be -1 for Budgets and Forecasts
4202 pra.planning_start_date,
4203 pra.planning_end_date,
4204 pra.schedule_start_date,
4205 pra.schedule_end_date,
4206 pra.resource_list_member_id -- Bug 3615617
4207 FROM pa_resource_assignments pra
4208 WHERE pra.budget_version_id = l_ci_apprv_cw_bv_id
4209 AND pra.task_id IN (SELECT t.task_id
4210 FROM pa_tasks t
4211 WHERE t.project_id = p_project_id
4212 CONNECT BY PRIOR t.task_id = t.parent_task_id
4213 START WITH t.task_id = c_task_id);
4214
4215 BEGIN
4216
4217 x_msg_count := 0;
4218 x_return_status := FND_API.G_RET_STS_SUCCESS;
4219 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.Create_CI_Resource_Assignments');
4220 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
4221 l_debug_mode := NVL(l_debug_mode, 'Y');
4222 IF P_PA_DEBUG_MODE = 'Y' THEN
4223 pa_debug.set_process('Create_CI_Resource_Assignments: ' || 'PLSQL','LOG',l_debug_mode);
4224 END IF;
4225
4226 -- Check for business rules violations
4227
4228 IF P_PA_DEBUG_MODE = 'Y' THEN
4229 pa_debug.g_err_stage:= 'Validating input parameters';
4230 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4231 END IF;
4232
4233 --Check if plan version id is null
4234
4235 IF (p_project_id IS NULL) OR
4236 (p_budget_version_id IS NULL) OR
4237 (p_impacted_task_id IS NULL) OR
4238 (p_version_type IS NULL)
4239 THEN
4240 IF P_PA_DEBUG_MODE = 'Y' THEN
4241 pa_debug.g_err_stage:= 'p_project_id = '||p_project_id;
4242 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4243
4244 pa_debug.g_err_stage:= 'p_budget_version_id = '||p_budget_version_id;
4245 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4246
4247 pa_debug.g_err_stage:= 'p_impacted_task_id = '||p_impacted_task_id;
4248 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4249
4250 pa_debug.g_err_stage:= 'p_version_type = '||p_version_type;
4251 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4252 END IF;
4253
4254 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
4255 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4256
4257 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4258 END IF;
4259
4260 -- Fetch the plan type fp options id and resource list attached
4261
4262 BEGIN
4263 SELECT bv.fin_plan_type_id
4264 INTO l_fin_plan_type_id
4265 FROM pa_budget_versions bv
4266 WHERE budget_version_id = p_budget_version_id;
4267 EXCEPTION
4268 WHEN OTHERS THEN
4269 pa_debug.g_err_stage:= 'Failed to fetch plan type and resource list for given budget version';
4270 IF P_PA_DEBUG_MODE = 'Y' THEN
4271 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4272 END IF;
4273 RAISE;
4274 END;
4275
4276 l_plan_version_planning_level := Pa_Fin_Plan_Utils.Get_Fin_Plan_Level_Code(
4277 p_fin_plan_version_id => p_budget_version_id);
4278
4279 -- Fetch current working approved budget version id
4280 Pa_Fp_Control_Items_Utils.CHK_APRV_CUR_WORKING_BV_EXISTS(
4281 p_project_id => p_project_id,
4282 p_fin_plan_type_id => l_fin_plan_type_id,
4283 p_version_type => p_version_type,
4284 x_cur_work_bv_id => l_ci_apprv_cw_bv_id,
4285 x_return_status => l_return_status,
4286 x_msg_count => l_msg_count,
4287 x_msg_data => l_msg_data );
4288 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4289 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4290 END IF;
4291
4292 /* Bug# 2676352 - Creating plannable elements based on the impacted task is ONLY applicable
4293 if the plan type level planning level is Task level.
4294
4295 If planning level is Project, only create the plannable resources, if using a resource list.
4296 Otherwise, just one resource assignment for entire project when not using a resource list.
4297
4298 Please refer bug for compelete business rules.
4299 */
4300
4301 IF l_plan_version_planning_level = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
4302
4303 pa_debug.g_err_stage := 'Planning level of the plan version is project ..';
4304 IF P_PA_DEBUG_MODE = 'Y' THEN
4305 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4306 END IF;
4307
4308 OPEN cur_elements_for_project;
4309 FETCH cur_elements_for_project BULK COLLECT INTO
4310 l_src_ra_id_tbl,
4311 l_src_elem_ver_id_tbl,
4312 l_targ_elem_ver_id_tbl,
4313 l_targ_proj_assmt_id_tbl,
4314 l_planning_start_date_tbl,
4315 l_planning_end_date_tbl,
4316 l_schedule_start_date_tbl,
4317 l_schedule_end_date_tbl,
4318 l_targ_rlm_id_tbl; -- Bug 3615617
4319 CLOSE cur_elements_for_project;
4320
4321 IF l_src_ra_id_tbl.count > 0 THEN
4322
4323 IF P_PA_DEBUG_MODE = 'Y' THEN
4324 pa_debug.g_err_stage := 'Calling create_res_task_map';
4325 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4326 END IF;
4327
4328 pa_fp_copy_from_pkg.create_res_task_maps(
4329 p_context => 'BUDGET'
4330 ,p_src_ra_id_tbl => l_src_ra_id_tbl
4331 ,p_src_elem_ver_id_tbl => l_src_elem_ver_id_tbl
4332 ,p_targ_elem_ver_id_tbl => l_targ_elem_ver_id_tbl
4333 ,p_targ_proj_assmt_id_tbl => l_targ_proj_assmt_id_tbl
4334 ,p_targ_rlm_id_tbl => l_targ_rlm_id_tbl -- Bug 3615617
4335 ,p_planning_start_date_tbl => l_planning_start_date_tbl
4336 ,p_planning_end_date_tbl => l_planning_end_date_tbl
4337 ,p_schedule_start_date_tbl => l_schedule_start_date_tbl
4338 ,p_schedule_end_date_tbl => l_schedule_end_date_tbl
4339 ,x_return_status => l_return_status
4340 ,x_msg_count => l_msg_count
4341 ,x_msg_data => l_msg_data );
4342
4343 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4344 IF P_PA_DEBUG_MODE = 'Y' THEN
4345 pa_debug.g_err_stage := 'The call to create_res_task_map returned with error';
4346 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4347 END IF;
4348 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4349 END IF;
4350
4351 IF P_PA_DEBUG_MODE = 'Y' THEN
4352 pa_debug.g_err_stage := 'copy_resource_assignments';
4353 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4354 END IF;
4355 pa_fp_copy_from_pkg.copy_resource_assignments(
4356 p_source_plan_version_id => l_ci_apprv_cw_bv_id
4357 ,p_target_plan_version_id => p_budget_version_id
4358 ,p_adj_percentage => -99
4359 -- Bug 4200168
4360 ,p_calling_context => 'CI'
4361 ,x_return_status => l_return_status
4362 ,x_msg_count => l_msg_count
4363 ,x_msg_data => l_msg_data );
4364
4365 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4366 IF P_PA_DEBUG_MODE = 'Y' THEN
4367 pa_debug.g_err_stage := 'The call to copy_resource_assignments returned with error';
4368 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4369 END IF;
4370 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4371 END IF;
4372 END IF; /* l_src_ra_id_tbl.count > 0 */
4373
4374 ELSE /* Task level planning */
4375
4376 OPEN cur_elements_for_task(p_impacted_task_id);
4377 FETCH cur_elements_for_task BULK COLLECT INTO
4378 l_src_ra_id_tbl,
4379 l_src_elem_ver_id_tbl,
4380 l_targ_elem_ver_id_tbl,
4381 l_targ_proj_assmt_id_tbl,
4382 l_planning_start_date_tbl,
4383 l_planning_end_date_tbl,
4384 l_schedule_start_date_tbl,
4385 l_schedule_end_date_tbl,
4386 l_targ_rlm_id_tbl; -- Bug 3615617
4387 CLOSE cur_elements_for_task;
4388
4389 IF l_src_ra_id_tbl.count = 0 THEN
4390
4391 OPEN impacted_task_cur(p_impacted_task_id);
4392 FETCH impacted_task_cur INTO impacted_task_rec;
4393 CLOSE impacted_task_cur;
4394
4395 IF impacted_task_rec.top_task_id = p_impacted_task_id THEN
4396
4397 /* No record are there to be inserted. Ideally, control should never come
4398 * here since is_create_ci_version_Allowed should have caught this case and
4399 * thrown an error! */
4400 null;
4401 ELSE
4402 OPEN cur_elements_for_task(impacted_task_rec.top_task_id);
4403 FETCH cur_elements_for_task BULK COLLECT INTO
4404 l_src_ra_id_tbl,
4405 l_src_elem_ver_id_tbl,
4406 l_targ_elem_ver_id_tbl,
4407 l_targ_proj_assmt_id_tbl,
4408 l_planning_start_date_tbl,
4409 l_planning_end_date_tbl,
4410 l_schedule_start_date_tbl,
4411 l_schedule_end_date_tbl,
4412 l_targ_rlm_id_tbl; -- Bug 3615617
4413 CLOSE cur_elements_for_task;
4414 END IF;
4415 END IF;
4416
4417 IF l_src_ra_id_tbl.count = 0 THEN
4418 /* No record are there to be inserted. Ideally, control should never come here since
4419 * is_create_ci_version_Allowed should have caught this case and thrown an error! */
4420 null;
4421 ELSE
4422 IF P_PA_DEBUG_MODE = 'Y' THEN
4423 pa_debug.g_err_stage := 'Calling create_res_task_map';
4424 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4425 END IF;
4426
4427 pa_fp_copy_from_pkg.create_res_task_maps(
4428 p_context => 'BUDGET'
4429 ,p_src_ra_id_tbl => l_src_ra_id_tbl
4430 ,p_src_elem_ver_id_tbl => l_src_elem_ver_id_tbl
4431 ,p_targ_elem_ver_id_tbl => l_targ_elem_ver_id_tbl
4432 ,p_targ_proj_assmt_id_tbl => l_targ_proj_assmt_id_tbl
4433 ,p_targ_rlm_id_tbl => l_targ_rlm_id_tbl -- Bug 3615617
4434 ,p_planning_start_date_tbl => l_planning_start_date_tbl
4435 ,p_planning_end_date_tbl => l_planning_end_date_tbl
4436 ,p_schedule_start_date_tbl => l_schedule_start_date_tbl
4437 ,p_schedule_end_date_tbl => l_schedule_end_date_tbl
4438 ,x_return_status => l_return_status
4439 ,x_msg_count => l_msg_count
4440 ,x_msg_data => l_msg_data );
4441
4442 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4443 IF P_PA_DEBUG_MODE = 'Y' THEN
4444 pa_debug.g_err_stage := 'The call to create_res_task_map returned with error';
4445 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4446 END IF;
4447 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4448 END IF;
4449
4450 IF P_PA_DEBUG_MODE = 'Y' THEN
4451 pa_debug.g_err_stage := 'copy_resource_assignments';
4452 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4453 END IF;
4454 pa_fp_copy_from_pkg.copy_resource_assignments(
4455 p_source_plan_version_id => l_ci_apprv_cw_bv_id
4456 ,p_target_plan_version_id => p_budget_version_id
4457 ,p_adj_percentage => -99
4458 -- Bug 4200168
4459 ,p_calling_context => 'CI'
4460 ,x_return_status => l_return_status
4461 ,x_msg_count => l_msg_count
4462 ,x_msg_data => l_msg_data );
4463
4464 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4465 IF P_PA_DEBUG_MODE = 'Y' THEN
4466 pa_debug.g_err_stage := 'The call to copy_resource_assignments returned with error';
4467 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4468 END IF;
4469 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4470 END IF;
4471 END IF; /* l_src_ra_id_tbl.count > 0 */
4472
4473 END IF;
4474
4475 IF P_PA_DEBUG_MODE = 'Y' THEN
4476 pa_debug.g_err_stage:= 'Exiting Create_CI_Resource_Assignments';
4477 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4478 END IF;
4479 pa_debug.reset_err_stack;
4480
4481 EXCEPTION
4482
4483 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
4484
4485 x_return_status := FND_API.G_RET_STS_ERROR;
4486 l_msg_count := FND_MSG_PUB.count_msg;
4487 IF l_msg_count = 1 THEN
4488 PA_INTERFACE_UTILS_PUB.get_messages
4489 (p_encoded => FND_API.G_TRUE
4490 ,p_msg_index => 1
4491 ,p_msg_count => l_msg_count
4492 ,p_msg_data => l_msg_data
4493 ,p_data => l_data
4494 ,p_msg_index_out => l_msg_index_out);
4495 x_msg_data := l_data;
4496 x_msg_count := l_msg_count;
4497 ELSE
4498 x_msg_count := l_msg_count;
4499 END IF;
4500
4501 pa_debug.g_err_stage:= 'Invalid Arguments Passed';
4502 IF P_PA_DEBUG_MODE = 'Y' THEN
4503 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4504 END IF;
4505 pa_debug.reset_err_stack;
4506 RAISE;
4507
4508 WHEN others THEN
4509
4510 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4511 x_msg_count := 1;
4512 x_msg_data := SQLERRM;
4513 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
4514 ,p_procedure_name => 'Create_CI_Resource_Assignments');
4515 pa_debug.g_err_stage:= 'Unexpected Error'||SQLERRM;
4516 IF P_PA_DEBUG_MODE = 'Y' THEN
4517 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4518 END IF;
4519 pa_debug.reset_err_stack;
4520 RAISE;
4521 END Create_CI_Resource_Assignments;
4522
4523 /*==================================================================
4524 When automatic resource selection is enabled for an option,this
4525 api inserts resources or resource group elements to a project
4526 or a pl/sql table of tasks based on the option planning level that
4527 is passed.
4528
4529 The api can also be called for an entire option in which case
4530 resource/ resource groups elements would be added to all the
4531 plannable tasks for that element type,fp option combination.
4532
4533 NOTE(S):-
4534 1. If the option planning level is project, the task_id tbl should
4535 contain one and only one record and that should be zero as we
4536 enter 0(zero) for task_id column in pa_fp_elements for project
4537 level planning options.
4538 ==================================================================*/
4539
4540 PROCEDURE Add_resources_automatically
4541 ( p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
4542 ,p_element_type IN pa_fp_elements.element_type%TYPE
4543 ,p_fin_plan_level_code IN pa_proj_fp_options.cost_fin_plan_level_code%TYPE
4544 ,p_resource_list_id IN pa_resource_lists_all_bg.resource_list_id%TYPE
4545 ,p_res_planning_level IN pa_proj_fp_options.cost_res_planning_level%TYPE
4546 ,p_entire_option IN VARCHAR2
4547 ,p_element_task_id_tbl IN pa_fp_elements_pub.l_task_id_tbl_typ
4548 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
4549 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
4550 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
4551 AS
4552
4553 l_msg_count NUMBER := 0;
4554 l_data VARCHAR2(2000);
4555 l_msg_data VARCHAR2(2000);
4556 l_msg_index_out NUMBER;
4557 l_return_status VARCHAR2(2000);
4558
4559 l_task_tbl_index NUMBER;
4560 l_rlm_tbl_index NUMBER;
4561 l_res_uncategorized_flag VARCHAR2(1);
4562 l_is_resource_list_grouped VARCHAR2(1);
4563 l_group_resource_type_id pa_resource_lists_all_bg.group_resource_type_id%TYPE;
4564
4565
4566 /*
4567 The following pl/sql tables are used to store task_id, top_task_id,
4568 resource_list_member_ids. The table types have defined in the package
4569 specification.
4570 */
4571 l_task_id_tbl l_task_id_tbl_typ;
4572 l_top_task_id_tbl l_top_task_id_tbl_typ;
4573 l_res_list_mem_id_tbl l_res_list_mem_id_tbl_typ;
4574
4575 /* The cursors used in the api*/
4576
4577 /*
4578 The following cursor is used to fetch project_id, plan_type_id
4579 based on the element type etc., for an option_id
4580 */
4581 CURSOR proj_fp_options_info_cur
4582 ( c_proj_fp_options_id pa_proj_fp_options.proj_fp_options_id%TYPE
4583 ,c_element_type pa_fp_elements.element_type%TYPE)
4584 IS
4585 SELECT project_id
4586 ,fin_plan_type_id
4587 ,fin_plan_version_id
4588 FROM pa_proj_fp_options
4589 WHERE proj_fp_options_id = c_proj_fp_options_id;
4590
4591 proj_fp_options_info_rec proj_fp_options_info_cur%ROWTYPE;
4592
4593 /*
4594 The following cursor is used to fetch all the tasks that can be
4595 planned for an option and element_type combination for automatic
4596 resource addition in the context of entire option
4597 */
4598 CURSOR all_plannable_tasks_cur
4599 ( c_proj_fp_options_id pa_proj_fp_options.proj_fp_options_id%TYPE
4600 ,c_element_type pa_fp_elements.element_type%TYPE)
4601 IS
4602 SELECT task_id
4603 ,top_task_id
4604 FROM pa_fp_elements
4605 WHERE proj_fp_options_id = c_proj_fp_options_id
4606 AND element_type = c_element_type
4607 AND resource_list_member_id = 0
4608 AND plannable_flag = 'Y';
4609
4610 /*
4611 The following cursor is used to fetch all the resource list
4612 members in case the input resource list is ungrouped.
4613 'UNCLASSIFIED' resource list member is filtered as that
4614 shouldn't be added to the option.
4615 */
4616 CURSOR ungrouped_res_cur
4617 ( c_resource_list_id pa_resource_lists_all_bg.resource_list_id%TYPE)
4618 IS
4619 SELECT resource_list_member_id
4620 FROM pa_resource_list_members
4621 WHERE resource_list_id = c_resource_list_id
4622 AND resource_type_code <> PA_FP_CONSTANTS_PKG.G_UNCLASSIFIED
4623 AND enabled_flag='Y' -- bug 3289243
4624 AND display_flag='Y'; -- bug 3289243
4625
4626 /*
4627 The following cursor is used to fetch all the resource list members
4628 in case the input resource list is grouped and resource planning level
4629 is Resource.'UNCLASSIFIED' resource list member is filtered as that
4630 shouldn't be added to the option.
4631 */
4632 CURSOR grouped_res_level_res_cur
4633 ( c_resource_list_id pa_resource_lists_all_bg.resource_list_id%TYPE)
4634 IS
4635 SELECT resource_list_member_id
4636 FROM pa_resource_list_members
4637 WHERE resource_list_id = c_resource_list_id
4638 AND resource_type_code <> PA_FP_CONSTANTS_PKG.G_UNCLASSIFIED
4639 AND enabled_flag='Y' -- bug 3289243
4640 AND display_flag='Y' -- bug 3289243
4641 AND parent_member_id IS NOT NULL; -- to filter all the resource group level records
4642
4643 /*
4644 The following cursor is used to fetch all the resource list members
4645 in case the input resource list is grouped and resource planning level
4646 is Resource Group.'UNCLASSIFIED' resource list member is filtered as that
4647 shouldn't be added to the option.
4648 */
4649 CURSOR grouped_resgrp_level_res_cur
4650 ( c_resource_list_id pa_resource_lists_all_bg.resource_list_id%TYPE)
4651 IS
4652 SELECT resource_list_member_id
4653 FROM pa_resource_list_members
4654 WHERE resource_list_id = c_resource_list_id
4655 AND resource_type_code <> PA_FP_CONSTANTS_PKG.G_UNCLASSIFIED
4656 AND enabled_flag='Y' -- bug 3289243
4657 AND display_flag='Y' -- bug 3289243
4658 AND parent_member_id IS NULL; -- to filter all the resource level records
4659
4660 BEGIN
4661 x_msg_count := 0;
4662 x_return_status := FND_API.G_RET_STS_SUCCESS;
4663 PA_DEBUG.Set_Curr_Function( p_function => 'Add_resources_automatically',
4664 p_debug_mode => p_pa_debug_mode );
4665
4666 -- Check for NOT NULL parameters
4667 IF (p_proj_fp_options_id IS NULL) OR
4668 (p_element_type IS NULL) OR
4669 (p_fin_plan_level_code IS NULL) OR
4670 (p_resource_list_id IS NULL) OR
4671 (p_res_planning_level IS NULL) OR
4672 (p_entire_option IS NULL)
4673 THEN
4674 IF p_pa_debug_mode = 'Y' THEN
4675 pa_debug.g_err_stage:= 'p_proj_fp_options_id = '|| p_proj_fp_options_id;
4676 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4677 pa_debug.g_err_stage:= 'p_element_type = '|| p_element_type;
4678 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4679 pa_debug.g_err_stage:= 'p_fin_plan_level_code = '|| p_fin_plan_level_code;
4680 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4681 pa_debug.g_err_stage:= 'p_resource_list_id = '|| p_resource_list_id;
4682 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4683 pa_debug.g_err_stage:= 'p_res_planning_level = '|| p_res_planning_level;
4684 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4685 pa_debug.g_err_stage:= 'p_entire_option = '|| p_entire_option;
4686 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4687 pa_debug.g_err_stage:= 'Invalid Arguments Passed';
4688 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4689 END IF;
4690 PA_UTILS.ADD_MESSAGE
4691 (p_app_short_name => 'PA',
4692 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4693 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4694 END IF;
4695
4696 -- Fetch project_id, plan_type_id for the i/p option, element_type
4697
4698 OPEN proj_fp_options_info_cur(p_proj_fp_options_id,p_element_type);
4699 FETCH proj_fp_options_info_cur INTO proj_fp_options_info_rec;
4700
4701 IF proj_fp_options_info_cur%NOTFOUND
4702 THEN
4703 IF p_pa_debug_mode = 'Y' THEN
4704 pa_debug.g_err_stage:= 'Unexpected error while fetching option_id Info for the option: '
4705 ||p_proj_fp_options_id||'the error message is: '||sqlerrm;
4706 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4707 END IF;
4708 PA_UTILS.ADD_MESSAGE
4709 (p_app_short_name => 'PA',
4710 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4711 CLOSE proj_fp_options_info_cur;
4712 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4713 END IF;
4714
4715 CLOSE proj_fp_options_info_cur;
4716
4717 /*
4718 If resources are to be added for an entire option we need to
4719 fetch all the plannable tasks for the option and element type.
4720 */
4721
4722 IF p_entire_option = 'Y'
4723 THEN
4724 /*
4725 If option planning level is 'Project', l_task_id_tbl
4726 table would contain only one record and top_task_id
4727 for this record is also populated as zero.
4728 Else fetch all the plannable tasks.
4729 */
4730 IF p_fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT
4731 THEN
4732 l_task_id_tbl(1) := 0;
4733 l_top_task_id_tbl(1) := 0;
4734 ELSE
4735 IF p_pa_debug_mode = 'Y' THEN
4736 pa_debug.g_err_stage:= 'Cursor all_plannable_tasks_cur is opened';
4737 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4738 END IF;
4739
4740 OPEN all_plannable_tasks_cur(p_proj_fp_options_id,p_element_type);
4741 FETCH all_plannable_tasks_cur
4742 BULK COLLECT INTO
4743 l_task_id_tbl
4744 ,l_top_task_id_tbl;
4745 CLOSE all_plannable_tasks_cur;
4746 END IF;
4747
4748 ELSE
4749
4750 -- If entire option is 'N', then table of pl/sql tables is passed as input
4751
4752 l_task_id_tbl := p_element_task_id_tbl;
4753
4754 IF l_task_id_tbl.count = 0
4755 THEN
4756 IF p_pa_debug_mode = 'Y' THEN
4757 pa_debug.g_err_stage:= 'l_task_id_Tbl is empty. Returning...';
4758 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4759 END IF;
4760 pa_debug.reset_curr_function;
4761 RETURN; -- as no tasks are to be processed.
4762 END IF;
4763
4764 /*
4765 If option planning level is 'Project', l_task_id_tbl
4766 table should contain only one record and top_task_id
4767 for this record is to be populated as zero.
4768 Else fetch top tasks all the tasks in the pl/sql table.
4769 */
4770
4771 IF p_fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT
4772 THEN
4773
4774 l_task_tbl_index := l_task_id_tbl.first;
4775
4776 IF (l_task_id_tbl.count <> 1) OR (l_task_id_tbl(l_task_tbl_index) <> 0)
4777 THEN
4778 IF p_pa_debug_mode = 'Y' THEN
4779 pa_debug.g_err_stage:= 'Invalid task(s) passed for project plan level case';
4780 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4781 END IF;
4782 PA_UTILS.ADD_MESSAGE
4783 (p_app_short_name => 'PA',
4784 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4785 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4786 ELSE
4787 l_top_task_id_tbl(l_task_tbl_index) := 0;
4788 END IF;
4789
4790 ELSE -- Option is not planned at project level
4791
4792 FOR l_task_tbl_index IN l_task_id_tbl.first .. l_task_id_tbl.last
4793 LOOP
4794
4795 IF p_pa_debug_mode = 'Y' THEN
4796 pa_debug.g_err_stage:= 'Fetching top task for each task_id';
4797 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4798 END IF;
4799
4800 BEGIN
4801 SELECT top_task_id
4802 INTO l_top_task_id_tbl(l_task_tbl_index)
4803 FROM pa_fp_elements
4804 WHERE proj_fp_options_id = p_proj_fp_options_id
4805 AND element_type = p_element_type
4806 AND task_id = l_task_id_tbl(l_task_tbl_index)
4807 AND resource_list_member_id = 0
4808 AND plannable_flag = 'Y';
4809 EXCEPTION
4810 WHEN NO_DATA_FOUND THEN
4811
4812 IF p_pa_debug_mode = 'Y' THEN
4813 pa_debug.g_err_stage:= 'While fetching top_task for the task: '
4814 ||l_task_id_tbl(l_task_tbl_index)|| 'Error is: '||sqlerrm;
4815 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4816 END IF;
4817 PA_UTILS.ADD_MESSAGE
4818 (p_app_short_name => 'PA',
4819 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4820 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4821 END;
4822 END LOOP;
4823
4824 END IF; -- Option planning level 'P' or not
4825
4826 END IF; -- entire option 'Y'/'N'
4827
4828 /*
4829 To know if the given resource list id is grouped/ ungrouped
4830 call pa_fin_plan_utils.get_resource_list_info.
4831 */
4832
4833 PA_FIN_PLAN_UTILS.GET_RESOURCE_LIST_INFO
4834 (
4835 p_resource_list_id => p_resource_list_id
4836 ,x_res_list_is_uncategorized => l_res_uncategorized_flag
4837 ,x_is_resource_list_grouped => l_is_resource_list_grouped
4838 ,x_group_resource_type_id => l_group_resource_type_id
4839 ,x_return_status => x_return_status
4840 ,x_msg_count => x_msg_count
4841 ,x_msg_data => x_msg_data
4842 );
4843
4844 /* return if resource list is uncategorized as no resources are to be added in this case*/
4845 IF l_res_uncategorized_flag = 'Y'
4846 THEN
4847 IF p_pa_debug_mode = 'Y' THEN
4848 pa_debug.g_err_stage:= 'l_res_uncategorized_flag is Y. Returning...';
4849 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4850 pa_debug.reset_curr_function;
4851 END IF;
4852 RETURN;
4853 END IF;
4854
4855 /*
4856 Depending on the resource list being grouped/ungrouped,
4857 p_res_planning_level 'R'(resource)/'G'(resource group)
4858 we need to open the appropriate cursor. bulk fetch all
4859 the resource list memners into l_res_list_mem_id_tbl.
4860 */
4861
4862 IF l_is_resource_list_grouped = 'N'
4863 THEN
4864
4865 IF p_pa_debug_mode = 'Y' THEN
4866 pa_debug.g_err_stage:= 'ungrouped_res_cur is opened';
4867 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4868 END IF;
4869
4870 OPEN ungrouped_res_cur (p_resource_list_id);
4871 FETCH ungrouped_res_cur BULK COLLECT INTO
4872 l_res_list_mem_id_tbl;
4873 CLOSE ungrouped_res_cur;
4874 ELSE
4875 IF p_res_planning_level = PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R
4876 THEN
4877
4878 IF p_pa_debug_mode = 'Y' THEN
4879 pa_debug.g_err_stage:= 'grouped_res_level_res_cur is opened';
4880 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4881 END IF;
4882
4883 OPEN grouped_res_level_res_cur(p_resource_list_id);
4884 FETCH grouped_res_level_res_cur BULK COLLECT INTO
4885 l_res_list_mem_id_tbl;
4886 CLOSE grouped_res_level_res_cur;
4887
4888 ELSIF p_res_planning_level = PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_G
4889 THEN
4890
4891 IF p_pa_debug_mode = 'Y' THEN
4892 pa_debug.g_err_stage:= 'grouped_resgrp_level_res_cur is opened';
4893 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4894 END IF;
4895
4896 OPEN grouped_resgrp_level_res_cur(p_resource_list_id);
4897 FETCH grouped_resgrp_level_res_cur BULK COLLECT INTO
4898 l_res_list_mem_id_tbl;
4899 CLOSE grouped_resgrp_level_res_cur;
4900 END IF;
4901 END IF;
4902
4903 /*
4904 For each task_id in the task_id table we need to insert
4905 all the resource_list_memebers fetched in pa_fp_elements table.
4906 */
4907
4908 IF p_pa_debug_mode = 'Y' THEN
4909 pa_debug.g_err_stage:= 'for each task in task_id_tbl inserting all the rlmids fetched';
4910 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4911 END IF;
4912
4913 FOR l_task_tbl_index IN l_task_id_tbl.first .. l_task_id_tbl.last
4914 LOOP
4915
4916 /* Insert all the resource_list_members fetched for each task */
4917
4918 FORALL l_rlm_tbl_index IN l_res_list_mem_id_tbl.first .. l_res_list_mem_id_tbl.last
4919 INSERT INTO pa_fp_elements
4920 (PROJ_FP_ELEMENTS_ID
4921 ,PROJ_FP_OPTIONS_ID
4922 ,PROJECT_ID
4923 ,FIN_PLAN_TYPE_ID
4924 ,ELEMENT_TYPE
4925 ,FIN_PLAN_VERSION_ID
4926 ,TASK_ID
4927 ,TOP_TASK_ID
4928 ,RESOURCE_LIST_MEMBER_ID
4929 ,TOP_TASK_PLANNING_LEVEL
4930 ,RESOURCE_PLANNING_LEVEL
4931 ,PLANNABLE_FLAG
4932 ,RESOURCES_PLANNED_FOR_TASK
4933 ,PLAN_AMOUNT_EXISTS_FLAG
4934 ,TMP_PLANNABLE_FLAG
4935 ,TMP_TOP_TASK_PLANNING_LEVEL
4936 ,RECORD_VERSION_NUMBER
4937 ,LAST_UPDATE_DATE
4938 ,LAST_UPDATED_BY
4939 ,CREATION_DATE
4940 ,CREATED_BY
4941 ,LAST_UPDATE_LOGIN)
4942 VALUES
4943 (pa_fp_elements_s.nextval
4944 ,p_proj_fp_options_id
4945 ,proj_fp_options_info_rec.project_id
4946 ,proj_fp_options_info_rec.fin_plan_type_id
4947 ,p_element_type
4948 ,proj_fp_options_info_rec.fin_plan_version_id
4949 ,l_task_id_tbl(l_task_tbl_index) -- task_id
4950 ,l_top_task_id_tbl(l_task_tbl_index) -- top_task_id
4951 ,l_res_list_mem_id_tbl(l_rlm_tbl_index) -- resource_list_member_id
4952 ,NULL -- top_task_planning_level
4953 ,NULL -- resource_planning_level
4954 ,'Y' -- plannable_flag
4955 ,NULL -- resources_planned_for_task
4956 ,'N' -- plan_amount_exists_flag
4957 ,'Y' -- tmp_plannable_flag
4958 ,NULL -- tmp_top_task_planning_level
4959 ,1 -- record_version_number
4960 ,sysdate
4961 ,fnd_global.user_id
4962 ,sysdate
4963 ,fnd_global.user_id
4964 ,fnd_global.login_id);
4965 END LOOP;
4966
4967 -- Bulk update all the task records to reflect that resources selection is done
4968
4969 IF p_pa_debug_mode = 'Y' THEN
4970 pa_debug.g_err_stage:= 'Bulk updating all the tasks to reflect resource selection status';
4971 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4972 END IF;
4973
4974 IF l_res_list_mem_id_tbl.count > 0
4975 THEN
4976 FORALL l_task_tbl_index IN l_task_id_tbl.first .. l_task_id_tbl.last
4977 UPDATE pa_fp_elements
4978 SET resources_planned_for_task = 'Y'
4979 ,resource_planning_level = p_res_planning_level
4980 ,record_version_number = record_version_number + 1
4981 ,last_update_date = sysdate
4982 ,last_updated_by = FND_GLOBAL.USER_ID
4983 ,last_update_login = FND_GLOBAL.LOGIN_ID
4984 WHERE proj_fp_options_id = p_proj_fp_options_id
4985 AND element_type = p_element_type
4986 AND task_id = l_task_id_tbl(l_task_tbl_index)
4987 AND resource_list_member_id = 0;
4988 END IF;
4989
4990 IF p_pa_debug_mode = 'Y' THEN
4991 pa_debug.g_err_stage:= 'Exiting Add_resources_automatically';
4992 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4993 END IF;
4994 pa_debug.reset_curr_function;
4995 EXCEPTION
4996
4997 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
4998
4999 x_return_status := FND_API.G_RET_STS_ERROR;
5000 l_msg_count := FND_MSG_PUB.count_msg;
5001 IF l_msg_count = 1 THEN
5002 PA_INTERFACE_UTILS_PUB.get_messages
5003 (p_encoded => FND_API.G_TRUE
5004 ,p_msg_index => 1
5005 ,p_msg_count => l_msg_count
5006 ,p_msg_data => l_msg_data
5007 ,p_data => l_data
5008 ,p_msg_index_out => l_msg_index_out);
5009 x_msg_data := l_data;
5010 x_msg_count := l_msg_count;
5011 ELSE
5012 x_msg_count := l_msg_count;
5013 END IF;
5014 pa_debug.reset_curr_function;
5015 RETURN;
5016 WHEN others THEN
5017
5018 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5019 x_msg_count := 1;
5020 x_msg_data := SQLERRM;
5021 FND_MSG_PUB.add_exc_msg
5022 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
5023 ,p_procedure_name => 'ADD_RESOURCES_AUTOMATICALLY'
5024 ,p_error_text => sqlerrm);
5025 pa_debug.reset_curr_function;
5026 RAISE;
5027 END Add_resources_automatically;
5028
5029 /* Bug 2920954 - This procedure deletes all the planning elements
5030 (pa_fp_elements/pa_resource_assignments) of this task and all
5031 its child tasks. This is called during the task deletion. These
5032 tasks would have plannable plan_amount_exists_flag as 'N'. Its
5033 assumed that the check apis would have been called to ensure
5034 that deletion of p_task_id is allowed. One main check in the check api
5035 is that p_task_id should not be present in pa_resource_assignments
5036 of a BASELINED version since we should not be touching RA table
5037 of BASELINED versions. When plan amounts donot exists, pa_proj_periods_denorm
5038 will not contain any data for that task.
5039
5040 Bug 2976168. Delete from pa_fp_excluded_elements */
5041
5042 PROCEDURE Delete_task_elements
5043 ( p_task_id IN pa_tasks.task_id%TYPE
5044 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5045 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
5046 ,x_msg_data OUT NOCOPY VARCHAR2) IS --File.Sql.39 bug 4440895
5047
5048 l_msg_count NUMBER := 0;
5049 l_data VARCHAR2(2000);
5050 l_msg_data VARCHAR2(2000);
5051 l_msg_index_out NUMBER;
5052 l_debug_mode VARCHAR2(1);
5053
5054 L_DEBUG_LEVEL2 CONSTANT NUMBER := 2;
5055 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
5056 L_DEBUG_LEVEL4 CONSTANT NUMBER := 4;
5057 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
5058
5059 l_records_deleted NUMBER;
5060 BEGIN
5061
5062 x_msg_count := 0;
5063 x_return_status := FND_API.G_RET_STS_SUCCESS;
5064 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
5065
5066 pa_debug.set_curr_function( p_function => 'delete_task_elements',
5067 p_debug_mode => l_debug_mode );
5068
5069 -- Check for business rules violations
5070
5071 IF l_debug_mode = 'Y' THEN
5072 pa_debug.g_err_stage:= 'Validating input parameters';
5073 pa_debug.write(l_module_name,pa_debug.g_err_stage,
5074 L_DEBUG_LEVEL3);
5075 END IF;
5076
5077 IF (p_task_id IS NULL)
5078 THEN
5079 IF l_debug_mode = 'Y' THEN
5080 pa_debug.g_err_stage:= 'p_task_id = '|| p_task_id;
5081 pa_debug.write(l_module_name,pa_debug.g_err_stage,
5082 L_DEBUG_LEVEL5);
5083 END IF;
5084 PA_UTILS.ADD_MESSAGE
5085 (p_app_short_name => 'PA',
5086 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
5087 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5088 END IF;
5089
5090 IF l_debug_mode = 'Y' THEN
5091 pa_debug.g_err_stage:= 'Deleting from pa_resource_assignments for task id ' || to_char(p_task_id);
5092 pa_debug.write(l_module_name,pa_debug.g_err_stage,
5093 L_DEBUG_LEVEL3);
5094 END IF;
5095
5096 DELETE FROM pa_resource_assignments r
5097 WHERE r.task_id IN (SELECT t.task_id
5098 FROM pa_tasks t
5099 CONNECT BY PRIOR t.task_id = t.parent_task_id
5100 START WITH t.task_id = p_task_id);
5101
5102 l_records_deleted := sql%rowcount;
5103
5104 IF l_debug_mode = 'Y' THEN
5105 pa_debug.g_err_stage:= To_char(l_records_deleted) || ' records deleted.';
5106 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5107 END IF;
5108
5109 IF l_debug_mode = 'Y' THEN
5110 pa_debug.g_err_stage:= 'Exiting delete_task_elements';
5111 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5112 END IF;
5113
5114 pa_debug.reset_curr_function;
5115
5116 EXCEPTION
5117
5118 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
5119
5120 x_return_status := FND_API.G_RET_STS_ERROR;
5121 l_msg_count := FND_MSG_PUB.count_msg;
5122
5123 IF l_msg_count = 1 and x_msg_data IS NULL THEN
5124 PA_INTERFACE_UTILS_PUB.get_messages
5125 (p_encoded => FND_API.G_TRUE
5126 ,p_msg_index => 1
5127 ,p_msg_count => l_msg_count
5128 ,p_msg_data => l_msg_data
5129 ,p_data => l_data
5130 ,p_msg_index_out => l_msg_index_out);
5131 x_msg_data := l_data;
5132 x_msg_count := l_msg_count;
5133 ELSE
5134 x_msg_count := l_msg_count;
5135 END IF;
5136 pa_debug.reset_curr_function;
5137 RETURN;
5138
5139 WHEN others THEN
5140
5141 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5142 x_msg_count := 1;
5143 x_msg_data := SQLERRM;
5144
5145 FND_MSG_PUB.add_exc_msg
5146 ( p_pkg_name => 'pa_Fp_elements_pub'
5147 ,p_procedure_name => 'delete_task_elements'
5148 ,p_error_text => x_msg_data);
5149
5150 IF l_debug_mode = 'Y' THEN
5151 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
5152 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5153 END IF;
5154 pa_debug.reset_curr_function;
5155 RAISE;
5156 END delete_task_elements;
5157 /*
5158 For bug 2976168.
5159 This API is called from pa_fp_elements_pub.make_new_tasks_plannable api for an option and element_type.
5160 This API will be used to decide whether to insert a task in fp elements table or not. This api will also
5161 provide the plannable flag and task planning level of all the tasks that are eligible for insertion.
5162 */
5163 PROCEDURE Get_Task_Element_Attributes
5164 ( p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
5165 ,p_element_type IN pa_fp_elements.element_type%TYPE
5166 ,p_task_id IN pa_fp_elements.task_id%TYPE
5167 ,p_top_task_id IN pa_fp_elements.top_task_id%TYPE
5168 ,p_task_level IN VARCHAR2
5169 ,p_option_plan_level_code IN pa_proj_fp_options.cost_fin_plan_level_code%TYPE
5170 ,x_task_inclusion_flag OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5171 ,x_task_plannable_flag OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5172 ,x_top_task_planning_level OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5173 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5174 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
5175 ,x_msg_data OUT NOCOPY VARCHAR2) IS --File.Sql.39 bug 4440895
5176
5177 --Declare the variables which are required as a standard
5178 l_msg_count NUMBER := 0;
5179 l_data VARCHAR2(2000);
5180 l_msg_data VARCHAR2(2000);
5181 l_msg_index_out NUMBER;
5182 l_debug_mode VARCHAR2(1);
5183
5184 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
5185 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
5186 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
5187 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
5188 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
5189 L_PROCEDURE_NAME CONSTANT VARCHAR2(100) :='Get_Task_Element_Attributes: '||
5190 l_module_name ;
5191
5192 --Variables required in this procedure
5193 l_continue_processing VARCHAR2(1) := 'Y';
5194 l_dummy VARCHAR2(1);
5195 l_child_task_exists NUMBER; /* Indicates if child tasks exists for a task
5196 0 - No child tasks exists
5197 1 - Child task exists
5198 Other Number - Sql Error */
5199
5200 --Cursors required for this procedure
5201
5202 --This cursor is used to know whether a task already exists in pa_fp_elements or not
5203 CURSOR task_element_info_cur (
5204 c_task_id pa_fp_elements.task_id%TYPE)
5205 IS
5206 SELECT pfe.top_task_planning_level,
5207 pfe.plannable_flag
5208 FROM pa_fp_elements pfe
5209 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5210 AND pfe.element_type = p_element_type
5211 AND pfe.task_id = c_task_id
5212 AND pfe.resource_list_member_id = 0;
5213
5214 task_element_info_rec task_element_info_cur%ROWTYPE;
5215
5216 --This cursor is used to know whether a task is explicitly made unplannable
5217 CURSOR excluded_task_cur
5218 ( c_task_id pa_tasks.task_id%TYPE
5219 ,c_top_task_id pa_tasks.task_id%TYPE)
5220 IS
5221 SELECT 'Y'
5222 FROM pa_fp_excluded_elements pfe
5223 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5224 AND pfe.element_type = p_element_type
5225 AND pfe.task_id IN (c_task_id,c_top_task_id);
5226
5227 BEGIN
5228 x_msg_count := 0;
5229 x_return_status := FND_API.G_RET_STS_SUCCESS;
5230 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
5231
5232 IF l_debug_mode = 'Y' THEN
5233 pa_debug.set_curr_function( p_function => 'Get_Task_Element_Attributes',
5234 p_debug_mode => l_debug_mode );
5235 END IF;
5236
5237 IF l_debug_mode = 'Y' THEN
5238 pa_debug.g_err_stage:= 'Validating input parameters';
5239 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5240 END IF;
5241
5242 IF p_proj_fp_options_id IS NULL OR
5243 p_element_type IS NULL OR
5244 p_task_id IS NULL OR
5245 p_top_task_id IS NULL OR
5246 p_task_level IS NULL OR
5247 p_option_plan_level_code IS NULL
5248 THEN
5249
5250 IF l_debug_mode = 'Y' THEN
5251 pa_debug.g_err_stage:= 'p_proj_fp_options_id = '|| p_proj_fp_options_id;
5252 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5253
5254 pa_debug.g_err_stage:= 'p_element_type = '|| p_element_type;
5255 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5256
5257 pa_debug.g_err_stage:= 'p_task_id = '|| p_task_id;
5258 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5259
5260 pa_debug.g_err_stage:= 'p_top_task_id = '|| p_top_task_id;
5261 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5262
5263 pa_debug.g_err_stage:= 'p_task_level = '|| p_task_level;
5264 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5265
5266 pa_debug.g_err_stage:= 'p_option_plan_level_code = '|| p_option_plan_level_code;
5267 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5268
5269 END IF;
5270 PA_UTILS.ADD_MESSAGE
5271 (p_app_short_name => 'PA',
5272 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
5273 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5274
5275 END IF;
5276
5277 --Check if the task is already included as a plannable element.
5278 IF l_debug_mode = 'Y' THEN
5279 pa_debug.g_err_stage:= 'Check if task is already plannable(existence in pa_fp_elements)';
5280 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5281 END IF;
5282
5283 -- If p_task_id already exists in pa_fp_elements for the option_id and element_type, no further
5284 -- processing is required.
5285
5286 OPEN task_element_info_cur(p_task_id);
5287 FETCH task_element_info_cur INTO task_element_info_rec;
5288 IF task_element_info_cur%NOTFOUND THEN
5289 l_continue_processing := 'Y';
5290 IF l_debug_mode = 'Y' THEN
5291 pa_debug.g_err_stage:= 'task doesnt exists in pa_fp_elements. Proceeding further..';
5292 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5293 END IF;
5294 ELSE
5295 l_continue_processing := 'N';
5296 x_task_inclusion_flag := 'N';
5297 IF l_debug_mode = 'Y' THEN
5298 pa_debug.g_err_stage:= 'task is already plannable and exists in pa_fp_elements. No processing required...';
5299 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5300 END IF;
5301 END IF;
5302 CLOSE task_element_info_cur;
5303
5304 --Check if the task is already made unplannable.
5305 IF l_continue_processing = 'Y' THEN
5306
5307 OPEN excluded_task_cur( p_task_id
5308 ,p_top_task_id);
5309 FETCH excluded_task_cur INTO l_dummy;
5310 IF excluded_task_cur%FOUND THEN
5311 l_continue_processing := 'N';
5312 x_task_inclusion_flag := 'N';
5313 IF l_debug_mode = 'Y' THEN
5314 pa_debug.g_err_stage:= 'Task ' ||p_task_id ||' is not processed as it exists in pa_fp_excluded_elements';
5315 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5316 END IF;
5317 END IF;
5318 CLOSE excluded_task_cur;
5319 END IF;
5320
5321 --Continue processing if the task is not either made plannable or unplannable.
5322 IF l_continue_processing='Y' THEN
5323 IF l_debug_mode = 'Y' THEN
5324 pa_debug.g_err_stage := 'Continuing with the processing of task ' || p_task_id;
5325 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5326 END IF;
5327
5328 -- Planning level for the options is top task
5329 IF p_option_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_TOP THEN
5330
5331 --The task passed is a top task
5332
5333 IF p_task_level = L_TASK_LEVEL_TOP THEN
5334
5335 -- When the planning level of the option is TOP,
5336 -- only top task are plannable
5337 x_task_inclusion_flag := 'Y';
5338 x_task_plannable_flag := 'Y';
5339 x_top_task_planning_level := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_TOP;
5340 ELSE
5341
5342 x_task_inclusion_flag := 'N';
5343
5344 END IF; /* p_task_id = p_top_task_id */
5345
5346 IF l_debug_mode = 'Y' THEN
5347 pa_debug.g_err_stage:= 'Option planned at Top Task and x_task_inclusion_flag = ' ||
5348 x_task_inclusion_flag || ' x_task_plannable_flag =' || x_task_plannable_flag ||
5349 ' x_top_task_planning_level ' || x_top_task_planning_level;
5350 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5351 END IF;
5352
5353 --Planning level of the options is either LOWEST or TOP AND LOWEST
5354
5355 ELSIF p_option_plan_level_code IN (PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_LOWEST,
5356 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_M) THEN
5357
5358 IF l_debug_mode = 'Y' THEN
5359 pa_debug.g_err_stage:= 'Option planned at Lowest Task or Top and Lowest Task';
5360 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5361 END IF;
5362
5363 --The task is a top task
5364 IF p_task_level = L_TASK_LEVEL_TOP THEN
5365
5366 l_child_task_exists := pa_task_utils.check_child_exists(x_task_id => p_task_id);
5367
5368 IF l_child_task_exists = 1 THEN /* Child task exsists */
5369
5370 /* This is a TOP task which is being created only now. But the planning
5371 level is L/M. Since we always have top task records in pa_fp_elements,
5372 this top task should be inserted in pa_fp_elements with plannable flag
5373 as N. Resource elements should not be added for this top task */
5374
5375 x_task_inclusion_flag := 'Y';
5376 x_task_plannable_flag := 'N' ;
5377 x_top_task_planning_level := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST;
5378
5379 IF l_debug_mode = 'Y' THEN
5380 pa_debug.g_err_stage:= 'Task is a TOP TASK and x_task_inclusion_flag = '
5381 || x_task_inclusion_flag || ' x_task_plannable_flag ='
5382 ||x_task_plannable_flag || ' and x_top_task_planning_level =' ||
5383 x_top_task_planning_level;
5384 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5385 END IF;
5386
5387 --The task is both top and lowest
5388 ELSIF l_child_task_exists = 0 THEN
5389
5390 /* TOP AND LOWEST TASK is always plannable when planning
5391 level of the option is LOWEST or TOP AND LOWEST */
5392
5393 x_task_inclusion_flag := 'Y';
5394 x_task_plannable_flag := 'Y' ;
5395 x_top_task_planning_level := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST;
5396
5397 IF l_debug_mode = 'Y' THEN
5398 pa_debug.g_err_stage:= 'Task is a TOP and LOWEST TASK and x_task_inclusion_flag = '
5399 || x_task_inclusion_flag || ' x_task_plannable_flag ='
5400 ||x_task_plannable_flag || ' and x_top_task_planning_level =' ||
5401 x_top_task_planning_level;
5402
5403 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5404 END IF;
5405
5406 ELSE
5407
5408 IF l_debug_mode = 'Y' THEN
5409 pa_debug.g_err_stage:= 'Error returned by pa_task_utils.check_child_exists. Sqlerrcode ' || to_char(l_child_task_exists);
5410 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5411 END IF;
5412
5413 RAISE FND_API.G_Exc_Unexpected_Error;
5414
5415 END IF;
5416
5417 ELSIF p_task_level = L_TASK_LEVEL_LOWEST THEN
5418
5419 /* p_task_id is a sub task.
5420 We need to check if the top task of p_task_id is marked plannable */
5421
5422 IF l_debug_mode = 'Y' THEN
5423 pa_debug.g_err_stage:= 'Task is a sub task';
5424 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5425 END IF;
5426
5427 OPEN task_element_info_cur(p_top_task_id);
5428 FETCH task_element_info_cur INTO task_element_info_rec;
5429
5430 /* If top task of p_task_id is not plannable,
5431 then p_task_id is not plannable */
5432
5433 IF task_element_info_cur%NOTFOUND THEN
5434
5435 /* Note that we dont expect this case to happen since our assumption is that
5436 the top task record would be first called to be made plannable and then the
5437 lowest task. If we need to handle this case, we have to first insert the
5438 p_top_task_id record into pa_fp_elements and then the p_task_id record. */
5439
5440 x_task_inclusion_flag := 'N';
5441
5442 CLOSE task_element_info_cur;
5443
5444 IF l_debug_mode = 'Y' THEN
5445 pa_debug.g_err_stage:= 'Top Task not found in pa_fp_elements and hence x_task_inclusion_flag ' || x_task_inclusion_flag;
5446 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5447 END IF;
5448
5449 ELSE
5450
5451 CLOSE task_element_info_cur;
5452 IF task_element_info_rec.top_task_planning_level = PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST THEN
5453
5454 /* If top task of p_task_id is plannable at LOWEST task level,
5455 then p_task_id (which is a lowest task here) should be made plannable */
5456
5457 x_task_inclusion_flag := 'Y';
5458 x_task_plannable_flag := 'Y';
5459
5460
5461 IF l_debug_mode = 'Y' THEN
5462 pa_debug.g_err_stage:= 'Top task is planned at lowest task level and x_task_inclusion_flag = ' || x_task_inclusion_flag
5463 ||' x_task_plannable_flag = ' ||x_task_plannable_flag;
5464 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5465 END IF;
5466
5467 ELSE
5468
5469 /* If top task is not plannable at LOWEST task level,
5470 then p_task_id should not be plannable */
5471
5472 x_task_inclusion_flag := 'N';
5473
5474 IF l_debug_mode = 'Y' THEN
5475 pa_debug.g_err_stage:= 'Top task is NOT planned at lowest task and so x_task_inclusion_flag = ' || x_task_inclusion_flag;
5476 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5477 END IF;
5478
5479 END IF; /* task_element_info_rec.top_task_planning_level = 'LOWEST' */
5480
5481 END IF; /* task_element_info_cur%NOTFOUND */
5482
5483 END IF; /* p_task_level = L_TASK_LEVEL_TOP */
5484
5485 END IF; /* p_option_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_TOP*/
5486
5487 END IF;/* If l_continue_processing = 'Y' */
5488
5489 IF l_debug_mode = 'Y' THEN
5490 pa_debug.g_err_stage:= 'Exiting Get_Task_Element_Attributes';
5491 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5492 pa_debug.reset_curr_function;
5493 END IF;
5494
5495 EXCEPTION
5496
5497 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
5498
5499 x_return_status := FND_API.G_RET_STS_ERROR;
5500 l_msg_count := FND_MSG_PUB.count_msg;
5501
5502 IF l_msg_count = 1 and x_msg_data IS NULL THEN
5503 PA_INTERFACE_UTILS_PUB.get_messages
5504 (p_encoded => FND_API.G_TRUE
5505 ,p_msg_index => 1
5506 ,p_msg_count => l_msg_count
5507 ,p_msg_data => l_msg_data
5508 ,p_data => l_data
5509 ,p_msg_index_out => l_msg_index_out);
5510 x_msg_data := l_data;
5511 x_msg_count := l_msg_count;
5512 ELSE
5513 x_msg_count := l_msg_count;
5514 END IF;
5515 IF l_debug_mode = 'Y' THEN
5516 pa_debug.reset_curr_function;
5517 END IF;
5518
5519 RETURN;
5520
5521 WHEN OTHERS THEN
5522
5523 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5524 x_msg_count := 1;
5525 x_msg_data := SQLERRM;
5526
5527 FND_MSG_PUB.add_exc_msg
5528 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
5529 ,p_procedure_name => 'Get_Task_Element_Attributes'
5530 ,p_error_text => x_msg_data);
5531
5532 IF l_debug_mode = 'Y' THEN
5533 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
5534 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5535 pa_debug.reset_curr_function;
5536 END IF;
5537 RAISE;
5538 END Get_Task_Element_Attributes;
5539
5540 /* Bug 2920954 - This is a PRIVATE api that would be called from the make_new_tasks_plannable
5541 api for each fp option in the context of COST/REVENUE/ALL. The api checks if the input
5542 new task can be made plannable depending on the planning level of the fp option and top
5543 task planning level. If the new task is plannable, task level record is inserted into
5544 fp elements table and if resources are to be added automatically, the procedure
5545 ADD_RESOURCES_AUTOMATICALLY api is called. Also, resource assignments and fp elements that
5546 were present for original task that was earlier plannable but now unplannable is deleted.
5547
5548 Bug 2976168. Changed the signature of the API. Also the logic of deriving is a task is
5549 plannable or not is moved to Get_Task_Element_Attributes Api
5550
5551 Bug 2989900. In case of CI versions, the tasks would be made plannable only if the task
5552 is an impacted task or a child task of impacted task */
5553
5554 PROCEDURE add_tasks_to_option
5555 ( p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
5556 ,p_element_type IN pa_fp_elements.element_type%TYPE
5557 ,p_tasks_tbl IN pa_fp_elements_pub.l_wbs_refresh_tasks_tbl_typ
5558 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5559 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
5560 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
5561 AS
5562
5563 l_msg_count NUMBER := 0;
5564 l_data VARCHAR2(2000);
5565 l_msg_data VARCHAR2(2000);
5566 l_msg_index_out NUMBER;
5567 l_debug_mode VARCHAR2(1);
5568
5569 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
5570 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
5571 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
5572 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
5573 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
5574
5575 CURSOR proj_fp_options_cur
5576 IS
5577 SELECT pfo.project_id,
5578 pfo.fin_plan_type_id,
5579 pfo.fin_plan_version_id,
5580 pfo.fin_plan_option_level_code,
5581 DECODE(p_element_type,
5582 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST,pfo.cost_fin_plan_level_code,
5583 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL,pfo.all_fin_plan_level_code,
5584 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.revenue_fin_plan_level_code) fin_plan_level_code,
5585 DECODE(p_element_type,
5586 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST,pfo.select_cost_res_auto_flag,
5587 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, pfo.select_all_res_auto_flag,
5588 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.select_rev_res_auto_flag) auto_res_selection_flag,
5589 DECODE(p_element_type,
5590 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, pfo.cost_res_planning_level,
5591 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, pfo.all_res_planning_level,
5592 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.revenue_res_planning_level) auto_res_plan_level,
5593 DECODE(p_element_type,
5594 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, pfo.cost_resource_list_id,
5595 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, pfo.all_resource_list_id,
5596 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.revenue_resource_list_id) resource_list_id
5597 FROM pa_proj_fp_options pfo
5598 WHERE pfo.proj_fp_options_id = p_proj_fp_options_id;
5599
5600 proj_fp_options_rec proj_fp_options_cur%ROWTYPE;
5601
5602
5603 l_task_id_tbl pa_fp_elements_pub.l_task_id_tbl_typ;
5604
5605 l_task_plannable_flag VARCHAR2(1); /* represents the plannable of the task to
5606 be inserted*/
5607
5608 --For Bug 2976168.
5609 l_task_inclusion_flag VARCHAR2(1); /*Required to know whether the task can be is
5610 eligible for inserting into pa_fp_elements or not*/
5611 CURSOR ci_version_info_cur
5612 (c_plan_version_id pa_proj_fp_options.fin_plan_version_id%TYPE)
5613 IS
5614 SELECT bv.ci_id,
5615 impacted_task_id
5616 FROM pa_budget_versions bv,
5617 pa_ci_impacts ci
5618 WHERE budget_version_id = c_plan_version_id
5619 AND bv.ci_id = ci.ci_id
5620 AND bv.ci_id IS NOT NULL;
5621
5622 ci_version_info_rec ci_version_info_cur%ROWTYPE;
5623
5624 CURSOR ci_impacted_tasks_cur
5625 (c_project_id NUMBER, c_impacted_task_id NUMBER) IS
5626 SELECT task_id
5627 FROM pa_tasks t
5628 WHERE t.project_id = c_project_id
5629 START WITH t.task_id = c_impacted_task_id
5630 CONNECT BY prior t.task_id = t.parent_task_id;
5631
5632 ci_impacted_tasks_rec ci_impacted_tasks_cur%ROWTYPE;
5633
5634 l_continue_processing VARCHAR2(1);
5635 l_ci_impacted_tasks_tbl PA_PLSQL_DATATYPES.NumTabTyp;
5636 l_top_task_planning_level pa_fp_elements.top_task_planning_level%TYPE;
5637 L_PROCEDURE_NAME CONSTANT VARCHAR2(100):='add_task_to_option :'||l_module_name;
5638
5639 BEGIN
5640 x_msg_count := 0;
5641 x_return_status := FND_API.G_RET_STS_SUCCESS;
5642 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
5643
5644
5645 -- Check for business rules violations
5646
5647 IF l_debug_mode = 'Y' THEN
5648 pa_debug.set_curr_function( p_function => 'add_task_to_option',
5649 p_debug_mode => l_debug_mode );
5650 pa_debug.g_err_stage:= 'Validating input parameters';
5651 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5652 END IF;
5653
5654 IF (p_proj_fp_options_id IS NULL) OR
5655 (p_element_type IS NULL) THEN
5656
5657 IF l_debug_mode = 'Y' THEN
5658 pa_debug.g_err_stage:= 'p_proj_fp_options_id = '|| p_proj_fp_options_id;
5659 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5660 pa_debug.g_err_stage:= 'p_element_type = '|| p_element_type;
5661 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5662 END IF;
5663 PA_UTILS.ADD_MESSAGE
5664 (p_app_short_name => 'PA',
5665 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
5666 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5667
5668 END IF;
5669
5670 IF l_debug_mode = 'Y' THEN
5671 pa_debug.g_err_stage:= 'Opening proj_fp_options_cur.';
5672 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5673 END IF;
5674
5675 OPEN proj_fp_options_cur;
5676 FETCH proj_fp_options_cur INTO proj_fp_options_rec;
5677 CLOSE proj_fp_options_cur;
5678
5679 IF proj_fp_options_rec.fin_plan_version_id IS NOT NULL THEN
5680
5681 OPEN ci_version_info_cur(proj_fp_options_rec.fin_plan_version_id);
5682 FETCH ci_version_info_cur INTO ci_version_info_rec;
5683 IF ci_version_info_cur%NOTFOUND THEN
5684 IF l_debug_mode = 'Y' THEN
5685 pa_debug.g_err_stage:= 'The Option does not correspond to a CI Version';
5686 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5687 END IF;
5688 ELSE
5689 IF l_debug_mode = 'Y' THEN
5690 pa_debug.g_err_stage:= 'The Option corresponds to a CI Version';
5691 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5692 END IF;
5693
5694 --Check whether an impacted task id exists or not. If it exists store all the tasks
5695 --below that task in wbs in a pl/sql table so that only those tasks are processed.
5696
5697 IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN
5698 IF l_debug_mode = 'Y' THEN
5699 pa_debug.g_err_stage:= 'The impacted task id is '
5700 ||ci_version_info_rec.impacted_task_id;
5701 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5702 END IF;
5703
5704 FOR ci_impacted_tasks_rec IN ci_impacted_tasks_cur( proj_fp_options_rec.project_id
5705 ,ci_version_info_rec.impacted_task_id) LOOP
5706
5707 l_ci_impacted_tasks_tbl(ci_impacted_tasks_rec.task_id) := 1 ;
5708
5709 END LOOP;
5710
5711 END IF; /* IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN */
5712
5713 END IF; /* IF ci_version_info_cur%NOTFOUND THEN */
5714
5715 CLOSE ci_version_info_cur;
5716
5717 END IF; /* IF proj_fp_options_rec.fin_plan_version_id IS NOT NULL THEN */
5718
5719 --Process the tasks passed by looping thru the pl/sql table (we are sure the plsql table contains records)
5720
5721 FOR i IN p_tasks_tbl.first .. p_tasks_tbl.last LOOP
5722
5723 l_continue_processing := 'Y';
5724
5725 IF p_tasks_tbl(i).task_level IN ( L_TASK_LEVEL_LOWEST
5726 ,L_TASK_LEVEL_TOP) THEN
5727
5728 IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN
5729
5730 /* Process the task only if the task is under the impacted task id */
5731
5732 IF l_ci_impacted_tasks_tbl.exists(p_tasks_tbl(i).task_id) THEN
5733
5734 l_continue_processing := 'Y';
5735 ELSE
5736
5737 l_continue_processing := 'N';
5738
5739 IF l_debug_mode = 'Y' THEN
5740 pa_debug.g_err_stage:= 'The task '||p_tasks_tbl(i).task_id
5741 ||' is not under the impacted task '
5742 ||ci_version_info_rec.impacted_task_id;
5743 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5744 END IF;
5745
5746 END IF;
5747
5748 END IF; /* IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN */
5749
5750 IF l_continue_processing = 'Y' THEN
5751
5752 l_task_inclusion_flag := Null;
5753 l_task_plannable_flag := Null;
5754 l_top_task_planning_level := Null;
5755
5756 --Call the api that helps in deciding whether to insert the task or not.
5757
5758 Get_Task_Element_Attributes
5759 ( p_proj_fp_options_id => p_proj_fp_options_id
5760 ,p_element_type => p_element_type
5761 ,p_task_id => p_tasks_tbl(i).task_id
5762 ,p_top_task_id => p_tasks_tbl(i).top_task_id
5763 ,p_task_level => p_tasks_tbl(i).task_level
5764 ,p_option_plan_level_code => proj_fp_options_rec.fin_plan_level_code
5765 ,x_task_inclusion_flag => l_task_inclusion_flag
5766 ,x_task_plannable_flag => l_task_plannable_flag
5767 ,x_top_task_planning_level => l_top_task_planning_level
5768 ,x_return_status => x_return_status
5769 ,x_msg_count => x_msg_count
5770 ,x_msg_data => x_msg_data);
5771
5772 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
5773
5774 IF l_debug_mode = 'Y' THEN
5775 pa_debug.g_err_stage := 'Error in Get_Task_Element_Attributes for task'
5776 || p_tasks_tbl(i).task_id ;
5777 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5778 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5779
5780 END IF;
5781
5782 END IF;
5783
5784 IF l_task_inclusion_flag = 'Y' THEN
5785
5786 IF p_tasks_tbl(i).parent_task_id = p_tasks_tbl(i).top_task_id THEN
5787
5788 /* If the parent task is a top task,
5789
5790 1. We need to remove only the resources elements attached
5791 to the parent task from pa_fp_elements.
5792
5793 2. Since we always have the top task record of a plannable
5794 task in pa_fp_elements, we shouldnt delete the top task
5795 record. We just have to set the plannable flag
5796 of this task to N. */
5797
5798 DELETE pa_fp_elements pfe
5799 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5800 AND pfe.element_type = p_element_type
5801 AND pfe.task_id = p_tasks_tbl(i).parent_task_id
5802 AND pfe.resource_list_member_id <> 0;
5803
5804 IF l_debug_mode = 'Y' THEN
5805 pa_debug.g_err_stage:= to_char(sql%rowcount) || ' records deleted from pa_fp_elements';
5806 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5807 END IF;
5808
5809 UPDATE pa_fp_elements pfe
5810 SET pfe.plannable_flag = 'N',
5811 pfe.tmp_plannable_flag = 'N',
5812 pfe.resources_planned_for_task = Null,
5813 pfe.record_version_number = pfe.record_version_number + 1,
5814 last_update_date = sysdate,
5815 last_updated_by = FND_GLOBAL.USER_ID,
5816 last_update_login = FND_GLOBAL.LOGIN_ID
5817 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5818 AND pfe.element_type = p_element_type
5819 AND pfe.task_id = p_tasks_tbl(i).parent_task_id
5820 AND pfe.resource_list_member_id = 0;
5821
5822 IF l_debug_mode = 'Y' THEN
5823 pa_debug.g_err_stage:= to_char(sql%rowcount) || ' records updated in pa_fp_elements';
5824 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5825 END IF;
5826
5827 IF proj_fp_options_rec.fin_plan_option_level_code = PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION THEN
5828
5829 /* If this option corresponds to a plan version, we should delete the resource assignments also
5830 for p_task_id. */
5831
5832 DELETE pa_resource_assignments pra
5833 WHERE pra.budget_version_id = proj_fp_options_rec.fin_plan_version_id
5834 AND pra.task_id = p_tasks_tbl(i).parent_task_id
5835 AND pra.resource_assignment_type = PA_FP_CONSTANTS_PKG.G_USER_ENTERED;
5836
5837 IF l_debug_mode = 'Y' THEN
5838 pa_debug.g_err_stage:= 'PLAN_VERSION option. ' || to_char(sql%rowcount) || ' records deleted from pa_resource_assignments';
5839 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5840 END IF;
5841
5842 END IF; /* Option is PLAN_VERSION */
5843
5844 ELSE
5845
5846 /* If p_task_id is not a top task then it would not be required to delete here
5847 as we BULK delete in make_new_tasks_plannable api for this case */
5848 Null;
5849
5850 END IF;
5851
5852 INSERT INTO PA_FP_ELEMENTS
5853 (PROJ_FP_ELEMENTS_ID
5854 ,PROJ_FP_OPTIONS_ID
5855 ,PROJECT_ID
5856 ,FIN_PLAN_TYPE_ID
5857 ,ELEMENT_TYPE
5858 ,FIN_PLAN_VERSION_ID
5859 ,TASK_ID
5860 ,TOP_TASK_ID
5861 ,RESOURCE_LIST_MEMBER_ID
5862 ,TOP_TASK_PLANNING_LEVEL
5863 ,RESOURCE_PLANNING_LEVEL
5864 ,PLANNABLE_FLAG
5865 ,RESOURCES_PLANNED_FOR_TASK
5866 ,PLAN_AMOUNT_EXISTS_FLAG
5867 ,TMP_PLANNABLE_FLAG
5868 ,TMP_TOP_TASK_PLANNING_LEVEL
5869 ,RECORD_VERSION_NUMBER
5870 ,LAST_UPDATE_DATE
5871 ,LAST_UPDATED_BY
5872 ,CREATION_DATE
5873 ,CREATED_BY
5874 ,LAST_UPDATE_LOGIN)
5875 VALUES
5876 (pa_fp_elements_s.nextval
5877 ,p_proj_fp_options_id
5878 ,proj_fp_options_rec.project_id
5879 ,proj_fp_options_rec.fin_plan_type_id
5880 ,p_element_type
5881 ,proj_fp_options_rec.fin_plan_version_id
5882 ,p_tasks_tbl(i).task_id
5883 ,p_tasks_tbl(i).top_task_id
5884 ,0 -- resource_list_member_id
5885 ,l_top_task_planning_level -- top_task_planning_level
5886 ,decode(l_task_plannable_flag,
5887 'N',Null,
5888 proj_fp_options_Rec.auto_res_plan_level) -- resource_planning_level
5889 ,l_task_plannable_flag -- plannable_flag
5890 ,proj_fp_options_rec.auto_res_selection_flag -- resources_planned_for_task
5891 ,'N' -- plan_amount_exists_flag
5892 ,l_task_plannable_flag -- tmp_plannable_flag
5893 ,l_top_task_planning_level -- tmp_top_task_planning_level
5894 ,1
5895 ,SYSDATE
5896 ,FND_GLOBAL.USER_ID
5897 ,SYSDATE
5898 ,FND_GLOBAL.USER_ID
5899 ,FND_GLOBAL.LOGIN_ID);
5900
5901 IF proj_fp_options_rec.auto_res_selection_flag = 'Y' THEN
5902
5903 /* We should be adding resources only if p_task_id is a plannable task record.
5904 It should not be added to a top task record that is plannable at lowest task level */
5905
5906 IF l_task_plannable_flag = 'Y' THEN
5907
5908 /* If automatic resource selection is 'Y' for the proj_fp_option/element type,
5909 then resource elements need to be added */
5910
5911 IF l_debug_mode = 'Y' THEN
5912 pa_debug.g_err_stage:= 'Calling add_resources_automatically...';
5913 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5914 END IF;
5915
5916 l_task_id_tbl(1) := p_tasks_tbl(i).task_id;
5917
5918 PA_FP_ELEMENTS_PUB.ADD_RESOURCES_AUTOMATICALLY
5919 ( p_proj_fp_options_id => p_proj_fp_options_id
5920 ,p_element_type => p_element_type
5921 ,p_fin_plan_level_code => proj_fp_options_rec.fin_plan_level_code
5922 ,p_resource_list_id => proj_fp_options_rec.resource_list_id
5923 ,p_res_planning_level => proj_fp_options_rec.auto_res_plan_level
5924 ,p_entire_option => 'N'
5925 ,p_element_task_id_tbl => l_task_id_tbl
5926 ,x_return_status => x_return_status
5927 ,x_msg_count => x_msg_count
5928 ,x_msg_data => x_msg_data);
5929
5930 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
5931
5932 pa_debug.g_err_stage := 'Error while adding resoruces to task id ' || p_tasks_tbl(i).task_id ||
5933 'for ' || p_element_type || ' option id ' || p_proj_fp_options_id;
5934 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5935
5936 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5937
5938 END IF;
5939
5940 END IF; /* l_task_plannable_flag = 'Y' */
5941
5942 END IF; /* proj_fp_options_rec.auto_res_selection_flag = 'Y' */
5943
5944 END IF; /* IF l_task_inclusion_flag = 'Y' THEN */
5945
5946 END IF; /* IF l_continue_processing = 'Y' THEN */
5947
5948 END IF; /* IF p_tasks_tbl(i).task_level IN (T,L) */
5949
5950 END LOOP; /* p_tasks_tbl.first .. p_tasks_tbl.last loop */
5951
5952 /* Add_tasks_to_option is called only when the planning level is NOT project */
5953
5954 IF proj_fp_options_rec.fin_plan_option_level_code = PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION THEN
5955
5956 IF l_debug_mode = 'Y' THEN
5957 pa_debug.g_err_stage:= 'Calling create_enterable_resources...';
5958 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5959 END IF;
5960
5961 PA_FP_ELEMENTS_PUB.create_enterable_resources
5962 ( p_plan_version_id => proj_fp_options_rec.fin_plan_version_id
5963 ,p_res_del_req_flag => 'N' /* Since deletion of resource assignments has already been done in this flow */
5964 ,x_return_status => x_return_status
5965 ,x_msg_count => x_msg_count
5966 ,x_msg_data => x_msg_data);
5967
5968 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
5969
5970 pa_debug.g_err_stage := 'Error calling create enterable resoruces for version id'
5971 || proj_fp_options_rec.fin_plan_version_id;
5972 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5973
5974 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5975 END IF;
5976
5977 END IF; /* IF proj_fp_options_rec.fin_plan_option_level_code = PLAN_VERSION */
5978
5979 IF l_debug_mode = 'Y' THEN
5980 pa_debug.g_err_stage:= 'Exiting add_task_to_option';
5981 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5982 pa_debug.reset_curr_function;
5983 END IF;
5984
5985 EXCEPTION
5986
5987 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
5988
5989 x_return_status := FND_API.G_RET_STS_ERROR;
5990 l_msg_count := FND_MSG_PUB.count_msg;
5991
5992 IF l_msg_count = 1 and x_msg_data IS NULL THEN
5993 PA_INTERFACE_UTILS_PUB.get_messages
5994 (p_encoded => FND_API.G_TRUE
5995 ,p_msg_index => 1
5996 ,p_msg_count => l_msg_count
5997 ,p_msg_data => l_msg_data
5998 ,p_data => l_data
5999 ,p_msg_index_out => l_msg_index_out);
6000 x_msg_data := l_data;
6001 x_msg_count := l_msg_count;
6002 ELSE
6003 x_msg_count := l_msg_count;
6004 END IF;
6005 IF l_debug_mode = 'Y' THEN
6006 pa_debug.reset_curr_function;
6007 END IF;
6008 RETURN;
6009
6010 WHEN others THEN
6011
6012 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6013 x_msg_count := 1;
6014 x_msg_data := SQLERRM;
6015
6016 FND_MSG_PUB.add_exc_msg
6017 ( p_pkg_name => 'pa_fp_elements_pub'
6018 ,p_procedure_name => 'add_task_to_option'
6019 ,p_error_text => x_msg_data);
6020
6021 IF l_debug_mode = 'Y' THEN
6022 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
6023 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6024 pa_debug.reset_curr_function;
6025 END IF;
6026 RAISE;
6027 END add_tasks_to_option;
6028
6029 /* Bug 2920954 - This is the main API that does the processing
6030 necessary to make the tasks plannable automatically at project level
6031 option, plan type level options and for all the working plan
6032 versions. This is api is called by projects / workplan code to make
6033 the new tasks that are created as plannable. */
6034
6035 /* Bug 2976168. Changed the signature of the api. This api will now be called from
6036 pa_fin_plan_maint_ver_global.resubmit_concurrent_request */
6037
6038 PROCEDURE make_new_tasks_plannable
6039 ( p_project_id IN pa_projects_all.project_id%TYPE
6040 ,p_tasks_tbl IN pa_fp_elements_pub.l_wbs_refresh_tasks_tbl_typ
6041 ,p_refresh_fp_options_tbl IN PA_PLSQL_DATATYPES.IdTabTyp
6042 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
6043 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
6044 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
6045 AS
6046
6047 l_msg_count NUMBER := 0;
6048 l_data VARCHAR2(2000);
6049 l_msg_data VARCHAR2(2000);
6050 l_msg_index_out NUMBER;
6051 l_debug_mode VARCHAR2(1);
6052
6053 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
6054 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
6055
6056
6057 CURSOR fp_options_info_cur
6058 (c_proj_fp_options_id pa_proj_fp_options.proj_fp_options_id%TYPE)
6059 IS
6060 SELECT pfo.proj_fp_options_id,
6061 pfo.fin_plan_option_level_code,
6062 pfo.fin_plan_preference_code,
6063 pfo.cost_fin_plan_level_code,
6064 pfo.revenue_fin_plan_level_code,
6065 pfo.all_fin_plan_level_code,
6066 pfo.fin_plan_version_id
6067 FROM pa_proj_fp_options pfo
6068 WHERE pfo.proj_fp_options_id = c_proj_fp_options_id;
6069 fp_options_info_rec fp_options_info_cur%ROWTYPE;
6070
6071 l_process_option VARCHAR2(1);
6072
6073 L_PROCEDURE_NAME CONSTANT VARCHAR2(100):='make_new_tasks_plannable :'||l_module_name;
6074 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
6075 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
6076 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
6077
6078 BEGIN
6079
6080 x_msg_count := 0;
6081 x_return_status := FND_API.G_RET_STS_SUCCESS;
6082 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
6083
6084
6085 -- Check for business rules violations
6086
6087 IF l_debug_mode = 'Y' THEN
6088 pa_debug.set_curr_function( p_function => 'make_new_tasks_plannable',
6089 p_debug_mode => l_debug_mode );
6090 pa_debug.g_err_stage:= 'Validating input parameters';
6091 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6092 END IF;
6093
6094 IF (p_project_id IS NULL)
6095 THEN
6096 IF l_debug_mode = 'Y' THEN
6097 pa_debug.g_err_stage:= 'p_project_id = '|| p_project_id;
6098 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6099 END IF;
6100 PA_UTILS.ADD_MESSAGE
6101 (p_app_short_name => 'PA',
6102 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6103 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6104
6105 END IF;
6106
6107 --Continue processing only if the task table has some records.
6108
6109 IF NVL(p_tasks_tbl.last,0) = 0 OR
6110 NVL(p_refresh_fp_options_tbl.last,0) = 0 THEN
6111
6112 IF l_debug_mode = 'Y' THEN
6113 pa_debug.g_err_stage:= 'task table/proj fp options table have no records. Returning from make_new_tasks_plannable ';
6114 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6115 END IF;
6116
6117 RETURN;
6118
6119 END IF;
6120
6121 IF l_debug_mode = 'Y' THEN
6122 pa_debug.g_err_stage:= 'task table has records.';
6123 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6124 END IF;
6125
6126 /* Loop through the table and process the task records */
6127
6128 FOR i IN p_tasks_tbl.first .. p_tasks_tbl.last
6129 LOOP
6130 /* If the task is a middle level task delete all the references of that task from
6131 pa_fp_elements and pa_resource_assignments */
6132
6133 IF l_debug_mode = 'Y' THEN
6134 pa_debug.g_err_stage:= 'task_id ' || p_tasks_tbl(i).task_id;
6135 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6136 pa_debug.g_err_stage:= 'task_level ' || p_tasks_tbl(i).task_level;
6137 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6138 END IF;
6139
6140 IF p_tasks_tbl(i).task_level = L_TASK_LEVEL_MIDDLE THEN
6141
6142 --Delete the task references from pa_fp_elements
6143 FORALL k IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last
6144 DELETE
6145 FROM pa_fp_elements
6146 WHERE task_id = p_tasks_tbl(i).task_id
6147 AND proj_fp_options_id = p_refresh_fp_options_tbl(k); /* We are deleting irrespective of element_type */
6148
6149 IF l_debug_mode = 'Y' THEN
6150 pa_debug.g_err_stage:= 'No of records deleted from pa_fp_elements ' ||SQL%ROWCOUNT;
6151 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6152 END IF;
6153
6154 --Delete the task references from pa_resource_assignments
6155 FORALL k IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last
6156 DELETE
6157 FROM pa_resource_assignments pra
6158 WHERE pra.task_id = p_tasks_tbl(i).task_id
6159 AND pra.budget_version_id in (SELECT pfo.fin_plan_version_id
6160 FROM pa_proj_fp_options pfo
6161 WHERE pfo.proj_fp_options_id =
6162 p_refresh_fp_options_tbl(k))
6163 AND pra.resource_assignment_type = PA_FP_CONSTANTS_PKG.G_USER_ENTERED;
6164
6165 IF l_debug_mode = 'Y' THEN
6166 pa_debug.g_err_stage:= 'No of records deleted from pa_resource_assignments ' ||SQL%ROWCOUNT;
6167 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6168 END IF;
6169
6170 END IF; /* IF p_tasks_tbl(i).task_level = M */
6171
6172 END LOOP; /* FOR i IN p_tasks_tbl.first .. p_tasks_tbl.last */
6173
6174 --Loop through the table and process the option records
6175 FOR j IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last LOOP
6176
6177 IF l_debug_mode = 'Y' THEN
6178 pa_debug.g_err_stage:= 'Opening fp_options_info_cur';
6179 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6180 END IF;
6181
6182 OPEN fp_options_info_cur(p_refresh_fp_options_tbl(j));
6183 FETCH fp_options_info_cur INTO fp_options_info_rec;
6184 IF fp_options_info_cur%NOTFOUND THEN
6185
6186 IF l_debug_mode = 'Y' THEN
6187 pa_debug.g_err_stage:= 'fp_options_info_cur did not return rows for option id '||p_refresh_fp_options_tbl(j);
6188 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6189 END IF;
6190 CLOSE fp_options_info_cur;
6191 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6192
6193 ELSE
6194 CLOSE fp_options_info_cur;
6195 l_process_option := 'Y' ;
6196 END IF;
6197
6198 IF l_process_option= 'Y' THEN
6199
6200 IF l_debug_mode = 'Y' THEN
6201 pa_debug.g_err_stage:= 'About to process the option id '||p_refresh_fp_options_tbl(j);
6202 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6203 END IF;
6204
6205 IF fp_options_info_rec.fin_plan_preference_code IN
6206 (PA_FP_CONSTANTS_PKG.G_PREF_COST_ONLY,
6207 PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SEP) THEN
6208
6209 IF fp_options_info_rec.cost_fin_plan_level_code <>
6210 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
6211
6212 add_tasks_to_option (p_proj_fp_options_id => p_refresh_fp_options_tbl(j)
6213 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST
6214 ,p_tasks_tbl => p_tasks_tbl
6215 ,x_return_status => x_return_status
6216 ,x_msg_count => x_msg_count
6217 ,x_msg_data => x_msg_data);
6218
6219 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6220
6221 pa_debug.g_err_stage := 'Error while adding tasks to cost option id ' || p_refresh_fp_options_tbl(j);
6222 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6223
6224 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6225
6226 END IF;
6227
6228 END IF; /* fp_options_info_rec.cost_fin_plan_level_code <> 'P' */
6229
6230 END IF; /* fp_options_info_rec.cost_fin_plan_level_code IN (COST_ONLY, COST_AND_REV_SEP */
6231
6232 IF fp_options_info_rec.fin_plan_preference_code IN
6233 (PA_FP_CONSTANTS_PKG.G_PREF_REVENUE_ONLY,
6234 PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SEP) THEN
6235
6236 IF fp_options_info_rec.revenue_fin_plan_level_code <>
6237 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
6238
6239 add_tasks_to_option (p_proj_fp_options_id => p_refresh_fp_options_tbl(j)
6240 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE
6241 ,p_tasks_tbl => p_tasks_tbl
6242 ,x_return_status => x_return_status
6243 ,x_msg_count => x_msg_count
6244 ,x_msg_data => x_msg_data);
6245
6246 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6247
6248 pa_debug.g_err_stage := 'Error while adding task id to revenue option id '
6249 || p_refresh_fp_options_tbl(j);
6250 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6251 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6252
6253 END IF;
6254
6255 END IF; /* fp_options_info_rec.fin_plan_preference_code <> 'P' */
6256
6257 END IF; /* fp_options_info_rec.revenue_fin_plan_level_code IN (REVENUE_ONLY, COST_AND_REV_SEP) */
6258
6259 IF fp_options_info_rec.fin_plan_preference_code in (PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SAME) THEN
6260
6261 IF fp_options_info_rec.all_fin_plan_level_code <>
6262 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
6263
6264 add_tasks_to_option (p_proj_fp_options_id => p_refresh_fp_options_tbl(j)
6265 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL
6266 ,p_tasks_tbl => p_tasks_tbl
6267 ,x_return_status => x_return_status
6268 ,x_msg_count => x_msg_count
6269 ,x_msg_data => x_msg_data);
6270
6271 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6272
6273 pa_debug.g_err_stage := 'Error while adding task id to ALL option id '
6274 || p_refresh_fp_options_tbl(j);
6275 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6276
6277 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6278
6279 END IF;
6280
6281 END IF; /* fp_options_info_rec.all_fin_plan_level_code <> 'P' */
6282
6283 END IF; /* fp_options_info_rec.fin_plan_preference_code IN (COST_AND_REV_SAME) */
6284
6285 END IF; /* l_process_option = 'Y' */
6286
6287 END LOOP; /* FOR j IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last */
6288
6289 IF l_debug_mode = 'Y' THEN
6290 pa_debug.g_err_stage:= 'Exiting make_new_tasks_plannable';
6291 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6292 pa_debug.reset_curr_function;
6293 END IF;
6294
6295
6296 EXCEPTION
6297
6298 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
6299
6300 x_return_status := FND_API.G_RET_STS_ERROR;
6301 l_msg_count := FND_MSG_PUB.count_msg;
6302
6303 IF l_msg_count = 1 and x_msg_data IS NULL THEN
6304 PA_INTERFACE_UTILS_PUB.get_messages
6305 (p_encoded => FND_API.G_TRUE
6306 ,p_msg_index => 1
6307 ,p_msg_count => l_msg_count
6308 ,p_msg_data => l_msg_data
6309 ,p_data => l_data
6310 ,p_msg_index_out => l_msg_index_out);
6311 x_msg_data := l_data;
6312 x_msg_count := l_msg_count;
6313 ELSE
6314 x_msg_count := l_msg_count;
6315 END IF;
6316 IF l_debug_mode = 'Y' THEN
6317 pa_debug.reset_curr_function;
6318 END IF;
6319 RETURN;
6320
6321 WHEN others THEN
6322
6323 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6324 x_msg_count := 1;
6325 x_msg_data := SQLERRM;
6326
6327 FND_MSG_PUB.add_exc_msg
6328 ( p_pkg_name => 'pa_fp_elements_pub'
6329 ,p_procedure_name => 'make_new_tasks_plannable'
6330 ,p_error_text => x_msg_data);
6331
6332 IF l_debug_mode = 'Y' THEN
6333 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
6334 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6335 pa_debug.reset_curr_function;
6336 END IF;
6337
6338 RAISE;
6339 END make_new_tasks_plannable;
6340
6341
6342 /* Bug 2920954 - This API does the bulk processing necessary to add and
6343 remove plannable tasks as a result of changes to the WBS. The api has
6344 to be called once for all impacted tasks. Impacted task here means,
6345 that task on which the action is taken and/or whose parent has changed. */
6346
6347 /* Valid values of ACTION in p_impacted_tasks_tbl are
6348 'INSERT','REPARENT','DELETE'
6349
6350 Please note that p_impacted_tasks_tbl has no relation to the impacted task of a CI version
6351
6352 When action is 'INSERT' the plsql record should contain the following:
6353 Impacted_task_id,
6354 New_parent_task_id,
6355 Top_task_id
6356 When the action is 'REPARENT' the plsql record should contain the following:
6357 Impacted_task_id,
6358 Old_parent_task_id,
6359 New_parent_task_id,
6360 Top_task_id
6361 When action is 'DELETE' the plsql record should contain the following:
6362 Impacted_task_id,
6363 Old_parent_task_id,
6364 Top_task_id
6365
6366 Assumptions:
6367 1. A task id cannot be present more than once as impacted_task_id in the
6368 p_impacted_tasks_tbl input parameter.
6369 2. When the action is DELETE, only the task that is deleted is passed in the
6370 plsql table and not all the tasks below the deleted task.
6371 3. The order of task records in the input plsql table p_impacted_tasks_tbl
6372 under a top task is same as the order of the tasks in the WBS, i.e.,
6373 task 2.0 would appear before any of its lowest tasks in the plsql table,
6374 if any. Its ok, if task 3.0 appears after task 4.0. The assumption is that
6375 3.1 cannot appear before 3.0.
6376 4. When action is INSERT and REPARENT, we assume that the operation INSERT/REPARENT
6377 operation has already been done for the tasks. But when action is DELETE,
6378 we assume that the tasks would be deleted only after the bulk api is called.
6379 5. This api would not be called for organization forecasting projects
6380
6381 Bug 2976168. This api is NOT being called now for INSERT and REPARENT. This api will be
6382 called only in the case of DELETE.
6383
6384 */
6385
6386 PROCEDURE maintain_plannable_tasks
6387 (p_project_id IN pa_projects_all.project_id%TYPE
6388 ,p_impacted_tasks_tbl IN l_impacted_task_in_tbl_typ
6389 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
6390 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
6391 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
6392 AS
6393 l_msg_count NUMBER := 0;
6394 l_data VARCHAR2(2000);
6395 l_msg_data VARCHAR2(2000);
6396 l_msg_index_out NUMBER;
6397 l_debug_mode VARCHAR2(1);
6398
6399 L_DEBUG_LEVEL2 CONSTANT NUMBER := 2;
6400 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
6401 L_DEBUG_LEVEL4 CONSTANT NUMBER := 4;
6402 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
6403
6404 L_ACTION_INSERT CONSTANT VARCHAR2(30) := 'INSERT';
6405 L_ACTION_REPARENT CONSTANT VARCHAR2(30) := 'REPARENT';
6406 L_ACTION_DELETE CONSTANT VARCHAR2(30) := 'DELETE';
6407
6408 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
6409 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
6410 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
6411
6412 TYPE l_char_typ IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
6413
6414 /* Indicates if financial planning options have been setup for the project.
6415 0 - Financial planning option has NOT been setup for the project
6416 1 - Financial planning option has been created for the project
6417 Other numbers - Sql error */
6418
6419 l_option_exists NUMBER;
6420
6421 /* Contains Y if no option exists for the project or
6422 p_impacted_tasks_tbl is empty */
6423
6424 l_continue_processing_flag VARCHAR2(1);
6425
6426 /* Indicates if task has to made be plannable. Used when action is INSERT */
6427
6428 l_make_task_plannable VARCHAR2(1);
6429
6430 /* Plsql table that contains the tasks in p_impacted_tasks_tbl
6431 for which child tasks exists */
6432
6433 l_middle_task_tbl l_char_typ;
6434
6435 /* Plsql table that contains the tasks in p_impacted_tasks_tbl
6436 that have been made plannable */
6437
6438 l_task_made_plannable_tbl l_char_typ;
6439
6440 /* Plsql table that contains the tasks in p_impacted_tasks_tbl
6441 that have been made unplannable */
6442
6443 l_tasks_removed_tbl l_char_typ;
6444
6445 l_records_deleted NUMBER;
6446
6447 /* start of Bug 3342975 */
6448
6449 CURSOR check_options_exists_cur
6450 IS
6451 select 1
6452 from sys.dual
6453 where exists
6454 (select 1 from pa_proj_fp_options
6455 where project_id = p_project_id);
6456
6457 /* end of Bug 3342975 */
6458 /* The below declarations are for Bug 2976168 */
6459
6460 CURSOR all_fp_options_cur
6461 IS
6462 SELECT pfo.proj_fp_options_id
6463 FROM pa_proj_fp_options pfo
6464 WHERE pfo.project_id = p_project_id
6465 AND pfo.fin_plan_option_level_code <> PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION
6466 UNION ALL
6467 SELECT pfo.proj_fp_options_id
6468 FROM pa_budget_versions bv,
6469 pa_proj_fp_options pfo
6470 WHERE bv.project_id = p_project_id
6471 AND pfo.fin_plan_option_level_code = PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION
6472 AND bv.budget_status_code <> PA_FP_CONSTANTS_PKG.G_BUDGET_STATUS_BASELINED /* Should not modify baselined versions */
6473 AND pfo.project_id = bv.project_id
6474 AND pfo.fin_plan_type_id = bv.fin_plan_type_id
6475 AND pfo.fin_plan_version_id = bv.budget_version_id;
6476
6477 l_all_fp_options_tbl PA_PLSQL_DATATYPES.IdTabTyp;
6478
6479 --If the task is not a top task , this cursor always returns L as the task level as all the middle
6480 --level would have been eliminated by the time this cursor is opened.
6481
6482 CURSOR task_info_cur(c_task_id pa_tasks.task_id%TYPE) IS
6483 SELECT pt.top_task_id top_task_id
6484 ,pt.parent_task_id parent_task_id
6485 ,DECODE(c_task_id,
6486 pt.top_task_id,L_TASK_LEVEL_TOP,
6487 L_TASK_LEVEL_LOWEST) task_level
6488 FROM pa_tasks pt
6489 WHERE pt.task_id = c_task_id;
6490
6491 task_info_rec task_info_cur%ROWTYPE;
6492
6493 l_wbs_refresh_tasks_tbl l_wbs_refresh_tasks_tbl_typ;
6494
6495 /****** This is a LOCAL function to the bulk api which checks if a task is middle level task
6496 ****** by checking l_middle_task_tbl and then the db. */
6497
6498 FUNCTION is_middle_level_task(p_task_id pa_tasks.task_id%TYPE,
6499 p_top_task_id pa_tasks.task_id%TYPE)
6500 RETURN VARCHAR2 IS
6501
6502 /* Indicates if child tasks exists for a particular task.
6503 0 - Child task does NOT exists
6504 1 - Child task exists
6505 Other numbers - Sql error */
6506
6507 l_child_task_exists NUMBER;
6508
6509 BEGIN
6510
6511
6512 IF l_middle_task_tbl.exists(p_task_id) THEN
6513
6514 /* Middle level task and this need NOT be inserted into pa_fp_elements */
6515
6516 return 'N';
6517
6518 ELSIF p_top_task_id = p_task_id THEN
6519
6520 /* Top task needs to be processed */
6521
6522 return 'Y';
6523
6524 ELSE
6525
6526 /* Refer db to know if the impacted_task_id is a middle level task.
6527 Child exists would mean that it is a middle level task (since we have eliminated
6528 top task records in the above condition). */
6529
6530 l_child_task_exists := pa_task_utils.check_child_exists(x_task_id => p_task_id);
6531
6532 IF l_child_task_exists = 1 THEN
6533
6534 /* Child task exists. So, impacted task is a middle level task */
6535
6536 l_middle_task_tbl(p_task_id) := 'Y';
6537
6538 return 'N';
6539
6540 ELSIF l_child_task_exists = 0 THEN
6541
6542 /* Child tasks donot exists. So, the task is a lowest level task */
6543 return 'Y';
6544
6545 ELSE
6546
6547 /* Oracle error returned */
6548
6549 IF l_debug_mode = 'Y' THEN
6550
6551 pa_debug.g_err_stage:= 'Oracle error occurred while calling check_child_exists. Sqlerrcode ' || to_char(l_child_task_exists);
6552 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6553
6554 END IF;
6555
6556 RAISE FND_API.G_Exc_Unexpected_Error;
6557
6558 END IF; /* l_child_tasks_exists = 1 */
6559
6560 END IF; /* l_middle_task_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id) */
6561
6562 END is_middle_level_task;
6563
6564 /****** END of function is_middle_level_task which is a local procedure to maintain_plannable_tasks ******/
6565
6566 BEGIN
6567
6568 x_msg_count := 0;
6569 x_return_status := FND_API.G_RET_STS_SUCCESS;
6570 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
6571
6572 IF l_debug_mode = 'Y' THEN
6573 pa_debug.set_curr_function( p_function => 'maintain_plannable_tasks',
6574 p_debug_mode => l_debug_mode );
6575 END IF;
6576
6577 -- Check for business rules violations
6578
6579 IF l_debug_mode = 'Y' THEN
6580 pa_debug.g_err_stage:= 'Validating input parameters';
6581 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6582 L_DEBUG_LEVEL3);
6583 END IF;
6584
6585 IF (p_project_id IS NULL) THEN
6586
6587 IF l_debug_mode = 'Y' THEN
6588 pa_debug.g_err_stage:= 'p_project_id = '|| p_project_id;
6589 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6590 L_DEBUG_LEVEL5);
6591 END IF;
6592 PA_UTILS.ADD_MESSAGE
6593 (p_app_short_name => 'PA',
6594 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6595 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6596
6597 END IF;
6598
6599 /* Checking if financial planning option have been setup for the task's project */
6600 /* commented for bug 3342975
6601 l_option_exists := pa_fin_plan_utils.Check_Proj_Fp_Options_Exists(p_project_id => p_project_id);
6602 start of bug 3342975
6603 */
6604 OPEN check_options_exists_cur;
6605 FETCH check_options_exists_cur
6606 INTO l_option_exists;
6607 IF check_options_exists_cur%NOTFOUND THEN
6608 l_option_exists := 0;
6609 END IF;
6610 CLOSE check_options_exists_cur;
6611 /* end of bug 3342975 */
6612 IF l_debug_mode = 'Y' THEN
6613 pa_debug.g_err_stage:= 'Option Exists for project id: '
6614 || to_char(p_project_id) || ' is '
6615 || l_option_exists;
6616 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6617 L_DEBUG_LEVEL3);
6618 pa_debug.g_err_stage:= 'Number of tasks to be processed: '
6619 || to_char(p_impacted_tasks_tbl.count);
6620 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6621 L_DEBUG_LEVEL3);
6622 END IF;
6623
6624 /* No processing is required if financial planning options
6625 have not been setup for the project or if the i/p tasks
6626 plsql table is empty */
6627
6628 IF l_option_exists = 0 OR p_impacted_tasks_tbl.count = 0 THEN
6629
6630 l_continue_processing_flag := 'N';
6631
6632 ELSIF l_option_exists = 1 THEN
6633
6634 l_continue_processing_flag := 'Y';
6635
6636 /* For bug 2976168. Store the options in a pl/sql table so that they can be
6637 passed to make_new_tasks_plannable api later. */
6638
6639 OPEN all_fp_options_cur;
6640 FETCH all_fp_options_cur
6641 BULK COLLECT INTO l_all_fp_options_tbl;
6642 CLOSE all_fp_options_cur;
6643
6644 ELSIF l_option_exists NOT IN (1,0) THEN
6645
6646 /* Unexpected oracle error */
6647
6648 IF l_debug_mode = 'Y' THEN
6649 pa_debug.g_err_stage:= 'Check_Proj_Fp_Options_Exists returned oracle error ' ||
6650 to_char(l_option_exists);
6651 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6652 L_DEBUG_LEVEL5);
6653 END IF;
6654
6655 Raise PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6656
6657 END IF;
6658
6659 IF l_continue_processing_flag = 'Y' THEN
6660
6661 /* Multiple tasks can be inserted, reparented or deleted.
6662
6663 Caching is implemented so that
6664
6665 1. We need not call make_new_tasks_plannable for a task that is already made plannable.
6666 2. We do not have to call delete_task_elements for the new parent task (to make it
6667 unplannable) if it has already been made unplannable.
6668
6669 To achieve this check if the inserted task is a middle level task. Since middle level
6670 task need not be inserted, we can store middle level tasks (new_parent_task_id) in
6671 l_middle_task_tbl plsql table. If l_middle_task_tbl plsql table doesnt contain an
6672 entry for a task id, only then we refer the database to check if the task is a
6673 middle level task and if so, cache it in the plsql table. */
6674
6675 IF l_debug_mode = 'Y' THEN
6676 pa_debug.g_err_stage:= 'Identifying middle level tasks by looping the p_impacted_tasks_tbl';
6677 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6678 L_DEBUG_LEVEL3);
6679 END IF;
6680
6681 FOR I in p_impacted_tasks_tbl.first .. p_impacted_tasks_tbl.last LOOP
6682
6683 /* If parent task exists for impacted_task_id and
6684 if impacted_task's parent is not a top task, it means
6685 impacted task's parent is a middle level task */
6686
6687 IF p_impacted_tasks_tbl(i).new_parent_task_id IS NOT NULL AND
6688 p_impacted_tasks_tbl(i).new_parent_task_id <> p_impacted_tasks_tbl(i).top_task_id THEN
6689
6690 l_middle_task_tbl(p_impacted_tasks_tbl(i).new_parent_task_id) := 'Y';
6691
6692 END IF;
6693
6694 END LOOP;
6695
6696 FOR I in p_impacted_tasks_tbl.first .. p_impacted_tasks_tbl.last LOOP
6697
6698 IF l_debug_mode = 'Y' THEN
6699
6700 pa_debug.g_err_stage:= 'impacted task id is ' || p_impacted_tasks_tbl(i).impacted_task_id;
6701 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6702 pa_debug.g_err_stage:= 'old parent task id is ' || p_impacted_tasks_tbl(i).old_parent_task_id;
6703 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6704 pa_debug.g_err_stage:= 'new parent task id is ' || p_impacted_tasks_tbl(i).new_parent_task_id;
6705 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6706 pa_debug.g_err_stage:= 'top task id is ' || p_impacted_tasks_tbl(i).top_task_id;
6707 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6708 pa_debug.g_err_stage:= 'action is ' || p_impacted_tasks_tbl(i).action;
6709 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6710
6711 END IF;
6712
6713 l_make_task_plannable := Null;
6714
6715 IF p_impacted_tasks_tbl(i).action = L_ACTION_INSERT THEN
6716
6717 IF p_impacted_tasks_tbl(i).impacted_task_id IS NULL OR
6718 (p_impacted_tasks_tbl(i).impacted_task_id <> p_impacted_tasks_tbl(i).top_task_id AND
6719 p_impacted_tasks_tbl(i).new_parent_task_id IS NULL) OR
6720 p_impacted_tasks_tbl(i).top_task_id IS NULL THEN
6721
6722 IF l_debug_mode = 'Y' THEN
6723 pa_debug.g_err_stage:= 'For INSERT action : ' ||
6724 'Impacted_task_id, New_parent_task_id, Top_task_id should be passed';
6725 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6726 END IF;
6727 PA_UTILS.ADD_MESSAGE
6728 (p_app_short_name => 'PA',
6729 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6730 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6731
6732 END IF;
6733
6734 /* If Impacted task has already been added as plannable task, we need not be
6735 adding it once again */
6736
6737 IF NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id)) THEN
6738
6739 /* Calling local function is_middle_level_task to check
6740 if impacted task id is a middle level task */
6741
6742 l_make_task_plannable :=
6743 is_middle_level_task(p_task_id => p_impacted_tasks_tbl(i).impacted_task_id,
6744 p_top_task_id => p_impacted_tasks_tbl(i).top_task_id);
6745
6746 IF l_debug_mode = 'Y' THEN
6747
6748 pa_debug.g_err_stage:= 'l_make_task_plannable = ' || l_make_task_plannable;
6749 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6750
6751 END IF;
6752
6753 IF l_make_task_plannable = 'Y' THEN
6754
6755 /* If Impacted task has already been added as plannable task, we need not be
6756 adding it once again */
6757
6758 IF l_debug_mode = 'Y' THEN
6759
6760 pa_debug.g_err_stage:= 'Calling make_new_tasks_plannable for impacted task id';
6761 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6762
6763 END IF;
6764
6765 /* Calling pa_fp_elements_pub.make_new_tasks_plannable for impacted task id */
6766
6767 /* For Bug 2976168. Modified the call to make new task plannable api.
6768
6769 PA_FP_ELEMENTS_PUB.make_new_task_plannable
6770 ( p_project_id => p_project_id
6771 ,p_task_id => p_impacted_tasks_tbl(i).impacted_task_id
6772 ,x_return_status => x_return_status
6773 ,x_msg_count => x_msg_count
6774 ,x_msg_data => x_msg_data);
6775
6776 */
6777
6778 OPEN task_info_cur(p_impacted_tasks_tbl(i).impacted_task_id);
6779 FETCH task_info_cur INTO task_info_rec;
6780 CLOSE task_info_cur;
6781
6782 l_wbs_refresh_tasks_tbl(1).task_id := p_impacted_tasks_tbl(i).impacted_task_id;
6783 l_wbs_refresh_tasks_tbl(1).parent_task_id := task_info_rec.parent_task_id;
6784 l_wbs_refresh_tasks_tbl(1).top_task_id := task_info_rec.top_task_id;
6785 l_wbs_refresh_tasks_tbl(1).task_level := task_info_rec.task_level;
6786
6787 PA_FP_ELEMENTS_PUB.make_new_tasks_plannable
6788 ( p_project_id => p_project_id
6789 ,p_tasks_tbl => l_wbs_refresh_tasks_tbl
6790 ,p_refresh_fp_options_tbl => l_all_fp_options_tbl
6791 ,x_return_status => x_return_status
6792 ,x_msg_count => x_msg_count
6793 ,x_msg_data => x_msg_data);
6794
6795
6796 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6797
6798 IF l_debug_mode = 'Y' THEN
6799 pa_debug.g_err_stage:= 'Error returned by make_new_tasks_plannable for task_id ' ||
6800 p_impacted_tasks_tbl(i).impacted_task_id;
6801 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6802 END IF;
6803
6804 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6805
6806 END IF;
6807
6808 l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).impacted_task_id) := 'Y';
6809
6810 END IF; /* l_make_task_plannable = 'Y' */
6811
6812 END IF; /* l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id) */
6813
6814 /* For reparenting old parent need to be made plannable if its a lowest task now and
6815 new parent need to be removed */
6816
6817 ELSIF p_impacted_tasks_tbl(i).action = L_ACTION_REPARENT THEN
6818
6819 IF p_impacted_tasks_tbl(i).impacted_task_id IS NULL OR
6820 p_impacted_tasks_tbl(i).new_parent_task_id IS NULL OR
6821 p_impacted_tasks_tbl(i).old_parent_task_id IS NULL OR
6822 p_impacted_tasks_tbl(i).top_task_id IS NULL THEN
6823
6824 IF l_debug_mode = 'Y' THEN
6825 pa_debug.g_err_stage:= 'For REPARENT action : ' ||
6826 'Impacted_task_id, New_parent_task_id, old_parent_task_id, Top_task_id should be passed';
6827 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6828 END IF;
6829 PA_UTILS.ADD_MESSAGE
6830 (p_app_short_name => 'PA',
6831 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6832 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6833
6834 END IF;
6835
6836 /* If old parent task and new parent task are same, no need to do any processing since
6837 no reparenting has happened */
6838
6839 IF p_impacted_tasks_tbl(i).old_parent_task_id <> p_impacted_tasks_tbl(i).new_parent_task_id THEN
6840
6841 /* If old parent task has already been added then
6842 nothing needs to be done for this */
6843
6844 IF NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).old_parent_task_id)) THEN
6845
6846 /* Calling is_middle_level_task to check if old parent task id is a middle level task */
6847
6848 l_make_task_plannable :=
6849 is_middle_level_task(p_task_id => p_impacted_tasks_tbl(i).old_parent_task_id,
6850 p_top_task_id => pa_task_utils.get_top_task_id(x_task_id => p_impacted_tasks_tbl(i).old_parent_task_id));
6851
6852 IF l_debug_mode = 'Y' THEN
6853
6854 pa_debug.g_err_stage:= 'l_make_task_plannable = ' || l_make_task_plannable;
6855 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6856
6857 END IF;
6858
6859 /* If old task is a middle level task then
6860 nothing needs to be done for this */
6861
6862 IF l_make_task_plannable = 'Y' THEN
6863
6864 IF l_debug_mode = 'Y' THEN
6865
6866 pa_debug.g_err_stage:= 'Calling make_new_tasks_plannable for old parent task id';
6867 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6868
6869 END IF;
6870
6871 /* Calling pa_fp_elements_pub.make_new_tasks_plannable for old parent task id */
6872
6873 /* Bug 2976168. Changed the way make_new_task_plannable is called
6874
6875 PA_FP_ELEMENTS_PUB.make_new_task_plannable
6876 ( p_project_id => p_project_id
6877 ,p_task_id => p_impacted_tasks_tbl(i).old_parent_task_id
6878 ,x_return_status => x_return_status
6879 ,x_msg_count => x_msg_count
6880 ,x_msg_data => x_msg_data);
6881 */
6882
6883 OPEN task_info_cur(p_impacted_tasks_tbl(i).old_parent_task_id);
6884 FETCH task_info_cur INTO task_info_rec;
6885 CLOSE task_info_cur;
6886
6887 l_wbs_refresh_tasks_tbl(1).task_id := p_impacted_tasks_tbl(i).old_parent_task_id;
6888 l_wbs_refresh_tasks_tbl(1).parent_task_id := task_info_rec.parent_task_id;
6889 l_wbs_refresh_tasks_tbl(1).top_task_id := task_info_rec.top_task_id;
6890 l_wbs_refresh_tasks_tbl(1).task_level := task_info_rec.task_level;
6891
6892 PA_FP_ELEMENTS_PUB.make_new_tasks_plannable
6893 ( p_project_id => p_project_id
6894 ,p_tasks_tbl => l_wbs_refresh_tasks_tbl
6895 ,p_refresh_fp_options_tbl => l_all_fp_options_tbl
6896 ,x_return_status => x_return_status
6897 ,x_msg_count => x_msg_count
6898 ,x_msg_data => x_msg_data);
6899
6900 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6901
6902 IF l_debug_mode = 'Y' THEN
6903 pa_debug.g_err_stage:= 'Error returned by make_new_tasks_plannable for task_id ' ||
6904 p_impacted_tasks_tbl(i).old_parent_task_id;
6905 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6906 END IF;
6907
6908 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6909
6910 END IF;
6911
6912 l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).old_parent_task_id) := 'Y';
6913
6914 END IF; /* l_make_task_plannable = 'Y' */
6915
6916 END IF; /* NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).old_parent_task_id)) THEN */
6917
6918 /* Note for removing new parent as plannable:
6919
6920 1. If it was a Top task earlier then no action required as none of its attribute changes.
6921 2. If it was a middle level task earlier then also no action required.
6922 3. New parent need to be removed from all options only if it was a lowest task earlier.
6923
6924 Only way to know if the task was earlier a lowest task can be to look into any of the
6925 existing option and see if this is plannable. */
6926
6927 IF NOT(l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).new_parent_task_id)) THEN
6928
6929 /* Check if new_parent_task_id is not a TOP task */
6930
6931 IF pa_task_utils.get_top_task_id(x_task_id => p_impacted_tasks_tbl(i).new_parent_task_id)
6932 <> p_impacted_tasks_tbl(i).new_parent_task_id THEN
6933
6934 /* Check if it exists in pa_fp_elements. If yes, then its a lowest task */
6935
6936 IF pa_fin_plan_utils.check_task_in_fp_option(p_task_id => p_impacted_tasks_tbl(i).new_parent_task_id) = 'Y' THEN
6937 /* Delete planning elements and resource assignments for new parent task id.
6938 Pls note that delete task elements deletes the task and its children from
6939 all plan options. Hence we cannot call it since it might delete a
6940 plannable impacted task also from pa_fp_elements and pa_resource_assignments */
6941
6942 IF l_debug_mode = 'Y' THEN
6943
6944 pa_debug.g_err_stage:= 'Deleting task fp elements for new parent task id';
6945 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6946
6947 END IF;
6948
6949 DELETE FROM pa_fp_elements e
6950 WHERE e.task_id = p_impacted_tasks_tbl(i).new_parent_task_id;
6951
6952 l_records_deleted := sql%rowcount;
6953
6954 IF l_debug_mode = 'Y' THEN
6955 pa_debug.g_err_stage:= To_char(l_records_deleted) || ' records deleted.';
6956 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6957 L_DEBUG_LEVEL3);
6958 END IF;
6959
6960 IF l_records_deleted <> 0 THEN
6961
6962 IF l_debug_mode = 'Y' THEN
6963 pa_debug.g_err_stage:= 'Deleting from pa_resource_assignments for task id ' || to_char(p_impacted_tasks_tbl(i).new_parent_task_id);
6964 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6965 L_DEBUG_LEVEL3);
6966 END IF;
6967
6968 DELETE FROM pa_resource_assignments r
6969 WHERE r.task_id = p_impacted_tasks_tbl(i).new_parent_task_id;
6970
6971 l_records_deleted := sql%rowcount;
6972
6973 IF l_debug_mode = 'Y' THEN
6974 pa_debug.g_err_stage:= To_char(l_records_deleted) || ' records deleted.';
6975 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6976 L_DEBUG_LEVEL3);
6977 END IF;
6978
6979 END IF;
6980
6981 l_tasks_removed_tbl(p_impacted_tasks_tbl(i).new_parent_task_id) := 'Y';
6982
6983 END IF; /* pa_fin_plan_utils.task_exists_in_option(p_task_id => p_impacted_tasks_tbl(i).new_parent_task_id) = 'Y' */
6984
6985 END IF; /* pa_task_utils.get_top_task_id(x_task_id => p_impacted_tasks_tbl(i).new_parent_task_id)
6986 <> p_impacted_tasks_tbl(i).new_parent_task_id */
6987
6988 END IF; /* l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).new_parent_task_id) */
6989
6990 END IF; /* p_impacted_tasks_tbl(i).old_parent_task_id <> p_impacted_tasks_tbl(i).new_parent_task_id */
6991
6992 ELSIF p_impacted_tasks_tbl(i).action = L_ACTION_DELETE THEN
6993
6994 IF p_impacted_tasks_tbl(i).impacted_task_id IS NULL OR
6995 (p_impacted_tasks_tbl(i).impacted_task_id <> p_impacted_tasks_tbl(i).top_task_id AND
6996 p_impacted_tasks_tbl(i).old_parent_task_id IS NULL) OR
6997 p_impacted_tasks_tbl(i).top_task_id IS NULL THEN
6998
6999 IF l_debug_mode = 'Y' THEN
7000 pa_debug.g_err_stage:= 'For DELETE action : ' ||
7001 'Impacted_task_id, old_parent_task_id, Top_task_id should be passed';
7002 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
7003 END IF;
7004 PA_UTILS.ADD_MESSAGE
7005 (p_app_short_name => 'PA',
7006 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
7007 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
7008
7009 END IF;
7010
7011 /* If impacted task has already been deleted then
7012 nothing needs to be done for this */
7013
7014 IF NOT(l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id)) THEN
7015
7016 IF l_debug_mode = 'Y' THEN
7017
7018 pa_debug.g_err_stage:= 'Calling delete_task_elements for impacted task id';
7019 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7020
7021 END IF;
7022
7023 /* Calling pa_fp_elements_pub.delete_task_elements for impacted task id */
7024 PA_FP_ELEMENTS_PUB.Delete_task_elements
7025 ( p_task_id => p_impacted_Tasks_tbl(i).impacted_task_id
7026 ,x_return_status => x_return_status
7027 ,x_msg_count => x_msg_count
7028 ,x_msg_data => x_msg_data);
7029
7030 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
7031
7032 IF l_debug_mode = 'Y' THEN
7033 pa_debug.g_err_stage:= 'Error returned by delete_task_elements for task_id ' ||
7034 p_impacted_tasks_tbl(i).impacted_task_id;
7035 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
7036 END IF;
7037
7038 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
7039
7040 END IF;
7041
7042 l_tasks_removed_tbl(p_impacted_tasks_tbl(i).impacted_task_id) := 'Y';
7043
7044 END IF; /* NOT(l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id)) */
7045
7046 /* Proceed only if old_parent_task_id has NOT already been added */
7047
7048 IF p_impacted_tasks_tbl(i).old_parent_task_id IS NOT NULL AND
7049 NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).old_parent_task_id)) THEN
7050
7051 /* We should not make the old_parent_task a plannable task if it is middle level task */
7052 /* Since tasks would not have yet been deleted, we need to check if the new parent would
7053 still be a middle level task after the impacted task id is deleted */
7054
7055 DECLARE
7056 cursor c1 is
7057 select 'N'
7058 from sys.dual
7059 where exists (SELECT null
7060 FROM pa_tasks
7061 where parent_task_id = p_impacted_tasks_tbl(i).old_parent_task_id
7062 and task_id <> p_impacted_tasks_tbl(i).impacted_task_id);
7063 BEGIN
7064 OPEN c1;
7065 FETCH c1 into l_make_task_plannable;
7066 IF c1%NOTFOUND THEN
7067 l_make_task_plannable := 'Y';
7068 END IF;
7069 CLOSE c1;
7070 END;
7071
7072 IF l_debug_mode = 'Y' THEN
7073
7074 pa_debug.g_err_stage:= 'l_make_task_plannable = ' || l_make_task_plannable;
7075 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7076
7077 END IF;
7078
7079 /* We need to call make new task plannable to add the old parent task id as plannable */
7080
7081 IF l_make_task_plannable = 'Y' THEN
7082
7083 IF l_debug_mode = 'Y' THEN
7084
7085 pa_debug.g_err_stage:= 'Calling make_new_tasks_plannable for old parent task id';
7086 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7087
7088 END IF;
7089
7090 /*
7091 Bug 2976168. Changed the way make_new_task_plannable is called
7092
7093 PA_FP_ELEMENTS_PUB.make_new_task_plannable
7094 ( p_project_id => p_project_id
7095 ,p_task_id => p_impacted_tasks_tbl(i).old_parent_task_id
7096 ,x_return_status => x_return_status
7097 ,x_msg_count => x_msg_count
7098 ,x_msg_data => x_msg_data);
7099 */
7100
7101 OPEN task_info_cur(p_impacted_tasks_tbl(i).impacted_task_id);
7102 FETCH task_info_cur INTO task_info_rec;
7103 CLOSE task_info_cur;
7104
7105 l_wbs_refresh_tasks_tbl(1).task_id := p_impacted_tasks_tbl(i).impacted_task_id;
7106 l_wbs_refresh_tasks_tbl(1).parent_task_id := task_info_rec.parent_task_id;
7107 l_wbs_refresh_tasks_tbl(1).top_task_id := task_info_rec.top_task_id;
7108 l_wbs_refresh_tasks_tbl(1).task_level := task_info_rec.task_level;
7109
7110 PA_FP_ELEMENTS_PUB.make_new_tasks_plannable
7111 ( p_project_id => p_project_id
7112 ,p_tasks_tbl => l_wbs_refresh_tasks_tbl
7113 ,p_refresh_fp_options_tbl => l_all_fp_options_tbl
7114 ,x_return_status => x_return_status
7115 ,x_msg_count => x_msg_count
7116 ,x_msg_data => x_msg_data);
7117
7118 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
7119
7120 IF l_debug_mode = 'Y' THEN
7121 pa_debug.g_err_stage:= 'Error returned by make_new_tasks_plannable for task_id ' ||
7122 p_impacted_tasks_tbl(i).old_parent_task_id;
7123 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
7124 END IF;
7125
7126 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
7127
7128 END IF;
7129
7130 l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).old_parent_task_id) := 'Y';
7131
7132 END IF; /* l_make_task_plannable = 'Y' */
7133
7134 END IF; /* p_impacted_tasks_tbl(i).old_parent_task_id IS NOT NULL AND
7135 NOT(l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).old_parent_task_id).exists) */
7136
7137 ELSE
7138
7139 /* Invalid action passed */
7140
7141 IF l_debug_mode = 'Y' THEN
7142 pa_debug.g_err_stage:= 'Invalid value for action passed. Action passed is ' ||
7143 p_impacted_tasks_tbl(i).action;
7144 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
7145 END IF;
7146
7147 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
7148
7149 END IF;
7150
7151 END LOOP;
7152
7153 /* Since planning elements have been modified for the proj fp option,
7154 we need to increase the record_version_number */
7155
7156 IF nvl(l_all_fp_options_tbl.last,0) >= 1 THEN /* only if something is fetched */
7157
7158 IF P_PA_DEBUG_MODE = 'Y' THEN
7159 pa_debug.g_err_stage := 'Updating pa_proj_fp_options with RVN and who columns.';
7160 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7161 END IF;
7162
7163 FORALL i in l_all_fp_options_tbl.first..l_all_fp_options_tbl.last
7164 UPDATE pa_proj_fp_options pfo
7165 SET pfo.record_version_number = pfo.record_version_number + 1,
7166 pfo.last_update_date = sysdate,
7167 pfo.last_updated_by = FND_GLOBAL.USER_ID,
7168 pfo.last_update_login = FND_GLOBAL.LOGIN_ID
7169 WHERE pfo.proj_fp_options_id = l_all_fp_options_tbl(i);
7170
7171 /* Since resource assignments might have been deleted and recreated
7172 for the new task, the version has been modified and its
7173 record version number has to be increased */
7174
7175 FORALL i in l_all_fp_options_tbl.first..l_all_fp_options_tbl.last
7176 UPDATE pa_budget_versions bv
7177 SET bv.record_version_number = bv.record_version_number + 1,
7178 bv.last_update_date = sysdate,
7179 bv.last_updated_by = FND_GLOBAL.USER_ID,
7180 bv.last_update_login = FND_GLOBAL.LOGIN_ID
7181 WHERE bv.budget_version_id in (SELECT pfo.fin_plan_version_id
7182 FROM pa_proj_fp_options pfo
7183 WHERE pfo.proj_fp_options_id = l_all_fp_options_tbl(i));
7184
7185 END IF; /* nvl(l_all_fp_options_tbl.last,0) >= 1 */
7186
7187 END IF; /* l_continue_processing_flag = 'Y' */
7188
7189 IF l_debug_mode = 'Y' THEN
7190 pa_debug.g_err_stage:= 'Exiting maintain_plannable_tasks';
7191 pa_debug.write(l_module_name,pa_debug.g_err_stage,
7192 L_DEBUG_LEVEL3);
7193 pa_debug.reset_curr_function;
7194 END IF;
7195
7196 EXCEPTION
7197
7198 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
7199
7200 x_return_status := FND_API.G_RET_STS_ERROR;
7201 l_msg_count := FND_MSG_PUB.count_msg;
7202
7203 IF l_msg_count = 1 and x_msg_data IS NULL THEN
7204 PA_INTERFACE_UTILS_PUB.get_messages
7205 (p_encoded => FND_API.G_TRUE
7206 ,p_msg_index => 1
7207 ,p_msg_count => l_msg_count
7208 ,p_msg_data => l_msg_data
7209 ,p_data => l_data
7210 ,p_msg_index_out => l_msg_index_out);
7211 x_msg_data := l_data;
7212 x_msg_count := l_msg_count;
7213 ELSE
7214 x_msg_count := l_msg_count;
7215 END IF;
7216
7217 IF l_debug_mode = 'Y' THEN
7218 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
7219 pa_debug.write(l_module_name,pa_debug.g_err_stage,
7220 L_DEBUG_LEVEL5);
7221 pa_debug.reset_curr_function;
7222 END IF;
7223
7224 RETURN;
7225
7226 WHEN others THEN
7227
7228 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7229 x_msg_count := 1;
7230 x_msg_data := SQLERRM;
7231
7232 FND_MSG_PUB.add_exc_msg
7233 ( p_pkg_name => 'pa_fp_elements_pub'
7234 ,p_procedure_name => 'maintain_plannable_tasks'
7235 ,p_error_text => x_msg_data);
7236
7237 IF l_debug_mode = 'Y' THEN
7238 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
7239 pa_debug.write(l_module_name,pa_debug.g_err_stage,
7240 L_DEBUG_LEVEL5);
7241 pa_debug.reset_curr_function;
7242 END IF;
7243 RAISE;
7244 END maintain_plannable_tasks;
7245
7246 End PA_FP_ELEMENTS_PUB;