1 package body PA_FP_ELEMENTS_PUB as
2 /* $Header: PAFPELPB.pls 120.2 2005/09/26 11:30:51 rnamburi noship $ */
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 l_rlm_id_tbl_tmp SYSTEM.PA_NUM_TBL_TYPE := SYSTEM.PA_NUM_TBL_TYPE();
3804 /*Bug # 3622551 --Added some parameters */
3805
3806 l_parent_structure_version_id pa_proj_element_versions.parent_structure_version_id%TYPE ;
3807 l_task_id_tmp_tbl SYSTEM.pa_num_tbl_type := SYSTEM.PA_NUM_TBL_TYPE();
3808
3809
3810 /*Bug # 3622551 -- Added a join to the cursor to get the value of wbs_element_version_id*/
3811 CURSOR res_assign_cur(c_version_id NUMBER
3812 ,c_parent_structure_version_id pa_proj_element_versions.parent_structure_version_id%TYPE) IS
3813 select distinct system_reference1 task_id
3814 ,system_reference2 resource_list_member_id
3815 ,system_reference4 unit_of_measure
3816 ,system_reference5 track_as_labor_flag
3817 ,decode(rollup.system_reference1,0,0,pelm.element_version_id) wbs_element_version_id
3818 /* included null columns after UT */
3819 -- ,null proj_raw_cost /* Bug 2677597 */
3820 -- ,null proj_burdened_cost
3821 -- ,null proj_revenue
3822 -- ,null projfunc_raw_cost
3823 -- ,null projfunc_burd_cost
3824 -- ,null projfunc_revenue
3825 -- ,null quantity
3826 from pa_fp_rollup_tmp rollup
3827 ,pa_proj_element_versions pelm
3828 where not exists
3829 (
3830 select pra.resource_assignment_id
3831 from pa_resource_assignments pra
3832 where pra.task_id=rollup.system_reference1
3833 and pra.resource_list_member_id = rollup.system_reference2
3834 and pra.budget_version_id = c_version_id
3835 )
3836 and decode(rollup.system_reference1,0,c_parent_structure_version_id,rollup.system_reference1)
3837 = decode(rollup.system_reference1,0,pelm.element_version_id,pelm.proj_element_id) -- Bug 3655290
3838 and pelm.parent_structure_version_id = c_parent_structure_version_id
3839 order by task_id,resource_list_member_id;
3840
3841 --Bug # 3507156 : Patchset M: B and F impact changes : AMG
3842 --Added a curosr to get the value of plan_class_code
3843
3844 CURSOR get_context_csr IS
3845 SELECT pfp.plan_class_code FROM pa_fin_plan_types_b pfp,pa_budget_versions pbv
3846 WHERE pfp.FIN_PLAN_TYPE_ID = pbv.FIN_PLAN_TYPE_ID
3847 AND pbv.budget_version_id =p_fin_plan_version_id ;
3848
3849 BEGIN
3850
3851 x_msg_count := 0;
3852 x_return_status := FND_API.G_RET_STS_SUCCESS;
3853 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.CREATE_ASSGMT_FROM_ROLLUPTMP');
3854 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
3855 l_debug_mode := NVL(l_debug_mode, 'Y');
3856 IF P_PA_DEBUG_MODE = 'Y' THEN
3857 pa_debug.set_process('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || 'PLSQL','LOG',l_debug_mode);
3858 END IF;
3859
3860 -- Check for business rules violations
3861
3862 pa_debug.g_err_stage:= 'Validating input parameters';
3863 IF P_PA_DEBUG_MODE = 'Y' THEN
3864 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3865 END IF;
3866
3867 --Validate plan version id
3868
3869 IF (p_fin_plan_version_id IS NULL)
3870 THEN
3871
3872 pa_debug.g_err_stage:= 'fin_plan_version_id = '|| p_fin_plan_version_id;
3873 IF P_PA_DEBUG_MODE = 'Y' THEN
3874 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
3875 END IF;
3876
3877 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
3878 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
3879
3880 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3881 END IF;
3882
3883 pa_debug.g_err_stage:= 'Obtain the relevant parameters for the version';
3884 IF P_PA_DEBUG_MODE = 'Y' THEN
3885 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3886 END IF;
3887
3888 BEGIN
3889 select opt.project_id,
3890 opt.proj_fp_options_id,
3891 pbv.version_type, -- Version type and element type are used interchangeably.
3892 pbv.resource_list_id
3893 into
3894 l_project_id
3895 ,l_fp_options_id
3896 ,l_element_type
3897 ,l_resource_list_id
3898 from pa_proj_fp_options opt,pa_budget_versions pbv
3899 where opt.fin_plan_version_id = pbv.budget_version_id
3900 and pbv.budget_version_id = p_fin_plan_version_id;
3901 EXCEPTION
3902 WHEN NO_DATA_FOUND THEN
3903 pa_debug.g_err_stage:= 'Could not get the details of the plan version option';
3904 IF P_PA_DEBUG_MODE = 'Y' THEN
3905 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3906 END IF;
3907 RAISE;
3908 END;
3909
3910 pa_debug.g_err_stage:= 'Create resource assignments - Bulk collect into the plsql tables';
3911 IF P_PA_DEBUG_MODE = 'Y' THEN
3912 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3913 END IF;
3914
3915 /*Bug # 3622551 -- Get the value of l_parent_structure_version_id */
3916 l_parent_structure_version_id := pa_project_structure_utils.get_fin_struc_ver_id(l_project_id);
3917
3918 OPEN res_assign_cur(p_fin_plan_version_id,l_parent_structure_version_id);
3919 LOOP
3920
3921 FETCH res_assign_cur
3922 BULK COLLECT INTO l_task_id_tbl
3923 ,l_resource_list_member_id_tbl
3924 ,l_unit_of_measure_tbl
3925 ,l_track_as_labor_flag_tbl
3926 ,l_task_elem_version_id_tbl
3927 -- ,l_proj_raw_cost_tbl /* Bug 2677597 */
3928 -- ,l_proj_burdened_cost_tbl
3929 -- ,l_proj_revenue_tbl
3930 -- ,l_projfunc_raw_cost_tbl
3931 -- ,l_projfunc_burd_cost_tbl
3932 -- ,l_projfunc_revenue_tbl
3933 -- ,l_quantity_tbl
3934 LIMIT g_plsql_max_array_size;
3935
3936 pa_debug.g_err_stage:= 'Create resource assignments - Call the API';
3937 IF P_PA_DEBUG_MODE = 'Y' THEN
3938 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3939 END IF;
3940
3941 -- getting the context
3942 OPEN get_context_csr ;
3943 FETCH get_context_csr INTO l_context ;
3944 CLOSE get_context_csr ;
3945
3946 IF(nvl(l_task_id_tbl.last,0) > 0) THEN
3947 /* Bug 4200168: calling add_planning_transactions with p_one_to_one_mapping as Y
3948 * and discarding the earlier logic to pass the cartesian product for task_id and rlm_id
3949 */
3950 pa_fp_planning_transaction_pub.add_planning_transactions
3951 (
3952 p_context => l_context
3953 ,p_one_to_one_mapping_flag => 'Y' /*Bug 4200168*/
3954 ,p_calling_module => 'CREATE_VERSION' -- Bug 3655290
3955 ,p_project_id => l_project_id
3956 ,p_budget_version_id => p_fin_plan_version_id
3957 ,p_task_elem_version_id_tbl => l_task_elem_version_id_tbl
3958 ,p_resource_list_member_id_tbl => l_resource_list_member_id_tbl
3959 ,x_return_status => x_return_status
3960 ,x_msg_count => x_msg_count
3961 ,x_msg_data => x_msg_data
3962 );
3963
3964 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
3965 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
3966 END IF;
3967
3968 END IF;
3969 EXIT WHEN nvl(l_task_id_tbl.last,0) < g_plsql_max_array_size;
3970 END LOOP;
3971
3972 --Update the roll up tmp table with the newly created resource assignment id.
3973 update pa_fp_rollup_tmp rollup
3974 set resource_assignment_id =
3975 (
3976 select resource_assignment_id
3977 from pa_resource_assignments ra
3978 where ra.budget_version_id = p_fin_plan_version_id
3979 and ra.task_id = rollup.system_reference1
3980 and ra.resource_list_member_id = system_reference2
3981 );
3982 pa_debug.g_err_stage:= 'No of records updated in rollup tmp-> ' || sql%rowcount;
3983 IF P_PA_DEBUG_MODE = 'Y' THEN
3984 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
3985 END IF;
3986
3987
3988 EXCEPTION
3989
3990 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
3991
3992 x_return_status := FND_API.G_RET_STS_ERROR;
3993 l_msg_count := FND_MSG_PUB.count_msg;
3994 IF l_msg_count = 1 THEN
3995 PA_INTERFACE_UTILS_PUB.get_messages
3996 (p_encoded => FND_API.G_TRUE
3997 ,p_msg_index => 1
3998 ,p_msg_count => l_msg_count
3999 ,p_msg_data => l_msg_data
4000 ,p_data => l_data
4001 ,p_msg_index_out => l_msg_index_out);
4002 x_msg_data := l_data;
4003 x_msg_count := l_msg_count;
4004 ELSE
4005 x_msg_count := l_msg_count;
4006 END IF;
4007
4008 pa_debug.g_err_stage:= 'Invalid Arguments Passed';
4009 IF P_PA_DEBUG_MODE = 'Y' THEN
4010 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4011 END IF;
4012 pa_debug.reset_err_stack;
4013 RAISE;
4014
4015 WHEN others THEN
4016
4017 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4018 x_msg_count := 1;
4019 x_msg_data := SQLERRM;
4020 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
4021 ,p_procedure_name => 'CREATE_ASSGMT_FROM_ROLLUPTMP');
4022 pa_debug.g_err_stage:= 'Unexpected Error'||SQLERRM;
4023 IF P_PA_DEBUG_MODE = 'Y' THEN
4024 pa_debug.write('CREATE_ASSGMT_FROM_ROLLUPTMP: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4025 END IF;
4026 pa_debug.reset_err_stack;
4027 RAISE;
4028
4029 END CREATE_ASSGMT_FROM_ROLLUPTMP;
4030
4031 /*==============================================================================
4032 This is a private api called from Create_CI_Resource_Assignments api for
4033 insertion of a record into PA_RESOURCE_ASSIGNMENTS package.
4034 ===============================================================================*/
4035
4036 PROCEDURE Insert_Resource_Assignment(
4037 p_project_id IN pa_resource_assignments.project_id%TYPE
4038 ,p_budget_version_id IN pa_resource_assignments.budget_version_id%TYPE
4039 ,p_task_id IN pa_resource_assignments.task_id%TYPE
4040 ,p_resource_list_member_id IN pa_resource_assignments.resource_list_member_id%TYPE
4041 ,p_unit_of_measure IN pa_resource_assignments.unit_of_measure%TYPE
4042 ,p_track_as_labor_flag IN pa_resource_assignments.track_as_labor_flag%TYPE )
4043 AS
4044
4045 l_row_id rowid;
4046 l_return_status VARCHAR2(30);
4047 l_resource_assignment_id pa_resource_assignments.resource_assignment_id%TYPE;
4048
4049 BEGIN
4050
4051 PA_FP_RESOURCE_ASSIGNMENTS_PKG.Insert_Row
4052 ( px_resource_assignment_id => l_resource_assignment_id
4053 ,p_budget_version_id => p_budget_version_id
4054 ,p_project_id => p_project_id
4055 ,p_task_id => p_task_id
4056 ,p_resource_list_member_id => p_resource_list_member_id
4057 ,p_unit_of_measure => p_unit_of_measure
4058 ,p_track_as_labor_flag => p_track_as_labor_flag
4059 ,p_standard_bill_rate => NULL
4060 ,p_average_bill_rate => NULL
4061 ,p_average_cost_rate => NULL
4062 ,p_project_assignment_id => -1
4063 ,p_plan_error_code => NULL
4064 ,p_total_plan_revenue => NULL
4065 ,p_total_plan_raw_cost => NULL
4066 ,p_total_plan_burdened_cost => NULL
4067 ,p_total_plan_quantity => NULL
4068 ,p_average_discount_percentage => NULL
4069 ,p_total_borrowed_revenue => NULL
4070 ,p_total_tp_revenue_in => NULL
4071 ,p_total_tp_revenue_out => NULL
4072 ,p_total_revenue_adj => NULL
4073 ,p_total_lent_resource_cost => NULL
4074 ,p_total_tp_cost_in => NULL
4075 ,p_total_tp_cost_out => NULL
4076 ,p_total_cost_adj => NULL
4077 ,p_total_unassigned_time_cost => NULL
4078 ,p_total_utilization_percent => NULL
4079 ,p_total_utilization_hours => NULL
4080 ,p_total_utilization_adj => NULL
4081 ,p_total_capacity => NULL
4082 ,p_total_head_count => NULL
4083 ,p_total_head_count_adj => NULL
4084 ,p_resource_assignment_type => PA_FP_CONSTANTS_PKG.G_USER_ENTERED
4085 ,p_total_project_raw_cost => NULL
4086 ,p_total_project_burdened_cost => NULL
4087 ,p_total_project_revenue => NULL
4088 ,p_parent_assignment_id => NULL
4089 ,x_row_id => l_row_id
4090 ,x_return_status => l_return_status);
4091
4092 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4093 pa_debug.g_err_stage:= 'Exception while inserting a row into pa_resource_assignments;';
4094 IF P_PA_DEBUG_MODE = 'Y' THEN
4095 pa_debug.write('Insert_Resource_Assignment: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4096 END IF;
4097 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4098 END IF;
4099 END Insert_Resource_Assignment;
4100
4101 /*==============================================================================
4102 This api is called to create resource assignments during creation of CI budget
4103 version for a given impacted task id.
4104 ===============================================================================*/
4105
4106 --
4107 -- 01-JUL-2003 jwhite - Bug 2989874
4108 -- For Create_CI_Resource_Assignment,
4109 -- default ci from the current working version.
4110
4111 -- 12-APR-2004 dbora FP.M Changes
4112 -- 13-MAY-2004 rravipat Bug 3615617
4113 -- Create_res_task_maps api specification has changed
4114 -- target resource list member id should be derived and
4115 -- passed to the api
4116
4117 PROCEDURE Create_CI_Resource_Assignments
4118 ( p_project_id IN pa_budget_versions.project_id%TYPE
4119 ,p_budget_version_id IN pa_budget_versions.budget_version_id%TYPE
4120 ,p_version_type IN pa_budget_versions.version_type%TYPE
4121 ,p_impacted_task_id IN pa_resource_assignments.task_id%TYPE
4122 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
4123 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
4124 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
4125 AS
4126
4127 l_msg_count NUMBER := 0;
4128 l_data VARCHAR2(2000);
4129 l_msg_data VARCHAR2(2000);
4130 l_error_msg_code VARCHAR2(30);
4131 l_msg_index_out NUMBER;
4132 l_return_status VARCHAR2(2000);
4133 l_debug_mode VARCHAR2(30);
4134
4135 l_err_code NUMBER;
4136 l_err_stage VARCHAR2(100);
4137 l_err_stack VARCHAR2(1000);
4138
4139 l_no_of_records_processed NUMBER;
4140 l_count NUMBER;
4141
4142 l_fin_plan_type_id pa_proj_fp_options.fin_plan_type_id%TYPE;
4143
4144 -- Bug Fix: 4569365. Removed MRC code.
4145 -- l_calling_context pa_mrc_finplan.g_calling_module%TYPE;
4146 l_calling_context VARCHAR2(30);
4147
4148 l_ci_apprv_cw_bv_id pa_budget_versions.budget_version_id%TYPE :=NULL;
4149 l_plan_version_planning_level pa_proj_fp_options.all_fin_plan_level_code%TYPE;
4150
4151 /* PL/SQL table types to be passed to create_res_task_map */
4152
4153 l_src_ra_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4154 l_src_elem_ver_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4155 l_targ_elem_ver_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4156 l_targ_proj_assmt_id_tbl SYSTEM.PA_NUM_TBL_TYPE;
4157 l_planning_start_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4158 l_planning_end_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4159 l_schedule_start_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4160 l_schedule_end_date_tbl SYSTEM.PA_DATE_TBL_TYPE;
4161 l_targ_rlm_id_tbl SYSTEM.PA_NUM_TBL_TYPE; -- bug 3615617
4162
4163 /* The existing cursors were replaced by the following cursors to get the resource assignments
4164 * for the impacted task, or its childrens or its parent's childrens as the case may be
4165 */
4166
4167 CURSOR impacted_task_cur(c_impacted_task_id pa_tasks.task_id%TYPE) IS
4168 SELECT parent_task_id,
4169 top_task_id
4170 FROM pa_tasks
4171 WHERE task_id = c_impacted_task_id;
4172
4173 impacted_task_rec impacted_task_cur%ROWTYPE;
4174
4175 CURSOR cur_elements_for_project IS
4176 SELECT pra.resource_assignment_id,
4177 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.
4178 pra.wbs_element_version_id, -- This would be null for budgets and forecasts!
4179 pra.project_assignment_id, -- This would be -1 for Budgets and Forecasts
4180 pra.planning_start_date,
4181 pra.planning_end_date,
4182 pra.schedule_start_date,
4183 pra.schedule_end_date,
4184 pra.resource_list_member_id -- Bug 3615617
4185 FROM pa_resource_assignments pra
4186 WHERE pra.budget_version_id = l_ci_apprv_cw_bv_id;
4187
4188 CURSOR cur_elements_for_task (c_task_id pa_tasks.task_id%TYPE) IS
4189 SELECT pra.resource_assignment_id,
4190 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.
4191 pra.wbs_element_version_id, -- This would be null for budgets and forecasts!
4192 pra.project_assignment_id, -- This would be -1 for Budgets and Forecasts
4193 pra.planning_start_date,
4194 pra.planning_end_date,
4195 pra.schedule_start_date,
4196 pra.schedule_end_date,
4197 pra.resource_list_member_id -- Bug 3615617
4198 FROM pa_resource_assignments pra
4199 WHERE pra.budget_version_id = l_ci_apprv_cw_bv_id
4200 AND pra.task_id IN (SELECT t.task_id
4201 FROM pa_tasks t
4202 WHERE t.project_id = p_project_id
4203 CONNECT BY PRIOR t.task_id = t.parent_task_id
4204 START WITH t.task_id = c_task_id);
4205
4206 BEGIN
4207
4208 x_msg_count := 0;
4209 x_return_status := FND_API.G_RET_STS_SUCCESS;
4210 pa_debug.set_err_stack('PA_FP_ELEMENTS_PUB.Create_CI_Resource_Assignments');
4211 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
4212 l_debug_mode := NVL(l_debug_mode, 'Y');
4213 IF P_PA_DEBUG_MODE = 'Y' THEN
4214 pa_debug.set_process('Create_CI_Resource_Assignments: ' || 'PLSQL','LOG',l_debug_mode);
4215 END IF;
4216
4217 -- Check for business rules violations
4218
4219 IF P_PA_DEBUG_MODE = 'Y' THEN
4220 pa_debug.g_err_stage:= 'Validating input parameters';
4221 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4222 END IF;
4223
4224 --Check if plan version id is null
4225
4226 IF (p_project_id IS NULL) OR
4227 (p_budget_version_id IS NULL) OR
4228 (p_impacted_task_id IS NULL) OR
4229 (p_version_type IS NULL)
4230 THEN
4231 IF P_PA_DEBUG_MODE = 'Y' THEN
4232 pa_debug.g_err_stage:= 'p_project_id = '||p_project_id;
4233 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4234
4235 pa_debug.g_err_stage:= 'p_budget_version_id = '||p_budget_version_id;
4236 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4237
4238 pa_debug.g_err_stage:= 'p_impacted_task_id = '||p_impacted_task_id;
4239 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4240
4241 pa_debug.g_err_stage:= 'p_version_type = '||p_version_type;
4242 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4243 END IF;
4244
4245 PA_UTILS.ADD_MESSAGE(p_app_short_name => 'PA',
4246 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4247
4248 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4249 END IF;
4250
4251 -- Fetch the plan type fp options id and resource list attached
4252
4253 BEGIN
4254 SELECT bv.fin_plan_type_id
4255 INTO l_fin_plan_type_id
4256 FROM pa_budget_versions bv
4257 WHERE budget_version_id = p_budget_version_id;
4258 EXCEPTION
4259 WHEN OTHERS THEN
4260 pa_debug.g_err_stage:= 'Failed to fetch plan type and resource list for given budget version';
4261 IF P_PA_DEBUG_MODE = 'Y' THEN
4262 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4263 END IF;
4264 RAISE;
4265 END;
4266
4267 l_plan_version_planning_level := Pa_Fin_Plan_Utils.Get_Fin_Plan_Level_Code(
4268 p_fin_plan_version_id => p_budget_version_id);
4269
4270 -- Fetch current working approved budget version id
4271 Pa_Fp_Control_Items_Utils.CHK_APRV_CUR_WORKING_BV_EXISTS(
4272 p_project_id => p_project_id,
4273 p_fin_plan_type_id => l_fin_plan_type_id,
4274 p_version_type => p_version_type,
4275 x_cur_work_bv_id => l_ci_apprv_cw_bv_id,
4276 x_return_status => l_return_status,
4277 x_msg_count => l_msg_count,
4278 x_msg_data => l_msg_data );
4279 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4280 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4281 END IF;
4282
4283 /* Bug# 2676352 - Creating plannable elements based on the impacted task is ONLY applicable
4284 if the plan type level planning level is Task level.
4285
4286 If planning level is Project, only create the plannable resources, if using a resource list.
4287 Otherwise, just one resource assignment for entire project when not using a resource list.
4288
4289 Please refer bug for compelete business rules.
4290 */
4291
4292 IF l_plan_version_planning_level = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
4293
4294 pa_debug.g_err_stage := 'Planning level of the plan version is project ..';
4295 IF P_PA_DEBUG_MODE = 'Y' THEN
4296 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4297 END IF;
4298
4299 OPEN cur_elements_for_project;
4300 FETCH cur_elements_for_project BULK COLLECT INTO
4301 l_src_ra_id_tbl,
4302 l_src_elem_ver_id_tbl,
4303 l_targ_elem_ver_id_tbl,
4304 l_targ_proj_assmt_id_tbl,
4305 l_planning_start_date_tbl,
4306 l_planning_end_date_tbl,
4307 l_schedule_start_date_tbl,
4308 l_schedule_end_date_tbl,
4309 l_targ_rlm_id_tbl; -- Bug 3615617
4310 CLOSE cur_elements_for_project;
4311
4312 IF l_src_ra_id_tbl.count > 0 THEN
4313
4314 IF P_PA_DEBUG_MODE = 'Y' THEN
4315 pa_debug.g_err_stage := 'Calling create_res_task_map';
4316 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4317 END IF;
4318
4319 pa_fp_copy_from_pkg.create_res_task_maps(
4320 p_context => 'BUDGET'
4321 ,p_src_ra_id_tbl => l_src_ra_id_tbl
4322 ,p_src_elem_ver_id_tbl => l_src_elem_ver_id_tbl
4323 ,p_targ_elem_ver_id_tbl => l_targ_elem_ver_id_tbl
4324 ,p_targ_proj_assmt_id_tbl => l_targ_proj_assmt_id_tbl
4325 ,p_targ_rlm_id_tbl => l_targ_rlm_id_tbl -- Bug 3615617
4326 ,p_planning_start_date_tbl => l_planning_start_date_tbl
4327 ,p_planning_end_date_tbl => l_planning_end_date_tbl
4328 ,p_schedule_start_date_tbl => l_schedule_start_date_tbl
4329 ,p_schedule_end_date_tbl => l_schedule_end_date_tbl
4330 ,x_return_status => l_return_status
4331 ,x_msg_count => l_msg_count
4332 ,x_msg_data => l_msg_data );
4333
4334 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4335 IF P_PA_DEBUG_MODE = 'Y' THEN
4336 pa_debug.g_err_stage := 'The call to create_res_task_map returned with error';
4337 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4338 END IF;
4339 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4340 END IF;
4341
4342 IF P_PA_DEBUG_MODE = 'Y' THEN
4343 pa_debug.g_err_stage := 'copy_resource_assignments';
4344 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4345 END IF;
4346 pa_fp_copy_from_pkg.copy_resource_assignments(
4347 p_source_plan_version_id => l_ci_apprv_cw_bv_id
4348 ,p_target_plan_version_id => p_budget_version_id
4349 ,p_adj_percentage => -99
4350 -- Bug 4200168
4351 ,p_calling_context => 'CI'
4352 ,x_return_status => l_return_status
4353 ,x_msg_count => l_msg_count
4354 ,x_msg_data => l_msg_data );
4355
4356 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4357 IF P_PA_DEBUG_MODE = 'Y' THEN
4358 pa_debug.g_err_stage := 'The call to copy_resource_assignments returned with error';
4359 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4360 END IF;
4361 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4362 END IF;
4363 END IF; /* l_src_ra_id_tbl.count > 0 */
4364
4365 ELSE /* Task level planning */
4366
4367 OPEN cur_elements_for_task(p_impacted_task_id);
4368 FETCH cur_elements_for_task BULK COLLECT INTO
4369 l_src_ra_id_tbl,
4370 l_src_elem_ver_id_tbl,
4371 l_targ_elem_ver_id_tbl,
4372 l_targ_proj_assmt_id_tbl,
4373 l_planning_start_date_tbl,
4374 l_planning_end_date_tbl,
4375 l_schedule_start_date_tbl,
4376 l_schedule_end_date_tbl,
4377 l_targ_rlm_id_tbl; -- Bug 3615617
4378 CLOSE cur_elements_for_task;
4379
4380 IF l_src_ra_id_tbl.count = 0 THEN
4381
4382 OPEN impacted_task_cur(p_impacted_task_id);
4383 FETCH impacted_task_cur INTO impacted_task_rec;
4384 CLOSE impacted_task_cur;
4385
4386 IF impacted_task_rec.top_task_id = p_impacted_task_id THEN
4387
4388 /* No record are there to be inserted. Ideally, control should never come
4389 * here since is_create_ci_version_Allowed should have caught this case and
4390 * thrown an error! */
4391 null;
4392 ELSE
4393 OPEN cur_elements_for_task(impacted_task_rec.top_task_id);
4394 FETCH cur_elements_for_task BULK COLLECT INTO
4395 l_src_ra_id_tbl,
4396 l_src_elem_ver_id_tbl,
4397 l_targ_elem_ver_id_tbl,
4398 l_targ_proj_assmt_id_tbl,
4399 l_planning_start_date_tbl,
4400 l_planning_end_date_tbl,
4401 l_schedule_start_date_tbl,
4402 l_schedule_end_date_tbl,
4403 l_targ_rlm_id_tbl; -- Bug 3615617
4404 CLOSE cur_elements_for_task;
4405 END IF;
4406 END IF;
4407
4408 IF l_src_ra_id_tbl.count = 0 THEN
4409 /* No record are there to be inserted. Ideally, control should never come here since
4410 * is_create_ci_version_Allowed should have caught this case and thrown an error! */
4411 null;
4412 ELSE
4413 IF P_PA_DEBUG_MODE = 'Y' THEN
4414 pa_debug.g_err_stage := 'Calling create_res_task_map';
4415 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4416 END IF;
4417
4418 pa_fp_copy_from_pkg.create_res_task_maps(
4419 p_context => 'BUDGET'
4420 ,p_src_ra_id_tbl => l_src_ra_id_tbl
4421 ,p_src_elem_ver_id_tbl => l_src_elem_ver_id_tbl
4422 ,p_targ_elem_ver_id_tbl => l_targ_elem_ver_id_tbl
4423 ,p_targ_proj_assmt_id_tbl => l_targ_proj_assmt_id_tbl
4424 ,p_targ_rlm_id_tbl => l_targ_rlm_id_tbl -- Bug 3615617
4425 ,p_planning_start_date_tbl => l_planning_start_date_tbl
4426 ,p_planning_end_date_tbl => l_planning_end_date_tbl
4427 ,p_schedule_start_date_tbl => l_schedule_start_date_tbl
4428 ,p_schedule_end_date_tbl => l_schedule_end_date_tbl
4429 ,x_return_status => l_return_status
4430 ,x_msg_count => l_msg_count
4431 ,x_msg_data => l_msg_data );
4432
4433 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4434 IF P_PA_DEBUG_MODE = 'Y' THEN
4435 pa_debug.g_err_stage := 'The call to create_res_task_map returned with error';
4436 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4437 END IF;
4438 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4439 END IF;
4440
4441 IF P_PA_DEBUG_MODE = 'Y' THEN
4442 pa_debug.g_err_stage := 'copy_resource_assignments';
4443 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4444 END IF;
4445 pa_fp_copy_from_pkg.copy_resource_assignments(
4446 p_source_plan_version_id => l_ci_apprv_cw_bv_id
4447 ,p_target_plan_version_id => p_budget_version_id
4448 ,p_adj_percentage => -99
4449 -- Bug 4200168
4450 ,p_calling_context => 'CI'
4451 ,x_return_status => l_return_status
4452 ,x_msg_count => l_msg_count
4453 ,x_msg_data => l_msg_data );
4454
4455 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4456 IF P_PA_DEBUG_MODE = 'Y' THEN
4457 pa_debug.g_err_stage := 'The call to copy_resource_assignments returned with error';
4458 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,3);
4459 END IF;
4460 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4461 END IF;
4462 END IF; /* l_src_ra_id_tbl.count > 0 */
4463
4464 END IF;
4465
4466 IF P_PA_DEBUG_MODE = 'Y' THEN
4467 pa_debug.g_err_stage:= 'Exiting Create_CI_Resource_Assignments';
4468 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4469 END IF;
4470 pa_debug.reset_err_stack;
4471
4472 EXCEPTION
4473
4474 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
4475
4476 x_return_status := FND_API.G_RET_STS_ERROR;
4477 l_msg_count := FND_MSG_PUB.count_msg;
4478 IF l_msg_count = 1 THEN
4479 PA_INTERFACE_UTILS_PUB.get_messages
4480 (p_encoded => FND_API.G_TRUE
4481 ,p_msg_index => 1
4482 ,p_msg_count => l_msg_count
4483 ,p_msg_data => l_msg_data
4484 ,p_data => l_data
4485 ,p_msg_index_out => l_msg_index_out);
4486 x_msg_data := l_data;
4487 x_msg_count := l_msg_count;
4488 ELSE
4489 x_msg_count := l_msg_count;
4490 END IF;
4491
4492 pa_debug.g_err_stage:= 'Invalid Arguments Passed';
4493 IF P_PA_DEBUG_MODE = 'Y' THEN
4494 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4495 END IF;
4496 pa_debug.reset_err_stack;
4497 RAISE;
4498
4499 WHEN others THEN
4500
4501 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4502 x_msg_count := 1;
4503 x_msg_data := SQLERRM;
4504 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
4505 ,p_procedure_name => 'Create_CI_Resource_Assignments');
4506 pa_debug.g_err_stage:= 'Unexpected Error'||SQLERRM;
4507 IF P_PA_DEBUG_MODE = 'Y' THEN
4508 pa_debug.write('Create_CI_Resource_Assignments: ' || l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4509 END IF;
4510 pa_debug.reset_err_stack;
4511 RAISE;
4512 END Create_CI_Resource_Assignments;
4513
4514 /*==================================================================
4515 When automatic resource selection is enabled for an option,this
4516 api inserts resources or resource group elements to a project
4517 or a pl/sql table of tasks based on the option planning level that
4518 is passed.
4519
4520 The api can also be called for an entire option in which case
4521 resource/ resource groups elements would be added to all the
4522 plannable tasks for that element type,fp option combination.
4523
4524 NOTE(S):-
4525 1. If the option planning level is project, the task_id tbl should
4526 contain one and only one record and that should be zero as we
4527 enter 0(zero) for task_id column in pa_fp_elements for project
4528 level planning options.
4529 ==================================================================*/
4530
4531 PROCEDURE Add_resources_automatically
4532 ( p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
4533 ,p_element_type IN pa_fp_elements.element_type%TYPE
4534 ,p_fin_plan_level_code IN pa_proj_fp_options.cost_fin_plan_level_code%TYPE
4535 ,p_resource_list_id IN pa_resource_lists_all_bg.resource_list_id%TYPE
4536 ,p_res_planning_level IN pa_proj_fp_options.cost_res_planning_level%TYPE
4537 ,p_entire_option IN VARCHAR2
4538 ,p_element_task_id_tbl IN pa_fp_elements_pub.l_task_id_tbl_typ
4539 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
4540 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
4541 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
4542 AS
4543
4544 l_msg_count NUMBER := 0;
4545 l_data VARCHAR2(2000);
4546 l_msg_data VARCHAR2(2000);
4547 l_msg_index_out NUMBER;
4548 l_return_status VARCHAR2(2000);
4549
4550 l_task_tbl_index NUMBER;
4551 l_rlm_tbl_index NUMBER;
4552 l_res_uncategorized_flag VARCHAR2(1);
4553 l_is_resource_list_grouped VARCHAR2(1);
4554 l_group_resource_type_id pa_resource_lists_all_bg.group_resource_type_id%TYPE;
4555
4556
4557 /*
4558 The following pl/sql tables are used to store task_id, top_task_id,
4559 resource_list_member_ids. The table types have defined in the package
4560 specification.
4561 */
4562 l_task_id_tbl l_task_id_tbl_typ;
4563 l_top_task_id_tbl l_top_task_id_tbl_typ;
4564 l_res_list_mem_id_tbl l_res_list_mem_id_tbl_typ;
4565
4566 /* The cursors used in the api*/
4567
4568 /*
4569 The following cursor is used to fetch project_id, plan_type_id
4570 based on the element type etc., for an option_id
4571 */
4572 CURSOR proj_fp_options_info_cur
4573 ( c_proj_fp_options_id pa_proj_fp_options.proj_fp_options_id%TYPE
4574 ,c_element_type pa_fp_elements.element_type%TYPE)
4575 IS
4576 SELECT project_id
4577 ,fin_plan_type_id
4578 ,fin_plan_version_id
4579 FROM pa_proj_fp_options
4580 WHERE proj_fp_options_id = c_proj_fp_options_id;
4581
4582 proj_fp_options_info_rec proj_fp_options_info_cur%ROWTYPE;
4583
4584 /*
4585 The following cursor is used to fetch all the tasks that can be
4586 planned for an option and element_type combination for automatic
4587 resource addition in the context of entire option
4588 */
4589 CURSOR all_plannable_tasks_cur
4590 ( c_proj_fp_options_id pa_proj_fp_options.proj_fp_options_id%TYPE
4591 ,c_element_type pa_fp_elements.element_type%TYPE)
4592 IS
4593 SELECT task_id
4594 ,top_task_id
4595 FROM pa_fp_elements
4596 WHERE proj_fp_options_id = c_proj_fp_options_id
4597 AND element_type = c_element_type
4598 AND resource_list_member_id = 0
4599 AND plannable_flag = 'Y';
4600
4601 /*
4602 The following cursor is used to fetch all the resource list
4603 members in case the input resource list is ungrouped.
4604 'UNCLASSIFIED' resource list member is filtered as that
4605 shouldn't be added to the option.
4606 */
4607 CURSOR ungrouped_res_cur
4608 ( c_resource_list_id pa_resource_lists_all_bg.resource_list_id%TYPE)
4609 IS
4610 SELECT resource_list_member_id
4611 FROM pa_resource_list_members
4612 WHERE resource_list_id = c_resource_list_id
4613 AND resource_type_code <> PA_FP_CONSTANTS_PKG.G_UNCLASSIFIED
4614 AND enabled_flag='Y' -- bug 3289243
4615 AND display_flag='Y'; -- bug 3289243
4616
4617 /*
4618 The following cursor is used to fetch all the resource list members
4619 in case the input resource list is grouped and resource planning level
4620 is Resource.'UNCLASSIFIED' resource list member is filtered as that
4621 shouldn't be added to the option.
4622 */
4623 CURSOR grouped_res_level_res_cur
4624 ( c_resource_list_id pa_resource_lists_all_bg.resource_list_id%TYPE)
4625 IS
4626 SELECT resource_list_member_id
4627 FROM pa_resource_list_members
4628 WHERE resource_list_id = c_resource_list_id
4629 AND resource_type_code <> PA_FP_CONSTANTS_PKG.G_UNCLASSIFIED
4630 AND enabled_flag='Y' -- bug 3289243
4631 AND display_flag='Y' -- bug 3289243
4632 AND parent_member_id IS NOT NULL; -- to filter all the resource group level records
4633
4634 /*
4635 The following cursor is used to fetch all the resource list members
4636 in case the input resource list is grouped and resource planning level
4637 is Resource Group.'UNCLASSIFIED' resource list member is filtered as that
4638 shouldn't be added to the option.
4639 */
4640 CURSOR grouped_resgrp_level_res_cur
4641 ( c_resource_list_id pa_resource_lists_all_bg.resource_list_id%TYPE)
4642 IS
4643 SELECT resource_list_member_id
4644 FROM pa_resource_list_members
4645 WHERE resource_list_id = c_resource_list_id
4646 AND resource_type_code <> PA_FP_CONSTANTS_PKG.G_UNCLASSIFIED
4647 AND enabled_flag='Y' -- bug 3289243
4648 AND display_flag='Y' -- bug 3289243
4649 AND parent_member_id IS NULL; -- to filter all the resource level records
4650
4651 BEGIN
4652 x_msg_count := 0;
4653 x_return_status := FND_API.G_RET_STS_SUCCESS;
4654 PA_DEBUG.Set_Curr_Function( p_function => 'Add_resources_automatically',
4655 p_debug_mode => p_pa_debug_mode );
4656
4657 -- Check for NOT NULL parameters
4658 IF (p_proj_fp_options_id IS NULL) OR
4659 (p_element_type IS NULL) OR
4660 (p_fin_plan_level_code IS NULL) OR
4661 (p_resource_list_id IS NULL) OR
4662 (p_res_planning_level IS NULL) OR
4663 (p_entire_option IS NULL)
4664 THEN
4665 IF p_pa_debug_mode = 'Y' THEN
4666 pa_debug.g_err_stage:= 'p_proj_fp_options_id = '|| p_proj_fp_options_id;
4667 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4668 pa_debug.g_err_stage:= 'p_element_type = '|| p_element_type;
4669 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4670 pa_debug.g_err_stage:= 'p_fin_plan_level_code = '|| p_fin_plan_level_code;
4671 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4672 pa_debug.g_err_stage:= 'p_resource_list_id = '|| p_resource_list_id;
4673 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4674 pa_debug.g_err_stage:= 'p_res_planning_level = '|| p_res_planning_level;
4675 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4676 pa_debug.g_err_stage:= 'p_entire_option = '|| p_entire_option;
4677 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4678 pa_debug.g_err_stage:= 'Invalid Arguments Passed';
4679 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4680 END IF;
4681 PA_UTILS.ADD_MESSAGE
4682 (p_app_short_name => 'PA',
4683 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4684 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4685 END IF;
4686
4687 -- Fetch project_id, plan_type_id for the i/p option, element_type
4688
4689 OPEN proj_fp_options_info_cur(p_proj_fp_options_id,p_element_type);
4690 FETCH proj_fp_options_info_cur INTO proj_fp_options_info_rec;
4691
4692 IF proj_fp_options_info_cur%NOTFOUND
4693 THEN
4694 IF p_pa_debug_mode = 'Y' THEN
4695 pa_debug.g_err_stage:= 'Unexpected error while fetching option_id Info for the option: '
4696 ||p_proj_fp_options_id||'the error message is: '||sqlerrm;
4697 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4698 END IF;
4699 PA_UTILS.ADD_MESSAGE
4700 (p_app_short_name => 'PA',
4701 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4702 CLOSE proj_fp_options_info_cur;
4703 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4704 END IF;
4705
4706 CLOSE proj_fp_options_info_cur;
4707
4708 /*
4709 If resources are to be added for an entire option we need to
4710 fetch all the plannable tasks for the option and element type.
4711 */
4712
4713 IF p_entire_option = 'Y'
4714 THEN
4715 /*
4716 If option planning level is 'Project', l_task_id_tbl
4717 table would contain only one record and top_task_id
4718 for this record is also populated as zero.
4719 Else fetch all the plannable tasks.
4720 */
4721 IF p_fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT
4722 THEN
4723 l_task_id_tbl(1) := 0;
4724 l_top_task_id_tbl(1) := 0;
4725 ELSE
4726 IF p_pa_debug_mode = 'Y' THEN
4727 pa_debug.g_err_stage:= 'Cursor all_plannable_tasks_cur is opened';
4728 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4729 END IF;
4730
4731 OPEN all_plannable_tasks_cur(p_proj_fp_options_id,p_element_type);
4732 FETCH all_plannable_tasks_cur
4733 BULK COLLECT INTO
4734 l_task_id_tbl
4735 ,l_top_task_id_tbl;
4736 CLOSE all_plannable_tasks_cur;
4737 END IF;
4738
4739 ELSE
4740
4741 -- If entire option is 'N', then table of pl/sql tables is passed as input
4742
4743 l_task_id_tbl := p_element_task_id_tbl;
4744
4745 IF l_task_id_tbl.count = 0
4746 THEN
4747 IF p_pa_debug_mode = 'Y' THEN
4748 pa_debug.g_err_stage:= 'l_task_id_Tbl is empty. Returning...';
4749 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4750 END IF;
4751 pa_debug.reset_curr_function;
4752 RETURN; -- as no tasks are to be processed.
4753 END IF;
4754
4755 /*
4756 If option planning level is 'Project', l_task_id_tbl
4757 table should contain only one record and top_task_id
4758 for this record is to be populated as zero.
4759 Else fetch top tasks all the tasks in the pl/sql table.
4760 */
4761
4762 IF p_fin_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT
4763 THEN
4764
4765 l_task_tbl_index := l_task_id_tbl.first;
4766
4767 IF (l_task_id_tbl.count <> 1) OR (l_task_id_tbl(l_task_tbl_index) <> 0)
4768 THEN
4769 IF p_pa_debug_mode = 'Y' THEN
4770 pa_debug.g_err_stage:= 'Invalid task(s) passed for project plan level case';
4771 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL5);
4772 END IF;
4773 PA_UTILS.ADD_MESSAGE
4774 (p_app_short_name => 'PA',
4775 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4776 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4777 ELSE
4778 l_top_task_id_tbl(l_task_tbl_index) := 0;
4779 END IF;
4780
4781 ELSE -- Option is not planned at project level
4782
4783 FOR l_task_tbl_index IN l_task_id_tbl.first .. l_task_id_tbl.last
4784 LOOP
4785
4786 IF p_pa_debug_mode = 'Y' THEN
4787 pa_debug.g_err_stage:= 'Fetching top task for each task_id';
4788 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4789 END IF;
4790
4791 BEGIN
4792 SELECT top_task_id
4793 INTO l_top_task_id_tbl(l_task_tbl_index)
4794 FROM pa_fp_elements
4795 WHERE proj_fp_options_id = p_proj_fp_options_id
4796 AND element_type = p_element_type
4797 AND task_id = l_task_id_tbl(l_task_tbl_index)
4798 AND resource_list_member_id = 0
4799 AND plannable_flag = 'Y';
4800 EXCEPTION
4801 WHEN NO_DATA_FOUND THEN
4802
4803 IF p_pa_debug_mode = 'Y' THEN
4804 pa_debug.g_err_stage:= 'While fetching top_task for the task: '
4805 ||l_task_id_tbl(l_task_tbl_index)|| 'Error is: '||sqlerrm;
4806 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4807 END IF;
4808 PA_UTILS.ADD_MESSAGE
4809 (p_app_short_name => 'PA',
4810 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
4811 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
4812 END;
4813 END LOOP;
4814
4815 END IF; -- Option planning level 'P' or not
4816
4817 END IF; -- entire option 'Y'/'N'
4818
4819 /*
4820 To know if the given resource list id is grouped/ ungrouped
4821 call pa_fin_plan_utils.get_resource_list_info.
4822 */
4823
4824 PA_FIN_PLAN_UTILS.GET_RESOURCE_LIST_INFO
4825 (
4826 p_resource_list_id => p_resource_list_id
4827 ,x_res_list_is_uncategorized => l_res_uncategorized_flag
4828 ,x_is_resource_list_grouped => l_is_resource_list_grouped
4829 ,x_group_resource_type_id => l_group_resource_type_id
4830 ,x_return_status => x_return_status
4831 ,x_msg_count => x_msg_count
4832 ,x_msg_data => x_msg_data
4833 );
4834
4835 /* return if resource list is uncategorized as no resources are to be added in this case*/
4836 IF l_res_uncategorized_flag = 'Y'
4837 THEN
4838 IF p_pa_debug_mode = 'Y' THEN
4839 pa_debug.g_err_stage:= 'l_res_uncategorized_flag is Y. Returning...';
4840 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4841 pa_debug.reset_curr_function;
4842 END IF;
4843 RETURN;
4844 END IF;
4845
4846 /*
4847 Depending on the resource list being grouped/ungrouped,
4848 p_res_planning_level 'R'(resource)/'G'(resource group)
4849 we need to open the appropriate cursor. bulk fetch all
4850 the resource list memners into l_res_list_mem_id_tbl.
4851 */
4852
4853 IF l_is_resource_list_grouped = 'N'
4854 THEN
4855
4856 IF p_pa_debug_mode = 'Y' THEN
4857 pa_debug.g_err_stage:= 'ungrouped_res_cur is opened';
4858 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4859 END IF;
4860
4861 OPEN ungrouped_res_cur (p_resource_list_id);
4862 FETCH ungrouped_res_cur BULK COLLECT INTO
4863 l_res_list_mem_id_tbl;
4864 CLOSE ungrouped_res_cur;
4865 ELSE
4866 IF p_res_planning_level = PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_R
4867 THEN
4868
4869 IF p_pa_debug_mode = 'Y' THEN
4870 pa_debug.g_err_stage:= 'grouped_res_level_res_cur is opened';
4871 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4872 END IF;
4873
4874 OPEN grouped_res_level_res_cur(p_resource_list_id);
4875 FETCH grouped_res_level_res_cur BULK COLLECT INTO
4876 l_res_list_mem_id_tbl;
4877 CLOSE grouped_res_level_res_cur;
4878
4879 ELSIF p_res_planning_level = PA_FP_CONSTANTS_PKG.G_RESOURCE_PLANNING_LEVEL_G
4880 THEN
4881
4882 IF p_pa_debug_mode = 'Y' THEN
4883 pa_debug.g_err_stage:= 'grouped_resgrp_level_res_cur is opened';
4884 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4885 END IF;
4886
4887 OPEN grouped_resgrp_level_res_cur(p_resource_list_id);
4888 FETCH grouped_resgrp_level_res_cur BULK COLLECT INTO
4889 l_res_list_mem_id_tbl;
4890 CLOSE grouped_resgrp_level_res_cur;
4891 END IF;
4892 END IF;
4893
4894 /*
4895 For each task_id in the task_id table we need to insert
4896 all the resource_list_memebers fetched in pa_fp_elements table.
4897 */
4898
4899 IF p_pa_debug_mode = 'Y' THEN
4900 pa_debug.g_err_stage:= 'for each task in task_id_tbl inserting all the rlmids fetched';
4901 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4902 END IF;
4903
4904 FOR l_task_tbl_index IN l_task_id_tbl.first .. l_task_id_tbl.last
4905 LOOP
4906
4907 /* Insert all the resource_list_members fetched for each task */
4908
4909 FORALL l_rlm_tbl_index IN l_res_list_mem_id_tbl.first .. l_res_list_mem_id_tbl.last
4910 INSERT INTO pa_fp_elements
4911 (PROJ_FP_ELEMENTS_ID
4912 ,PROJ_FP_OPTIONS_ID
4913 ,PROJECT_ID
4914 ,FIN_PLAN_TYPE_ID
4915 ,ELEMENT_TYPE
4916 ,FIN_PLAN_VERSION_ID
4917 ,TASK_ID
4918 ,TOP_TASK_ID
4919 ,RESOURCE_LIST_MEMBER_ID
4920 ,TOP_TASK_PLANNING_LEVEL
4921 ,RESOURCE_PLANNING_LEVEL
4922 ,PLANNABLE_FLAG
4923 ,RESOURCES_PLANNED_FOR_TASK
4924 ,PLAN_AMOUNT_EXISTS_FLAG
4925 ,TMP_PLANNABLE_FLAG
4926 ,TMP_TOP_TASK_PLANNING_LEVEL
4927 ,RECORD_VERSION_NUMBER
4928 ,LAST_UPDATE_DATE
4929 ,LAST_UPDATED_BY
4930 ,CREATION_DATE
4931 ,CREATED_BY
4932 ,LAST_UPDATE_LOGIN)
4933 VALUES
4934 (pa_fp_elements_s.nextval
4935 ,p_proj_fp_options_id
4936 ,proj_fp_options_info_rec.project_id
4937 ,proj_fp_options_info_rec.fin_plan_type_id
4938 ,p_element_type
4939 ,proj_fp_options_info_rec.fin_plan_version_id
4940 ,l_task_id_tbl(l_task_tbl_index) -- task_id
4941 ,l_top_task_id_tbl(l_task_tbl_index) -- top_task_id
4942 ,l_res_list_mem_id_tbl(l_rlm_tbl_index) -- resource_list_member_id
4943 ,NULL -- top_task_planning_level
4944 ,NULL -- resource_planning_level
4945 ,'Y' -- plannable_flag
4946 ,NULL -- resources_planned_for_task
4947 ,'N' -- plan_amount_exists_flag
4948 ,'Y' -- tmp_plannable_flag
4949 ,NULL -- tmp_top_task_planning_level
4950 ,1 -- record_version_number
4951 ,sysdate
4952 ,fnd_global.user_id
4953 ,sysdate
4954 ,fnd_global.user_id
4955 ,fnd_global.login_id);
4956 END LOOP;
4957
4958 -- Bulk update all the task records to reflect that resources selection is done
4959
4960 IF p_pa_debug_mode = 'Y' THEN
4961 pa_debug.g_err_stage:= 'Bulk updating all the tasks to reflect resource selection status';
4962 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4963 END IF;
4964
4965 IF l_res_list_mem_id_tbl.count > 0
4966 THEN
4967 FORALL l_task_tbl_index IN l_task_id_tbl.first .. l_task_id_tbl.last
4968 UPDATE pa_fp_elements
4969 SET resources_planned_for_task = 'Y'
4970 ,resource_planning_level = p_res_planning_level
4971 ,record_version_number = record_version_number + 1
4972 ,last_update_date = sysdate
4973 ,last_updated_by = FND_GLOBAL.USER_ID
4974 ,last_update_login = FND_GLOBAL.LOGIN_ID
4975 WHERE proj_fp_options_id = p_proj_fp_options_id
4976 AND element_type = p_element_type
4977 AND task_id = l_task_id_tbl(l_task_tbl_index)
4978 AND resource_list_member_id = 0;
4979 END IF;
4980
4981 IF p_pa_debug_mode = 'Y' THEN
4982 pa_debug.g_err_stage:= 'Exiting Add_resources_automatically';
4983 pa_debug.write(l_module_name,pa_debug.g_err_stage,PA_FP_CONSTANTS_PKG.G_DEBUG_LEVEL3);
4984 END IF;
4985 pa_debug.reset_curr_function;
4986 EXCEPTION
4987
4988 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
4989
4990 x_return_status := FND_API.G_RET_STS_ERROR;
4991 l_msg_count := FND_MSG_PUB.count_msg;
4992 IF l_msg_count = 1 THEN
4993 PA_INTERFACE_UTILS_PUB.get_messages
4994 (p_encoded => FND_API.G_TRUE
4995 ,p_msg_index => 1
4996 ,p_msg_count => l_msg_count
4997 ,p_msg_data => l_msg_data
4998 ,p_data => l_data
4999 ,p_msg_index_out => l_msg_index_out);
5000 x_msg_data := l_data;
5001 x_msg_count := l_msg_count;
5002 ELSE
5003 x_msg_count := l_msg_count;
5004 END IF;
5005 pa_debug.reset_curr_function;
5006 RETURN;
5007 WHEN others THEN
5008
5009 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5010 x_msg_count := 1;
5011 x_msg_data := SQLERRM;
5012 FND_MSG_PUB.add_exc_msg
5013 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
5014 ,p_procedure_name => 'ADD_RESOURCES_AUTOMATICALLY'
5015 ,p_error_text => sqlerrm);
5016 pa_debug.reset_curr_function;
5017 RAISE;
5018 END Add_resources_automatically;
5019
5020 /* Bug 2920954 - This procedure deletes all the planning elements
5021 (pa_fp_elements/pa_resource_assignments) of this task and all
5022 its child tasks. This is called during the task deletion. These
5023 tasks would have plannable plan_amount_exists_flag as 'N'. Its
5024 assumed that the check apis would have been called to ensure
5025 that deletion of p_task_id is allowed. One main check in the check api
5026 is that p_task_id should not be present in pa_resource_assignments
5027 of a BASELINED version since we should not be touching RA table
5028 of BASELINED versions. When plan amounts donot exists, pa_proj_periods_denorm
5029 will not contain any data for that task.
5030
5031 Bug 2976168. Delete from pa_fp_excluded_elements */
5032
5033 PROCEDURE Delete_task_elements
5034 ( p_task_id IN pa_tasks.task_id%TYPE
5035 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5036 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
5037 ,x_msg_data OUT NOCOPY VARCHAR2) IS --File.Sql.39 bug 4440895
5038
5039 l_msg_count NUMBER := 0;
5040 l_data VARCHAR2(2000);
5041 l_msg_data VARCHAR2(2000);
5042 l_msg_index_out NUMBER;
5043 l_debug_mode VARCHAR2(1);
5044
5045 L_DEBUG_LEVEL2 CONSTANT NUMBER := 2;
5046 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
5047 L_DEBUG_LEVEL4 CONSTANT NUMBER := 4;
5048 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
5049
5050 l_records_deleted NUMBER;
5051 BEGIN
5052
5053 x_msg_count := 0;
5054 x_return_status := FND_API.G_RET_STS_SUCCESS;
5055 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
5056
5057 pa_debug.set_curr_function( p_function => 'delete_task_elements',
5058 p_debug_mode => l_debug_mode );
5059
5060 -- Check for business rules violations
5061
5062 IF l_debug_mode = 'Y' THEN
5063 pa_debug.g_err_stage:= 'Validating input parameters';
5064 pa_debug.write(l_module_name,pa_debug.g_err_stage,
5065 L_DEBUG_LEVEL3);
5066 END IF;
5067
5068 IF (p_task_id IS NULL)
5069 THEN
5070 IF l_debug_mode = 'Y' THEN
5071 pa_debug.g_err_stage:= 'p_task_id = '|| p_task_id;
5072 pa_debug.write(l_module_name,pa_debug.g_err_stage,
5073 L_DEBUG_LEVEL5);
5074 END IF;
5075 PA_UTILS.ADD_MESSAGE
5076 (p_app_short_name => 'PA',
5077 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
5078 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5079 END IF;
5080
5081 IF l_debug_mode = 'Y' THEN
5082 pa_debug.g_err_stage:= 'Deleting from pa_resource_assignments for task id ' || to_char(p_task_id);
5083 pa_debug.write(l_module_name,pa_debug.g_err_stage,
5084 L_DEBUG_LEVEL3);
5085 END IF;
5086
5087 DELETE FROM pa_resource_assignments r
5088 WHERE r.task_id IN (SELECT t.task_id
5089 FROM pa_tasks t
5090 CONNECT BY PRIOR t.task_id = t.parent_task_id
5091 START WITH t.task_id = p_task_id);
5092
5093 l_records_deleted := sql%rowcount;
5094
5095 IF l_debug_mode = 'Y' THEN
5096 pa_debug.g_err_stage:= To_char(l_records_deleted) || ' records deleted.';
5097 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5098 END IF;
5099
5100 IF l_debug_mode = 'Y' THEN
5101 pa_debug.g_err_stage:= 'Exiting delete_task_elements';
5102 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5103 END IF;
5104
5105 pa_debug.reset_curr_function;
5106
5107 EXCEPTION
5108
5109 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
5110
5111 x_return_status := FND_API.G_RET_STS_ERROR;
5112 l_msg_count := FND_MSG_PUB.count_msg;
5113
5114 IF l_msg_count = 1 and x_msg_data IS NULL THEN
5115 PA_INTERFACE_UTILS_PUB.get_messages
5116 (p_encoded => FND_API.G_TRUE
5117 ,p_msg_index => 1
5118 ,p_msg_count => l_msg_count
5119 ,p_msg_data => l_msg_data
5120 ,p_data => l_data
5121 ,p_msg_index_out => l_msg_index_out);
5122 x_msg_data := l_data;
5123 x_msg_count := l_msg_count;
5124 ELSE
5125 x_msg_count := l_msg_count;
5126 END IF;
5127 pa_debug.reset_curr_function;
5128 RETURN;
5129
5130 WHEN others THEN
5131
5132 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5133 x_msg_count := 1;
5134 x_msg_data := SQLERRM;
5135
5136 FND_MSG_PUB.add_exc_msg
5137 ( p_pkg_name => 'pa_Fp_elements_pub'
5138 ,p_procedure_name => 'delete_task_elements'
5139 ,p_error_text => x_msg_data);
5140
5141 IF l_debug_mode = 'Y' THEN
5142 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
5143 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5144 END IF;
5145 pa_debug.reset_curr_function;
5146 RAISE;
5147 END delete_task_elements;
5148 /*
5149 For bug 2976168.
5150 This API is called from pa_fp_elements_pub.make_new_tasks_plannable api for an option and element_type.
5151 This API will be used to decide whether to insert a task in fp elements table or not. This api will also
5152 provide the plannable flag and task planning level of all the tasks that are eligible for insertion.
5153 */
5154 PROCEDURE Get_Task_Element_Attributes
5155 ( p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
5156 ,p_element_type IN pa_fp_elements.element_type%TYPE
5157 ,p_task_id IN pa_fp_elements.task_id%TYPE
5158 ,p_top_task_id IN pa_fp_elements.top_task_id%TYPE
5159 ,p_task_level IN VARCHAR2
5160 ,p_option_plan_level_code IN pa_proj_fp_options.cost_fin_plan_level_code%TYPE
5161 ,x_task_inclusion_flag OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5162 ,x_task_plannable_flag OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5163 ,x_top_task_planning_level OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5164 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5165 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
5166 ,x_msg_data OUT NOCOPY VARCHAR2) IS --File.Sql.39 bug 4440895
5167
5168 --Declare the variables which are required as a standard
5169 l_msg_count NUMBER := 0;
5170 l_data VARCHAR2(2000);
5171 l_msg_data VARCHAR2(2000);
5172 l_msg_index_out NUMBER;
5173 l_debug_mode VARCHAR2(1);
5174
5175 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
5176 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
5177 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
5178 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
5179 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
5180 L_PROCEDURE_NAME CONSTANT VARCHAR2(100) :='Get_Task_Element_Attributes: '||
5181 l_module_name ;
5182
5183 --Variables required in this procedure
5184 l_continue_processing VARCHAR2(1) := 'Y';
5185 l_dummy VARCHAR2(1);
5186 l_child_task_exists NUMBER; /* Indicates if child tasks exists for a task
5187 0 - No child tasks exists
5188 1 - Child task exists
5189 Other Number - Sql Error */
5190
5191 --Cursors required for this procedure
5192
5193 --This cursor is used to know whether a task already exists in pa_fp_elements or not
5194 CURSOR task_element_info_cur (
5195 c_task_id pa_fp_elements.task_id%TYPE)
5196 IS
5197 SELECT pfe.top_task_planning_level,
5198 pfe.plannable_flag
5199 FROM pa_fp_elements pfe
5200 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5201 AND pfe.element_type = p_element_type
5202 AND pfe.task_id = c_task_id
5203 AND pfe.resource_list_member_id = 0;
5204
5205 task_element_info_rec task_element_info_cur%ROWTYPE;
5206
5207 --This cursor is used to know whether a task is explicitly made unplannable
5208 CURSOR excluded_task_cur
5209 ( c_task_id pa_tasks.task_id%TYPE
5210 ,c_top_task_id pa_tasks.task_id%TYPE)
5211 IS
5212 SELECT 'Y'
5213 FROM pa_fp_excluded_elements pfe
5214 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5215 AND pfe.element_type = p_element_type
5216 AND pfe.task_id IN (c_task_id,c_top_task_id);
5217
5218 BEGIN
5219 x_msg_count := 0;
5220 x_return_status := FND_API.G_RET_STS_SUCCESS;
5221 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
5222
5223 IF l_debug_mode = 'Y' THEN
5224 pa_debug.set_curr_function( p_function => 'Get_Task_Element_Attributes',
5225 p_debug_mode => l_debug_mode );
5226 END IF;
5227
5228 IF l_debug_mode = 'Y' THEN
5229 pa_debug.g_err_stage:= 'Validating input parameters';
5230 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5231 END IF;
5232
5233 IF p_proj_fp_options_id IS NULL OR
5234 p_element_type IS NULL OR
5235 p_task_id IS NULL OR
5236 p_top_task_id IS NULL OR
5237 p_task_level IS NULL OR
5238 p_option_plan_level_code IS NULL
5239 THEN
5240
5241 IF l_debug_mode = 'Y' THEN
5242 pa_debug.g_err_stage:= 'p_proj_fp_options_id = '|| p_proj_fp_options_id;
5243 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5244
5245 pa_debug.g_err_stage:= 'p_element_type = '|| p_element_type;
5246 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5247
5248 pa_debug.g_err_stage:= 'p_task_id = '|| p_task_id;
5249 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5250
5251 pa_debug.g_err_stage:= 'p_top_task_id = '|| p_top_task_id;
5252 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5253
5254 pa_debug.g_err_stage:= 'p_task_level = '|| p_task_level;
5255 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5256
5257 pa_debug.g_err_stage:= 'p_option_plan_level_code = '|| p_option_plan_level_code;
5258 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5259
5260 END IF;
5261 PA_UTILS.ADD_MESSAGE
5262 (p_app_short_name => 'PA',
5263 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
5264 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5265
5266 END IF;
5267
5268 --Check if the task is already included as a plannable element.
5269 IF l_debug_mode = 'Y' THEN
5270 pa_debug.g_err_stage:= 'Check if task is already plannable(existence in pa_fp_elements)';
5271 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5272 END IF;
5273
5274 -- If p_task_id already exists in pa_fp_elements for the option_id and element_type, no further
5275 -- processing is required.
5276
5277 OPEN task_element_info_cur(p_task_id);
5278 FETCH task_element_info_cur INTO task_element_info_rec;
5279 IF task_element_info_cur%NOTFOUND THEN
5280 l_continue_processing := 'Y';
5281 IF l_debug_mode = 'Y' THEN
5282 pa_debug.g_err_stage:= 'task doesnt exists in pa_fp_elements. Proceeding further..';
5283 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5284 END IF;
5285 ELSE
5286 l_continue_processing := 'N';
5287 x_task_inclusion_flag := 'N';
5288 IF l_debug_mode = 'Y' THEN
5289 pa_debug.g_err_stage:= 'task is already plannable and exists in pa_fp_elements. No processing required...';
5290 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5291 END IF;
5292 END IF;
5293 CLOSE task_element_info_cur;
5294
5295 --Check if the task is already made unplannable.
5296 IF l_continue_processing = 'Y' THEN
5297
5298 OPEN excluded_task_cur( p_task_id
5299 ,p_top_task_id);
5300 FETCH excluded_task_cur INTO l_dummy;
5301 IF excluded_task_cur%FOUND THEN
5302 l_continue_processing := 'N';
5303 x_task_inclusion_flag := 'N';
5304 IF l_debug_mode = 'Y' THEN
5305 pa_debug.g_err_stage:= 'Task ' ||p_task_id ||' is not processed as it exists in pa_fp_excluded_elements';
5306 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5307 END IF;
5308 END IF;
5309 CLOSE excluded_task_cur;
5310 END IF;
5311
5312 --Continue processing if the task is not either made plannable or unplannable.
5313 IF l_continue_processing='Y' THEN
5314 IF l_debug_mode = 'Y' THEN
5315 pa_debug.g_err_stage := 'Continuing with the processing of task ' || p_task_id;
5316 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5317 END IF;
5318
5319 -- Planning level for the options is top task
5320 IF p_option_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_TOP THEN
5321
5322 --The task passed is a top task
5323
5324 IF p_task_level = L_TASK_LEVEL_TOP THEN
5325
5326 -- When the planning level of the option is TOP,
5327 -- only top task are plannable
5328 x_task_inclusion_flag := 'Y';
5329 x_task_plannable_flag := 'Y';
5330 x_top_task_planning_level := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_TOP;
5331 ELSE
5332
5333 x_task_inclusion_flag := 'N';
5334
5335 END IF; /* p_task_id = p_top_task_id */
5336
5337 IF l_debug_mode = 'Y' THEN
5338 pa_debug.g_err_stage:= 'Option planned at Top Task and x_task_inclusion_flag = ' ||
5339 x_task_inclusion_flag || ' x_task_plannable_flag =' || x_task_plannable_flag ||
5340 ' x_top_task_planning_level ' || x_top_task_planning_level;
5341 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5342 END IF;
5343
5344 --Planning level of the options is either LOWEST or TOP AND LOWEST
5345
5346 ELSIF p_option_plan_level_code IN (PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_LOWEST,
5347 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_M) THEN
5348
5349 IF l_debug_mode = 'Y' THEN
5350 pa_debug.g_err_stage:= 'Option planned at Lowest Task or Top and Lowest Task';
5351 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5352 END IF;
5353
5354 --The task is a top task
5355 IF p_task_level = L_TASK_LEVEL_TOP THEN
5356
5357 l_child_task_exists := pa_task_utils.check_child_exists(x_task_id => p_task_id);
5358
5359 IF l_child_task_exists = 1 THEN /* Child task exsists */
5360
5361 /* This is a TOP task which is being created only now. But the planning
5362 level is L/M. Since we always have top task records in pa_fp_elements,
5363 this top task should be inserted in pa_fp_elements with plannable flag
5364 as N. Resource elements should not be added for this top task */
5365
5366 x_task_inclusion_flag := 'Y';
5367 x_task_plannable_flag := 'N' ;
5368 x_top_task_planning_level := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST;
5369
5370 IF l_debug_mode = 'Y' THEN
5371 pa_debug.g_err_stage:= 'Task is a TOP TASK and x_task_inclusion_flag = '
5372 || x_task_inclusion_flag || ' x_task_plannable_flag ='
5373 ||x_task_plannable_flag || ' and x_top_task_planning_level =' ||
5374 x_top_task_planning_level;
5375 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5376 END IF;
5377
5378 --The task is both top and lowest
5379 ELSIF l_child_task_exists = 0 THEN
5380
5381 /* TOP AND LOWEST TASK is always plannable when planning
5382 level of the option is LOWEST or TOP AND LOWEST */
5383
5384 x_task_inclusion_flag := 'Y';
5385 x_task_plannable_flag := 'Y' ;
5386 x_top_task_planning_level := PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST;
5387
5388 IF l_debug_mode = 'Y' THEN
5389 pa_debug.g_err_stage:= 'Task is a TOP and LOWEST TASK and x_task_inclusion_flag = '
5390 || x_task_inclusion_flag || ' x_task_plannable_flag ='
5391 ||x_task_plannable_flag || ' and x_top_task_planning_level =' ||
5392 x_top_task_planning_level;
5393
5394 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5395 END IF;
5396
5397 ELSE
5398
5399 IF l_debug_mode = 'Y' THEN
5400 pa_debug.g_err_stage:= 'Error returned by pa_task_utils.check_child_exists. Sqlerrcode ' || to_char(l_child_task_exists);
5401 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5402 END IF;
5403
5404 RAISE FND_API.G_Exc_Unexpected_Error;
5405
5406 END IF;
5407
5408 ELSIF p_task_level = L_TASK_LEVEL_LOWEST THEN
5409
5410 /* p_task_id is a sub task.
5411 We need to check if the top task of p_task_id is marked plannable */
5412
5413 IF l_debug_mode = 'Y' THEN
5414 pa_debug.g_err_stage:= 'Task is a sub task';
5415 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5416 END IF;
5417
5418 OPEN task_element_info_cur(p_top_task_id);
5419 FETCH task_element_info_cur INTO task_element_info_rec;
5420
5421 /* If top task of p_task_id is not plannable,
5422 then p_task_id is not plannable */
5423
5424 IF task_element_info_cur%NOTFOUND THEN
5425
5426 /* Note that we dont expect this case to happen since our assumption is that
5427 the top task record would be first called to be made plannable and then the
5428 lowest task. If we need to handle this case, we have to first insert the
5429 p_top_task_id record into pa_fp_elements and then the p_task_id record. */
5430
5431 x_task_inclusion_flag := 'N';
5432
5433 CLOSE task_element_info_cur;
5434
5435 IF l_debug_mode = 'Y' THEN
5436 pa_debug.g_err_stage:= 'Top Task not found in pa_fp_elements and hence x_task_inclusion_flag ' || x_task_inclusion_flag;
5437 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5438 END IF;
5439
5440 ELSE
5441
5442 CLOSE task_element_info_cur;
5443 IF task_element_info_rec.top_task_planning_level = PA_FP_CONSTANTS_PKG.G_TASK_PLAN_LEVEL_LOWEST THEN
5444
5445 /* If top task of p_task_id is plannable at LOWEST task level,
5446 then p_task_id (which is a lowest task here) should be made plannable */
5447
5448 x_task_inclusion_flag := 'Y';
5449 x_task_plannable_flag := 'Y';
5450
5451
5452 IF l_debug_mode = 'Y' THEN
5453 pa_debug.g_err_stage:= 'Top task is planned at lowest task level and x_task_inclusion_flag = ' || x_task_inclusion_flag
5454 ||' x_task_plannable_flag = ' ||x_task_plannable_flag;
5455 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5456 END IF;
5457
5458 ELSE
5459
5460 /* If top task is not plannable at LOWEST task level,
5461 then p_task_id should not be plannable */
5462
5463 x_task_inclusion_flag := 'N';
5464
5465 IF l_debug_mode = 'Y' THEN
5466 pa_debug.g_err_stage:= 'Top task is NOT planned at lowest task and so x_task_inclusion_flag = ' || x_task_inclusion_flag;
5467 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5468 END IF;
5469
5470 END IF; /* task_element_info_rec.top_task_planning_level = 'LOWEST' */
5471
5472 END IF; /* task_element_info_cur%NOTFOUND */
5473
5474 END IF; /* p_task_level = L_TASK_LEVEL_TOP */
5475
5476 END IF; /* p_option_plan_level_code = PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_TOP*/
5477
5478 END IF;/* If l_continue_processing = 'Y' */
5479
5480 IF l_debug_mode = 'Y' THEN
5481 pa_debug.g_err_stage:= 'Exiting Get_Task_Element_Attributes';
5482 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5483 pa_debug.reset_curr_function;
5484 END IF;
5485
5486 EXCEPTION
5487
5488 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
5489
5490 x_return_status := FND_API.G_RET_STS_ERROR;
5491 l_msg_count := FND_MSG_PUB.count_msg;
5492
5493 IF l_msg_count = 1 and x_msg_data IS NULL THEN
5494 PA_INTERFACE_UTILS_PUB.get_messages
5495 (p_encoded => FND_API.G_TRUE
5496 ,p_msg_index => 1
5497 ,p_msg_count => l_msg_count
5498 ,p_msg_data => l_msg_data
5499 ,p_data => l_data
5500 ,p_msg_index_out => l_msg_index_out);
5501 x_msg_data := l_data;
5502 x_msg_count := l_msg_count;
5503 ELSE
5504 x_msg_count := l_msg_count;
5505 END IF;
5506 IF l_debug_mode = 'Y' THEN
5507 pa_debug.reset_curr_function;
5508 END IF;
5509
5510 RETURN;
5511
5512 WHEN OTHERS THEN
5513
5514 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5515 x_msg_count := 1;
5516 x_msg_data := SQLERRM;
5517
5518 FND_MSG_PUB.add_exc_msg
5519 ( p_pkg_name => 'PA_FP_ELEMENTS_PUB'
5520 ,p_procedure_name => 'Get_Task_Element_Attributes'
5521 ,p_error_text => x_msg_data);
5522
5523 IF l_debug_mode = 'Y' THEN
5524 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
5525 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5526 pa_debug.reset_curr_function;
5527 END IF;
5528 RAISE;
5529 END Get_Task_Element_Attributes;
5530
5531 /* Bug 2920954 - This is a PRIVATE api that would be called from the make_new_tasks_plannable
5532 api for each fp option in the context of COST/REVENUE/ALL. The api checks if the input
5533 new task can be made plannable depending on the planning level of the fp option and top
5534 task planning level. If the new task is plannable, task level record is inserted into
5535 fp elements table and if resources are to be added automatically, the procedure
5536 ADD_RESOURCES_AUTOMATICALLY api is called. Also, resource assignments and fp elements that
5537 were present for original task that was earlier plannable but now unplannable is deleted.
5538
5539 Bug 2976168. Changed the signature of the API. Also the logic of deriving is a task is
5540 plannable or not is moved to Get_Task_Element_Attributes Api
5541
5542 Bug 2989900. In case of CI versions, the tasks would be made plannable only if the task
5543 is an impacted task or a child task of impacted task */
5544
5545 PROCEDURE add_tasks_to_option
5546 ( p_proj_fp_options_id IN pa_proj_fp_options.proj_fp_options_id%TYPE
5547 ,p_element_type IN pa_fp_elements.element_type%TYPE
5548 ,p_tasks_tbl IN pa_fp_elements_pub.l_wbs_refresh_tasks_tbl_typ
5549 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
5550 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
5551 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
5552 AS
5553
5554 l_msg_count NUMBER := 0;
5555 l_data VARCHAR2(2000);
5556 l_msg_data VARCHAR2(2000);
5557 l_msg_index_out NUMBER;
5558 l_debug_mode VARCHAR2(1);
5559
5560 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
5561 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
5562 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
5563 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
5564 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
5565
5566 CURSOR proj_fp_options_cur
5567 IS
5568 SELECT pfo.project_id,
5569 pfo.fin_plan_type_id,
5570 pfo.fin_plan_version_id,
5571 pfo.fin_plan_option_level_code,
5572 DECODE(p_element_type,
5573 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST,pfo.cost_fin_plan_level_code,
5574 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL,pfo.all_fin_plan_level_code,
5575 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.revenue_fin_plan_level_code) fin_plan_level_code,
5576 DECODE(p_element_type,
5577 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST,pfo.select_cost_res_auto_flag,
5578 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, pfo.select_all_res_auto_flag,
5579 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.select_rev_res_auto_flag) auto_res_selection_flag,
5580 DECODE(p_element_type,
5581 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, pfo.cost_res_planning_level,
5582 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, pfo.all_res_planning_level,
5583 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.revenue_res_planning_level) auto_res_plan_level,
5584 DECODE(p_element_type,
5585 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST, pfo.cost_resource_list_id,
5586 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL, pfo.all_resource_list_id,
5587 PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE, pfo.revenue_resource_list_id) resource_list_id
5588 FROM pa_proj_fp_options pfo
5589 WHERE pfo.proj_fp_options_id = p_proj_fp_options_id;
5590
5591 proj_fp_options_rec proj_fp_options_cur%ROWTYPE;
5592
5593
5594 l_task_id_tbl pa_fp_elements_pub.l_task_id_tbl_typ;
5595
5596 l_task_plannable_flag VARCHAR2(1); /* represents the plannable of the task to
5597 be inserted*/
5598
5599 --For Bug 2976168.
5600 l_task_inclusion_flag VARCHAR2(1); /*Required to know whether the task can be is
5601 eligible for inserting into pa_fp_elements or not*/
5602 CURSOR ci_version_info_cur
5603 (c_plan_version_id pa_proj_fp_options.fin_plan_version_id%TYPE)
5604 IS
5605 SELECT bv.ci_id,
5606 impacted_task_id
5607 FROM pa_budget_versions bv,
5608 pa_ci_impacts ci
5609 WHERE budget_version_id = c_plan_version_id
5610 AND bv.ci_id = ci.ci_id
5611 AND bv.ci_id IS NOT NULL;
5612
5613 ci_version_info_rec ci_version_info_cur%ROWTYPE;
5614
5615 CURSOR ci_impacted_tasks_cur
5616 (c_project_id NUMBER, c_impacted_task_id NUMBER) IS
5617 SELECT task_id
5618 FROM pa_tasks t
5619 WHERE t.project_id = c_project_id
5620 START WITH t.task_id = c_impacted_task_id
5621 CONNECT BY prior t.task_id = t.parent_task_id;
5622
5623 ci_impacted_tasks_rec ci_impacted_tasks_cur%ROWTYPE;
5624
5625 l_continue_processing VARCHAR2(1);
5626 l_ci_impacted_tasks_tbl PA_PLSQL_DATATYPES.NumTabTyp;
5627 l_top_task_planning_level pa_fp_elements.top_task_planning_level%TYPE;
5628 L_PROCEDURE_NAME CONSTANT VARCHAR2(100):='add_task_to_option :'||l_module_name;
5629
5630 BEGIN
5631 x_msg_count := 0;
5632 x_return_status := FND_API.G_RET_STS_SUCCESS;
5633 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
5634
5635
5636 -- Check for business rules violations
5637
5638 IF l_debug_mode = 'Y' THEN
5639 pa_debug.set_curr_function( p_function => 'add_task_to_option',
5640 p_debug_mode => l_debug_mode );
5641 pa_debug.g_err_stage:= 'Validating input parameters';
5642 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5643 END IF;
5644
5645 IF (p_proj_fp_options_id IS NULL) OR
5646 (p_element_type IS NULL) THEN
5647
5648 IF l_debug_mode = 'Y' THEN
5649 pa_debug.g_err_stage:= 'p_proj_fp_options_id = '|| p_proj_fp_options_id;
5650 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5651 pa_debug.g_err_stage:= 'p_element_type = '|| p_element_type;
5652 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5653 END IF;
5654 PA_UTILS.ADD_MESSAGE
5655 (p_app_short_name => 'PA',
5656 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
5657 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5658
5659 END IF;
5660
5661 IF l_debug_mode = 'Y' THEN
5662 pa_debug.g_err_stage:= 'Opening proj_fp_options_cur.';
5663 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5664 END IF;
5665
5666 OPEN proj_fp_options_cur;
5667 FETCH proj_fp_options_cur INTO proj_fp_options_rec;
5668 CLOSE proj_fp_options_cur;
5669
5670 IF proj_fp_options_rec.fin_plan_version_id IS NOT NULL THEN
5671
5672 OPEN ci_version_info_cur(proj_fp_options_rec.fin_plan_version_id);
5673 FETCH ci_version_info_cur INTO ci_version_info_rec;
5674 IF ci_version_info_cur%NOTFOUND THEN
5675 IF l_debug_mode = 'Y' THEN
5676 pa_debug.g_err_stage:= 'The Option does not correspond to a CI Version';
5677 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5678 END IF;
5679 ELSE
5680 IF l_debug_mode = 'Y' THEN
5681 pa_debug.g_err_stage:= 'The Option corresponds to a CI Version';
5682 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5683 END IF;
5684
5685 --Check whether an impacted task id exists or not. If it exists store all the tasks
5686 --below that task in wbs in a pl/sql table so that only those tasks are processed.
5687
5688 IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN
5689 IF l_debug_mode = 'Y' THEN
5690 pa_debug.g_err_stage:= 'The impacted task id is '
5691 ||ci_version_info_rec.impacted_task_id;
5692 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5693 END IF;
5694
5695 FOR ci_impacted_tasks_rec IN ci_impacted_tasks_cur( proj_fp_options_rec.project_id
5696 ,ci_version_info_rec.impacted_task_id) LOOP
5697
5698 l_ci_impacted_tasks_tbl(ci_impacted_tasks_rec.task_id) := 1 ;
5699
5700 END LOOP;
5701
5702 END IF; /* IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN */
5703
5704 END IF; /* IF ci_version_info_cur%NOTFOUND THEN */
5705
5706 CLOSE ci_version_info_cur;
5707
5708 END IF; /* IF proj_fp_options_rec.fin_plan_version_id IS NOT NULL THEN */
5709
5710 --Process the tasks passed by looping thru the pl/sql table (we are sure the plsql table contains records)
5711
5712 FOR i IN p_tasks_tbl.first .. p_tasks_tbl.last LOOP
5713
5714 l_continue_processing := 'Y';
5715
5716 IF p_tasks_tbl(i).task_level IN ( L_TASK_LEVEL_LOWEST
5717 ,L_TASK_LEVEL_TOP) THEN
5718
5719 IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN
5720
5721 /* Process the task only if the task is under the impacted task id */
5722
5723 IF l_ci_impacted_tasks_tbl.exists(p_tasks_tbl(i).task_id) THEN
5724
5725 l_continue_processing := 'Y';
5726 ELSE
5727
5728 l_continue_processing := 'N';
5729
5730 IF l_debug_mode = 'Y' THEN
5731 pa_debug.g_err_stage:= 'The task '||p_tasks_tbl(i).task_id
5732 ||' is not under the impacted task '
5733 ||ci_version_info_rec.impacted_task_id;
5734 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5735 END IF;
5736
5737 END IF;
5738
5739 END IF; /* IF ci_version_info_rec.impacted_task_id IS NOT NULL THEN */
5740
5741 IF l_continue_processing = 'Y' THEN
5742
5743 l_task_inclusion_flag := Null;
5744 l_task_plannable_flag := Null;
5745 l_top_task_planning_level := Null;
5746
5747 --Call the api that helps in deciding whether to insert the task or not.
5748
5749 Get_Task_Element_Attributes
5750 ( p_proj_fp_options_id => p_proj_fp_options_id
5751 ,p_element_type => p_element_type
5752 ,p_task_id => p_tasks_tbl(i).task_id
5753 ,p_top_task_id => p_tasks_tbl(i).top_task_id
5754 ,p_task_level => p_tasks_tbl(i).task_level
5755 ,p_option_plan_level_code => proj_fp_options_rec.fin_plan_level_code
5756 ,x_task_inclusion_flag => l_task_inclusion_flag
5757 ,x_task_plannable_flag => l_task_plannable_flag
5758 ,x_top_task_planning_level => l_top_task_planning_level
5759 ,x_return_status => x_return_status
5760 ,x_msg_count => x_msg_count
5761 ,x_msg_data => x_msg_data);
5762
5763 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
5764
5765 IF l_debug_mode = 'Y' THEN
5766 pa_debug.g_err_stage := 'Error in Get_Task_Element_Attributes for task'
5767 || p_tasks_tbl(i).task_id ;
5768 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5769 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5770
5771 END IF;
5772
5773 END IF;
5774
5775 IF l_task_inclusion_flag = 'Y' THEN
5776
5777 IF p_tasks_tbl(i).parent_task_id = p_tasks_tbl(i).top_task_id THEN
5778
5779 /* If the parent task is a top task,
5780
5781 1. We need to remove only the resources elements attached
5782 to the parent task from pa_fp_elements.
5783
5784 2. Since we always have the top task record of a plannable
5785 task in pa_fp_elements, we shouldnt delete the top task
5786 record. We just have to set the plannable flag
5787 of this task to N. */
5788
5789 DELETE pa_fp_elements pfe
5790 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5791 AND pfe.element_type = p_element_type
5792 AND pfe.task_id = p_tasks_tbl(i).parent_task_id
5793 AND pfe.resource_list_member_id <> 0;
5794
5795 IF l_debug_mode = 'Y' THEN
5796 pa_debug.g_err_stage:= to_char(sql%rowcount) || ' records deleted from pa_fp_elements';
5797 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5798 END IF;
5799
5800 UPDATE pa_fp_elements pfe
5801 SET pfe.plannable_flag = 'N',
5802 pfe.tmp_plannable_flag = 'N',
5803 pfe.resources_planned_for_task = Null,
5804 pfe.record_version_number = pfe.record_version_number + 1,
5805 last_update_date = sysdate,
5806 last_updated_by = FND_GLOBAL.USER_ID,
5807 last_update_login = FND_GLOBAL.LOGIN_ID
5808 WHERE pfe.proj_fp_options_id = p_proj_fp_options_id
5809 AND pfe.element_type = p_element_type
5810 AND pfe.task_id = p_tasks_tbl(i).parent_task_id
5811 AND pfe.resource_list_member_id = 0;
5812
5813 IF l_debug_mode = 'Y' THEN
5814 pa_debug.g_err_stage:= to_char(sql%rowcount) || ' records updated in pa_fp_elements';
5815 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5816 END IF;
5817
5818 IF proj_fp_options_rec.fin_plan_option_level_code = PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION THEN
5819
5820 /* If this option corresponds to a plan version, we should delete the resource assignments also
5821 for p_task_id. */
5822
5823 DELETE pa_resource_assignments pra
5824 WHERE pra.budget_version_id = proj_fp_options_rec.fin_plan_version_id
5825 AND pra.task_id = p_tasks_tbl(i).parent_task_id
5826 AND pra.resource_assignment_type = PA_FP_CONSTANTS_PKG.G_USER_ENTERED;
5827
5828 IF l_debug_mode = 'Y' THEN
5829 pa_debug.g_err_stage:= 'PLAN_VERSION option. ' || to_char(sql%rowcount) || ' records deleted from pa_resource_assignments';
5830 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5831 END IF;
5832
5833 END IF; /* Option is PLAN_VERSION */
5834
5835 ELSE
5836
5837 /* If p_task_id is not a top task then it would not be required to delete here
5838 as we BULK delete in make_new_tasks_plannable api for this case */
5839 Null;
5840
5841 END IF;
5842
5843 INSERT INTO PA_FP_ELEMENTS
5844 (PROJ_FP_ELEMENTS_ID
5845 ,PROJ_FP_OPTIONS_ID
5846 ,PROJECT_ID
5847 ,FIN_PLAN_TYPE_ID
5848 ,ELEMENT_TYPE
5849 ,FIN_PLAN_VERSION_ID
5850 ,TASK_ID
5851 ,TOP_TASK_ID
5852 ,RESOURCE_LIST_MEMBER_ID
5853 ,TOP_TASK_PLANNING_LEVEL
5854 ,RESOURCE_PLANNING_LEVEL
5855 ,PLANNABLE_FLAG
5856 ,RESOURCES_PLANNED_FOR_TASK
5857 ,PLAN_AMOUNT_EXISTS_FLAG
5858 ,TMP_PLANNABLE_FLAG
5859 ,TMP_TOP_TASK_PLANNING_LEVEL
5860 ,RECORD_VERSION_NUMBER
5861 ,LAST_UPDATE_DATE
5862 ,LAST_UPDATED_BY
5863 ,CREATION_DATE
5864 ,CREATED_BY
5865 ,LAST_UPDATE_LOGIN)
5866 VALUES
5867 (pa_fp_elements_s.nextval
5868 ,p_proj_fp_options_id
5869 ,proj_fp_options_rec.project_id
5870 ,proj_fp_options_rec.fin_plan_type_id
5871 ,p_element_type
5872 ,proj_fp_options_rec.fin_plan_version_id
5873 ,p_tasks_tbl(i).task_id
5874 ,p_tasks_tbl(i).top_task_id
5875 ,0 -- resource_list_member_id
5876 ,l_top_task_planning_level -- top_task_planning_level
5877 ,decode(l_task_plannable_flag,
5878 'N',Null,
5879 proj_fp_options_Rec.auto_res_plan_level) -- resource_planning_level
5880 ,l_task_plannable_flag -- plannable_flag
5881 ,proj_fp_options_rec.auto_res_selection_flag -- resources_planned_for_task
5882 ,'N' -- plan_amount_exists_flag
5883 ,l_task_plannable_flag -- tmp_plannable_flag
5884 ,l_top_task_planning_level -- tmp_top_task_planning_level
5885 ,1
5886 ,SYSDATE
5887 ,FND_GLOBAL.USER_ID
5888 ,SYSDATE
5889 ,FND_GLOBAL.USER_ID
5890 ,FND_GLOBAL.LOGIN_ID);
5891
5892 IF proj_fp_options_rec.auto_res_selection_flag = 'Y' THEN
5893
5894 /* We should be adding resources only if p_task_id is a plannable task record.
5895 It should not be added to a top task record that is plannable at lowest task level */
5896
5897 IF l_task_plannable_flag = 'Y' THEN
5898
5899 /* If automatic resource selection is 'Y' for the proj_fp_option/element type,
5900 then resource elements need to be added */
5901
5902 IF l_debug_mode = 'Y' THEN
5903 pa_debug.g_err_stage:= 'Calling add_resources_automatically...';
5904 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5905 END IF;
5906
5907 l_task_id_tbl(1) := p_tasks_tbl(i).task_id;
5908
5909 PA_FP_ELEMENTS_PUB.ADD_RESOURCES_AUTOMATICALLY
5910 ( p_proj_fp_options_id => p_proj_fp_options_id
5911 ,p_element_type => p_element_type
5912 ,p_fin_plan_level_code => proj_fp_options_rec.fin_plan_level_code
5913 ,p_resource_list_id => proj_fp_options_rec.resource_list_id
5914 ,p_res_planning_level => proj_fp_options_rec.auto_res_plan_level
5915 ,p_entire_option => 'N'
5916 ,p_element_task_id_tbl => l_task_id_tbl
5917 ,x_return_status => x_return_status
5918 ,x_msg_count => x_msg_count
5919 ,x_msg_data => x_msg_data);
5920
5921 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
5922
5923 pa_debug.g_err_stage := 'Error while adding resoruces to task id ' || p_tasks_tbl(i).task_id ||
5924 'for ' || p_element_type || ' option id ' || p_proj_fp_options_id;
5925 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5926
5927 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5928
5929 END IF;
5930
5931 END IF; /* l_task_plannable_flag = 'Y' */
5932
5933 END IF; /* proj_fp_options_rec.auto_res_selection_flag = 'Y' */
5934
5935 END IF; /* IF l_task_inclusion_flag = 'Y' THEN */
5936
5937 END IF; /* IF l_continue_processing = 'Y' THEN */
5938
5939 END IF; /* IF p_tasks_tbl(i).task_level IN (T,L) */
5940
5941 END LOOP; /* p_tasks_tbl.first .. p_tasks_tbl.last loop */
5942
5943 /* Add_tasks_to_option is called only when the planning level is NOT project */
5944
5945 IF proj_fp_options_rec.fin_plan_option_level_code = PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION THEN
5946
5947 IF l_debug_mode = 'Y' THEN
5948 pa_debug.g_err_stage:= 'Calling create_enterable_resources...';
5949 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5950 END IF;
5951
5952 PA_FP_ELEMENTS_PUB.create_enterable_resources
5953 ( p_plan_version_id => proj_fp_options_rec.fin_plan_version_id
5954 ,p_res_del_req_flag => 'N' /* Since deletion of resource assignments has already been done in this flow */
5955 ,x_return_status => x_return_status
5956 ,x_msg_count => x_msg_count
5957 ,x_msg_data => x_msg_data);
5958
5959 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
5960
5961 pa_debug.g_err_stage := 'Error calling create enterable resoruces for version id'
5962 || proj_fp_options_rec.fin_plan_version_id;
5963 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
5964
5965 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
5966 END IF;
5967
5968 END IF; /* IF proj_fp_options_rec.fin_plan_option_level_code = PLAN_VERSION */
5969
5970 IF l_debug_mode = 'Y' THEN
5971 pa_debug.g_err_stage:= 'Exiting add_task_to_option';
5972 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
5973 pa_debug.reset_curr_function;
5974 END IF;
5975
5976 EXCEPTION
5977
5978 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
5979
5980 x_return_status := FND_API.G_RET_STS_ERROR;
5981 l_msg_count := FND_MSG_PUB.count_msg;
5982
5983 IF l_msg_count = 1 and x_msg_data IS NULL THEN
5984 PA_INTERFACE_UTILS_PUB.get_messages
5985 (p_encoded => FND_API.G_TRUE
5986 ,p_msg_index => 1
5987 ,p_msg_count => l_msg_count
5988 ,p_msg_data => l_msg_data
5989 ,p_data => l_data
5990 ,p_msg_index_out => l_msg_index_out);
5991 x_msg_data := l_data;
5992 x_msg_count := l_msg_count;
5993 ELSE
5994 x_msg_count := l_msg_count;
5995 END IF;
5996 IF l_debug_mode = 'Y' THEN
5997 pa_debug.reset_curr_function;
5998 END IF;
5999 RETURN;
6000
6001 WHEN others THEN
6002
6003 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6004 x_msg_count := 1;
6005 x_msg_data := SQLERRM;
6006
6007 FND_MSG_PUB.add_exc_msg
6008 ( p_pkg_name => 'pa_fp_elements_pub'
6009 ,p_procedure_name => 'add_task_to_option'
6010 ,p_error_text => x_msg_data);
6011
6012 IF l_debug_mode = 'Y' THEN
6013 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
6014 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6015 pa_debug.reset_curr_function;
6016 END IF;
6017 RAISE;
6018 END add_tasks_to_option;
6019
6020 /* Bug 2920954 - This is the main API that does the processing
6021 necessary to make the tasks plannable automatically at project level
6022 option, plan type level options and for all the working plan
6023 versions. This is api is called by projects / workplan code to make
6024 the new tasks that are created as plannable. */
6025
6026 /* Bug 2976168. Changed the signature of the api. This api will now be called from
6027 pa_fin_plan_maint_ver_global.resubmit_concurrent_request */
6028
6029 PROCEDURE make_new_tasks_plannable
6030 ( p_project_id IN pa_projects_all.project_id%TYPE
6031 ,p_tasks_tbl IN pa_fp_elements_pub.l_wbs_refresh_tasks_tbl_typ
6032 ,p_refresh_fp_options_tbl IN PA_PLSQL_DATATYPES.IdTabTyp
6033 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
6034 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
6035 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
6036 AS
6037
6038 l_msg_count NUMBER := 0;
6039 l_data VARCHAR2(2000);
6040 l_msg_data VARCHAR2(2000);
6041 l_msg_index_out NUMBER;
6042 l_debug_mode VARCHAR2(1);
6043
6044 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
6045 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
6046
6047
6048 CURSOR fp_options_info_cur
6049 (c_proj_fp_options_id pa_proj_fp_options.proj_fp_options_id%TYPE)
6050 IS
6051 SELECT pfo.proj_fp_options_id,
6052 pfo.fin_plan_option_level_code,
6053 pfo.fin_plan_preference_code,
6054 pfo.cost_fin_plan_level_code,
6055 pfo.revenue_fin_plan_level_code,
6056 pfo.all_fin_plan_level_code,
6057 pfo.fin_plan_version_id
6058 FROM pa_proj_fp_options pfo
6059 WHERE pfo.proj_fp_options_id = c_proj_fp_options_id;
6060 fp_options_info_rec fp_options_info_cur%ROWTYPE;
6061
6062 l_process_option VARCHAR2(1);
6063
6064 L_PROCEDURE_NAME CONSTANT VARCHAR2(100):='make_new_tasks_plannable :'||l_module_name;
6065 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
6066 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
6067 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
6068
6069 BEGIN
6070
6071 x_msg_count := 0;
6072 x_return_status := FND_API.G_RET_STS_SUCCESS;
6073 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
6074
6075
6076 -- Check for business rules violations
6077
6078 IF l_debug_mode = 'Y' THEN
6079 pa_debug.set_curr_function( p_function => 'make_new_tasks_plannable',
6080 p_debug_mode => l_debug_mode );
6081 pa_debug.g_err_stage:= 'Validating input parameters';
6082 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6083 END IF;
6084
6085 IF (p_project_id IS NULL)
6086 THEN
6087 IF l_debug_mode = 'Y' THEN
6088 pa_debug.g_err_stage:= 'p_project_id = '|| p_project_id;
6089 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6090 END IF;
6091 PA_UTILS.ADD_MESSAGE
6092 (p_app_short_name => 'PA',
6093 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6094 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6095
6096 END IF;
6097
6098 --Continue processing only if the task table has some records.
6099
6100 IF NVL(p_tasks_tbl.last,0) = 0 OR
6101 NVL(p_refresh_fp_options_tbl.last,0) = 0 THEN
6102
6103 IF l_debug_mode = 'Y' THEN
6104 pa_debug.g_err_stage:= 'task table/proj fp options table have no records. Returning from make_new_tasks_plannable ';
6105 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6106 END IF;
6107
6108 RETURN;
6109
6110 END IF;
6111
6112 IF l_debug_mode = 'Y' THEN
6113 pa_debug.g_err_stage:= 'task table has records.';
6114 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6115 END IF;
6116
6117 /* Loop through the table and process the task records */
6118
6119 FOR i IN p_tasks_tbl.first .. p_tasks_tbl.last
6120 LOOP
6121 /* If the task is a middle level task delete all the references of that task from
6122 pa_fp_elements and pa_resource_assignments */
6123
6124 IF l_debug_mode = 'Y' THEN
6125 pa_debug.g_err_stage:= 'task_id ' || p_tasks_tbl(i).task_id;
6126 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6127 pa_debug.g_err_stage:= 'task_level ' || p_tasks_tbl(i).task_level;
6128 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6129 END IF;
6130
6131 IF p_tasks_tbl(i).task_level = L_TASK_LEVEL_MIDDLE THEN
6132
6133 --Delete the task references from pa_fp_elements
6134 FORALL k IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last
6135 DELETE
6136 FROM pa_fp_elements
6137 WHERE task_id = p_tasks_tbl(i).task_id
6138 AND proj_fp_options_id = p_refresh_fp_options_tbl(k); /* We are deleting irrespective of element_type */
6139
6140 IF l_debug_mode = 'Y' THEN
6141 pa_debug.g_err_stage:= 'No of records deleted from pa_fp_elements ' ||SQL%ROWCOUNT;
6142 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6143 END IF;
6144
6145 --Delete the task references from pa_resource_assignments
6146 FORALL k IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last
6147 DELETE
6148 FROM pa_resource_assignments pra
6149 WHERE pra.task_id = p_tasks_tbl(i).task_id
6150 AND pra.budget_version_id in (SELECT pfo.fin_plan_version_id
6151 FROM pa_proj_fp_options pfo
6152 WHERE pfo.proj_fp_options_id =
6153 p_refresh_fp_options_tbl(k))
6154 AND pra.resource_assignment_type = PA_FP_CONSTANTS_PKG.G_USER_ENTERED;
6155
6156 IF l_debug_mode = 'Y' THEN
6157 pa_debug.g_err_stage:= 'No of records deleted from pa_resource_assignments ' ||SQL%ROWCOUNT;
6158 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6159 END IF;
6160
6161 END IF; /* IF p_tasks_tbl(i).task_level = M */
6162
6163 END LOOP; /* FOR i IN p_tasks_tbl.first .. p_tasks_tbl.last */
6164
6165 --Loop through the table and process the option records
6166 FOR j IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last LOOP
6167
6168 IF l_debug_mode = 'Y' THEN
6169 pa_debug.g_err_stage:= 'Opening fp_options_info_cur';
6170 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6171 END IF;
6172
6173 OPEN fp_options_info_cur(p_refresh_fp_options_tbl(j));
6174 FETCH fp_options_info_cur INTO fp_options_info_rec;
6175 IF fp_options_info_cur%NOTFOUND THEN
6176
6177 IF l_debug_mode = 'Y' THEN
6178 pa_debug.g_err_stage:= 'fp_options_info_cur did not return rows for option id '||p_refresh_fp_options_tbl(j);
6179 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6180 END IF;
6181 CLOSE fp_options_info_cur;
6182 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6183
6184 ELSE
6185 CLOSE fp_options_info_cur;
6186 l_process_option := 'Y' ;
6187 END IF;
6188
6189 IF l_process_option= 'Y' THEN
6190
6191 IF l_debug_mode = 'Y' THEN
6192 pa_debug.g_err_stage:= 'About to process the option id '||p_refresh_fp_options_tbl(j);
6193 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6194 END IF;
6195
6196 IF fp_options_info_rec.fin_plan_preference_code IN
6197 (PA_FP_CONSTANTS_PKG.G_PREF_COST_ONLY,
6198 PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SEP) THEN
6199
6200 IF fp_options_info_rec.cost_fin_plan_level_code <>
6201 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
6202
6203 add_tasks_to_option (p_proj_fp_options_id => p_refresh_fp_options_tbl(j)
6204 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_COST
6205 ,p_tasks_tbl => p_tasks_tbl
6206 ,x_return_status => x_return_status
6207 ,x_msg_count => x_msg_count
6208 ,x_msg_data => x_msg_data);
6209
6210 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6211
6212 pa_debug.g_err_stage := 'Error while adding tasks to cost option id ' || p_refresh_fp_options_tbl(j);
6213 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6214
6215 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6216
6217 END IF;
6218
6219 END IF; /* fp_options_info_rec.cost_fin_plan_level_code <> 'P' */
6220
6221 END IF; /* fp_options_info_rec.cost_fin_plan_level_code IN (COST_ONLY, COST_AND_REV_SEP */
6222
6223 IF fp_options_info_rec.fin_plan_preference_code IN
6224 (PA_FP_CONSTANTS_PKG.G_PREF_REVENUE_ONLY,
6225 PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SEP) THEN
6226
6227 IF fp_options_info_rec.revenue_fin_plan_level_code <>
6228 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
6229
6230 add_tasks_to_option (p_proj_fp_options_id => p_refresh_fp_options_tbl(j)
6231 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_REVENUE
6232 ,p_tasks_tbl => p_tasks_tbl
6233 ,x_return_status => x_return_status
6234 ,x_msg_count => x_msg_count
6235 ,x_msg_data => x_msg_data);
6236
6237 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6238
6239 pa_debug.g_err_stage := 'Error while adding task id to revenue option id '
6240 || p_refresh_fp_options_tbl(j);
6241 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6242 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6243
6244 END IF;
6245
6246 END IF; /* fp_options_info_rec.fin_plan_preference_code <> 'P' */
6247
6248 END IF; /* fp_options_info_rec.revenue_fin_plan_level_code IN (REVENUE_ONLY, COST_AND_REV_SEP) */
6249
6250 IF fp_options_info_rec.fin_plan_preference_code in (PA_FP_CONSTANTS_PKG.G_PREF_COST_AND_REV_SAME) THEN
6251
6252 IF fp_options_info_rec.all_fin_plan_level_code <>
6253 PA_FP_CONSTANTS_PKG.G_BUDGET_ENTRY_LEVEL_PROJECT THEN
6254
6255 add_tasks_to_option (p_proj_fp_options_id => p_refresh_fp_options_tbl(j)
6256 ,p_element_type => PA_FP_CONSTANTS_PKG.G_ELEMENT_TYPE_ALL
6257 ,p_tasks_tbl => p_tasks_tbl
6258 ,x_return_status => x_return_status
6259 ,x_msg_count => x_msg_count
6260 ,x_msg_data => x_msg_data);
6261
6262 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6263
6264 pa_debug.g_err_stage := 'Error while adding task id to ALL option id '
6265 || p_refresh_fp_options_tbl(j);
6266 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6267
6268 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6269
6270 END IF;
6271
6272 END IF; /* fp_options_info_rec.all_fin_plan_level_code <> 'P' */
6273
6274 END IF; /* fp_options_info_rec.fin_plan_preference_code IN (COST_AND_REV_SAME) */
6275
6276 END IF; /* l_process_option = 'Y' */
6277
6278 END LOOP; /* FOR j IN p_refresh_fp_options_tbl.first .. p_refresh_fp_options_tbl.last */
6279
6280 IF l_debug_mode = 'Y' THEN
6281 pa_debug.g_err_stage:= 'Exiting make_new_tasks_plannable';
6282 pa_debug.write(L_PROCEDURE_NAME,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6283 pa_debug.reset_curr_function;
6284 END IF;
6285
6286
6287 EXCEPTION
6288
6289 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
6290
6291 x_return_status := FND_API.G_RET_STS_ERROR;
6292 l_msg_count := FND_MSG_PUB.count_msg;
6293
6294 IF l_msg_count = 1 and x_msg_data IS NULL THEN
6295 PA_INTERFACE_UTILS_PUB.get_messages
6296 (p_encoded => FND_API.G_TRUE
6297 ,p_msg_index => 1
6298 ,p_msg_count => l_msg_count
6299 ,p_msg_data => l_msg_data
6300 ,p_data => l_data
6301 ,p_msg_index_out => l_msg_index_out);
6302 x_msg_data := l_data;
6303 x_msg_count := l_msg_count;
6304 ELSE
6305 x_msg_count := l_msg_count;
6306 END IF;
6307 IF l_debug_mode = 'Y' THEN
6308 pa_debug.reset_curr_function;
6309 END IF;
6310 RETURN;
6311
6312 WHEN others THEN
6313
6314 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6315 x_msg_count := 1;
6316 x_msg_data := SQLERRM;
6317
6318 FND_MSG_PUB.add_exc_msg
6319 ( p_pkg_name => 'pa_fp_elements_pub'
6320 ,p_procedure_name => 'make_new_tasks_plannable'
6321 ,p_error_text => x_msg_data);
6322
6323 IF l_debug_mode = 'Y' THEN
6324 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
6325 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6326 pa_debug.reset_curr_function;
6327 END IF;
6328
6329 RAISE;
6330 END make_new_tasks_plannable;
6331
6332
6333 /* Bug 2920954 - This API does the bulk processing necessary to add and
6334 remove plannable tasks as a result of changes to the WBS. The api has
6335 to be called once for all impacted tasks. Impacted task here means,
6336 that task on which the action is taken and/or whose parent has changed. */
6337
6338 /* Valid values of ACTION in p_impacted_tasks_tbl are
6339 'INSERT','REPARENT','DELETE'
6340
6341 Please note that p_impacted_tasks_tbl has no relation to the impacted task of a CI version
6342
6343 When action is 'INSERT' the plsql record should contain the following:
6344 Impacted_task_id,
6345 New_parent_task_id,
6346 Top_task_id
6347 When the action is 'REPARENT' the plsql record should contain the following:
6348 Impacted_task_id,
6349 Old_parent_task_id,
6350 New_parent_task_id,
6351 Top_task_id
6352 When action is 'DELETE' the plsql record should contain the following:
6353 Impacted_task_id,
6354 Old_parent_task_id,
6355 Top_task_id
6356
6357 Assumptions:
6358 1. A task id cannot be present more than once as impacted_task_id in the
6359 p_impacted_tasks_tbl input parameter.
6360 2. When the action is DELETE, only the task that is deleted is passed in the
6361 plsql table and not all the tasks below the deleted task.
6362 3. The order of task records in the input plsql table p_impacted_tasks_tbl
6363 under a top task is same as the order of the tasks in the WBS, i.e.,
6364 task 2.0 would appear before any of its lowest tasks in the plsql table,
6365 if any. Its ok, if task 3.0 appears after task 4.0. The assumption is that
6366 3.1 cannot appear before 3.0.
6367 4. When action is INSERT and REPARENT, we assume that the operation INSERT/REPARENT
6368 operation has already been done for the tasks. But when action is DELETE,
6369 we assume that the tasks would be deleted only after the bulk api is called.
6370 5. This api would not be called for organization forecasting projects
6371
6372 Bug 2976168. This api is NOT being called now for INSERT and REPARENT. This api will be
6373 called only in the case of DELETE.
6374
6375 */
6376
6377 PROCEDURE maintain_plannable_tasks
6378 (p_project_id IN pa_projects_all.project_id%TYPE
6379 ,p_impacted_tasks_tbl IN l_impacted_task_in_tbl_typ
6380 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
6381 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
6382 ,x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
6383 AS
6384 l_msg_count NUMBER := 0;
6385 l_data VARCHAR2(2000);
6386 l_msg_data VARCHAR2(2000);
6387 l_msg_index_out NUMBER;
6388 l_debug_mode VARCHAR2(1);
6389
6390 L_DEBUG_LEVEL2 CONSTANT NUMBER := 2;
6391 L_DEBUG_LEVEL3 CONSTANT NUMBER := 3;
6392 L_DEBUG_LEVEL4 CONSTANT NUMBER := 4;
6393 L_DEBUG_LEVEL5 CONSTANT NUMBER := 5;
6394
6395 L_ACTION_INSERT CONSTANT VARCHAR2(30) := 'INSERT';
6396 L_ACTION_REPARENT CONSTANT VARCHAR2(30) := 'REPARENT';
6397 L_ACTION_DELETE CONSTANT VARCHAR2(30) := 'DELETE';
6398
6399 L_TASK_LEVEL_TOP CONSTANT VARCHAR2(1) := 'T';
6400 L_TASK_LEVEL_MIDDLE CONSTANT VARCHAR2(1) := 'M';
6401 L_TASK_LEVEL_LOWEST CONSTANT VARCHAR2(1) := 'L';
6402
6403 TYPE l_char_typ IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
6404
6405 /* Indicates if financial planning options have been setup for the project.
6406 0 - Financial planning option has NOT been setup for the project
6407 1 - Financial planning option has been created for the project
6408 Other numbers - Sql error */
6409
6410 l_option_exists NUMBER;
6411
6412 /* Contains Y if no option exists for the project or
6413 p_impacted_tasks_tbl is empty */
6414
6415 l_continue_processing_flag VARCHAR2(1);
6416
6417 /* Indicates if task has to made be plannable. Used when action is INSERT */
6418
6419 l_make_task_plannable VARCHAR2(1);
6420
6421 /* Plsql table that contains the tasks in p_impacted_tasks_tbl
6422 for which child tasks exists */
6423
6424 l_middle_task_tbl l_char_typ;
6425
6426 /* Plsql table that contains the tasks in p_impacted_tasks_tbl
6427 that have been made plannable */
6428
6429 l_task_made_plannable_tbl l_char_typ;
6430
6431 /* Plsql table that contains the tasks in p_impacted_tasks_tbl
6432 that have been made unplannable */
6433
6434 l_tasks_removed_tbl l_char_typ;
6435
6436 l_records_deleted NUMBER;
6437
6438 /* start of Bug 3342975 */
6439
6440 CURSOR check_options_exists_cur
6441 IS
6442 select 1
6443 from sys.dual
6444 where exists
6445 (select 1 from pa_proj_fp_options
6446 where project_id = p_project_id);
6447
6448 /* end of Bug 3342975 */
6449 /* The below declarations are for Bug 2976168 */
6450
6451 CURSOR all_fp_options_cur
6452 IS
6453 SELECT pfo.proj_fp_options_id
6454 FROM pa_proj_fp_options pfo
6455 WHERE pfo.project_id = p_project_id
6456 AND pfo.fin_plan_option_level_code <> PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION
6457 UNION ALL
6458 SELECT pfo.proj_fp_options_id
6459 FROM pa_budget_versions bv,
6460 pa_proj_fp_options pfo
6461 WHERE bv.project_id = p_project_id
6462 AND pfo.fin_plan_option_level_code = PA_FP_CONSTANTS_PKG.G_OPTION_LEVEL_PLAN_VERSION
6463 AND bv.budget_status_code <> PA_FP_CONSTANTS_PKG.G_BUDGET_STATUS_BASELINED /* Should not modify baselined versions */
6464 AND pfo.project_id = bv.project_id
6465 AND pfo.fin_plan_type_id = bv.fin_plan_type_id
6466 AND pfo.fin_plan_version_id = bv.budget_version_id;
6467
6468 l_all_fp_options_tbl PA_PLSQL_DATATYPES.IdTabTyp;
6469
6470 --If the task is not a top task , this cursor always returns L as the task level as all the middle
6471 --level would have been eliminated by the time this cursor is opened.
6472
6473 CURSOR task_info_cur(c_task_id pa_tasks.task_id%TYPE) IS
6474 SELECT pt.top_task_id top_task_id
6475 ,pt.parent_task_id parent_task_id
6476 ,DECODE(c_task_id,
6477 pt.top_task_id,L_TASK_LEVEL_TOP,
6478 L_TASK_LEVEL_LOWEST) task_level
6479 FROM pa_tasks pt
6480 WHERE pt.task_id = c_task_id;
6481
6482 task_info_rec task_info_cur%ROWTYPE;
6483
6484 l_wbs_refresh_tasks_tbl l_wbs_refresh_tasks_tbl_typ;
6485
6486 /****** This is a LOCAL function to the bulk api which checks if a task is middle level task
6487 ****** by checking l_middle_task_tbl and then the db. */
6488
6489 FUNCTION is_middle_level_task(p_task_id pa_tasks.task_id%TYPE,
6490 p_top_task_id pa_tasks.task_id%TYPE)
6491 RETURN VARCHAR2 IS
6492
6493 /* Indicates if child tasks exists for a particular task.
6494 0 - Child task does NOT exists
6495 1 - Child task exists
6496 Other numbers - Sql error */
6497
6498 l_child_task_exists NUMBER;
6499
6500 BEGIN
6501
6502
6503 IF l_middle_task_tbl.exists(p_task_id) THEN
6504
6505 /* Middle level task and this need NOT be inserted into pa_fp_elements */
6506
6507 return 'N';
6508
6509 ELSIF p_top_task_id = p_task_id THEN
6510
6511 /* Top task needs to be processed */
6512
6513 return 'Y';
6514
6515 ELSE
6516
6517 /* Refer db to know if the impacted_task_id is a middle level task.
6518 Child exists would mean that it is a middle level task (since we have eliminated
6519 top task records in the above condition). */
6520
6521 l_child_task_exists := pa_task_utils.check_child_exists(x_task_id => p_task_id);
6522
6523 IF l_child_task_exists = 1 THEN
6524
6525 /* Child task exists. So, impacted task is a middle level task */
6526
6527 l_middle_task_tbl(p_task_id) := 'Y';
6528
6529 return 'N';
6530
6531 ELSIF l_child_task_exists = 0 THEN
6532
6533 /* Child tasks donot exists. So, the task is a lowest level task */
6534 return 'Y';
6535
6536 ELSE
6537
6538 /* Oracle error returned */
6539
6540 IF l_debug_mode = 'Y' THEN
6541
6542 pa_debug.g_err_stage:= 'Oracle error occurred while calling check_child_exists. Sqlerrcode ' || to_char(l_child_task_exists);
6543 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6544
6545 END IF;
6546
6547 RAISE FND_API.G_Exc_Unexpected_Error;
6548
6549 END IF; /* l_child_tasks_exists = 1 */
6550
6551 END IF; /* l_middle_task_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id) */
6552
6553 END is_middle_level_task;
6554
6555 /****** END of function is_middle_level_task which is a local procedure to maintain_plannable_tasks ******/
6556
6557 BEGIN
6558
6559 x_msg_count := 0;
6560 x_return_status := FND_API.G_RET_STS_SUCCESS;
6561 l_debug_mode := NVL(FND_PROFILE.value('PA_DEBUG_MODE'),'N');
6562
6563 IF l_debug_mode = 'Y' THEN
6564 pa_debug.set_curr_function( p_function => 'maintain_plannable_tasks',
6565 p_debug_mode => l_debug_mode );
6566 END IF;
6567
6568 -- Check for business rules violations
6569
6570 IF l_debug_mode = 'Y' THEN
6571 pa_debug.g_err_stage:= 'Validating input parameters';
6572 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6573 L_DEBUG_LEVEL3);
6574 END IF;
6575
6576 IF (p_project_id IS NULL) THEN
6577
6578 IF l_debug_mode = 'Y' THEN
6579 pa_debug.g_err_stage:= 'p_project_id = '|| p_project_id;
6580 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6581 L_DEBUG_LEVEL5);
6582 END IF;
6583 PA_UTILS.ADD_MESSAGE
6584 (p_app_short_name => 'PA',
6585 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6586 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6587
6588 END IF;
6589
6590 /* Checking if financial planning option have been setup for the task's project */
6591 /* commented for bug 3342975
6592 l_option_exists := pa_fin_plan_utils.Check_Proj_Fp_Options_Exists(p_project_id => p_project_id);
6593 start of bug 3342975
6594 */
6595 OPEN check_options_exists_cur;
6596 FETCH check_options_exists_cur
6597 INTO l_option_exists;
6598 IF check_options_exists_cur%NOTFOUND THEN
6599 l_option_exists := 0;
6600 END IF;
6601 CLOSE check_options_exists_cur;
6602 /* end of bug 3342975 */
6603 IF l_debug_mode = 'Y' THEN
6604 pa_debug.g_err_stage:= 'Option Exists for project id: '
6605 || to_char(p_project_id) || ' is '
6606 || l_option_exists;
6607 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6608 L_DEBUG_LEVEL3);
6609 pa_debug.g_err_stage:= 'Number of tasks to be processed: '
6610 || to_char(p_impacted_tasks_tbl.count);
6611 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6612 L_DEBUG_LEVEL3);
6613 END IF;
6614
6615 /* No processing is required if financial planning options
6616 have not been setup for the project or if the i/p tasks
6617 plsql table is empty */
6618
6619 IF l_option_exists = 0 OR p_impacted_tasks_tbl.count = 0 THEN
6620
6621 l_continue_processing_flag := 'N';
6622
6623 ELSIF l_option_exists = 1 THEN
6624
6625 l_continue_processing_flag := 'Y';
6626
6627 /* For bug 2976168. Store the options in a pl/sql table so that they can be
6628 passed to make_new_tasks_plannable api later. */
6629
6630 OPEN all_fp_options_cur;
6631 FETCH all_fp_options_cur
6632 BULK COLLECT INTO l_all_fp_options_tbl;
6633 CLOSE all_fp_options_cur;
6634
6635 ELSIF l_option_exists NOT IN (1,0) THEN
6636
6637 /* Unexpected oracle error */
6638
6639 IF l_debug_mode = 'Y' THEN
6640 pa_debug.g_err_stage:= 'Check_Proj_Fp_Options_Exists returned oracle error ' ||
6641 to_char(l_option_exists);
6642 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6643 L_DEBUG_LEVEL5);
6644 END IF;
6645
6646 Raise PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6647
6648 END IF;
6649
6650 IF l_continue_processing_flag = 'Y' THEN
6651
6652 /* Multiple tasks can be inserted, reparented or deleted.
6653
6654 Caching is implemented so that
6655
6656 1. We need not call make_new_tasks_plannable for a task that is already made plannable.
6657 2. We do not have to call delete_task_elements for the new parent task (to make it
6658 unplannable) if it has already been made unplannable.
6659
6660 To achieve this check if the inserted task is a middle level task. Since middle level
6661 task need not be inserted, we can store middle level tasks (new_parent_task_id) in
6662 l_middle_task_tbl plsql table. If l_middle_task_tbl plsql table doesnt contain an
6663 entry for a task id, only then we refer the database to check if the task is a
6664 middle level task and if so, cache it in the plsql table. */
6665
6666 IF l_debug_mode = 'Y' THEN
6667 pa_debug.g_err_stage:= 'Identifying middle level tasks by looping the p_impacted_tasks_tbl';
6668 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6669 L_DEBUG_LEVEL3);
6670 END IF;
6671
6672 FOR I in p_impacted_tasks_tbl.first .. p_impacted_tasks_tbl.last LOOP
6673
6674 /* If parent task exists for impacted_task_id and
6675 if impacted_task's parent is not a top task, it means
6676 impacted task's parent is a middle level task */
6677
6678 IF p_impacted_tasks_tbl(i).new_parent_task_id IS NOT NULL AND
6679 p_impacted_tasks_tbl(i).new_parent_task_id <> p_impacted_tasks_tbl(i).top_task_id THEN
6680
6681 l_middle_task_tbl(p_impacted_tasks_tbl(i).new_parent_task_id) := 'Y';
6682
6683 END IF;
6684
6685 END LOOP;
6686
6687 FOR I in p_impacted_tasks_tbl.first .. p_impacted_tasks_tbl.last LOOP
6688
6689 IF l_debug_mode = 'Y' THEN
6690
6691 pa_debug.g_err_stage:= 'impacted task id is ' || p_impacted_tasks_tbl(i).impacted_task_id;
6692 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6693 pa_debug.g_err_stage:= 'old parent task id is ' || p_impacted_tasks_tbl(i).old_parent_task_id;
6694 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6695 pa_debug.g_err_stage:= 'new parent task id is ' || p_impacted_tasks_tbl(i).new_parent_task_id;
6696 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6697 pa_debug.g_err_stage:= 'top task id is ' || p_impacted_tasks_tbl(i).top_task_id;
6698 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6699 pa_debug.g_err_stage:= 'action is ' || p_impacted_tasks_tbl(i).action;
6700 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6701
6702 END IF;
6703
6704 l_make_task_plannable := Null;
6705
6706 IF p_impacted_tasks_tbl(i).action = L_ACTION_INSERT THEN
6707
6708 IF p_impacted_tasks_tbl(i).impacted_task_id IS NULL OR
6709 (p_impacted_tasks_tbl(i).impacted_task_id <> p_impacted_tasks_tbl(i).top_task_id AND
6710 p_impacted_tasks_tbl(i).new_parent_task_id IS NULL) OR
6711 p_impacted_tasks_tbl(i).top_task_id IS NULL THEN
6712
6713 IF l_debug_mode = 'Y' THEN
6714 pa_debug.g_err_stage:= 'For INSERT action : ' ||
6715 'Impacted_task_id, New_parent_task_id, Top_task_id should be passed';
6716 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6717 END IF;
6718 PA_UTILS.ADD_MESSAGE
6719 (p_app_short_name => 'PA',
6720 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6721 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6722
6723 END IF;
6724
6725 /* If Impacted task has already been added as plannable task, we need not be
6726 adding it once again */
6727
6728 IF NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id)) THEN
6729
6730 /* Calling local function is_middle_level_task to check
6731 if impacted task id is a middle level task */
6732
6733 l_make_task_plannable :=
6734 is_middle_level_task(p_task_id => p_impacted_tasks_tbl(i).impacted_task_id,
6735 p_top_task_id => p_impacted_tasks_tbl(i).top_task_id);
6736
6737 IF l_debug_mode = 'Y' THEN
6738
6739 pa_debug.g_err_stage:= 'l_make_task_plannable = ' || l_make_task_plannable;
6740 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6741
6742 END IF;
6743
6744 IF l_make_task_plannable = 'Y' THEN
6745
6746 /* If Impacted task has already been added as plannable task, we need not be
6747 adding it once again */
6748
6749 IF l_debug_mode = 'Y' THEN
6750
6751 pa_debug.g_err_stage:= 'Calling make_new_tasks_plannable for impacted task id';
6752 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6753
6754 END IF;
6755
6756 /* Calling pa_fp_elements_pub.make_new_tasks_plannable for impacted task id */
6757
6758 /* For Bug 2976168. Modified the call to make new task plannable api.
6759
6760 PA_FP_ELEMENTS_PUB.make_new_task_plannable
6761 ( p_project_id => p_project_id
6762 ,p_task_id => p_impacted_tasks_tbl(i).impacted_task_id
6763 ,x_return_status => x_return_status
6764 ,x_msg_count => x_msg_count
6765 ,x_msg_data => x_msg_data);
6766
6767 */
6768
6769 OPEN task_info_cur(p_impacted_tasks_tbl(i).impacted_task_id);
6770 FETCH task_info_cur INTO task_info_rec;
6771 CLOSE task_info_cur;
6772
6773 l_wbs_refresh_tasks_tbl(1).task_id := p_impacted_tasks_tbl(i).impacted_task_id;
6774 l_wbs_refresh_tasks_tbl(1).parent_task_id := task_info_rec.parent_task_id;
6775 l_wbs_refresh_tasks_tbl(1).top_task_id := task_info_rec.top_task_id;
6776 l_wbs_refresh_tasks_tbl(1).task_level := task_info_rec.task_level;
6777
6778 PA_FP_ELEMENTS_PUB.make_new_tasks_plannable
6779 ( p_project_id => p_project_id
6780 ,p_tasks_tbl => l_wbs_refresh_tasks_tbl
6781 ,p_refresh_fp_options_tbl => l_all_fp_options_tbl
6782 ,x_return_status => x_return_status
6783 ,x_msg_count => x_msg_count
6784 ,x_msg_data => x_msg_data);
6785
6786
6787 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6788
6789 IF l_debug_mode = 'Y' THEN
6790 pa_debug.g_err_stage:= 'Error returned by make_new_tasks_plannable for task_id ' ||
6791 p_impacted_tasks_tbl(i).impacted_task_id;
6792 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6793 END IF;
6794
6795 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6796
6797 END IF;
6798
6799 l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).impacted_task_id) := 'Y';
6800
6801 END IF; /* l_make_task_plannable = 'Y' */
6802
6803 END IF; /* l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id) */
6804
6805 /* For reparenting old parent need to be made plannable if its a lowest task now and
6806 new parent need to be removed */
6807
6808 ELSIF p_impacted_tasks_tbl(i).action = L_ACTION_REPARENT THEN
6809
6810 IF p_impacted_tasks_tbl(i).impacted_task_id IS NULL OR
6811 p_impacted_tasks_tbl(i).new_parent_task_id IS NULL OR
6812 p_impacted_tasks_tbl(i).old_parent_task_id IS NULL OR
6813 p_impacted_tasks_tbl(i).top_task_id IS NULL THEN
6814
6815 IF l_debug_mode = 'Y' THEN
6816 pa_debug.g_err_stage:= 'For REPARENT action : ' ||
6817 'Impacted_task_id, New_parent_task_id, old_parent_task_id, Top_task_id should be passed';
6818 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6819 END IF;
6820 PA_UTILS.ADD_MESSAGE
6821 (p_app_short_name => 'PA',
6822 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6823 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6824
6825 END IF;
6826
6827 /* If old parent task and new parent task are same, no need to do any processing since
6828 no reparenting has happened */
6829
6830 IF p_impacted_tasks_tbl(i).old_parent_task_id <> p_impacted_tasks_tbl(i).new_parent_task_id THEN
6831
6832 /* If old parent task has already been added then
6833 nothing needs to be done for this */
6834
6835 IF NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).old_parent_task_id)) THEN
6836
6837 /* Calling is_middle_level_task to check if old parent task id is a middle level task */
6838
6839 l_make_task_plannable :=
6840 is_middle_level_task(p_task_id => p_impacted_tasks_tbl(i).old_parent_task_id,
6841 p_top_task_id => pa_task_utils.get_top_task_id(x_task_id => p_impacted_tasks_tbl(i).old_parent_task_id));
6842
6843 IF l_debug_mode = 'Y' THEN
6844
6845 pa_debug.g_err_stage:= 'l_make_task_plannable = ' || l_make_task_plannable;
6846 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6847
6848 END IF;
6849
6850 /* If old task is a middle level task then
6851 nothing needs to be done for this */
6852
6853 IF l_make_task_plannable = 'Y' THEN
6854
6855 IF l_debug_mode = 'Y' THEN
6856
6857 pa_debug.g_err_stage:= 'Calling make_new_tasks_plannable for old parent task id';
6858 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6859
6860 END IF;
6861
6862 /* Calling pa_fp_elements_pub.make_new_tasks_plannable for old parent task id */
6863
6864 /* Bug 2976168. Changed the way make_new_task_plannable is called
6865
6866 PA_FP_ELEMENTS_PUB.make_new_task_plannable
6867 ( p_project_id => p_project_id
6868 ,p_task_id => p_impacted_tasks_tbl(i).old_parent_task_id
6869 ,x_return_status => x_return_status
6870 ,x_msg_count => x_msg_count
6871 ,x_msg_data => x_msg_data);
6872 */
6873
6874 OPEN task_info_cur(p_impacted_tasks_tbl(i).old_parent_task_id);
6875 FETCH task_info_cur INTO task_info_rec;
6876 CLOSE task_info_cur;
6877
6878 l_wbs_refresh_tasks_tbl(1).task_id := p_impacted_tasks_tbl(i).old_parent_task_id;
6879 l_wbs_refresh_tasks_tbl(1).parent_task_id := task_info_rec.parent_task_id;
6880 l_wbs_refresh_tasks_tbl(1).top_task_id := task_info_rec.top_task_id;
6881 l_wbs_refresh_tasks_tbl(1).task_level := task_info_rec.task_level;
6882
6883 PA_FP_ELEMENTS_PUB.make_new_tasks_plannable
6884 ( p_project_id => p_project_id
6885 ,p_tasks_tbl => l_wbs_refresh_tasks_tbl
6886 ,p_refresh_fp_options_tbl => l_all_fp_options_tbl
6887 ,x_return_status => x_return_status
6888 ,x_msg_count => x_msg_count
6889 ,x_msg_data => x_msg_data);
6890
6891 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
6892
6893 IF l_debug_mode = 'Y' THEN
6894 pa_debug.g_err_stage:= 'Error returned by make_new_tasks_plannable for task_id ' ||
6895 p_impacted_tasks_tbl(i).old_parent_task_id;
6896 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6897 END IF;
6898
6899 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6900
6901 END IF;
6902
6903 l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).old_parent_task_id) := 'Y';
6904
6905 END IF; /* l_make_task_plannable = 'Y' */
6906
6907 END IF; /* NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).old_parent_task_id)) THEN */
6908
6909 /* Note for removing new parent as plannable:
6910
6911 1. If it was a Top task earlier then no action required as none of its attribute changes.
6912 2. If it was a middle level task earlier then also no action required.
6913 3. New parent need to be removed from all options only if it was a lowest task earlier.
6914
6915 Only way to know if the task was earlier a lowest task can be to look into any of the
6916 existing option and see if this is plannable. */
6917
6918 IF NOT(l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).new_parent_task_id)) THEN
6919
6920 /* Check if new_parent_task_id is not a TOP task */
6921
6922 IF pa_task_utils.get_top_task_id(x_task_id => p_impacted_tasks_tbl(i).new_parent_task_id)
6923 <> p_impacted_tasks_tbl(i).new_parent_task_id THEN
6924
6925 /* Check if it exists in pa_fp_elements. If yes, then its a lowest task */
6926
6927 IF pa_fin_plan_utils.check_task_in_fp_option(p_task_id => p_impacted_tasks_tbl(i).new_parent_task_id) = 'Y' THEN
6928 /* Delete planning elements and resource assignments for new parent task id.
6929 Pls note that delete task elements deletes the task and its children from
6930 all plan options. Hence we cannot call it since it might delete a
6931 plannable impacted task also from pa_fp_elements and pa_resource_assignments */
6932
6933 IF l_debug_mode = 'Y' THEN
6934
6935 pa_debug.g_err_stage:= 'Deleting task fp elements for new parent task id';
6936 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
6937
6938 END IF;
6939
6940 DELETE FROM pa_fp_elements e
6941 WHERE e.task_id = p_impacted_tasks_tbl(i).new_parent_task_id;
6942
6943 l_records_deleted := sql%rowcount;
6944
6945 IF l_debug_mode = 'Y' THEN
6946 pa_debug.g_err_stage:= To_char(l_records_deleted) || ' records deleted.';
6947 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6948 L_DEBUG_LEVEL3);
6949 END IF;
6950
6951 IF l_records_deleted <> 0 THEN
6952
6953 IF l_debug_mode = 'Y' THEN
6954 pa_debug.g_err_stage:= 'Deleting from pa_resource_assignments for task id ' || to_char(p_impacted_tasks_tbl(i).new_parent_task_id);
6955 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6956 L_DEBUG_LEVEL3);
6957 END IF;
6958
6959 DELETE FROM pa_resource_assignments r
6960 WHERE r.task_id = p_impacted_tasks_tbl(i).new_parent_task_id;
6961
6962 l_records_deleted := sql%rowcount;
6963
6964 IF l_debug_mode = 'Y' THEN
6965 pa_debug.g_err_stage:= To_char(l_records_deleted) || ' records deleted.';
6966 pa_debug.write(l_module_name,pa_debug.g_err_stage,
6967 L_DEBUG_LEVEL3);
6968 END IF;
6969
6970 END IF;
6971
6972 l_tasks_removed_tbl(p_impacted_tasks_tbl(i).new_parent_task_id) := 'Y';
6973
6974 END IF; /* pa_fin_plan_utils.task_exists_in_option(p_task_id => p_impacted_tasks_tbl(i).new_parent_task_id) = 'Y' */
6975
6976 END IF; /* pa_task_utils.get_top_task_id(x_task_id => p_impacted_tasks_tbl(i).new_parent_task_id)
6977 <> p_impacted_tasks_tbl(i).new_parent_task_id */
6978
6979 END IF; /* l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).new_parent_task_id) */
6980
6981 END IF; /* p_impacted_tasks_tbl(i).old_parent_task_id <> p_impacted_tasks_tbl(i).new_parent_task_id */
6982
6983 ELSIF p_impacted_tasks_tbl(i).action = L_ACTION_DELETE THEN
6984
6985 IF p_impacted_tasks_tbl(i).impacted_task_id IS NULL OR
6986 (p_impacted_tasks_tbl(i).impacted_task_id <> p_impacted_tasks_tbl(i).top_task_id AND
6987 p_impacted_tasks_tbl(i).old_parent_task_id IS NULL) OR
6988 p_impacted_tasks_tbl(i).top_task_id IS NULL THEN
6989
6990 IF l_debug_mode = 'Y' THEN
6991 pa_debug.g_err_stage:= 'For DELETE action : ' ||
6992 'Impacted_task_id, old_parent_task_id, Top_task_id should be passed';
6993 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
6994 END IF;
6995 PA_UTILS.ADD_MESSAGE
6996 (p_app_short_name => 'PA',
6997 p_msg_name => 'PA_FP_INV_PARAM_PASSED');
6998 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
6999
7000 END IF;
7001
7002 /* If impacted task has already been deleted then
7003 nothing needs to be done for this */
7004
7005 IF NOT(l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id)) THEN
7006
7007 IF l_debug_mode = 'Y' THEN
7008
7009 pa_debug.g_err_stage:= 'Calling delete_task_elements for impacted task id';
7010 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7011
7012 END IF;
7013
7014 /* Calling pa_fp_elements_pub.delete_task_elements for impacted task id */
7015 PA_FP_ELEMENTS_PUB.Delete_task_elements
7016 ( p_task_id => p_impacted_Tasks_tbl(i).impacted_task_id
7017 ,x_return_status => x_return_status
7018 ,x_msg_count => x_msg_count
7019 ,x_msg_data => x_msg_data);
7020
7021 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
7022
7023 IF l_debug_mode = 'Y' THEN
7024 pa_debug.g_err_stage:= 'Error returned by delete_task_elements for task_id ' ||
7025 p_impacted_tasks_tbl(i).impacted_task_id;
7026 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
7027 END IF;
7028
7029 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
7030
7031 END IF;
7032
7033 l_tasks_removed_tbl(p_impacted_tasks_tbl(i).impacted_task_id) := 'Y';
7034
7035 END IF; /* NOT(l_tasks_removed_tbl.exists(p_impacted_tasks_tbl(i).impacted_task_id)) */
7036
7037 /* Proceed only if old_parent_task_id has NOT already been added */
7038
7039 IF p_impacted_tasks_tbl(i).old_parent_task_id IS NOT NULL AND
7040 NOT(l_task_made_plannable_tbl.exists(p_impacted_tasks_tbl(i).old_parent_task_id)) THEN
7041
7042 /* We should not make the old_parent_task a plannable task if it is middle level task */
7043 /* Since tasks would not have yet been deleted, we need to check if the new parent would
7044 still be a middle level task after the impacted task id is deleted */
7045
7046 DECLARE
7047 cursor c1 is
7048 select 'N'
7049 from sys.dual
7050 where exists (SELECT null
7051 FROM pa_tasks
7052 where parent_task_id = p_impacted_tasks_tbl(i).old_parent_task_id
7053 and task_id <> p_impacted_tasks_tbl(i).impacted_task_id);
7054 BEGIN
7055 OPEN c1;
7056 FETCH c1 into l_make_task_plannable;
7057 IF c1%NOTFOUND THEN
7058 l_make_task_plannable := 'Y';
7059 END IF;
7060 CLOSE c1;
7061 END;
7062
7063 IF l_debug_mode = 'Y' THEN
7064
7065 pa_debug.g_err_stage:= 'l_make_task_plannable = ' || l_make_task_plannable;
7066 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7067
7068 END IF;
7069
7070 /* We need to call make new task plannable to add the old parent task id as plannable */
7071
7072 IF l_make_task_plannable = 'Y' THEN
7073
7074 IF l_debug_mode = 'Y' THEN
7075
7076 pa_debug.g_err_stage:= 'Calling make_new_tasks_plannable for old parent task id';
7077 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7078
7079 END IF;
7080
7081 /*
7082 Bug 2976168. Changed the way make_new_task_plannable is called
7083
7084 PA_FP_ELEMENTS_PUB.make_new_task_plannable
7085 ( p_project_id => p_project_id
7086 ,p_task_id => p_impacted_tasks_tbl(i).old_parent_task_id
7087 ,x_return_status => x_return_status
7088 ,x_msg_count => x_msg_count
7089 ,x_msg_data => x_msg_data);
7090 */
7091
7092 OPEN task_info_cur(p_impacted_tasks_tbl(i).impacted_task_id);
7093 FETCH task_info_cur INTO task_info_rec;
7094 CLOSE task_info_cur;
7095
7096 l_wbs_refresh_tasks_tbl(1).task_id := p_impacted_tasks_tbl(i).impacted_task_id;
7097 l_wbs_refresh_tasks_tbl(1).parent_task_id := task_info_rec.parent_task_id;
7098 l_wbs_refresh_tasks_tbl(1).top_task_id := task_info_rec.top_task_id;
7099 l_wbs_refresh_tasks_tbl(1).task_level := task_info_rec.task_level;
7100
7101 PA_FP_ELEMENTS_PUB.make_new_tasks_plannable
7102 ( p_project_id => p_project_id
7103 ,p_tasks_tbl => l_wbs_refresh_tasks_tbl
7104 ,p_refresh_fp_options_tbl => l_all_fp_options_tbl
7105 ,x_return_status => x_return_status
7106 ,x_msg_count => x_msg_count
7107 ,x_msg_data => x_msg_data);
7108
7109 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
7110
7111 IF l_debug_mode = 'Y' THEN
7112 pa_debug.g_err_stage:= 'Error returned by make_new_tasks_plannable for task_id ' ||
7113 p_impacted_tasks_tbl(i).old_parent_task_id;
7114 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
7115 END IF;
7116
7117 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
7118
7119 END IF;
7120
7121 l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).old_parent_task_id) := 'Y';
7122
7123 END IF; /* l_make_task_plannable = 'Y' */
7124
7125 END IF; /* p_impacted_tasks_tbl(i).old_parent_task_id IS NOT NULL AND
7126 NOT(l_task_made_plannable_tbl(p_impacted_tasks_tbl(i).old_parent_task_id).exists) */
7127
7128 ELSE
7129
7130 /* Invalid action passed */
7131
7132 IF l_debug_mode = 'Y' THEN
7133 pa_debug.g_err_stage:= 'Invalid value for action passed. Action passed is ' ||
7134 p_impacted_tasks_tbl(i).action;
7135 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL5);
7136 END IF;
7137
7138 RAISE PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc;
7139
7140 END IF;
7141
7142 END LOOP;
7143
7144 /* Since planning elements have been modified for the proj fp option,
7145 we need to increase the record_version_number */
7146
7147 IF nvl(l_all_fp_options_tbl.last,0) >= 1 THEN /* only if something is fetched */
7148
7149 IF P_PA_DEBUG_MODE = 'Y' THEN
7150 pa_debug.g_err_stage := 'Updating pa_proj_fp_options with RVN and who columns.';
7151 pa_debug.write(l_module_name,pa_debug.g_err_stage,L_DEBUG_LEVEL3);
7152 END IF;
7153
7154 FORALL i in l_all_fp_options_tbl.first..l_all_fp_options_tbl.last
7155 UPDATE pa_proj_fp_options pfo
7156 SET pfo.record_version_number = pfo.record_version_number + 1,
7157 pfo.last_update_date = sysdate,
7158 pfo.last_updated_by = FND_GLOBAL.USER_ID,
7159 pfo.last_update_login = FND_GLOBAL.LOGIN_ID
7160 WHERE pfo.proj_fp_options_id = l_all_fp_options_tbl(i);
7161
7162 /* Since resource assignments might have been deleted and recreated
7163 for the new task, the version has been modified and its
7164 record version number has to be increased */
7165
7166 FORALL i in l_all_fp_options_tbl.first..l_all_fp_options_tbl.last
7167 UPDATE pa_budget_versions bv
7168 SET bv.record_version_number = bv.record_version_number + 1,
7169 bv.last_update_date = sysdate,
7170 bv.last_updated_by = FND_GLOBAL.USER_ID,
7171 bv.last_update_login = FND_GLOBAL.LOGIN_ID
7172 WHERE bv.budget_version_id in (SELECT pfo.fin_plan_version_id
7173 FROM pa_proj_fp_options pfo
7174 WHERE pfo.proj_fp_options_id = l_all_fp_options_tbl(i));
7175
7176 END IF; /* nvl(l_all_fp_options_tbl.last,0) >= 1 */
7177
7178 END IF; /* l_continue_processing_flag = 'Y' */
7179
7180 IF l_debug_mode = 'Y' THEN
7181 pa_debug.g_err_stage:= 'Exiting maintain_plannable_tasks';
7182 pa_debug.write(l_module_name,pa_debug.g_err_stage,
7183 L_DEBUG_LEVEL3);
7184 pa_debug.reset_curr_function;
7185 END IF;
7186
7187 EXCEPTION
7188
7189 WHEN PA_FP_CONSTANTS_PKG.Invalid_Arg_Exc THEN
7190
7191 x_return_status := FND_API.G_RET_STS_ERROR;
7192 l_msg_count := FND_MSG_PUB.count_msg;
7193
7194 IF l_msg_count = 1 and x_msg_data IS NULL THEN
7195 PA_INTERFACE_UTILS_PUB.get_messages
7196 (p_encoded => FND_API.G_TRUE
7197 ,p_msg_index => 1
7198 ,p_msg_count => l_msg_count
7199 ,p_msg_data => l_msg_data
7200 ,p_data => l_data
7201 ,p_msg_index_out => l_msg_index_out);
7202 x_msg_data := l_data;
7203 x_msg_count := l_msg_count;
7204 ELSE
7205 x_msg_count := l_msg_count;
7206 END IF;
7207
7208 IF l_debug_mode = 'Y' THEN
7209 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
7210 pa_debug.write(l_module_name,pa_debug.g_err_stage,
7211 L_DEBUG_LEVEL5);
7212 pa_debug.reset_curr_function;
7213 END IF;
7214
7215 RETURN;
7216
7217 WHEN others THEN
7218
7219 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7220 x_msg_count := 1;
7221 x_msg_data := SQLERRM;
7222
7223 FND_MSG_PUB.add_exc_msg
7224 ( p_pkg_name => 'pa_fp_elements_pub'
7225 ,p_procedure_name => 'maintain_plannable_tasks'
7226 ,p_error_text => x_msg_data);
7227
7228 IF l_debug_mode = 'Y' THEN
7229 pa_debug.g_err_stage:= 'Unexpected Error'||x_msg_data;
7230 pa_debug.write(l_module_name,pa_debug.g_err_stage,
7231 L_DEBUG_LEVEL5);
7232 pa_debug.reset_curr_function;
7233 END IF;
7234 RAISE;
7235 END maintain_plannable_tasks;
7236
7237 End PA_FP_ELEMENTS_PUB;