1 PACKAGE BODY pa_schedule_pub as
2 /* $Header: PARGPUBB.pls 120.11.12010000.11 2010/06/21 12:50:38 nisinha ship $ */
3
4 l_out_of_range_date EXCEPTION; -- Exception variable for raising the exception when date is out of range
5 l_out_of_range_from_date EXCEPTION; -- Exception variable for raising the exception when date is out of range
6 l_out_of_range_to_date EXCEPTION; -- Exception variable for raising the exception when date is out of range
7 l_empty_tab_record EXCEPTION; -- Variable to raise the exception if the passing table of records is empty
8 l_x_return_status VARCHAR2(50);
9 l_from_to_date_null EXCEPTION; -- This exception is raise when the start date or end date is null
10 l_asgn_stus_not_for_proj_stus EXCEPTION; -- Exception variable for raising the exception when the assignment status is not allowed for the project status
11
12 -- procedure : update_schedule
13 -- Purpose : This procedure will change the schedule records of the assignments passed in.
14 -- It can accept either one assignment ID or an assignment ID array.
15 --
16 -- Input parameters
17 -- Parameters Type Required Description
18 -- --------------------------- ------ -------- --------------------------------------------------------
19 -- P_Project_Id NUMBER YES project id of the associated calendar
20 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this assignment
21
22 PROCEDURE update_schedule
23 ( p_project_id IN NUMBER
24 ,p_mass_update_flag IN VARCHAR2 := FND_API.G_FALSE
25 ,p_exception_type_code IN VARCHAR2
26 ,p_record_version_number IN NUMBER := NULL
27 ,p_assignment_id IN NUMBER := NULL
28 ,p_assignment_id_array IN SYSTEM.PA_NUM_TBL_TYPE := NULL
29 ,p_change_start_date IN DATE := NULL
30 ,p_change_end_date IN DATE := NULL
31 ,p_requirement_status_code IN VARCHAR2 := NULL
32 ,p_assignment_status_code IN VARCHAR2 := NULL
33 ,p_monday_hours IN NUMBER := NULL
34 ,p_tuesday_hours IN NUMBER := NULL
35 ,p_wednesday_hours IN NUMBER := NULL
36 ,p_thursday_hours IN NUMBER := NULL
37 ,p_friday_hours IN NUMBER := NULL
38 ,p_saturday_hours IN NUMBER := NULL
39 ,p_sunday_hours IN NUMBER := NULL
40 ,p_non_working_day_flag IN VARCHAR2 := 'N'
41 ,p_change_hours_type_code IN VARCHAR2 := NULL
42 ,p_hrs_per_day IN NUMBER := NULL
43 ,p_calendar_percent IN NUMBER := NULL
44 ,p_change_calendar_type_code IN VARCHAR2 := NULL
45 ,p_change_calendar_name IN VARCHAR2 := NULL
46 ,p_change_calendar_id IN NUMBER := NULL
47 ,p_duration_shift_type_code IN VARCHAR2 := NULL
48 ,p_duration_shift_unit_code IN VARCHAR2 := NULL
49 ,p_number_of_shift IN NUMBER := NULL
50 ,p_last_row_flag IN VARCHAR2 := 'Y'
51 ,p_change_start_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
52 ,p_change_end_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
53 ,p_monday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
54 ,p_tuesday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
55 ,p_wednesday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
56 ,p_thursday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
57 ,p_friday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
58 ,p_saturday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
59 ,p_sunday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
60 ,p_commit IN VARCHAR2 := FND_API.G_FALSE
61 ,p_validate_only IN VARCHAR2 := FND_API.G_TRUE
62 ,p_called_by_proj_party IN VARCHAR2 := 'N' -- Added for Bug 6631033
63 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
64 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
65 ,x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
66 IS
67
68 l_err_msg_code fnd_new_messages.message_name%TYPE;
69 l_updated_calendar_id NUMBER;
70 l_msg_data VARCHAR2(2000);
71 l_msg_count NUMBER;
72 l_msg_index_out NUMBER;
73 l_change_calendar_id NUMBER;
74 l_valid_assign_start_flag VARCHAR2(1) := 'Y'; -- Bug 6411422
75 l_profile_begin_date DATE; -- Bug 6411422
76
77 BEGIN
78 -- Initialize the return status to success
79 x_return_status := FND_API.G_RET_STS_SUCCESS ;
80
81
82
83 --Clear the global PL/SQL message table
84 FND_MSG_PUB.initialize;
85
86 -- Initialize the Error Stack
87 PA_DEBUG.init_err_stack('PA_SCHEDULE_PUB.update_schedule');
88
89 -- Issue API savepoint if the transaction is to be committed
90 IF (p_commit = FND_API.G_TRUE) THEN
91 SAVEPOINT SCH_PUB_UPDATE_SCH;
92 END IF;
93
94 -- Bug 6411422
95 l_valid_assign_start_flag := PA_PROJECT_DATES_UTILS.IS_VALID_ASSIGN_START_DATE( p_project_id => p_project_id,
96 p_assign_start_date => p_change_start_date ) ;
97 IF ( l_valid_assign_start_flag = 'Y' )
98 THEN -- Bug 6411422
99
100 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub', 'Start online validation', 6);
101 ----------------------------------------------------------------------------------------------
102 --
103 -- On Line Validation
104 --
105 ----------------------------------------------------------------------------------------------
106
107 -- If this api has been called from the page which has start_date, end_date input
108 IF (p_exception_type_code = 'CHANGE_DURATION' OR p_exception_type_code = 'CHANGE_HOURS' OR
109 p_exception_type_code = 'CHANGE_WORK_PATTERN' OR p_exception_type_code = 'CHANGE_STATUS') THEN
110
111 -- If p_exception_type_code = 'CHANGE_DURATION', at least one of start_date or end_date
112 -- should not be null. The reason is that if both are null, actually it wouldn't update anything.
113 IF (p_exception_type_code = 'CHANGE_DURATION' AND
114 p_change_start_date IS NULL AND p_change_end_date IS NULL) THEN
115 PA_UTILS.Add_Message ('PA', 'PA_SCH_FROM_OR_TO_DATE_NULL');
116 RAISE FND_API.G_EXC_ERROR;
117 END IF;
118
119 -- If p_exception_type_code = 'CHANGE_HOURS' or 'CHANGE_WORK_PATTERN' or 'CHANGE_STATUS',
120 -- End date or Start date should not be null.
121 IF ( (p_exception_type_code = 'CHANGE_HOURS' OR p_exception_type_code = 'CHANGE_WORK_PATTERN' OR
122 p_exception_type_code = 'CHANGE_STATUS') AND
123 (p_change_start_date IS NULL OR p_change_end_date IS NULL) )THEN
124 PA_UTILS.Add_Message ('PA', 'PA_SCH_FROM_TO_DATE_NULL');
125 RAISE FND_API.G_EXC_ERROR;
126 END IF;
127
128 -- If this api has been called from the page which has start_date, end_date input, call
129 -- the validation date procedure. It will validate the date i.e. start_date should not be greater
130 -- than end_date. If end date date greater than start_date, then it will return l_x_return_status as error.
131 PA_SCHEDULE_UTILS.validate_date_range (p_change_start_date, p_change_end_date, l_x_return_status, l_err_msg_code);
132
133 -- If validate_date_range fails, put error message into error stack and stop to process.
134 IF (l_x_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
135 PA_UTILS.Add_Message ('PA', l_err_msg_code);
136 RAISE FND_API.G_EXC_ERROR;
137 END IF;
138 END IF;
139
140 -- If p_exception_type_code = 'SHIFT_DURATION' then throw exception in following cases.
141 -- single update: if 'status for new days'(p_assignment_status_code) is null. (-> this field
142 -- should be required on front end)
143 -- mass update: if both 'p_requirement_status_code' and 'p_assignment_status_code' are null.
144 -- Modified below code for 7663765
145 IF ( (p_exception_type_code = 'SHIFT_DURATION' OR p_exception_type_code = 'CHANGE_STATUS' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT') AND
146 (p_requirement_status_code is NULL AND p_assignment_status_code is NULL AND
147 p_mass_update_flag = FND_API.G_TRUE) ) THEN
148 PA_UTILS.Add_Message ('PA', 'PA_SCH_ASGN_STATUS_NULL');
149 RAISE FND_API.G_EXC_ERROR;
150 END IF;
151
152 -- validations when p_exception_type_code = 'CHANGE_HOURS'
153 IF (p_exception_type_code = 'CHANGE_HOURS') THEN
154
155 -- Checking that if the we want to change the hours by taking the hours type code as HOURS
156 -- then the hours per day should not be null and should not beyond the 0 to 24 hours
157 -- same with the PERCENTAGE then calendar percentage should not be null and should not beyond the
158 -- the 0 to 100 percent
159 IF (p_change_hours_type_code = 'HOURS') THEN
160
161 IF (p_hrs_per_day IS NULL) THEN
162 PA_UTILS.Add_Message ('PA', 'PA_SCH_HOURS_NULL');
163 RAISE FND_API.G_EXC_ERROR;
164 ELSIF (p_hrs_per_day NOT BETWEEN 0 AND 24 ) THEN
165 PA_UTILS.Add_Message ('PA', 'PA_SCH_HOURS_OUT_OF_RANGE');
166 RAISE FND_API.G_EXC_ERROR;
167 END IF;
168
169 ELSIF (p_change_hours_type_code = 'PERCENTAGE') THEN
170 IF (p_calendar_percent IS NULL) THEN
171 PA_UTILS.Add_Message ('PA', 'PA_SCH_PERCENTAGE_NULL');
172 RAISE FND_API.G_EXC_ERROR;
173 ELSIF (p_calendar_percent NOT BETWEEN 0 AND 100 ) THEN
174 PA_UTILS.Add_Message ('PA', 'PA_SCH_PERCENTAGE_OUT_OF_RANGE');
175 RAISE FND_API.G_EXC_ERROR;
176 END IF;
177
178 -- Value/ID validation for calendar_name/id entered through 'OTHER' text input field on
179 -- the Update Hours Of Days screen.
180 IF (p_change_calendar_type_code = 'OTHER') THEN
181
182 -- IF both calendar_name and calendar_id are null, error out.
183 IF (p_change_calendar_name is NULL AND p_change_calendar_id IS NULL) THEN
184 PA_UTILS.Add_Message ('PA', 'PA_OTHER_CALENDAR_NULL');
185 RAISE FND_API.G_EXC_ERROR;
186 END IF;
187
188 PA_CALENDAR_UTILS.Check_Calendar_Name_Or_Id(
189 p_calendar_id => p_change_calendar_id
190 ,p_calendar_name => p_change_calendar_name
191 ,p_check_id_flag => 'N'
192 ,x_calendar_id => l_change_calendar_id
193 ,x_return_status => l_x_return_status
194 ,x_error_message_code => l_err_msg_code);
195
196 -- If calendar_name/id validation fails, put error message into error stack.
197 IF (l_x_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
198 PA_UTILS.Add_Message ('PA', l_err_msg_code);
199 RAISE FND_API.G_EXC_ERROR;
200 END IF;
201 END IF; -- IF(p_change_calendar_type_code = 'OTHER')
202 END IF; -- ELSIF (p_change_hours_type_code = 'PERCENTAGE')
203
204 END IF; -- p_exception_type_code = 'CHANGE_HOURS'
205
206 -- validations when p_exception_type_code = 'CHANGE_WORK_PATTERN'
207 IF (p_exception_type_code = 'CHANGE_WORK_PATTERN') THEN
208
209 -- If all of working hours are null, error out.
210 IF (p_monday_hours IS NULL AND p_tuesday_hours IS NULL AND
211 p_wednesday_hours IS NULL AND p_thursday_hours IS NULL AND
212 p_friday_hours IS NULL AND p_saturday_hours IS NULL AND
213 p_sunday_hours IS NULL) THEN
214 PA_UTILS.Add_Message ('PA', 'PA_SCH_HOURS_ALL_NULL');
215 RAISE FND_API.G_EXC_ERROR;
216 END IF;
217
218 -- if anyday hours is not null and not valid number(between 0 and 24), throw an errors.
219 IF ( (p_monday_hours IS NOT NULL AND (p_monday_hours NOT BETWEEN 0 AND 24)) OR
220 (p_tuesday_hours IS NOT NULL AND (p_tuesday_hours NOT BETWEEN 0 AND 24)) OR
221 (p_wednesday_hours IS NOT NULL AND (p_wednesday_hours NOT BETWEEN 0 AND 24)) OR
222 (p_thursday_hours IS NOT NULL AND (p_thursday_hours NOT BETWEEN 0 AND 24)) OR
223 (p_friday_hours IS NOT NULL AND (p_friday_hours NOT BETWEEN 0 AND 24)) OR
224 (p_saturday_hours IS NOT NULL AND (p_saturday_hours NOT BETWEEN 0 AND 24)) OR
225 (p_sunday_hours IS NOT NULL AND (p_sunday_hours NOT BETWEEN 0 AND 24)) ) THEN
226 PA_UTILS.Add_Message ('PA', 'PA_SCH_HOURS_OUT_OF_RANGE');
227 RAISE FND_API.G_EXC_ERROR;
228 END IF;
229
230 -- Cross-row validation when p_last_row_flag = 'Y'
231 IF p_change_start_date_tbl IS NOT NULL THEN
232 IF p_last_row_flag = 'Y' and p_change_start_date_tbl.COUNT > 1 THEN
233 FOR i IN p_change_start_date_tbl.FIRST .. p_change_start_date_tbl.LAST LOOP
234 FOR j IN i+1 .. p_change_start_date_tbl.LAST LOOP
235 IF ((p_change_start_date_tbl(j) >= p_change_start_date_tbl(i) AND p_change_start_date_tbl(j) <= p_change_end_date_tbl(i))
236 OR (p_change_end_date_tbl(j) >= p_change_start_date_tbl(i) AND p_change_end_date_tbl(j) <= p_change_end_date_tbl(i))
237 OR (p_change_start_date_tbl(j) <= p_change_start_date_tbl(i) AND p_change_end_date_tbl(j) >= p_change_end_date_tbl(i))
238 OR (p_change_start_date_tbl(j) >= p_change_start_date_tbl(i) AND p_change_end_date_tbl(j) <= p_change_end_date_tbl(i)))
239 THEN
240 PA_UTILS.Add_Message ('PA', 'PA_SCH_OVERLAP_WORK_PATTERN');
241 RAISE FND_API.G_EXC_ERROR;
242 END IF;
243 END LOOP;
244 END LOOP;
245 END IF;
246 END IF;
247
248 END IF; -- p_exception_type_code = 'CHANGE_WORK_PATTERN'
249
250 ----------------------------------------------------------------------------------------------
251 --
252 -- 'Continue and Submit' button? => return
253 --
254 ----------------------------------------------------------------------------------------------
255
256 -- If p_validate_only = 'T', it won't do anything other than on line validation i.e. validate_date_range.
257 -- From the Update Schedule page,
258 -- p_validate_only = 'T' : 'Continue and Submit' button
259 -- p_validate_only = 'F' : 'Apply' button
260 IF (p_validate_only = FND_API.G_TRUE) THEN
261 RETURN;
262 END IF;
263
264 ----------------------------------------------------------------------------------------------
265 --
266 -- Mass Schedule Update
267 --
268 ----------------------------------------------------------------------------------------------
269 -- If this is for Mass schedule update, call Mass Transaction Workflow.
270 IF (p_mass_update_flag = FND_API.G_TRUE AND p_last_row_flag = 'Y') THEN
271 --start the mass WF
272 PA_MASS_ASGMT_TRX.Start_Mass_Asgmt_Trx_Wf(
273 p_mode => PA_MASS_ASGMT_TRX.G_MASS_UPDATE_SCHEDULE
274 ,p_action => PA_MASS_ASGMT_TRX.G_SAVE
275 ,p_project_id => p_project_id
276 ,p_exception_type_code => p_exception_type_code
277 ,p_assignment_id_tbl => p_assignment_id_array
278 ,p_change_start_date => p_change_start_date
279 ,p_change_end_date => p_change_end_date
280 ,p_change_rqmt_status_code => p_requirement_status_code
281 ,p_change_asgmt_status_code => p_assignment_status_code
282 ,p_change_start_date_tbl => p_change_start_date_tbl
283 ,p_change_end_date_tbl => p_change_end_date_tbl
284 ,p_monday_hours_tbl => p_monday_hours_tbl
285 ,p_tuesday_hours_tbl => p_tuesday_hours_tbl
286 ,p_wednesday_hours_tbl => p_wednesday_hours_tbl
287 ,p_thursday_hours_tbl => p_thursday_hours_tbl
288 ,p_friday_hours_tbl => p_friday_hours_tbl
289 ,p_saturday_hours_tbl => p_saturday_hours_tbl
290 ,p_sunday_hours_tbl => p_sunday_hours_tbl
291 ,p_non_working_day_flag => p_non_working_day_flag
292 ,p_change_hours_type_code => p_change_hours_type_code
293 ,p_hrs_per_day => p_hrs_per_day
294 ,p_calendar_percent => p_calendar_percent
295 ,p_change_calendar_type_code => p_change_calendar_type_code
296 ,p_change_calendar_name => p_change_calendar_name
297 ,p_change_calendar_id => p_change_calendar_id
298 ,p_duration_shift_type_code => p_duration_shift_type_code
299 ,p_duration_shift_unit_code => p_duration_shift_unit_code
300 ,p_num_of_shift => p_number_of_shift
301 ,x_return_status => l_x_return_status );
302
303
304 ----------------------------------------------------------------------------------------------
305 --
306 -- Single Schedule Update
307 --
308 ----------------------------------------------------------------------------------------------
309 -- If this is for Single schedule update, call an appropriate procedure depends on
310 -- p_exception_type_code.
311 ELSIF (p_mass_update_flag = FND_API.G_FALSE) THEN
312 -- call execute_update_schedule procedure for single schedule update.
313
314 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub', 'Calling single_update_schedule', 6);
315
316 single_update_schedule (
317 p_project_id => p_project_id
318 ,p_exception_type_code => p_exception_type_code
319 ,p_record_version_number => p_record_version_number
320 ,p_assignment_id => p_assignment_id
321 ,p_change_start_date => p_change_start_date
322 ,p_change_end_date => p_change_end_date
323 ,p_assignment_status_code => p_assignment_status_code
324 ,p_monday_hours => p_monday_hours
325 ,p_tuesday_hours => p_tuesday_hours
326 ,p_wednesday_hours => p_wednesday_hours
327 ,p_thursday_hours => p_thursday_hours
328 ,p_friday_hours => p_friday_hours
329 ,p_saturday_hours => p_saturday_hours
330 ,p_sunday_hours => p_sunday_hours
331 ,p_non_working_day_flag => p_non_working_day_flag
332 ,p_change_hours_type_code => p_change_hours_type_code
333 ,p_hrs_per_day => p_hrs_per_day
334 ,p_calendar_percent => p_calendar_percent
335 ,p_change_calendar_type_code => p_change_calendar_type_code
336 --,p_change_calendar_name => p_change_calendar_name
337 ,p_change_calendar_id => l_change_calendar_id
338 ,p_duration_shift_type_code => p_duration_shift_type_code
339 ,p_duration_shift_unit_code => p_duration_shift_unit_code
340 ,p_number_of_shift => p_number_of_shift
341 ,p_last_row_flag => p_last_row_flag
342 ,p_init_msg_list => FND_API.G_TRUE
343 ,p_commit => FND_API.G_FALSE
344 ,p_called_by_proj_party => p_called_by_proj_party -- Added for Bug 6631033
345 ,x_return_status => l_x_return_status
346 ,x_msg_count => l_msg_count
347 ,x_msg_data => l_msg_data);
348 END IF;
349
350 -- If the called API fails, raise an exception.
351 IF (l_x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
352 RAISE FND_API.G_EXC_ERROR;
353 END IF;
354
355 ELSE -- Bug 6411422
356
357 --l_profile_begin_date := to_date(fnd_profile.value('PA_UTL_START_DATE'), 'DD/MM/YYYY'); /* commenting for For Bug 7304151 */
358 l_profile_begin_date := to_date(fnd_profile.value('PA_UTL_START_DATE'), 'DD/MM/YYYY', 'NLS_DATE_LANGUAGE=AMERICAN'); /*Adding For Bug 7304151*/
359 PA_UTILS.Add_Message( p_app_short_name => 'PA'
360 ,p_msg_name => 'PA_INVALID_ASSIGN_START_DATE'
361 ,p_token1 => 'PROFILE_DATE'
362 ,p_value1 => l_profile_begin_date );
363 RAISE FND_API.G_EXC_ERROR;
364
365 END IF; -- Bug 6411422
366
367 ----------------------------------------------------------------------------------------------
368 --
369 -- Exception Handling
370 --
371 ----------------------------------------------------------------------------------------------
372 EXCEPTION
373
374 WHEN FND_API.G_EXC_ERROR THEN
375 x_return_status := FND_API.G_RET_STS_ERROR;
376 x_msg_count := FND_MSG_PUB.Count_Msg;
377
378 IF x_msg_count = 1 THEN
379 pa_interface_utils_pub.get_messages
380 (p_encoded => FND_API.G_TRUE,
381 p_msg_index => 1,
382 p_data => x_msg_data,
383 p_msg_index_out => l_msg_index_out );
384 END IF;
385
386 WHEN OTHERS THEN
387 IF p_commit = FND_API.G_TRUE THEN
388 ROLLBACK TO SCH_PUB_UPDATE_SCH;
389 END IF;
390
391 -- 4537865 : RESET x_msg_data also.
392 x_msg_data := SUBSTRB(SQLERRM,1,240);
393
394 -- Set the excetption Message and the stack
395 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB'
396 ,p_procedure_name => 'execute_update_schedule'
397 ,p_error_text => x_msg_data ); -- 4537865
398
399 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
400 x_msg_count := 1;
401
402 RAISE; -- This is optional depending on the needs
403
404 END update_schedule;
405
406
407 /* Bug 7693634 Start */
408
409 PROCEDURE update_schedule_bulk
410 ( p_project_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE
411 ,p_mass_update_flag_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := FND_API.G_FALSE
412 ,p_exception_type_code_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE
413 ,p_record_version_number_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
414 ,p_assignment_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
415 ,p_change_start_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
416 ,p_change_end_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
417 ,p_requirement_status_code_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := NULL
418 ,p_assignment_status_code_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := NULL
419 ,p_last_row_flag_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := 'Y'
420 ,p_commit_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := FND_API.G_FALSE
421 ,p_validate_only_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := FND_API.G_TRUE
422 ,p_msg_data_in_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE
423 ,x_return_status_tbl OUT NOCOPY SYSTEM.PA_VARCHAR2_2000_TBL_TYPE --File.Sql.39 bug 4440895
424 ,x_msg_count_tbl OUT NOCOPY SYSTEM.PA_NUM_TBL_TYPE --File.Sql.39 bug 4440895
425 ,x_msg_data_tbl OUT NOCOPY SYSTEM.PA_VARCHAR2_2000_TBL_TYPE ) --File.Sql.39 bug 4440895
426 IS
427
428 l_err_msg_code fnd_new_messages.message_name%TYPE;
429 l_updated_calendar_id NUMBER;
430 l_msg_data VARCHAR2(2000);
431 l_msg_count NUMBER;
432 l_msg_index_out NUMBER;
433 l_change_calendar_id NUMBER;
434 l_valid_assign_start_flag VARCHAR2(1) := 'Y'; -- Bug 6411422
435 l_profile_begin_date DATE; -- Bug 6411422
436
437 /* 7693634 new variables */
438 l_mass_update_flag_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_mass_update_flag_tbl;
439 l_last_row_flag_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_mass_update_flag_tbl;
440 l_commit_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_commit_tbl;
441 l_validate_only_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_validate_only_tbl;
442
443
444 l_msg_count_tbl SYSTEM.PA_NUM_TBL_TYPE := p_project_id_tbl;
445 l_return_status_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_validate_only_tbl;
446 l_msg_data_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_validate_only_tbl;
447 --Bug#9817752 start
448 l_assignment_type pa_project_assignments.assignment_type%TYPE :=NULL ;
449 l_assignment_status_code VARCHAR2(50) := NULL;
450 --Bug#9817752 end
451
452
453 BEGIN
454 fnd_msg_pub.initialize; -- 8233045
455
456 PA_SCHEDULE_PUB.G_update_schedule_bulk_call := 'Y'; -- 8233045
457
458 /* Initializing some of the parameters */
459 for k in p_project_id_tbl.first .. p_project_id_tbl.last loop
460
461 if ( p_msg_data_in_tbl(k) is null
462 or p_msg_data_in_tbl(k) = 'StartDateWarning'
463 or p_msg_data_in_tbl(k) = 'EndDateWarning') then
464 l_mass_update_flag_tbl(k) := p_mass_update_flag_tbl(k);
465 if l_mass_update_flag_tbl(k) is null then
466 l_mass_update_flag_tbl(k) := FND_API.G_FALSE;
467 end if;
468
469 l_last_row_flag_tbl(k) := p_last_row_flag_tbl(k);
470 if l_last_row_flag_tbl(k) is null then
471 l_last_row_flag_tbl(k) := 'Y';
472 end if;
473
474 l_commit_tbl(k) := p_commit_tbl(k);
475 if l_commit_tbl(k) is null then
476 l_commit_tbl(k) := FND_API.G_FALSE;
477 end if;
478
479 l_validate_only_tbl(k) := p_validate_only_tbl(k);
480 if l_validate_only_tbl(k) is null then
481 l_validate_only_tbl(k) := FND_API.G_TRUE;
482 end if;
483
484 end if;
485 end loop;
486
487 for k in p_project_id_tbl.first .. p_project_id_tbl.last loop
488
489 if ( p_msg_data_in_tbl(k) is null
490 or p_msg_data_in_tbl(k) = 'StartDateWarning'
491 or p_msg_data_in_tbl(k) = 'EndDateWarning') then
492
493 BEGIN
494 -- Initialize the return status to success
495 l_return_status_tbl(k) := FND_API.G_RET_STS_SUCCESS ;
496
497 --Clear the global PL/SQL message table
498 FND_MSG_PUB.initialize;
499
500 -- Initialize the Error Stack
501 PA_DEBUG.init_err_stack('PA_SCHEDULE_PUB.update_schedule');
502
503 -- Issue API savepoint if the transaction is to be committed
504 IF (l_commit_tbl(k) = FND_API.G_TRUE) THEN
505 SAVEPOINT SCH_PUB_UPDATE_SCH;
506 END IF;
507
508
509 ----------------------------------------------------------------------------------------------
510 --
511 -- Mass Schedule Update
512 --
513 ----------------------------------------------------------------------------------------------
514 -- If this is for Mass schedule update, call Mass Transaction Workflow.
515 IF (l_mass_update_flag_tbl(k) = FND_API.G_TRUE AND l_last_row_flag_tbl(k) = 'Y') THEN
516 PA_MASS_ASGMT_TRX.Start_Mass_Asgmt_Trx_Wf(
517 p_mode => PA_MASS_ASGMT_TRX.G_MASS_UPDATE_SCHEDULE
518 ,p_action => PA_MASS_ASGMT_TRX.G_SAVE
519 ,p_project_id => p_project_id_tbl(k)
520 ,p_exception_type_code => p_exception_type_code_tbl(k)
521 -- ,p_assignment_id_tbl => p_assignment_id_array_tbl(k)
522 ,p_change_start_date => p_change_start_date_tbl(k)
523 ,p_change_end_date => p_change_end_date_tbl(k)
524 ,p_change_rqmt_status_code => p_requirement_status_code_tbl(k)
525 ,p_change_asgmt_status_code => p_assignment_status_code_tbl(k)
526 ,x_return_status => l_x_return_status );
527
528 ----------------------------------------------------------------------------------------------
529 --
530 -- Single Schedule Update
531 --
532 ----------------------------------------------------------------------------------------------
533 -- If this is for Single schedule update, call an appropriate procedure depends on
534 -- p_exception_type_code.
535 ELSIF (l_mass_update_flag_tbl(k) = FND_API.G_FALSE) THEN
536 -- call execute_update_schedule procedure for single schedule update.
537 --Bug#9817752 start
538 -- For new period of schedule generated from update scheduled people page, the status should always be Provisional
539 IF PA_ASSIGNMENTS_PUB.G_update_assignment_bulk_call = 'Y' THEN
540 SELECT Assignment_type
541 INTO l_assignment_type
542 FROM pa_project_assignments
543 WHERE assignment_id= p_assignment_id_tbl(k);
544
545 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub.update_schedule_bulk', 'Assignment_type:'||l_assignment_type, 6);
546 IF l_assignment_type IN ('STAFFED_ASSIGNMENT','STAFFED_ADMIN_ASSIGNMENT') THEN
547 l_assignment_status_code := '104';
548 END IF;
549 END IF;
550
551 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub.update_schedule_bulk', 'Calling single_update_schedule', 6);
552
553 --Bug#9817752 end
554
555
556 single_update_schedule (
557 p_project_id => p_project_id_tbl(k)
558 ,p_exception_type_code => p_exception_type_code_tbl(k)
559 ,p_record_version_number => p_record_version_number_tbl(k)
560 ,p_assignment_id => p_assignment_id_tbl(k)
561 ,p_change_start_date => p_change_start_date_tbl(k)
562 ,p_change_end_date => p_change_end_date_tbl(k)
563 ,p_assignment_status_code => Nvl(l_assignment_status_code,p_assignment_status_code_tbl(k))
564 ,p_init_msg_list => FND_API.G_TRUE
565 ,p_commit => l_commit_tbl(k)
566 ,x_return_status => l_x_return_status
567 ,x_msg_count => l_msg_count
568 ,x_msg_data => l_msg_data);
569 l_msg_data_tbl(k) := l_msg_data;
570 END IF;
571
572 -- If the called API fails, raise an exception.
573 IF (l_x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
574 RAISE FND_API.G_EXC_ERROR;
575 END IF;
576
577
578 x_msg_count_tbl := l_msg_count_tbl;
579 x_return_status_tbl := l_return_status_tbl;
580 x_msg_data_tbl := l_msg_data_tbl;
581 ----------------------------------------------------------------------------------------------
582 --
583 -- Exception Handling
584 --
585 ----------------------------------------------------------------------------------------------
586 EXCEPTION
587
588 WHEN FND_API.G_EXC_ERROR THEN
589 l_return_status_tbl(k) := FND_API.G_RET_STS_ERROR;
590 l_msg_count_tbl(k) := FND_MSG_PUB.Count_Msg;
591
592 IF l_msg_count_tbl(k) = 1 THEN
593 pa_interface_utils_pub.get_messages
594 (p_encoded => FND_API.G_TRUE,
595 p_msg_index => 1,
596 p_data => l_msg_data_tbl(k),
597 p_msg_index_out => l_msg_index_out );
598 END IF;
599 x_msg_count_tbl := l_msg_count_tbl;
600 x_return_status_tbl := l_return_status_tbl;
601 x_msg_data_tbl := l_msg_data_tbl;
602
603 WHEN OTHERS THEN
604 IF l_commit_tbl(k) = FND_API.G_TRUE THEN
605 ROLLBACK TO SCH_PUB_UPDATE_SCH;
606 END IF;
607 -- 4537865 : RESET x_msg_data also.
608 l_msg_data_tbl(k) := SUBSTRB(SQLERRM,1,240);
609
610 -- Set the excetption Message and the stack
611 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB'
612 ,p_procedure_name => 'execute_update_schedule'
613 ,p_error_text => l_msg_data_tbl(k) ); -- 4537865
614
615 l_return_status_tbl(k) := FND_API.G_RET_STS_UNEXP_ERROR ;
616 l_msg_count_tbl(k) := 1;
617
618 x_msg_count_tbl := l_msg_count_tbl;
619 x_return_status_tbl := l_return_status_tbl;
620 x_msg_data_tbl := l_msg_data_tbl;
621
622 RAISE; -- This is optional depending on the needs
623 END;
624
625 end if; -- p_msg_data_in_tbl
626
627 end loop;
628
629 END update_schedule_bulk;
630
631 /* Bug 7693634 End */
632
633
634
635 PROCEDURE update_new_schedule_bulk
636 ( p_project_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE
637 ,p_mass_update_flag_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := FND_API.G_FALSE
638 ,p_exception_type_code_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE
639 ,p_record_version_number_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
640 ,p_assignment_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
641 ,p_change_start_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
642 ,p_change_end_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
643 ,p_requirement_status_code_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := NULL
644 ,p_assignment_status_code_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := NULL
645 ,p_last_row_flag_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := 'Y'
646 ,p_commit_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := FND_API.G_FALSE
647 ,p_validate_only_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE -- := FND_API.G_TRUE
648 ,p_msg_data_in_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE
649 ,p_change_hours_type_code_tbl IN SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := NULL
650 ,p_calendar_percent_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
651 ,p_change_calendar_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
652 ,x_return_status_tbl OUT NOCOPY SYSTEM.PA_VARCHAR2_2000_TBL_TYPE --File.Sql.39 bug 4440895
653 ,x_msg_count_tbl OUT NOCOPY SYSTEM.PA_NUM_TBL_TYPE --File.Sql.39 bug 4440895
654 ,x_msg_data_tbl OUT NOCOPY SYSTEM.PA_VARCHAR2_2000_TBL_TYPE --File.Sql.39 bug 4440895
655 )
656
657 IS
658
659 l_err_msg_code fnd_new_messages.message_name%TYPE;
660 l_updated_calendar_id NUMBER;
661 l_msg_data VARCHAR2(2000);
662 l_msg_count NUMBER;
663 l_msg_index_out NUMBER;
664 l_change_calendar_id NUMBER;
665 l_valid_assign_start_flag VARCHAR2(1) := 'Y'; -- Bug 6411422
666 l_profile_begin_date DATE; -- Bug 6411422
667 l_change_calendar_type_code VARCHAR2(20);
668
669 /* 7693634 new variables */
670 l_mass_update_flag_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_mass_update_flag_tbl;
671 l_last_row_flag_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_mass_update_flag_tbl;
672 l_commit_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_commit_tbl;
673 l_validate_only_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_validate_only_tbl;
674
675
676 l_msg_count_tbl SYSTEM.PA_NUM_TBL_TYPE := p_project_id_tbl;
677 l_return_status_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_validate_only_tbl;
678 l_msg_data_tbl SYSTEM.PA_VARCHAR2_2000_TBL_TYPE := p_validate_only_tbl;
679
680
681
682 BEGIN
683 fnd_msg_pub.initialize; -- 8233045
684
685 PA_SCHEDULE_PUB.G_update_schedule_bulk_call := 'Y'; -- 8233045
686
687 /* Initializing some of the parameters */
688 for k in p_project_id_tbl.first .. p_project_id_tbl.last loop
689
690 if ( p_msg_data_in_tbl(k) is null
691 or p_msg_data_in_tbl(k) = 'StartDateWarning'
692 or p_msg_data_in_tbl(k) = 'EndDateWarning') then
693 l_mass_update_flag_tbl(k) := p_mass_update_flag_tbl(k);
694 if l_mass_update_flag_tbl(k) is null then
695 l_mass_update_flag_tbl(k) := FND_API.G_FALSE;
696 end if;
697
698 l_last_row_flag_tbl(k) := p_last_row_flag_tbl(k);
699 if l_last_row_flag_tbl(k) is null then
700 l_last_row_flag_tbl(k) := 'Y';
701 end if;
702
703
704
705
706 l_commit_tbl(k) := p_commit_tbl(k);
707 if l_commit_tbl(k) is null then
708 l_commit_tbl(k) := FND_API.G_FALSE;
709 end if;
710
711 l_validate_only_tbl(k) := p_validate_only_tbl(k);
712 if l_validate_only_tbl(k) is null then
713 l_validate_only_tbl(k) := FND_API.G_TRUE;
714 end if;
715
716 end if;
717 end loop;
718
719 for k in p_project_id_tbl.first .. p_project_id_tbl.last loop
720
721 if ( p_msg_data_in_tbl(k) is null
722 or p_msg_data_in_tbl(k) = 'StartDateWarning'
723 or p_msg_data_in_tbl(k) = 'EndDateWarning') then
724
725 BEGIN
726 -- Initialize the return status to success
727 l_return_status_tbl(k) := FND_API.G_RET_STS_SUCCESS ;
728
729 --Clear the global PL/SQL message table
730 FND_MSG_PUB.initialize;
731
732 -- Initialize the Error Stack
733 PA_DEBUG.init_err_stack('PA_SCHEDULE_PUB.update_schedule');
734
735 -- Issue API savepoint if the transaction is to be committed
736 IF (l_commit_tbl(k) = FND_API.G_TRUE) THEN
737 SAVEPOINT SCH_PUB_UPDATE_SCH;
738 END IF;
739
740
741 ----------------------------------------------------------------------------------------------
742 --
743 -- Mass Schedule Update
744 --
745 ----------------------------------------------------------------------------------------------
746 -- If this is for Mass schedule update, call Mass Transaction Workflow.
747 IF (l_mass_update_flag_tbl(k) = FND_API.G_TRUE AND l_last_row_flag_tbl(k) = 'Y') THEN
748 PA_MASS_ASGMT_TRX.Start_Mass_Asgmt_Trx_Wf(
749 p_mode => PA_MASS_ASGMT_TRX.G_MASS_UPDATE_SCHEDULE
750 ,p_action => PA_MASS_ASGMT_TRX.G_SAVE
751 ,p_project_id => p_project_id_tbl(k)
752 ,p_exception_type_code => p_exception_type_code_tbl(k)
753 -- ,p_assignment_id_tbl => p_assignment_id_array_tbl(k)
754 ,p_change_start_date => p_change_start_date_tbl(k)
755 ,p_change_end_date => p_change_end_date_tbl(k)
756 ,p_change_rqmt_status_code => p_requirement_status_code_tbl(k)
757 ,p_change_asgmt_status_code => p_assignment_status_code_tbl(k)
758 ,x_return_status => l_x_return_status );
759
760 ----------------------------------------------------------------------------------------------
761 --
762 -- Single Schedule Update
763 --
764 ----------------------------------------------------------------------------------------------
765 -- If this is for Single schedule update, call an appropriate procedure depends on
766 -- p_exception_type_code.
767 ELSIF (l_mass_update_flag_tbl(k) = FND_API.G_FALSE) THEN
768 -- call execute_update_schedule procedure for single schedule update.
769
770 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub', 'Calling single_update_schedule', 6);
771
772 -- Bug#9710585 START Adding Validation for percent
773 IF (p_change_hours_type_code_tbl(k) = 'PERCENTAGE') THEN
774 IF (p_calendar_percent_tbl(k) NOT BETWEEN 0 AND 100 ) THEN
775 PA_UTILS.Add_Message ('PA', 'PA_SCH_PERCENTAGE_OUT_OF_RANGE');
776 RAISE FND_API.G_EXC_ERROR;
777 END IF;
778 END IF;
779 --Bug#9710585 END Adding Validation for percent
780 single_update_schedule (
781 p_project_id => p_project_id_tbl(k)
782 ,p_exception_type_code => p_exception_type_code_tbl(k)
783 ,p_record_version_number => p_record_version_number_tbl(k)
784 ,p_assignment_id => p_assignment_id_tbl(k)
785 ,p_change_start_date => p_change_start_date_tbl(k)
786 ,p_change_end_date => p_change_end_date_tbl(k)
787 ,p_assignment_status_code => p_assignment_status_code_tbl(k)
788 ,p_change_hours_type_code => p_change_hours_type_code_tbl(k)
789 ,p_calendar_percent => p_calendar_percent_tbl(k)
790 ,p_change_calendar_id => p_change_calendar_id_tbl(k) -- Bug#9710585
791 ,p_change_calendar_type_code => 'OTHER' --Bug#9710585
792 ,p_init_msg_list => FND_API.G_TRUE
793 ,p_commit => l_commit_tbl(k)
794 ,x_return_status => l_x_return_status
795 ,x_msg_count => l_msg_count
796 ,x_msg_data => l_msg_data);
797
798 l_msg_data_tbl(k) := l_msg_data;
799 END IF;
800
801 -- If the called API fails, raise an exception.
802 IF (l_x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
803 RAISE FND_API.G_EXC_ERROR;
804 END IF;
805
806
807 x_msg_count_tbl := l_msg_count_tbl;
808 x_return_status_tbl := l_return_status_tbl;
809 x_msg_data_tbl := l_msg_data_tbl;
810 ----------------------------------------------------------------------------------------------
811 --
812 -- Exception Handling
813 --
814 ----------------------------------------------------------------------------------------------
815 EXCEPTION
816
817 WHEN FND_API.G_EXC_ERROR THEN
818 l_return_status_tbl(k) := FND_API.G_RET_STS_ERROR;
819 l_msg_count_tbl(k) := FND_MSG_PUB.Count_Msg;
820
821 IF l_msg_count_tbl(k) = 1 THEN
822 pa_interface_utils_pub.get_messages
823 (p_encoded => FND_API.G_TRUE,
824 p_msg_index => 1,
825 p_data => l_msg_data_tbl(k),
826 p_msg_index_out => l_msg_index_out );
827 END IF;
828 x_msg_count_tbl := l_msg_count_tbl;
829 x_return_status_tbl := l_return_status_tbl;
830 x_msg_data_tbl := l_msg_data_tbl;
831
832 WHEN OTHERS THEN
833 IF l_commit_tbl(k) = FND_API.G_TRUE THEN
834 ROLLBACK TO SCH_PUB_UPDATE_SCH;
835 END IF;
836 -- 4537865 : RESET x_msg_data also.
837 l_msg_data_tbl(k) := SUBSTRB(SQLERRM,1,240);
838
839 -- Set the excetption Message and the stack
840 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB'
841 ,p_procedure_name => 'execute_update_schedule'
842 ,p_error_text => l_msg_data_tbl(k) ); -- 4537865
843
844 l_return_status_tbl(k) := FND_API.G_RET_STS_UNEXP_ERROR ;
845 l_msg_count_tbl(k) := 1;
846
847 x_msg_count_tbl := l_msg_count_tbl;
848 x_return_status_tbl := l_return_status_tbl;
849 x_msg_data_tbl := l_msg_data_tbl;
850
851 RAISE; -- This is optional depending on the needs
852 END;
853
854 end if; -- p_msg_data_in_tbl
855
856 end loop;
857
858 END update_new_schedule_bulk;
859
860
861
862
863
864 -- procedure : single_update_schedule
865 -- Purpose : This procedure will change the schedule records of a single assignment.
866 --
867 -- Input parameters
868 -- Parameters Type Required Description
869 -- --------------------------- ------ -------- --------------------------------------------------------
870 -- P_Project_Id NUMBER YES project id of the associated calendar
871 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this assignment
872
873 PROCEDURE single_update_schedule
874 ( p_project_id IN NUMBER
875 ,p_exception_type_code IN VARCHAR2
876 ,p_record_version_number IN NUMBER := NULL
877 ,p_assignment_id IN NUMBER := NULL
878 ,p_change_start_date IN DATE := NULL
879 ,p_change_end_date IN DATE := NULL
880 ,p_assignment_status_code IN VARCHAR2 := NULL
881 ,p_monday_hours IN NUMBER := NULL
882 ,p_tuesday_hours IN NUMBER := NULL
883 ,p_wednesday_hours IN NUMBER := NULL
884 ,p_thursday_hours IN NUMBER := NULL
885 ,p_friday_hours IN NUMBER := NULL
886 ,p_saturday_hours IN NUMBER := NULL
887 ,p_sunday_hours IN NUMBER := NULL
888 ,p_non_working_day_flag IN VARCHAR2 := 'N'
889 ,p_change_hours_type_code IN VARCHAR2 := NULL
890 ,p_hrs_per_day IN NUMBER := NULL
891 ,p_calendar_percent IN NUMBER := NULL
892 ,p_change_calendar_type_code IN VARCHAR2 := NULL
893 --,p_change_calendar_name IN VARCHAR2 := NULL
894 ,p_change_calendar_id IN NUMBER := NULL
895 ,p_duration_shift_type_code IN VARCHAR2 := NULL
896 ,p_duration_shift_unit_code IN VARCHAR2 := NULL
897 ,p_number_of_shift IN NUMBER := NULL
898 ,p_last_row_flag IN VARCHAR2 := 'Y'
899 ,p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE
900 ,p_commit IN VARCHAR2 := FND_API.G_FALSE
901 ,p_called_by_proj_party IN VARCHAR2 := 'N' -- Added for Bug 6631033
902 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
903 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
904 ,x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
905 IS
906
907 l_err_msg_code fnd_new_messages.message_name%TYPE;
908 l_updated_calendar_id NUMBER;
909 l_msg_data VARCHAR2(2000);
910 l_msg_count NUMBER;
911 l_msg_index_out NUMBER;
912 l_assignment_type VARCHAR2(30);
913 l_assignment_status_code VARCHAR2(30);
914 l_calendar_id NUMBER;
915 l_cur_asgn_start_date DATE;
916 l_cur_asgn_end_date DATE;
917
918 -- To get information for the given assignment
919 CURSOR get_asgmt_info_csr IS
920 SELECT assignment_type,
921 status_code,
922 calendar_id,
923 start_date,
924 end_date
925 FROM pa_project_assignments
926 WHERE assignment_id = p_assignment_id;
927
928 BEGIN
929
930
931 --Clear the global PL/SQL message table
932 IF (p_init_msg_list = FND_API.G_TRUE) THEN
933 FND_MSG_PUB.initialize;
934 END IF;
935
936 -- Initialize the return status to success
937 x_return_status := FND_API.G_RET_STS_SUCCESS ;
938
939 -- Initialize the Error Stack
940 PA_DEBUG.init_err_stack('PA_SCHEDULE_PUB.single_update_schedule');
941
942 -- Issue API savepoint if the transaction is to be committed
943 IF p_commit = FND_API.G_TRUE THEN
944 SAVEPOINT SCH_PUB_SINGLE_UPDATE_SCH;
945 END IF;
946
947 -- Get assignment information to pass to change_XXX apis.
948 OPEN get_asgmt_info_csr;
949 FETCH get_asgmt_info_csr
950 INTO l_assignment_type, l_assignment_status_code,
951 l_calendar_id,
952 l_cur_asgn_start_date, l_cur_asgn_end_date;
953 CLOSE get_asgmt_info_csr;
954
955
956
957 -- Call an appropriate procedure depends on p_exception_type_code.
958 -- Modified code for 7663765
959 IF (p_exception_type_code = 'CHANGE_DURATION' OR p_exception_type_code = 'SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
960 change_duration (
961 p_record_version_number => p_record_version_number
962 ,p_project_id => p_project_id
963 ,p_exception_type_code => p_exception_type_code
964 ,p_calendar_id => l_calendar_id
965 ,p_assignment_id => p_assignment_id
966 ,p_assignment_type => l_assignment_type
967 ,p_start_date => p_change_start_date
968 ,p_end_date => p_change_end_date
969 ,p_assignment_status_code => p_assignment_status_code
970 ,p_asgn_start_date => l_cur_asgn_start_date
971 ,p_asgn_end_date => l_cur_asgn_end_date
972 ,p_duration_shift_type_code => p_duration_shift_type_code
973 ,p_duration_shift_unit_code => p_duration_shift_unit_code
974 ,p_number_of_shift => p_number_of_shift
975 ,p_called_by_proj_party => p_called_by_proj_party -- Added for Bug 6631033
976 ,x_return_status => l_x_return_status
977 ,x_msg_count => l_msg_count
978 ,x_msg_data => l_msg_data);
979
980 ELSIF (p_exception_type_code = 'CHANGE_STATUS') THEN
981 change_status (
982 p_record_version_number => p_record_version_number
983 ,p_project_id => p_project_id
984 ,p_calendar_id => l_calendar_id
985 ,p_assignment_id => p_assignment_id
986 ,p_assignment_type => l_assignment_type
987 ,p_status_type => NULL
988 ,p_start_date => p_change_start_date
989 ,p_end_date => p_change_end_date
990 ,p_assignment_status_code => p_assignment_status_code
991 ,p_asgn_start_date => l_cur_asgn_start_date
992 ,p_asgn_end_date => l_cur_asgn_end_date
993 ,x_return_status => l_x_return_status
994 ,x_msg_count => l_msg_count
995 ,x_msg_data => l_msg_data);
996
997 ELSIF (p_exception_type_code = 'CHANGE_WORK_PATTERN') THEN
998 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub', 'Calling change_work_pattern', 6);
999 change_work_pattern (
1000 p_record_version_number => p_record_version_number
1001 ,p_project_id => p_project_id
1002 ,p_calendar_id => l_calendar_id
1003 ,p_assignment_id => p_assignment_id
1004 ,p_assignment_type => l_assignment_type
1005 ,p_start_date => p_change_start_date
1006 ,p_end_date => p_change_end_date
1007 ,p_monday_hours => p_monday_hours
1008 ,p_tuesday_hours => p_tuesday_hours
1009 ,p_wednesday_hours => p_wednesday_hours
1010 ,p_thursday_hours => p_thursday_hours
1011 ,p_friday_hours => p_friday_hours
1012 ,p_saturday_hours => p_saturday_hours
1013 ,p_sunday_hours => p_sunday_hours
1014 ,p_asgn_start_date => l_cur_asgn_start_date
1015 ,p_asgn_end_date => l_cur_asgn_end_date
1016 ,p_last_row_flag => p_last_row_flag
1017 ,x_return_status => l_x_return_status
1018 ,x_msg_count => l_msg_count
1019 ,x_msg_data => l_msg_data);
1020
1021 ELSIF (p_exception_type_code = 'CHANGE_HOURS') THEN
1022 change_hours (
1023 p_record_version_number => p_record_version_number
1024 ,p_project_id => p_project_id
1025 ,p_calendar_id => l_calendar_id
1026 ,p_assignment_id => p_assignment_id
1027 ,p_assignment_type => l_assignment_type
1028 ,p_start_date => p_change_start_date
1029 ,p_end_date => p_change_end_date
1030 ,p_assignment_status_code => l_assignment_status_code
1031 ,p_change_hours_type_code => p_change_hours_type_code
1032 ,p_hrs_per_day => p_hrs_per_day
1033 ,p_non_working_day_flag => p_non_working_day_flag
1034 ,p_calendar_percent => p_calendar_percent
1035 ,p_change_calendar_type_code => p_change_calendar_type_code
1036 -- ,p_change_calendar_name => p_change_calendar_name
1037 ,p_change_calendar_id => p_change_calendar_id
1038 ,p_asgn_start_date => l_cur_asgn_start_date
1039 ,p_asgn_end_date => l_cur_asgn_end_date
1040 ,x_return_status => l_x_return_status
1041 ,x_msg_count => l_msg_count
1042 ,x_msg_data => l_msg_data);
1043
1044 END IF;
1045
1046 -- If the called API fails, raise an exception.
1047 IF l_x_return_status = FND_API.G_RET_STS_ERROR THEN
1048 RAISE FND_API.G_EXC_ERROR;
1049 ELSIF l_x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1050 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1051 END IF;
1052
1053 ----------------------------------------------------------------------------------------------
1054 --
1055 -- Exception Handling
1056 --
1057 ----------------------------------------------------------------------------------------------
1058 EXCEPTION
1059
1060 WHEN FND_API.G_EXC_ERROR THEN
1061 x_return_status := FND_API.G_RET_STS_ERROR;
1062 x_msg_count := FND_MSG_PUB.Count_Msg;
1063
1064 IF x_msg_count = 1 THEN
1065 pa_interface_utils_pub.get_messages
1066 (p_encoded => FND_API.G_TRUE,
1067 p_msg_index => 1,
1068 p_data => x_msg_data,
1069 p_msg_index_out => l_msg_index_out );
1070 END IF;
1071
1072 WHEN OTHERS THEN
1073 IF p_commit = FND_API.G_TRUE THEN
1074 ROLLBACK TO SCH_PUB_SINGLE_UPDATE_SCH;
1075 END IF;
1076
1077 -- 4537865 : RESET x_msg_data also
1078 x_msg_data := SUBSTRB(SQLERRM,1,240);
1079
1080 -- Set the excetption Message and the stack
1081 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB'
1082 ,p_procedure_name => 'single_update_schedule',
1083 p_error_text => x_msg_data ); -- 4537865
1084
1085 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
1086 x_msg_count := 1;
1087
1088 RAISE; -- This is optional depending on the needs
1089
1090 END single_update_schedule;
1091
1092
1093
1094 -- procedure : mass_update_schedule
1095 -- Purpose : This procedure will change the schedule records of the assignments passed in.
1096 -- Currently, this procedure will only be called by the Mass Transaction Workflow API.
1097 --
1098 -- Input parameters
1099 -- Parameters Type Required Description
1100 -- --------------------------- ------ -------- --------------------------------------------------------
1101 -- P_Project_Id NUMBER YES project id of the associated calendar
1102 PROCEDURE mass_update_schedule
1103 ( p_project_id IN NUMBER
1104 ,p_exception_type_code IN VARCHAR2
1105 ,p_assignment_id_array IN SYSTEM.PA_NUM_TBL_TYPE
1106 ,p_change_start_date IN DATE := NULL
1107 ,p_change_end_date IN DATE := NULL
1108 ,p_change_rqmt_status_code IN VARCHAR2 := NULL
1109 ,p_change_asgmt_status_code IN VARCHAR2 := NULL
1110 ,p_change_start_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
1111 ,p_change_end_date_tbl IN SYSTEM.PA_DATE_TBL_TYPE := NULL
1112 ,p_monday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
1113 ,p_tuesday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
1114 ,p_wednesday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
1115 ,p_thursday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
1116 ,p_friday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
1117 ,p_saturday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
1118 ,p_sunday_hours_tbl IN SYSTEM.PA_NUM_TBL_TYPE := NULL
1119 ,p_non_working_day_flag IN VARCHAR2 := 'N'
1120 ,p_change_hours_type_code IN VARCHAR2 := NULL
1121 ,p_hrs_per_day IN NUMBER := NULL
1122 ,p_calendar_percent IN NUMBER := NULL
1123 ,p_change_calendar_type_code IN VARCHAR2 := NULL
1124 ,p_change_calendar_name IN VARCHAR2 := NULL
1125 ,p_change_calendar_id IN NUMBER := NULL
1126 ,p_duration_shift_type_code IN VARCHAR2 := NULL
1127 ,p_duration_shift_unit_code IN VARCHAR2 := NULL
1128 ,p_number_of_shift IN NUMBER := NULL
1129 ,p_init_msg_list IN VARCHAR2 := FND_API.G_TRUE
1130 ,p_validate_only IN VARCHAR2 := FND_API.G_TRUE
1131 ,p_commit IN VARCHAR2 := FND_API.G_FALSE
1132 ,x_success_assignment_id_tbl OUT NOCOPY SYSTEM.PA_NUM_TBL_TYPE /* Added NOCOPY for bug#2674619 */
1133 ,x_return_status OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
1134 ,x_msg_count OUT NOCOPY NUMBER --File.Sql.39 bug 4440895
1135 ,x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
1136 IS
1137
1138 l_err_msg_code fnd_new_messages.message_name%TYPE;
1139 l_updated_calendar_id NUMBER;
1140 l_msg_data VARCHAR2(2000);
1141 l_msg_count NUMBER;
1142 l_assignment_id NUMBER;
1143 l_assignment_type VARCHAR2(30);
1144 l_assignment_status_code VARCHAR2(30);
1145 l_asgmt_system_status_code VARCHAR2(30);
1146 l_change_asgmt_status_code VARCHAR2(30);
1147 l_resource_id NUMBER;
1148 l_return_status VARCHAR2(50);
1149 l_return_code VARCHAR2(30);
1150 l_rownum NUMBER;
1151 l_privilege VARCHAR2(30);
1152 l_success_assignment_id_tbl system.pa_num_tbl_type := p_assignment_id_array;
1153 l_last_row_flag VARCHAR2(1);
1154
1155 -- To get information for the gieven assignment
1156 CURSOR get_asgmt_info_csr(l_assignment_id IN NUMBER) IS
1157 SELECT assignment_type,
1158 status_code,
1159 resource_id
1160 FROM pa_project_assignments
1161 WHERE assignment_id = l_assignment_id;
1162
1163
1164 BEGIN
1165 -- Initialize the return status to success
1166 x_return_status := FND_API.G_RET_STS_SUCCESS ;
1167
1168 --Clear the global PL/SQL message table
1169 IF (p_init_msg_list = FND_API.G_TRUE) THEN
1170 FND_MSG_PUB.initialize;
1171 END IF;
1172
1173 -- Initialize the Error Stack
1174 PA_DEBUG.init_err_stack('PA_SCHEDULE_PUB.mass_update_schedule');
1175
1176
1177 ----------------------------------------------------------------------------------------------
1178 --
1179 -- Loop through Assignment_Id_Array
1180 --
1181 ----------------------------------------------------------------------------------------------
1182 -- loop through assignmentId_array and process for each single update_schedule
1183 FOR i IN p_assignment_id_array.FIRST..p_assignment_id_array.LAST LOOP
1184
1185 BEGIN
1186 -- We need to commit for each schedule update rather than one time after
1187 -- completing mass schedule update.
1188 IF p_commit = FND_API.G_TRUE THEN
1189 SAVEPOINT SCH_PUB_MASS_UPDATE_SCH;
1190 END IF;
1191
1192 -- get the detail information of the assignment to prepare the parameters for change_XXX api
1193 l_assignment_id := p_assignment_id_array(i);
1194
1195 OPEN get_asgmt_info_csr(l_assignment_id);
1196 FETCH get_asgmt_info_csr
1197 INTO l_assignment_type, l_assignment_status_code, l_resource_id;
1198
1199 l_rownum := get_asgmt_info_csr%ROWCOUNT;
1200 CLOSE get_asgmt_info_csr;
1201
1202 -- If there is no record for the assignment_id
1203 IF (l_rownum = 0) THEN
1204 -- set l_success_assignment_id_tbl(i) to null, which will be passed as a out arameter
1205 -- so that notification won't be sent for the assignment_id.
1206 l_success_assignment_id_tbl(i) := null;
1207
1208 -- add appropriate error message to the error stack as raise error where the error will be
1209 -- copied to the error table.
1210 PA_UTILS.Add_Message ('PA', 'PA_NO_ASGMT');
1211 RAISE FND_API.G_EXC_ERROR;
1212
1213 -- If there is only record for the assignment_id, call single_update_schedule after security check
1214 -- if necessary.
1215 ELSIF (l_rownum = 1) THEN
1216
1217 -- Actually l_change_asgmt_status_code is used for requirement_status_code for OPEN_ASSIGNMENT.
1218 IF (l_assignment_type = 'OPEN_ASSIGNMENT') THEN
1219 l_change_asgmt_status_code := p_change_rqmt_status_code;
1220 ELSE
1221 l_change_asgmt_status_code := p_change_asgmt_status_code;
1222 END IF;
1223
1224 -- call single_update_schedule procedure for single schedule update.
1225 -- Need to pass NULL for p_record_version_number so that it doesn't check record_version_number.
1226 -- Because we don't need to care about it for mass schedule update.
1227
1228 -- For CHANGE_WORK_PATTERN
1229 IF p_exception_type_code = 'CHANGE_WORK_PATTERN' THEN
1230 IF p_change_start_date_tbl.COUNT > 0 THEN
1231 FOR j IN p_change_start_date_tbl.FIRST .. p_change_start_date_tbl.LAST LOOP
1232 IF j < p_change_start_date_tbl.LAST THEN
1233 l_last_row_flag := 'N';
1234 ELSE
1235 l_last_row_flag := 'Y';
1236 END IF;
1237
1238 single_update_schedule (
1239 p_project_id => p_project_id
1240 ,p_exception_type_code => p_exception_type_code
1241 ,p_record_version_number => NULL
1242 ,p_assignment_id => p_assignment_id_array(i)
1243 ,p_change_start_date => p_change_start_date_tbl(j)
1244 ,p_change_end_date => p_change_end_date_tbl(j)
1245 ,p_assignment_status_code => l_change_asgmt_status_code
1246 ,p_monday_hours => p_monday_hours_tbl(j)
1247 ,p_tuesday_hours => p_tuesday_hours_tbl(j)
1248 ,p_wednesday_hours => p_wednesday_hours_tbl(j)
1249 ,p_thursday_hours => p_thursday_hours_tbl(j)
1250 ,p_friday_hours => p_friday_hours_tbl(j)
1251 ,p_saturday_hours => p_saturday_hours_tbl(j)
1252 ,p_sunday_hours => p_sunday_hours_tbl(j)
1253 ,p_non_working_day_flag => p_non_working_day_flag
1254 ,p_change_hours_type_code => p_change_hours_type_code
1255 ,p_hrs_per_day => p_hrs_per_day
1256 ,p_calendar_percent => p_calendar_percent
1257 ,p_change_calendar_type_code => p_change_calendar_type_code
1258 --,p_change_calendar_name => p_change_calendar_name
1259 ,p_change_calendar_id => p_change_calendar_id
1260 ,p_duration_shift_type_code => p_duration_shift_type_code
1261 ,p_duration_shift_unit_code => p_duration_shift_unit_code
1262 ,p_number_of_shift => p_number_of_shift
1263 ,p_last_row_flag => l_last_row_flag
1264 ,p_init_msg_list => FND_API.G_TRUE
1265 ,p_commit => FND_API.G_FALSE
1266 ,x_return_status => l_x_return_status
1267 ,x_msg_count => l_msg_count
1268 ,x_msg_data => l_msg_data);
1269
1270 END LOOP;
1271 END IF;
1272 -- For all other schedule changes
1273 ELSE
1274 l_last_row_flag := 'Y';
1275
1276 single_update_schedule (
1277 p_project_id => p_project_id
1278 ,p_exception_type_code => p_exception_type_code
1279 ,p_record_version_number => NULL
1280 ,p_assignment_id => p_assignment_id_array(i)
1281 ,p_change_start_date => p_change_start_date
1282 ,p_change_end_date => p_change_end_date
1283 ,p_assignment_status_code => l_change_asgmt_status_code
1284 ,p_monday_hours => NULL
1285 ,p_tuesday_hours => NULL
1286 ,p_wednesday_hours => NULL
1287 ,p_thursday_hours => NULL
1288 ,p_friday_hours => NULL
1289 ,p_saturday_hours => NULL
1290 ,p_sunday_hours => NULL
1291 ,p_non_working_day_flag => p_non_working_day_flag
1292 ,p_change_hours_type_code => p_change_hours_type_code
1293 ,p_hrs_per_day => p_hrs_per_day
1294 ,p_calendar_percent => p_calendar_percent
1295 ,p_change_calendar_type_code => p_change_calendar_type_code
1296 --,p_change_calendar_name => p_change_calendar_name
1297 ,p_change_calendar_id => p_change_calendar_id
1298 ,p_duration_shift_type_code => p_duration_shift_type_code
1299 ,p_duration_shift_unit_code => p_duration_shift_unit_code
1300 ,p_number_of_shift => p_number_of_shift
1301 ,p_last_row_flag => l_last_row_flag
1302 ,p_init_msg_list => FND_API.G_TRUE
1303 ,p_commit => FND_API.G_FALSE
1304 ,x_return_status => l_x_return_status
1305 ,x_msg_count => l_msg_count
1306 ,x_msg_data => l_msg_data);
1307 END IF; -- end if for calling single_update_schedule
1308
1309 -- If the called API succeeded, put the assingnment_id to the out parameter 'x_assignment_id_array'
1310 -- and commit.
1311 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS) THEN
1312 l_success_assignment_id_tbl(i) := p_assignment_id_array(i);
1313
1314 IF (p_commit = FND_API.G_TRUE) THEN
1315 COMMIT;
1316 END IF;
1317
1318 -- If the called API doesn't succeeded, set null to tthe out parameter 'x_assignment_id_array'
1319 -- instead of the failed assignment_id so that workflow won't be started for the failed assignments.
1320 -- And need to rollback.
1321 ELSE
1322 l_success_assignment_id_tbl(i) := null;
1323
1324 IF (p_commit = FND_API.G_TRUE) THEN
1325 ROLLBACK TO SCH_PUB_MASS_UPDATE_SCH;
1326 RAISE FND_API.G_EXC_ERROR;
1327 END IF;
1328 END IF;
1329
1330 END IF; -- if l_rownum = 1
1331
1332 EXCEPTION
1333 -- need to catch error for system_status_code being not found
1334 WHEN NO_DATA_FOUND THEN
1335 PA_UTILS.Add_Message ('PA', 'PA_STATUS_CODE_NOT_FOUND');
1336
1337 -- save the error message to the proper table so that we can retrive them later
1338 -- from workflow notification page.
1339 PA_MESSAGE_UTILS.save_messages
1340 (p_user_id => PA_MASS_ASGMT_TRX.G_SUBMITTER_USER_ID,
1341 p_source_type1 => PA_MASS_ASGMT_TRX.G_SOURCE_TYPE1,
1342 p_source_type2 => PA_MASS_ASGMT_TRX.G_MASS_UPDATE_SCHEDULE,
1343 p_source_identifier1 => PA_MASS_ASGMT_TRX.G_WORKFLOW_ITEM_TYPE,
1344 p_source_identifier2 => PA_MASS_ASGMT_TRX.G_WORKFLOW_ITEM_KEY,
1345 p_context1 => p_project_id,
1346 p_context2 => p_assignment_id_array(i),
1347 p_context3 => NULL,
1348 p_commit => FND_API.G_TRUE,
1349 x_return_status => l_return_status);
1350
1351 WHEN FND_API.G_EXC_ERROR THEN
1352 -- save the error message to the proper table so that we can retrive them later
1353 -- from workflow notification page.
1354 PA_MESSAGE_UTILS.save_messages
1355 (p_user_id => PA_MASS_ASGMT_TRX.G_SUBMITTER_USER_ID,
1356 p_source_type1 => PA_MASS_ASGMT_TRX.G_SOURCE_TYPE1,
1357 p_source_type2 => PA_MASS_ASGMT_TRX.G_MASS_UPDATE_SCHEDULE,
1358 p_source_identifier1 => PA_MASS_ASGMT_TRX.G_WORKFLOW_ITEM_TYPE,
1359 p_source_identifier2 => PA_MASS_ASGMT_TRX.G_WORKFLOW_ITEM_KEY,
1360 p_context1 => p_project_id,
1361 p_context2 => p_assignment_id_array(i),
1362 p_context3 => NULL,
1363 p_commit => FND_API.G_TRUE,
1364 x_return_status => l_return_status);
1365 END;
1366
1367 END LOOP;
1368
1369 -- put the success_assignment_id_table to the out parameter to invoke workflow only for
1370 -- those success ones.
1371 X_success_assignment_id_tbl := l_success_assignment_id_tbl;
1372
1373 ----------------------------------------------------------------------------------------------
1374 --
1375 -- Exception Handling
1376 --
1377 ----------------------------------------------------------------------------------------------
1378 EXCEPTION
1379 WHEN OTHERS THEN
1380
1381 -- 4537865 : RESET x_msg_data also
1382 x_msg_data := SUBSTRB(SQLERRM,1,240);
1383
1384 -- Set the excetption Message and the stack
1385 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB'
1386 ,p_procedure_name => 'mass_update_schedule'
1387 ,p_error_text => x_msg_data ); -- 4537865
1388
1389 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1390 x_msg_count := FND_MSG_PUB.Count_Msg;
1391
1392 RAISE; -- This is optional depending on the needs
1393 END mass_update_schedule;
1394
1395
1396
1397 -- procedure : change_duration
1398 -- Purpose : This procedure will change the duration of the given assignment
1399 -- on the basis of start date and end date it will shift the assignment
1400 -- , extend the assignment or contract the assignment
1401 -- Input parameters
1402 -- Parameters Type Required Description
1403 -- P_Project_Id NUMBER YES project id of the associated calendar
1404 -- p_record_version_number NUMBER YES
1405 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this assignment
1406 -- P_Assignment_Id NUMBER YES Assignment id of the changed duration assignment
1407 -- P_Assignment_Type VARCHAR2 YES It is type of the assignment e.g OPEN /STAFFED ASSIGNMENT
1408 -- P_Start_Date DATE YES starting date for the changed duration
1409 -- P_End_Date DATE YES ending date for the changed duration
1410 -- P_Assignment_Status_Code VARCHAR2 YES Status of the assignment e.g OPEN/CONFIRM/PROVISIONAL
1411 -- P_Asgn_Start_Date DATE YES Start date of the assignment for which you want to
1412 -- change duration
1413 -- P_Asgn_End_Date DATE YES End date of the assignment for which you want to
1414 -- change duration
1415
1416 PROCEDURE change_duration
1417 (
1418 p_record_version_number IN Number ,
1419 p_exception_type_code IN Varchar2 ,
1420 p_project_id IN Number ,
1421 p_calendar_id IN Number ,
1422 p_assignment_id IN Number ,
1423 p_assignment_type IN Varchar2 ,
1424 p_start_date IN date := NULL,
1425 p_end_date IN date := NULL,
1426 p_assignment_status_code IN varchar2 := NULL,
1427 p_asgn_start_date IN DATE := NULL,
1428 p_asgn_end_date IN DATE := NULL,
1429 p_duration_shift_type_code IN Varchar2 := NULL,
1430 p_duration_shift_unit_code IN VARCHAR2 := NULL,
1431 p_number_of_shift IN Varchar2 := NULL,
1432 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
1433 p_generate_timeline_flag IN VARCHAR2 := 'Y', --Unilog
1434 p_called_by_proj_party IN VARCHAR2 := 'N', -- Added for Bug 6631033
1435 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
1436 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
1437 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
1438 IS
1439 l_assignment_status_null EXCEPTION;
1440 l_stale_asmt_data EXCEPTION;
1441 l_status_type VARCHAR2(30);
1442 l_error_message_code VARCHAR2(50);
1443 l_record_version_number NUMBER;
1444 l_person_id NUMBER;
1445 l_start_date DATE;
1446 l_end_date DATE;
1447 l_msg_index_out NUMBER;
1448 l_shifted_days NUMBER;
1449 l_exception_id NUMBER;
1450 l_return_status VARCHAR2(1);
1451 l_assignment_status_name pa_project_statuses.project_status_name%TYPE;
1452
1453 -- For error message tokens
1454 l_asgn_req_text VARCHAR2(30);
1455 l_a_an_text VARCHAR2(30);
1456 l_asgn_req_poss_text VARCHAR2(30);
1457
1458 l_data VARCHAR2(2000); -- 4537865
1459 l_new_resource_id NUMBER; -- 4537865
1460 -- For retrieving resource_source_id
1461 CURSOR get_resource_source_id IS
1462 SELECT a.person_id, b.resource_id
1463 FROM pa_resource_txn_attributes a, pa_project_assignments b
1464 WHERE a.resource_id = b.resource_id
1465 AND b.assignment_id = p_assignment_id;
1466
1467 l_resource_source_id NUMBER;
1468 l_resource_id NUMBER;
1469 l_resource_type_id NUMBER;
1470 l_resource_out_of_range EXCEPTION;
1471 l_resource_cc_error_u EXCEPTION;
1472 l_resource_cc_error_e EXCEPTION;
1473 l_cc_ok VARCHAR2(1);
1474 l_ei_asgn_out_of_range EXCEPTION;
1475
1476 -- For retrieving project_status_name
1477 -- 3054787: Select from tables directly to improve performance.
1478 CURSOR get_project_status_name IS
1479 SELECT pps.project_status_name
1480 FROM pa_projects_all ppa, pa_project_statuses pps
1481 WHERE ppa.project_id = p_project_id
1482 AND ppa.project_status_code = pps.project_status_code;
1483
1484 l_project_status_name pa_project_statuses.project_status_name%TYPE;
1485
1486 BEGIN
1487 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
1488
1489 --Clear the global PL/SQL message table
1490 IF (p_init_msg_list = FND_API.G_TRUE) THEN
1491 FND_MSG_PUB.initialize;
1492 END IF;
1493
1494 IF ( p_assignment_type = 'OPEN_ASSIGNMENT' ) THEN
1495 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_TEXT');
1496 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_A_TEXT');
1497 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_POSS_TEXT');
1498 ELSE
1499 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_TEXT');
1500 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_AN_TEXT');
1501 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_POSS_TEXT');
1502 END IF;
1503
1504
1505 ----------------------------------------------------------------------------------------------
1506 --
1507 -- Logic for Duration
1508 --
1509 ----------------------------------------------------------------------------------------------
1510 IF (p_exception_type_code = 'CHANGE_DURATION') THEN
1511
1512 -- The dates are valid now checking the passing date should valid for the asignment dates
1513 IF (( p_start_date IS NOT NULL ) AND (p_end_date IS NULL ) AND (p_start_date > p_asgn_end_date )) THEN
1514 RAISE l_out_of_range_from_date;
1515 ELSIF (( p_start_date IS NULL ) AND (p_end_date IS NOT NULL ) AND ( p_end_date < p_asgn_start_date )) THEN
1516 RAISE l_out_of_range_to_date;
1517 END IF;
1518
1519 -- for change duration page, set the input value 'p_start_date' and 'p_end_date' to local
1520 -- variables which are used for checking validation resource for the updated date.
1521 l_start_date := p_start_date;
1522 l_end_date := p_end_date;
1523
1524 END IF; -- IF (p_exception_type_code = 'CHANGE_DURATION')
1525
1526
1527 ----------------------------------------------------------------------------------------------
1528 --
1529 -- Logic For Duration Shift
1530 -- Modified below for 7663765
1531 ----------------------------------------------------------------------------------------------
1532 IF (p_exception_type_code = 'SHIFT_DURATION' OR p_exception_type_code = 'DURATION_PATTERN_SHIFT') THEN
1533
1534 -- If p_number_of_shift is not null, calculate the new start_date and end_date by adding
1535 -- or substracting p_number_of_shift from p_asgn_start_date and p_asgn_end_date
1536 IF (p_number_of_shift is NOT NULL) THEN
1537
1538 -- compute shifted_days
1539 IF (p_duration_shift_unit_code = 'DAYS') THEN
1540 l_shifted_days := p_number_of_shift;
1541 ELSIF (p_duration_shift_unit_code = 'WEEKS') THEN
1542 l_shifted_days := p_number_of_shift*7;
1543 END IF;
1544
1545 -- set start_Date, end_date according to shift_type_code and shifed_days
1546 IF (p_duration_shift_type_code = 'FORWARD') THEN
1547 IF (p_duration_shift_unit_code = 'MONTHS') THEN
1548 l_start_date := add_months(p_asgn_start_date, p_number_of_shift) ;
1549 l_end_date := add_months(p_asgn_end_date, p_number_of_shift) ;
1550 ELSE
1551 l_start_date := p_asgn_start_date + l_shifted_days;
1552 l_end_date := p_asgn_end_date + l_shifted_days;
1553 END IF;
1554 ELSIF (p_duration_shift_type_code = 'BACKWARD') THEN
1555 IF (p_duration_shift_unit_code = 'MONTHS') THEN
1556 l_start_date := add_months(p_asgn_start_date, p_number_of_shift * -1) ;
1557 l_end_date := add_months(p_asgn_end_date, p_number_of_shift * -1) ;
1558 ELSE
1559 l_start_date := p_asgn_start_date - l_shifted_days;
1560 l_end_date := p_asgn_end_date - l_shifted_days;
1561 END IF;
1562
1563 END IF;
1564
1565 END IF;
1566
1567 END IF; -- IF (p_exception_type_code = 'SHIFT_DURATION')
1568
1569 ----------------------------------------------------------------------------------------------
1570 --
1571 -- Common Logic for both Duration and Duration Shift
1572 --
1573 ----------------------------------------------------------------------------------------------
1574 -- If extending or contracting the duration the the assignment status should not be null for the new duration
1575 -- If extending the staffed assignment duration with a new status, the status should be allowed for the status
1576 -- of the project this assignment belongs to.
1577 -- Bug 8233045: Added G_update_schedule_bulk_call condition.
1578 IF( ((l_start_date IS NOT NULL) AND (l_start_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date)) OR
1579 ((l_end_date IS NOT NULL) AND (l_end_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date)) ) AND
1580 PA_SCHEDULE_PUB.G_update_schedule_bulk_call <> 'Y' THEN
1581
1582 IF(p_assignment_status_code IS NULL) THEN
1583 RAISE l_assignment_status_null;
1584
1585 ELSIF (p_assignment_status_code IS NOT NULL) AND (p_assignment_type <> 'OPEN_ASSIGNMENT') THEN
1586
1587 l_return_status := PA_ASSIGNMENT_UTILS.is_asgmt_allow_stus_ctl_check(
1588 p_asgmt_status_code => p_assignment_status_code,
1589 p_project_id => p_project_id,
1590 p_add_message => 'N');
1591
1592 IF l_return_status <> 'Y' THEN
1593 OPEN get_project_status_name;
1594 FETCH get_project_status_name INTO l_project_status_name;
1595 CLOSE get_project_status_name;
1596
1597 SELECT project_status_name
1598 INTO l_assignment_status_name
1599 FROM pa_project_statuses
1600 WHERE project_status_code = p_assignment_status_code;
1601
1602 RAISE l_asgn_stus_not_for_proj_stus;
1603 END IF;
1604 END IF;
1605
1606 END IF; --IF(( (p_start_date IS NOT NULL ..
1607
1608 --
1609 -- Validate that resource is valid for new start date
1610 --
1611 PA_SCHEDULE_UTILS.log_message(1,'Validate that resource is valid for new start date?');
1612 IF p_assignment_type <> 'OPEN_ASSIGNMENT' THEN
1613 PA_SCHEDULE_UTILS.log_message(1,'Validating resource');
1614 -- Get resource source id for assignment
1615 OPEN get_resource_source_id;
1616 FETCH get_resource_source_id INTO l_resource_source_id, l_resource_id;
1617 CLOSE get_resource_source_id;
1618
1619 PA_RESOURCE_UTILS.Check_ResourceName_Or_Id (
1620 p_resource_id => l_resource_source_id
1621 ,p_resource_name => null
1622 ,p_check_id_flag => 'Y' --3235018 Changed from N to Y --'N' /* Bug#2822950-Modified null to 'N' */
1623 ,p_date => NVL(l_start_date, p_asgn_start_date) -- 3235018 : replaced p_start_date to l_start_date
1624 ,p_end_date => NVL(l_end_date, p_asgn_end_date) -- 3235018 : Added this
1625 -- 4537865 : ,x_resource_id => l_resource_source_id
1626 ,x_resource_id => l_new_resource_id -- 4537865 : For NOCOPY related Changes.
1627 ,x_resource_type_id => l_resource_type_id
1628 ,x_return_status => l_x_return_status
1629 ,x_error_message_code => l_error_message_code);
1630
1631 IF (l_x_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
1632 PA_SCHEDULE_UTILS.log_message(1,'Resource dates are not valid');
1633 Raise l_resource_out_of_range;
1634 ELSE -- IF if l_x_return_status is success : 4537865
1635 l_resource_source_id := l_new_resource_id ;
1636 END IF;
1637
1638 PA_SCHEDULE_UTILS.log_message(1,'Resource dates are valid');
1639
1640 -- Check if resource is assigned to a valid organization
1641 PA_RESOURCE_UTILS.check_cc_for_resource(p_resource_id => l_resource_id,
1642 p_project_id => p_project_id,
1643 p_start_date => NVL(l_start_date, p_asgn_start_date),
1644 p_end_date => NVL(l_end_date, p_asgn_end_date),
1645 x_cc_ok => l_cc_ok,
1646 x_return_status => l_x_return_status,
1647 x_error_message_code => l_error_message_code);
1648
1649 IF (l_x_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
1650 PA_SCHEDULE_UTILS.log_message(1,'Resource cc is not valid: u');
1651 Raise l_resource_cc_error_u;
1652 END IF;
1653
1654 IF l_cc_ok <> 'Y' THEN
1655 PA_SCHEDULE_UTILS.log_message(1,'Resource cc is not valid: e');
1656 Raise l_resource_cc_error_e;
1657 END IF;
1658
1659 PA_SCHEDULE_UTILS.log_message(1,'Resource cc is valid');
1660
1661 -- Make sure duration change does not cause existing actuals to
1662 -- be out of range.
1663 -- 2797890: Added parameter p_project_id, p_person_id.
1664 PA_TRANS_UTILS.check_txn_exists (
1665 p_assignment_id => p_assignment_id
1666 ,p_old_start_date => p_asgn_start_date
1667 ,p_old_end_date => p_asgn_end_date
1668 ,p_new_start_date => NVL(l_start_date, p_asgn_start_date)
1669 ,p_new_end_date => NVL(l_end_date, p_asgn_end_date)
1670 ,p_calling_mode => 'UPDATE'
1671 ,p_project_id => p_project_id
1672 ,p_person_id => l_resource_source_id
1673 ,x_error_message_code => l_error_message_code
1674 ,x_return_status => x_return_status);
1675 -- End of 2797890
1676 if (x_return_status <> FND_API.G_RET_STS_SUCCESS) then
1677 raise l_ei_asgn_out_of_range;
1678 end if;
1679 END IF;
1680
1681 --
1682 -- Insert row to PA_SCHEDULE_EXCEPTIONS
1683 --
1684 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_duration API ..... ');
1685 PA_SCH_EXCEPT_PKG.Insert_Rows(
1686 p_calendar_id => p_calendar_id
1687 ,p_assignment_id => p_assignment_id
1688 ,p_project_id => p_project_id
1689 ,p_schedule_type_code => p_assignment_type
1690 ,p_assignment_status_code => p_assignment_status_code
1691 ,p_exception_type_code => p_exception_type_code
1692 ,p_start_date => l_start_date
1693 ,p_end_date => l_end_date
1694 ,p_duration_shift_type_code => p_duration_shift_type_code
1695 ,p_duration_shift_unit_code => p_duration_shift_unit_code
1696 ,p_number_of_shift => p_number_of_shift
1697 ,x_exception_id => l_exception_id
1698 ,x_return_status => l_x_return_status
1699 ,x_msg_count => x_msg_count
1700 ,x_msg_data => x_msg_data );
1701
1702 -- Calling the change assignment schedule procedure which will
1703 -- generate the schedule after applying the duration change
1704 PA_SCHEDULE_PUB.change_asgn_schedule(
1705 p_record_version_number => p_record_version_number,
1706 p_assignment_id => p_assignment_id,
1707 p_project_id => p_project_id,
1708 p_exception_id => l_exception_id,
1709 p_generate_timeline_flag => p_generate_timeline_flag,--Unilog
1710 p_called_by_proj_party => p_called_by_proj_party, -- Added for Bug 6631033
1711 x_return_status => l_x_return_status,
1712 x_msg_count => x_msg_count,
1713 x_msg_data => x_msg_data);
1714
1715
1716 -- Bug 2255963: Call reevaluate_adv_action_set AFTER the start date of
1717 -- requirement (but not asssignment) is updated and before changes are committed.
1718 IF l_x_return_status = FND_API.G_RET_STS_SUCCESS THEN
1719 IF (p_assignment_type = 'OPEN_ASSIGNMENT' AND l_start_date <> p_asgn_start_date) THEN
1720 PA_ADVERTISEMENTS_PUB.Reevaluate_Adv_Action_Set (
1721 p_object_id => p_assignment_id,
1722 p_object_type => 'OPEN_ASSIGNMENT',
1723 p_new_object_start_date => l_start_date,
1724 p_validate_only => FND_API.G_FALSE,
1725 p_init_msg_list => FND_API.G_FALSE,
1726 p_commit => FND_API.G_FALSE,
1727 x_return_status => l_x_return_status);
1728 END IF;
1729 END IF;
1730
1731 -- Bug 2441437: Update the no of active candidates after duration
1732 -- has been changed.
1733 IF l_x_return_status = FND_API.G_RET_STS_SUCCESS THEN
1734 PA_CANDIDATE_UTILS.Update_No_Of_Active_Candidates (
1735 p_assignment_id => p_assignment_id,
1736 x_return_status => l_x_return_status);
1737 END IF;
1738
1739 ----------------------------------------------------------------------
1740 --
1741 -- Exception Handling
1742 --
1743 ----------------------------------------------------------------------
1744 PA_SCHEDULE_UTILS.log_message(1,'End of the change_duration API ..... ');
1745 x_return_status := l_x_return_status;
1746
1747 x_msg_count := FND_MSG_PUB.Count_Msg;
1748 If x_msg_count = 1 THEN
1749 pa_interface_utils_pub.get_messages
1750 (p_encoded => FND_API.G_TRUE ,
1751 p_msg_index => 1,
1752 p_msg_count => x_msg_count ,
1753 p_msg_data => x_msg_data ,
1754 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1755 p_msg_index_out => l_msg_index_out );
1756 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
1757 End If;
1758
1759 EXCEPTION
1760 WHEN l_ei_asgn_out_of_range THEN
1761 PA_UTILS.Add_Message('PA', l_error_message_code);
1762 x_return_status := FND_API.G_RET_STS_ERROR;
1763 x_msg_data := l_error_message_code;
1764 x_msg_count := FND_MSG_PUB.Count_Msg;
1765 If x_msg_count = 1 THEN
1766 pa_interface_utils_pub.get_messages
1767 (p_encoded => FND_API.G_TRUE,
1768 p_msg_index => 1,
1769 p_msg_count => x_msg_count,
1770 p_msg_data => x_msg_data,
1771 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1772 p_msg_index_out => l_msg_index_out );
1773 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
1774 End If;
1775 WHEN l_resource_cc_error_u THEN
1776 PA_UTILS.Add_Message('PA', l_error_message_code);
1777 x_return_status := FND_API.G_RET_STS_ERROR;
1778 x_msg_data := l_error_message_code;
1779 x_msg_count := FND_MSG_PUB.Count_Msg;
1780 If x_msg_count = 1 THEN
1781 pa_interface_utils_pub.get_messages
1782 (p_encoded => FND_API.G_TRUE,
1783 p_msg_index => 1,
1784 p_msg_count => x_msg_count,
1785 p_msg_data => x_msg_data,
1786 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1787 p_msg_index_out => l_msg_index_out );
1788 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
1789 End If;
1790 WHEN l_resource_cc_error_e THEN
1791 PA_UTILS.Add_Message('PA', 'CROSS_CHARGE_VALIDATION_FAILED');
1792 x_return_status := FND_API.G_RET_STS_ERROR;
1793 x_msg_data := 'CROSS_CHARGE_VALIDATION_FAILED';
1794 x_msg_count := FND_MSG_PUB.Count_Msg;
1795 If x_msg_count = 1 THEN
1796 pa_interface_utils_pub.get_messages
1797 (p_encoded => FND_API.G_TRUE,
1798 p_msg_index => 1,
1799 p_msg_count => x_msg_count,
1800 p_msg_data => x_msg_data,
1801 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1802 p_msg_index_out => l_msg_index_out );
1803 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
1804 End If;
1805 WHEN l_resource_out_of_range THEN
1806 PA_UTILS.Add_Message( 'PA', 'PA_RESOURCE_OUT_OF_RANGE');
1807 x_return_status := FND_API.G_RET_STS_ERROR;
1808 x_msg_data := 'PA_RESOURCE_OUT_OF_RANGE';
1809 x_msg_count := FND_MSG_PUB.Count_Msg;
1810 If x_msg_count = 1 THEN
1811 pa_interface_utils_pub.get_messages
1812 (p_encoded => FND_API.G_TRUE,
1813 p_msg_index => 1,
1814 p_msg_count => x_msg_count,
1815 p_msg_data => x_msg_data,
1816 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1817 p_msg_index_out => l_msg_index_out );
1818 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
1819 End If;
1820 WHEN l_stale_asmt_data THEN
1821 PA_UTILS.add_message('PA','PA_XC_RECORD_CHANGED');
1822 x_return_status := FND_API.G_RET_STS_ERROR;
1823 x_msg_data := 'PA_XC_RECORD_CHANGED';
1824 x_msg_count := FND_MSG_PUB.Count_Msg;
1825 If x_msg_count = 1 THEN
1826 pa_interface_utils_pub.get_messages
1827 (p_encoded => FND_API.G_TRUE,
1828 p_msg_index => 1,
1829 p_msg_count => x_msg_count,
1830 p_msg_data => x_msg_data,
1831 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1832 p_msg_index_out => l_msg_index_out );
1833 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
1834 End If;
1835 WHEN l_assignment_status_null THEN
1836 PA_UTILS.add_message('PA','PA_SCH_ASGN_STATUS_NULL');
1837 x_return_status := FND_API.G_RET_STS_ERROR;
1838 x_msg_data := 'PA_SCH_ASGN_STATUS_NULL';
1839 x_msg_count := FND_MSG_PUB.Count_Msg;
1840 If x_msg_count = 1 THEN
1841 pa_interface_utils_pub.get_messages
1842 (p_encoded => FND_API.G_TRUE,
1843 p_msg_index => 1,
1844 p_msg_count => x_msg_count,
1845 p_msg_data => x_msg_data,
1846 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1847 p_msg_index_out => l_msg_index_out );
1848 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
1849 End If;
1850 WHEN l_out_of_range_from_date THEN
1851 PA_UTILS.add_message('PA','PA_SCH_INVALID_FROM_DATE',
1852 'ASMT_TYPE_POSS', l_asgn_req_poss_text,
1853 'ASMT_TYPE', l_asgn_req_text);
1854 x_msg_data := 'PA_SCH_INVALID_FROM_DATE';
1855 x_return_status := FND_API.G_RET_STS_ERROR;
1856 x_msg_count := FND_MSG_PUB.Count_Msg;
1857 If x_msg_count = 1 THEN
1858 pa_interface_utils_pub.get_messages
1859 (p_encoded => FND_API.G_TRUE,
1860 p_msg_index => 1,
1861 p_msg_count => x_msg_count,
1862 p_msg_data => x_msg_data,
1863 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1864 p_msg_index_out => l_msg_index_out );
1865 x_msg_data := l_data; -- 4537865 : NOCOPY related change
1866 End If;
1867 WHEN l_out_of_range_to_date THEN
1868 PA_UTILS.add_message('PA','PA_SCH_INVALID_TO_DATE',
1869 'ASMT_TYPE_POSS', l_asgn_req_poss_text,
1870 'ASMT_TYPE', l_asgn_req_text);
1871 x_return_status := FND_API.G_RET_STS_ERROR;
1872 x_msg_data := 'PA_SCH_INVALID_TO_DATE';
1873 x_msg_count := FND_MSG_PUB.Count_Msg;
1874 If x_msg_count = 1 THEN
1875 pa_interface_utils_pub.get_messages
1876 (p_encoded => FND_API.G_TRUE,
1877 p_msg_index => 1,
1878 p_msg_count => x_msg_count,
1879 p_msg_data => x_msg_data,
1880 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1881 p_msg_index_out => l_msg_index_out );
1882 x_msg_data := l_data; -- 4537865 : NOCOPY related change
1883 End If;
1884 WHEN l_asgn_stus_not_for_proj_stus THEN
1885 PA_UTILS.Add_Message( p_app_short_name => 'PA',
1886 p_msg_name => 'PA_ASGN_STUS_NOT_FOR_PROJ_STUS',
1887 p_token1 => 'PROJ_STATUS',
1888 p_value1 => l_project_status_name,
1889 p_token2 => 'ASGN_STATUS',
1890 p_value2 => l_assignment_status_name);
1891 x_return_status := FND_API.G_RET_STS_ERROR;
1892 x_msg_data := 'PA_ASGN_STUS_NOT_FOR_PROJ_STUS';
1893 x_msg_count := FND_MSG_PUB.Count_Msg;
1894 If x_msg_count = 1 THEN
1895 pa_interface_utils_pub.get_messages
1896 (p_encoded => FND_API.G_TRUE,
1897 p_msg_index => 1,
1898 p_msg_count => x_msg_count,
1899 p_msg_data => x_msg_data,
1900 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1901 p_msg_index_out => l_msg_index_out );
1902 x_msg_data := l_data; -- 4537865 : NOCOPY related change
1903 End If;
1904 WHEN OTHERS THEN
1905 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_durarion API ..'||sqlerrm);
1906 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1907 x_msg_count := 1;
1908 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : Changed substr to substrb
1909 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
1910 p_procedure_name => 'change_duration');
1911 If x_msg_count = 1 THEN
1912 pa_interface_utils_pub.get_messages
1913 (p_encoded => FND_API.G_TRUE,
1914 p_msg_index => 1,
1915 p_msg_count => x_msg_count,
1916 p_msg_data => x_msg_data,
1917 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
1918 p_msg_index_out => l_msg_index_out );
1919 x_msg_data := l_data; -- 4537865 : NOCOPY related change
1920 End If;
1921 RAISE; -- This is optional depending on the needs
1922 END change_duration;
1923
1924
1925 -- Purpose : This procedure will change the hours of the passed assignment
1926 -- From its passed start date till the passed end date .
1927 -- It will change the hours either percentage or hours wise.
1928 -- Input parameters
1929 -- Parameters Type Required Description
1930 -- P_Project_Id NUMBER YES project id of the associated calendar
1931 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this assignment
1932 -- P_Assignment_Id NUMBER YES Assignment id of the changed hours assignment
1933 -- P_Assignment_Type VARCHAR2 YES It is type of the assignment e.g OPEN /STAFFED ASSIGNMENT
1934 -- P_Start_Date DATE YES starting date for the changed hours
1935 -- P_End_Date DATE YES ending date for the changed hours
1936 -- P_Assignment_Status_Code VARCHAR2 YES Status of the assignment e.g OPEN/CONFIRM/PROVISIONAL
1937 -- P_Change_Hours_Type_Code VARCHAR2 YES It is the type of code by which you want to change the hours
1938 -- e.g. HOURS/PERCENTAGE
1939 -- P_Hrs_Per_Day NUMBER YES It is the changed hours value
1940 -- P_Non_Working_Day_Flag VARCHAR2 YES It is the flag which indicate that the non working day should
1941 -- include or not e.g Y/N
1942 -- P_Calendar_Percent NUMBER YES if the hours type code is percentage then this is the percent
1943 -- age value for the changed hours
1944 -- P_Asgn_Start_Date DATE YES Start date of the assignment for which you want to
1945 -- change hours
1946 -- P_Asgn_End_Date DATE YES End date of the assignment for which you want to
1947 -- change hours
1948 --
1949
1950 PROCEDURE change_hours
1951 (
1952 p_record_version_number IN Number ,
1953 p_project_id IN Number ,
1954 p_calendar_id IN Number ,
1955 p_assignment_id IN Number ,
1956 p_assignment_type IN Varchar2 ,
1957 p_start_date IN date ,
1958 p_end_date IN date ,
1959 p_non_working_day_flag IN varchar2 := 'N',
1960 p_assignment_status_code IN Varchar2 ,
1961 p_change_hours_type_code IN varchar2 ,
1962 p_hrs_per_day IN Number ,
1963 p_calendar_percent IN Number ,
1964 p_change_calendar_type_code IN VARCHAR2 ,
1965 -- p_change_calendar_name IN VARCHAR2 ,
1966 p_change_calendar_id IN VARCHAR2 ,
1967 p_asgn_start_date IN DATE ,
1968 p_asgn_end_date IN DATE ,
1969 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
1970 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
1971 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
1972 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
1973 IS
1974 l_t_exception_id NUMBER;
1975 l_msg_index_out NUMBER;
1976 l_data VARCHAR2(2000) ; -- 4537865
1977 -- For error message tokens
1978 l_asgn_req_text VARCHAR2(30);
1979 l_a_an_text VARCHAR2(30);
1980 l_asgn_req_poss_text VARCHAR2(30);
1981 BEGIN
1982 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
1983
1984 --Clear the global PL/SQL message table
1985 IF (p_init_msg_list = FND_API.G_TRUE) THEN
1986 FND_MSG_PUB.initialize;
1987 END IF;
1988
1989 IF ( p_assignment_type = 'OPEN_ASSIGNMENT' ) THEN
1990 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_TEXT');
1991 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_A_TEXT');
1992 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_POSS_TEXT');
1993 ELSE
1994 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_TEXT');
1995 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_AN_TEXT');
1996 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_POSS_TEXT');
1997 END IF;
1998
1999 -- The passed dates for changing the hours should be between
2000 -- start and end date of the assignment.
2001 IF ((p_start_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date ) OR
2002 (p_end_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date )) THEN
2003 Raise l_out_of_range_date;
2004 END IF;
2005
2006 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_hours API ... ');
2007
2008 PA_SCH_EXCEPT_PKG.Insert_Rows(
2009 p_calendar_id => p_calendar_id ,
2010 p_assignment_id => p_assignment_id ,
2011 p_project_id => p_project_id ,
2012 p_schedule_type_code => p_assignment_type ,
2013 p_assignment_status_code => p_assignment_status_code ,
2014 p_exception_type_code => 'CHANGE_HOURS' ,
2015 p_start_date => p_start_date ,
2016 p_end_date => p_end_date ,
2017 p_resource_calendar_percent=> p_calendar_percent ,
2018 p_non_working_day_flag => p_non_working_day_flag ,
2019 p_change_hours_type_code => p_change_hours_type_code ,
2020 p_change_calendar_type_code => p_change_calendar_type_code ,
2021 -- p_change_calendar_name => p_change_calendar_name ,
2022 p_change_calendar_id => p_change_calendar_id ,
2023 p_monday_hours => p_hrs_per_day ,
2024 p_tuesday_hours => p_hrs_per_day ,
2025 p_wednesday_hours => p_hrs_per_day ,
2026 p_thursday_hours => p_hrs_per_day ,
2027 p_friday_hours => p_hrs_per_day ,
2028 p_saturday_hours => p_hrs_per_day ,
2029 p_sunday_hours => p_hrs_per_day ,
2030 x_exception_id => l_t_exception_id ,
2031 x_return_status => l_x_return_status ,
2032 x_msg_count => x_msg_count ,
2033 x_msg_data => x_msg_data );
2034
2035 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2036 -- Calling the change assignment schedule procedure
2037 -- which will generate the schedule after applying the hours change
2038 PA_SCHEDULE_PUB.change_asgn_schedule(
2039 p_record_version_number => p_record_version_number,
2040 p_assignment_id => p_assignment_id,
2041 p_project_id => p_project_id,
2042 p_exception_id => l_t_exception_id,
2043 x_return_status => l_x_return_status,
2044 x_msg_count => x_msg_count,
2045 x_msg_data => x_msg_data);
2046 END IF;
2047
2048 PA_SCHEDULE_UTILS.log_message(1,'End of the change_hours API ... ');
2049 x_return_status := l_x_return_status;
2050 x_msg_count := FND_MSG_PUB.Count_Msg;
2051 If x_msg_count = 1 THEN
2052 pa_interface_utils_pub.get_messages
2053 (p_encoded => FND_API.G_TRUE ,
2054 p_msg_index => 1,
2055 p_msg_count => x_msg_count ,
2056 p_msg_data => x_msg_data ,
2057 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2058 p_msg_index_out => l_msg_index_out );
2059 x_msg_data := l_data ; -- 4537865 : NOCOPY related Change
2060 End If;
2061
2062 EXCEPTION
2063 WHEN l_out_of_range_date THEN
2064 PA_UTILS.add_message('PA','PA_SCH_INVALID_FROM_TO_DATE',
2065 'ASMT_TYPE', l_asgn_req_text);
2066 x_return_status := FND_API.G_RET_STS_ERROR;
2067 x_msg_data := 'PA_SCH_INVALID_FROM_TO_DATE';
2068 x_msg_count := FND_MSG_PUB.Count_Msg;
2069 If x_msg_count = 1 THEN
2070 pa_interface_utils_pub.get_messages
2071 (p_encoded => FND_API.G_TRUE,
2072 p_msg_index => 1,
2073 p_msg_count => x_msg_count,
2074 p_msg_data => x_msg_data,
2075 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2076 p_msg_index_out => l_msg_index_out );
2077 x_msg_data := l_data ; -- 4537865 : NOCOPY related Change
2078 End If;
2079 WHEN OTHERS THEN
2080 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_hours API ..'||sqlerrm);
2081 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2082 x_msg_count := 1;
2083 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : Changed substr to substrb
2084 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
2085 p_procedure_name => 'change_duration');
2086 If x_msg_count = 1 THEN
2087 pa_interface_utils_pub.get_messages
2088 (p_encoded => FND_API.G_TRUE,
2089 p_msg_index => 1,
2090 p_msg_count => x_msg_count,
2091 p_msg_data => x_msg_data,
2092 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2093 p_msg_index_out => l_msg_index_out );
2094 x_msg_data := l_data ; -- 4537865 : NOCOPY related Change
2095 End If;
2096
2097 RAISE; -- This is optional depending on the needs
2098 END change_hours;
2099
2100 -- procedure : change_work_pattern
2101 -- Purpose : This procedure will change the work pattern of the passed assignment on the basis of your
2102 -- passed pattern i.e monady hours,tuesday hours and so on for the passed period only.
2103 -- Input parameters
2104 -- Parameters Type Required Description
2105 -- P_Project_Id NUMBER YES project id of the associated calendar
2106 -- P_Calendar_Id NUMBER YES Id for that calendar which is associated to this assignment
2107 -- P_Assignment_Id NUMBER YES Assignment id of the changed work pattern assignment
2108 -- P_Assignment_Type VARCHAR2 YES It is type of the assignment e.g OPEN /STAFFED ASSIGNMENT
2109 -- P_Start_Date DATE YES starting date for the changed work pattern
2110 -- P_End_Date DATE YES ending date for the changed work pattern
2111 -- P_Monday_Hours NUMBER YES No. of hours of this day
2112 -- P_Tuesday_Hours NUMBER YES No. of hours of this day
2113 -- P_Wednesday_Hours NUMBER YES No. of hours of this day
2114 -- P_Thursday_Hours NUMBER YES No. of hours of this day
2115 -- P_Friday_Hours NUMBER YES No. of hours of this day
2116 -- P_Saturday_Hours NUMBER YES No. of hours of this day
2117 -- P_Sunday_Hours NUMBER YES No. of hours of this day
2118 -- P_Asgn_Start_Date DATE YES Start date of the assignment for which you want to
2119 -- change work pattern
2120 -- P_Asgn_End_Date DATE YES End date of the assignment for which you want to
2121 -- change work pattern
2122 --
2123
2124 PROCEDURE change_work_pattern
2125 (
2126 p_record_version_number IN Number ,
2127 p_project_id IN Number ,
2128 p_calendar_id IN Number ,
2129 p_assignment_id IN Number ,
2130 p_assignment_type IN Varchar2 ,
2131 p_start_date IN date ,
2132 p_end_date IN date ,
2133 p_monday_hours IN Number := NULL,
2134 p_tuesday_hours IN Number := NULL,
2135 p_wednesday_hours IN Number := NULL,
2136 p_thursday_hours IN Number := NULL,
2137 p_friday_hours IN Number := NULL,
2138 p_saturday_hours IN Number := NULL,
2139 p_sunday_hours IN Number := NULL,
2140 p_asgn_start_date IN DATE ,
2141 p_asgn_end_date IN DATE ,
2142 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
2143 p_remove_conflict_flag IN VARCHAR2 := 'N',
2144 p_last_row_flag IN VARCHAR2 := 'Y',
2145 p_generate_timeline_flag IN VARCHAR2 := 'Y', --Unilog
2146 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
2147 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
2148 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
2149 IS
2150 l_t_exception_id NUMBER; -- Temp variable
2151 l_p_monday_hours NUMBER;
2152 l_p_tuesday_hours NUMBER;
2153 l_p_wednesday_hours NUMBER;
2154 l_p_thursday_hours NUMBER;
2155 l_p_friday_hours NUMBER;
2156 l_p_saturday_hours NUMBER;
2157 l_p_sunday_hours NUMBER;
2158 l_msg_index_out NUMBER;
2159
2160 -- For error message tokens
2161 l_asgn_req_text VARCHAR2(30);
2162 l_a_an_text VARCHAR2(30);
2163 l_asgn_req_poss_text VARCHAR2(30);
2164
2165 l_data VARCHAR2(200); -- 4537865
2166 BEGIN
2167 -- Storing status success to track the error
2168 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
2169
2170 --Clear the global PL/SQL message table
2171 IF (p_init_msg_list = FND_API.G_TRUE) THEN
2172 FND_MSG_PUB.initialize;
2173 END IF;
2174
2175 IF ( p_assignment_type = 'OPEN_ASSIGNMENT' ) THEN
2176 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_TEXT');
2177 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_A_TEXT');
2178 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_POSS_TEXT');
2179 ELSE
2180 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_TEXT');
2181 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_AN_TEXT');
2182 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_POSS_TEXT');
2183 END IF;
2184
2185
2186 -- The passed start date and end date should be between the
2187 -- passed start and end date of the assignmente */
2188 IF ((p_start_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date ) OR
2189 (p_end_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date )) THEN
2190 RAISE l_out_of_range_date;
2191 END IF;
2192
2193 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_work_pattern API ... ');
2194
2195 l_p_monday_hours := p_monday_hours;
2196 l_p_tuesday_hours := p_tuesday_hours;
2197 l_p_wednesday_hours := p_wednesday_hours;
2198 l_p_thursday_hours := p_thursday_hours;
2199 l_p_friday_hours := p_friday_hours;
2200 l_p_saturday_hours := p_saturday_hours;
2201 l_p_sunday_hours := p_sunday_hours;
2202
2203
2204 /*
2205 -- The passing day hours should not beyond the 24 hours and should not null
2206 IF (p_monday_hours IS NULL ) THEN
2207 l_p_monday_hours := 0;
2208 ELSE
2209 l_p_monday_hours := p_monday_hours;
2210 END IF;
2211
2212 IF (p_tuesday_hours IS NULL ) THEN
2213 l_p_tuesday_hours := 0;
2214 ELSE
2215 l_p_tuesday_hours := p_tuesday_hours;
2216 END IF;
2217
2218 IF (p_wednesday_hours IS NULL ) THEN
2219 l_p_wednesday_hours := 0;
2220 ELSE
2221 l_p_wednesday_hours := p_wednesday_hours;
2222 END IF;
2223
2224 IF (p_thursday_hours IS NULL ) THEN
2225 l_p_thursday_hours := 0;
2226 ELSE
2227 l_p_thursday_hours := p_thursday_hours;
2228 END IF;
2229
2230 IF (p_friday_hours IS NULL ) THEN
2231 l_p_friday_hours := 0;
2232 ELSE
2233 l_p_friday_hours := p_friday_hours;
2234 END IF;
2235
2236 IF (p_saturday_hours IS NULL ) THEN
2237 l_p_saturday_hours := 0;
2238 ELSE
2239 l_p_saturday_hours := p_saturday_hours;
2240 END IF;
2241
2242 IF (p_sunday_hours IS NULL ) THEN
2243 l_p_sunday_hours := 0;
2244 ELSE
2245 l_p_sunday_hours := p_sunday_hours;
2246 END IF;
2247 */
2248
2249 -- When called by mass_update_schedule, null working hours are passed in as -99.
2250 -- Need to convert -99 back to null.
2251 IF p_monday_hours = -99 THEN
2252 l_p_monday_hours := null;
2253 END IF;
2254 IF p_tuesday_hours = -99 THEN
2255 l_p_tuesday_hours := null;
2256 END IF;
2257 IF p_wednesday_hours = -99 THEN
2258 l_p_wednesday_hours := null;
2259 END IF;
2260 IF p_thursday_hours = -99 THEN
2261 l_p_thursday_hours := null;
2262 END IF;
2263 IF p_friday_hours = -99 THEN
2264 l_p_friday_hours := null;
2265 END IF;
2266 IF p_saturday_hours = -99 THEN
2267 l_p_saturday_hours := null;
2268 END IF;
2269 IF p_sunday_hours = -99 THEN
2270 l_p_sunday_hours := null;
2271 END IF;
2272
2273 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub', 'Calling pa_sch_except_pkg.insert_rows', 6);
2274
2275 PA_SCH_EXCEPT_PKG.Insert_Rows(
2276 p_calendar_id => p_calendar_id ,
2277 p_assignment_id => p_assignment_id ,
2278 p_project_id => p_project_id ,
2279 p_schedule_type_code => p_assignment_type ,
2280 p_exception_type_code => 'CHANGE_WORK_PATTERN' ,
2281 p_start_date => p_start_date ,
2282 p_end_date => p_end_date ,
2283 p_monday_hours => l_p_monday_hours ,
2284 p_tuesday_hours => l_p_tuesday_hours ,
2285 p_wednesday_hours => l_p_wednesday_hours ,
2286 p_thursday_hours => l_p_thursday_hours ,
2287 p_friday_hours => l_p_friday_hours ,
2288 p_saturday_hours => l_p_saturday_hours ,
2289 p_sunday_hours => l_p_sunday_hours ,
2290 x_exception_id => l_t_exception_id ,
2291 x_return_status => l_x_return_status ,
2292 x_msg_count => x_msg_count ,
2293 x_msg_data => x_msg_data );
2294
2295 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS AND p_last_row_flag = 'Y') THEN
2296 -- Calling the change assignment schedule procedure that will generate the changed schedule
2297 -- of the passed assignment for the given exception i.e change work patern
2298 pa_schedule_utils.debug('pa.plsql.pa_schedule_pub', 'Calling change_asgn_schedule', 6);
2299 PA_SCHEDULE_PUB.change_asgn_schedule(
2300 p_record_version_number => p_record_version_number,
2301 p_assignment_id => p_assignment_id,
2302 p_project_id => p_project_id,
2303 p_exception_id => NULL,
2304 p_remove_conflict_flag => p_remove_conflict_flag,
2305 p_generate_timeline_flag => p_generate_timeline_flag,--Unilog
2306 x_return_status => l_x_return_status,
2307 x_msg_count => x_msg_count,
2308 x_msg_data => x_msg_data);
2309 END IF;
2310
2311 PA_SCHEDULE_UTILS.log_message(1,'End of the change_work_pattern API ... ');
2312 x_return_status := l_x_return_status;
2313
2314 x_msg_count := FND_MSG_PUB.Count_Msg;
2315 If x_msg_count = 1 THEN
2316 pa_interface_utils_pub.get_messages
2317 (p_encoded => FND_API.G_TRUE ,
2318 p_msg_index => 1,
2319 p_msg_count => x_msg_count ,
2320 p_msg_data => x_msg_data ,
2321 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2322 p_msg_index_out => l_msg_index_out );
2323 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2324 End If;
2325
2326 EXCEPTION
2327 WHEN l_out_of_range_date THEN
2328 PA_UTILS.add_message('PA','PA_SCH_INVALID_FROM_TO_DATE',
2329 'ASMT_TYPE', l_asgn_req_text);
2330 x_return_status := FND_API.G_RET_STS_ERROR;
2331 x_msg_data := 'PA_SCH_INVALID_FROM_TO_DATE';
2332 x_msg_count := FND_MSG_PUB.Count_Msg;
2333 If x_msg_count = 1 THEN
2334 pa_interface_utils_pub.get_messages
2335 (p_encoded => FND_API.G_TRUE,
2336 p_msg_index => 1,
2337 p_msg_count => x_msg_count,
2338 p_msg_data => x_msg_data,
2339 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2340 p_msg_index_out => l_msg_index_out );
2341 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2342 End If;
2343 WHEN OTHERS THEN
2344 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_work_pattern API ..'||sqlerrm);
2345 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2346 x_msg_count := 1;
2347 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : Replaced substr with substrb
2348 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
2349 p_procedure_name => 'change_work_pattern');
2350 If x_msg_count = 1 THEN
2351 pa_interface_utils_pub.get_messages
2352 (p_encoded => FND_API.G_TRUE,
2353 p_msg_index => 1,
2354 p_msg_count => x_msg_count,
2355 p_msg_data => x_msg_data,
2356 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2357 p_msg_index_out => l_msg_index_out );
2358 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2359 End If;
2360
2361 RAISE; -- This is optional depending on the needs
2362 END change_work_pattern;
2363
2364
2365
2366 -- Procedure : change_status
2367 -- Purpose : This procedure will change tha status of the passed assignment i.e provisional.confirm
2368 -- etc. It will change the status only for the passed period i.e start date and end date.
2369 -- Input parameters
2370 -- Parameters Type Required Description
2371 -- P_Project_Id NUMBER YES project id of the associated calendar
2372 -- P_Calendar_Id NUMBER NO Id for that calendar which is associated to this assignment
2373 -- P_Assignment_Id NUMBER YES Assignment id of the changed status assignment
2374 -- P_Assignment_Type VARCHAR2 YES It is type of the assignment e.g OPEN /STAFFED ASSIGNMENT
2375 -- P_Status_Type VARCHAR2 YES It is status type.
2376 -- P_Start_Date DATE YES starting date for the changed status
2377 -- P_End_Date DATE YES ending date for the changed status
2378 -- P_Assignment_Status_Code VARCHAR2 YES Status of the assignment e.g OPEN/CONFIRM/PROVISIONAL
2379 -- P_Asgn_Start_Date DATE YES Start date of the assignment for which you want to
2380 -- change status
2381 -- P_Asgn_End_Date DATE YES End date of the assignment for which you want to
2382 -- change status
2383 -- p_save_to_hist VARCHAR2 NO If TRUE, then the change_approval_status proc.
2384 -- is called and the change is saved to the
2385 -- exceptions history. This is the case when
2386 -- the procedure is called from the UI.
2387 -- If FALSE, the the change_approval_status proc.
2388 -- is not called and the change is not saved to
2389 -- the exceptions history. FALSE should be used in
2390 -- all cases except when called from UI.
2391 --
2392
2393 PROCEDURE change_status
2394 (
2395 p_record_version_number IN Number ,
2396 p_project_id IN Number ,
2397 p_calendar_id IN Number ,
2398 p_assignment_id IN Number ,
2399 p_assignment_type IN Varchar2 ,
2400 p_status_type IN Varchar2 ,
2401 p_start_date IN date ,
2402 p_end_date IN date ,
2403 p_assignment_status_code IN Varchar2 ,
2404 p_asgn_start_date IN DATE ,
2405 p_asgn_end_date IN DATE ,
2406 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
2407 p_save_to_hist IN VARCHAR2 := FND_API.G_TRUE,
2408 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
2409 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
2410 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
2411 IS
2412 l_t_check_cancel VARCHAR2(1); --Temp variable
2413 l_invalid_asgn_cancelled_date EXCEPTION;
2414 l_stale_asmt_data EXCEPTION;
2415 l_status_type VARCHAR2(30);
2416 l_error_message_code VARCHAR2(50);
2417 l_record_version_number NUMBER;
2418 l_person_id NUMBER;
2419 l_msg_index_out NUMBER;
2420 l_exception_id NUMBER;
2421 l_return_status VARCHAR2(1);
2422 l_assignment_status_name pa_project_statuses.project_status_name%TYPE;
2423
2424 -- For error message tokens
2425 l_asgn_req_text VARCHAR2(30);
2426 l_a_an_text VARCHAR2(30);
2427 l_asgn_req_poss_text VARCHAR2(30);
2428 l_data VARCHAR2(2000); -- 4537865
2429 -- For retrieving project_status_name
2430 -- 3054787: Select from tables directly to improve performance.
2431 CURSOR get_project_status_name IS
2432 SELECT pps.project_status_name
2433 FROM pa_projects_all ppa, pa_project_statuses pps
2434 WHERE ppa.project_id = p_project_id
2435 AND ppa.project_status_code = pps.project_status_code;
2436
2437 l_project_status_name pa_project_statuses.project_status_name%TYPE;
2438
2439 BEGIN
2440 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
2441
2442 --Clear the global PL/SQL message table
2443 IF FND_API.TO_BOOLEAN( p_init_msg_list ) THEN
2444 FND_MSG_PUB.initialize;
2445 END IF;
2446
2447 IF ( p_assignment_type = 'OPEN_ASSIGNMENT' ) THEN
2448 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_TEXT');
2449 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_A_TEXT');
2450 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_POSS_TEXT');
2451 ELSE
2452 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_TEXT');
2453 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_AN_TEXT');
2454 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_POSS_TEXT');
2455 END IF;
2456
2457 PA_SCHEDULE_UTILS.log_message(1,'Start of Change_Status ... ');
2458
2459 -- p_assignment_status_code should not be null
2460 IF (p_assignment_status_code is NULL) THEN
2461 PA_UTILS.Add_Message ('PA', 'PA_SCH_ASGN_STATUS_NULL'); -- is this message okay?
2462 RAISE FND_API.G_EXC_ERROR;
2463 END IF;
2464
2465 -- The passed dates should fall between the assignment start date and assignment end date */
2466 IF ((p_start_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date ) OR
2467 (p_end_date NOT BETWEEN p_asgn_start_date AND p_asgn_end_date )) THEN
2468 Raise l_out_of_range_date;
2469 END IF;
2470
2471 -- New Project Status Control added for PRM v1.0.2.
2472 -- If extending the staffed assignment duration with a new status, the status should be allowed for the status of the project this assignment belongs to.
2473 IF (p_assignment_status_code IS NOT NULL) AND (p_assignment_type <> 'OPEN_ASSIGNMENT') THEN
2474 l_return_status := PA_ASSIGNMENT_UTILS.is_asgmt_allow_stus_ctl_check(
2475 p_asgmt_status_code => p_assignment_status_code,
2476 p_project_id => p_project_id,
2477 p_add_message => 'N');
2478
2479 IF l_return_status <> 'Y' THEN
2480 OPEN get_project_status_name;
2481 FETCH get_project_status_name INTO l_project_status_name;
2482 CLOSE get_project_status_name;
2483
2484 SELECT project_status_name
2485 INTO l_assignment_status_name
2486 FROM pa_project_statuses
2487 WHERE project_status_code = p_assignment_status_code;
2488
2489 RAISE l_asgn_stus_not_for_proj_stus;
2490 END IF;
2491 END IF;
2492
2493 -- Added this code , since status_type is derived parameter.
2494 IF p_status_type is NULL then
2495 if ( p_assignment_type = 'OPEN_ASSIGNMENT' ) then
2496 l_status_type := 'OPEN_ASGMT';
2497 else
2498 l_status_type := 'STAFFED_ASGMT';
2499 end if;
2500 else
2501 l_status_type := p_status_type;
2502 end if;
2503
2504 PA_SCHEDULE_UTILS.log_message(1,'Calling Assignment API ... ');
2505
2506 -- Partially cancelled assignments are now possible, so we are removing the
2507 -- check.
2508
2509 -- Checking the assignment that if it is cancelled then it will not be partialy cancelled it
2510 -- should be fully cancelled
2511 -- IF (p_assignment_type = 'OPEN_ASSIGNMENT') THEN
2512 -- l_t_check_cancel := PA_ASSIGNMENT_UTILS.is_open_asgmt_cancelled(
2513 -- p_status_code => p_assignment_status_code,
2514 -- p_status_type => l_status_type);
2515 -- IF(UPPER(l_t_check_cancel) = 'Y') THEN
2516 -- IF ((p_start_date <> p_asgn_start_date) OR
2517 -- (p_end_date <> p_asgn_end_date)) THEN
2518 -- RAISE l_invalid_asgn_cancelled_date;
2519 -- END IF;
2520 -- END IF;
2521 -- ELSIF (p_assignment_type = 'STAFFED_ASSIGNMENT') THEN
2522 -- l_t_check_cancel := PA_ASSIGNMENT_UTILS.is_staffed_asgmt_cancelled(
2523 -- p_status_code => p_assignment_status_code,
2524 -- p_status_type => l_status_type);
2525 -- IF(UPPER(l_t_check_cancel) = 'Y') THEN
2526 -- IF ((p_start_date <> p_asgn_start_date) OR
2527 -- (p_end_date <> p_asgn_end_date)) THEN
2528 -- RAISE l_invalid_asgn_cancelled_date;
2529 -- END IF;
2530 -- END IF;
2531 -- END IF;
2532 -- */
2533
2534 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_status API ... ');
2535 PA_SCH_EXCEPT_PKG.Insert_Rows(
2536 p_calendar_id => p_calendar_id ,
2537 p_assignment_id => p_assignment_id ,
2538 p_project_id => p_project_id ,
2539 p_schedule_type_code => p_assignment_type ,
2540 p_assignment_status_code => p_assignment_status_code ,
2541 p_exception_type_code => 'CHANGE_STATUS' ,
2542 p_start_date => p_start_date ,
2543 p_end_date => p_end_date ,
2544 x_exception_id => l_exception_id ,
2545 x_return_status => l_x_return_status ,
2546 x_msg_count => x_msg_count ,
2547 x_msg_data => x_msg_data );
2548
2549 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2550 -- Calling the procedure change assignment schedule that will
2551 -- generate the changed schedule for the
2552 -- passed asignment only for the passed period
2553 PA_SCHEDULE_PUB.change_asgn_schedule(
2554 p_record_version_number => p_record_version_number,
2555 p_assignment_id => p_assignment_id,
2556 p_project_id => p_project_id,
2557 p_exception_id => l_exception_id,
2558 p_save_to_hist => p_save_to_hist,
2559 x_return_status => l_x_return_status,
2560 x_msg_count => x_msg_count,
2561 x_msg_data => x_msg_data);
2562 END IF;
2563
2564 PA_SCHEDULE_UTILS.log_message(1,'End of the change_status API ... ');
2565 x_return_status := l_x_return_status;
2566
2567 x_msg_count := FND_MSG_PUB.Count_Msg;
2568 If x_msg_count = 1 THEN
2569 pa_interface_utils_pub.get_messages
2570 (p_encoded => FND_API.G_TRUE ,
2571 p_msg_index => 1,
2572 p_msg_count => x_msg_count ,
2573 p_msg_data => x_msg_data ,
2574 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2575 p_msg_index_out => l_msg_index_out );
2576 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2577 End If;
2578
2579 EXCEPTION
2580 WHEN FND_API.G_EXC_ERROR THEN
2581 x_return_status := FND_API.G_RET_STS_ERROR;
2582 x_msg_count := FND_MSG_PUB.Count_Msg;
2583
2584 IF x_msg_count = 1 THEN
2585 pa_interface_utils_pub.get_messages
2586 (p_encoded => FND_API.G_TRUE,
2587 p_msg_index => 1,
2588 p_data => x_msg_data,
2589 p_msg_index_out => l_msg_index_out );
2590 END IF;
2591 WHEN l_stale_asmt_data THEN
2592 PA_UTILS.add_message('PA','PA_XC_RECORD_CHANGED');
2593 x_return_status := FND_API.G_RET_STS_ERROR;
2594 x_msg_data := 'PA_XC_RECORD_CHANGED';
2595 x_msg_count := FND_MSG_PUB.Count_Msg;
2596 If x_msg_count = 1 THEN
2597 pa_interface_utils_pub.get_messages
2598 (p_encoded => FND_API.G_TRUE,
2599 p_msg_index => 1,
2600 p_msg_count => x_msg_count,
2601 p_msg_data => x_msg_data,
2602 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2603 p_msg_index_out => l_msg_index_out );
2604 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2605 End If;
2606 WHEN l_invalid_asgn_cancelled_date THEN
2607 PA_UTILS.add_message('PA','PA_INVALID_ASGN_CANCELLED_DATE',
2608 'ASMT_TYPE_POSS', l_asgn_req_poss_text,
2609 'A_OR_AN', l_a_an_text,
2610 'ASMT_TYPE', l_asgn_req_text);
2611 x_return_status := FND_API.G_RET_STS_ERROR;
2612 x_msg_data := 'PA_INVALID_ASGN_CANCELLED_DATE';
2613 x_msg_count := FND_MSG_PUB.Count_Msg;
2614 If x_msg_count = 1 THEN
2615 pa_interface_utils_pub.get_messages
2616 (p_encoded => FND_API.G_TRUE,
2617 p_msg_index => 1,
2618 p_msg_count => x_msg_count,
2619 p_msg_data => x_msg_data,
2620 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2621 p_msg_index_out => l_msg_index_out );
2622 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2623 End If;
2624 WHEN l_out_of_range_date THEN
2625 PA_UTILS.add_message('PA','PA_SCH_INVALID_FROM_TO_DATE',
2626 'ASMT_TYPE', l_asgn_req_text);
2627 x_return_status := FND_API.G_RET_STS_ERROR;
2628 x_msg_data := 'PA_SCH_INVALID_FROM_TO_DATE';
2629 x_msg_count := FND_MSG_PUB.Count_Msg;
2630 If x_msg_count = 1 THEN
2631 pa_interface_utils_pub.get_messages
2632 (p_encoded => FND_API.G_TRUE,
2633 p_msg_index => 1,
2634 p_msg_count => x_msg_count,
2635 p_msg_data => x_msg_data,
2636 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2637 p_msg_index_out => l_msg_index_out );
2638 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2639 End If;
2640 WHEN l_asgn_stus_not_for_proj_stus THEN
2641 PA_UTILS.Add_Message( p_app_short_name => 'PA',
2642 p_msg_name => 'PA_ASGN_STUS_NOT_FOR_PROJ_STUS',
2643 p_token1 => 'PROJ_STATUS',
2644 p_value1 => l_project_status_name,
2645 p_token2 => 'ASGN_STATUS',
2646 p_value2 => l_assignment_status_name);
2647 x_return_status := FND_API.G_RET_STS_ERROR;
2648 x_msg_data := 'PA_ASGN_STUS_NOT_FOR_PROJ_STUS';
2649 x_msg_count := FND_MSG_PUB.Count_Msg;
2650 If x_msg_count = 1 THEN
2651 pa_interface_utils_pub.get_messages
2652 (p_encoded => FND_API.G_TRUE,
2653 p_msg_index => 1,
2654 p_msg_count => x_msg_count,
2655 p_msg_data => x_msg_data,
2656 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2657 p_msg_index_out => l_msg_index_out );
2658 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2659 End If;
2660 WHEN OTHERS THEN
2661 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2662 x_msg_count := 1;
2663 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 Replaced substr with substrb
2664 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_status API ..'||sqlerrm);
2665 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
2666 p_procedure_name => 'change_status');
2667 If x_msg_count = 1 THEN
2668 pa_interface_utils_pub.get_messages
2669 (p_encoded => FND_API.G_TRUE,
2670 p_msg_index => 1,
2671 p_msg_count => x_msg_count,
2672 p_msg_data => x_msg_data,
2673 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2674 p_msg_index_out => l_msg_index_out );
2675 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2676 End If;
2677 RAISE; -- This is optional depending on the needs
2678 END change_status;
2679
2680 --
2681 -- Procedure : change_calendar
2682 -- Purpose : This procedure will change the calendar for the passed assignment But it will
2683 -- change the calendar only for the passed period i.e start date and end date.
2684 -- Input parameters
2685 -- Parameters Type Required Description
2686 -- P_Project_Id NUMBER YES project id of the associated calendar
2687 -- P_Calendar_Id NUMBER YES Id for that calendar which is associated to this assignment
2688 -- P_Calendar_Name VARCHAR2 YES It is the name of the calendar
2689 -- P_Assignment_Id NUMBER YES Assignment id of the changed calendar assignment
2690 -- P_Assignment_Type VARCHAR2 YES It is type of the assignment e.g OPEN /STAFFED ASSIGNMENT
2691 -- P_Start_Date DATE YES starting date for the changed calendar
2692 -- P_End_Date DATE YES ending date for the changed calendar
2693 -- P_Asgn_Start_Date DATE YES Start date of the assignment for which you want to
2694 -- change calendar
2695 -- P_Asgn_End_Date DATE YES End date of the assignment for which you want to
2696 -- change calendar
2697 --
2698
2699 PROCEDURE change_calendar
2700 (
2701 p_record_version_number IN Number ,
2702 p_project_id IN Number ,
2703 p_calendar_id IN Number ,
2704 p_calendar_name IN varchar2 ,
2705 p_assignment_id IN Number ,
2706 p_assignment_type IN Varchar2 ,
2707 p_start_date IN date ,
2708 p_end_date IN date ,
2709 p_asgn_start_date IN DATE ,
2710 p_asgn_end_date IN DATE ,
2711 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
2712 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
2713 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
2714 IS
2715 l_t_exception_id NUMBER; -- temp variable
2716 l_calendar_id NUMBER; -- temp variable
2717 l_invalid_duplicate_cal_name EXCEPTION;
2718 l_msg_index_out NUMBER;
2719 l_data VARCHAR2(2000) ; -- 4537865
2720 -- For error message tokens
2721 l_asgn_req_text VARCHAR2(30);
2722 l_a_an_text VARCHAR2(30);
2723 l_asgn_req_poss_text VARCHAR2(30);
2724 BEGIN
2725 -- storing the status success to track the error
2726 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
2727
2728 --Clear the global PL/SQL message table
2729 fnd_msg_pub.initialize;
2730
2731 IF ( p_assignment_type = 'OPEN_ASSIGNMENT' ) THEN
2732 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_TEXT');
2733 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_A_TEXT');
2734 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_REQUIREMENT_POSS_TEXT');
2735 ELSE
2736 l_asgn_req_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_TEXT');
2737 l_a_an_text := FND_MESSAGE.GET_STRING('PA','PA_AN_TEXT');
2738 l_asgn_req_poss_text := FND_MESSAGE.GET_STRING('PA','PA_ASSIGNMENT_POSS_TEXT');
2739 END IF;
2740
2741 -- Current functionality allows user to change the work patern by specifing the calendar
2742 -- for the whole period so we don't need to check the start /end date for null.
2743 -- End date or Start date or both should not be null for the change calendar
2744 -- IF ((p_start_date IS NULL) OR (p_end_date IS NULL)) THEN
2745 -- RAISE l_from_to_date_null;
2746 -- END IF;
2747
2748 -- If the user select calendar name only then taking the calendar id
2749 IF (p_calendar_id IS NULL ) THEN
2750 BEGIN
2751 SELECT calendar_id
2752 INTO l_calendar_id
2753 FROM jtf_calendars_vl
2754 WHERE calendar_name = p_calendar_name;
2755
2756
2757 x_msg_count := FND_MSG_PUB.Count_Msg;
2758 If x_msg_count = 1 THEN
2759 pa_interface_utils_pub.get_messages
2760 (p_encoded => FND_API.G_TRUE ,
2761 p_msg_index => 1,
2762 p_msg_count => x_msg_count ,
2763 p_msg_data => x_msg_data ,
2764 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2765 p_msg_index_out => l_msg_index_out );
2766 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2767 End If;
2768
2769 EXCEPTION
2770 WHEN NO_DATA_FOUND or TOO_MANY_ROWS THEN
2771 RAISE l_invalid_duplicate_cal_name;
2772 WHEN OTHERS THEN
2773 Raise;
2774 END;
2775 ELSE
2776 l_calendar_id := p_calendar_id;
2777 END IF;
2778
2779 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_calendar API ... ');
2780 PA_SCH_EXCEPT_PKG.Insert_Rows(
2781 p_calendar_id => l_calendar_id ,
2782 p_assignment_id => p_assignment_id ,
2783 p_project_id => p_project_id ,
2784 p_schedule_type_code => p_assignment_type ,
2785 p_exception_type_code => 'CHANGE_CALENDAR' ,
2786 p_start_date => p_start_date ,
2787 p_end_date => p_end_date ,
2788 x_exception_id => l_t_exception_id ,
2789 x_return_status => l_x_return_status ,
2790 x_msg_count => x_msg_count ,
2791 x_msg_data => x_msg_data );
2792
2793 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
2794 -- Calling the change assignment schedule procedure that will generate the changed schedule
2795 -- according to the passed calendar but only for given period
2796 PA_SCHEDULE_PUB.change_asgn_schedule(
2797 p_record_version_number => p_record_version_number,
2798 p_assignment_id => p_assignment_id,
2799 p_project_id => p_project_id,
2800 p_exception_id => l_t_exception_id,
2801 x_return_status => l_x_return_status,
2802 x_msg_count => x_msg_count,
2803 x_msg_data => x_msg_data);
2804 END IF;
2805
2806 PA_SCHEDULE_UTILS.log_message(1,'End of the change_calendar API ... ');
2807 x_return_status := l_x_return_status;
2808
2809 x_msg_count := FND_MSG_PUB.Count_Msg;
2810 If x_msg_count = 1 THEN
2811 pa_interface_utils_pub.get_messages
2812 (p_encoded => FND_API.G_TRUE ,
2813 p_msg_index => 1,
2814 p_msg_count => x_msg_count ,
2815 p_msg_data => x_msg_data ,
2816 p_data => l_data, -- 4537865 : Replaced x_msg_data with l_data
2817 p_msg_index_out => l_msg_index_out );
2818 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2819 End If;
2820
2821
2822 EXCEPTION
2823 WHEN l_invalid_duplicate_cal_name THEN
2824 PA_UTILS.add_message('PA','PA_CALENDAR_INVALID_AMBIGOUS');
2825 x_return_status := FND_API.G_RET_STS_ERROR;
2826 x_msg_data := 'PA_CALENDAR_INVALID_AMBIGOUS';
2827 x_msg_count := FND_MSG_PUB.Count_Msg;
2828 If x_msg_count = 1 THEN
2829 pa_interface_utils_pub.get_messages
2830 (p_encoded => FND_API.G_TRUE,
2831 p_msg_index => 1,
2832 p_msg_count => x_msg_count,
2833 p_msg_data => x_msg_data,
2834 p_data => l_data, -- 4537865 :Replaced x_msg_data with l_data
2835 p_msg_index_out => l_msg_index_out );
2836 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2837 End If;
2838 WHEN l_from_to_date_null THEN
2839 PA_UTILS.add_message('PA','PA_SCH_FROM_TO_DATE_NULL');
2840 x_return_status := FND_API.G_RET_STS_ERROR;
2841 x_msg_data := 'PA_SCH_FROM_TO_DATE_NULL';
2842 x_msg_count := FND_MSG_PUB.Count_Msg;
2843 If x_msg_count = 1 THEN
2844 pa_interface_utils_pub.get_messages
2845 (p_encoded => FND_API.G_TRUE,
2846 p_msg_index => 1,
2847 p_msg_count => x_msg_count,
2848 p_msg_data => x_msg_data,
2849 p_data => l_data, -- 4537865 :Replaced x_msg_data with l_data
2850 p_msg_index_out => l_msg_index_out );
2851 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2852 End If;
2853 WHEN OTHERS THEN
2854 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_calendar API ..'||sqlerrm);
2855 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2856 x_msg_count := 1;
2857 x_msg_data := substrb(SQLERRM,1,240); -- Changed substr to substrb : 4537865
2858 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
2859 p_procedure_name => 'change_calendar');
2860 If x_msg_count = 1 THEN
2861 pa_interface_utils_pub.get_messages
2862 (p_encoded => FND_API.G_TRUE,
2863 p_msg_index => 1,
2864 p_msg_count => x_msg_count,
2865 p_msg_data => x_msg_data,
2866 p_data => l_data, -- 4537865 :Replaced x_msg_data with l_data
2867 p_msg_index_out => l_msg_index_out );
2868 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2869 End If;
2870 END change_calendar;
2871
2872
2873
2874 -- Procedure : change_schedule
2875 -- Purpose : Once the schedule is created for the assignment it cane be changed by this procedure on the basis of its exception.
2876 -- This procedure does not seem to be used.
2877
2878 PROCEDURE change_schedule
2879 (x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2880 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2881 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
2882 IS
2883 l_msg_index_out NUMBER;
2884 l_data varchar2(2000) ; -- 4537865
2885
2886 -- This cursor will select the distinct assignment id
2887 CURSOR csr_sch_excp IS
2888 SELECT distinct a.assignment_id, b.record_version_number, b.project_id
2889 FROM pa_schedule_exceptions a , pa_project_assignments b
2890 WHERE a.assignment_id = b.assignment_id
2891 ORDER by a.assignment_id;
2892 BEGIN
2893 -- store the status success to track the error
2894 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
2895
2896 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_schedule API ... ');
2897
2898 FOR rec_sch_excp IN csr_sch_excp LOOP
2899 PA_SCHEDULE_UTILS.log_message(1,
2900 'Schedule Exception table - assignment Id :'||
2901 to_char(rec_sch_excp.assignment_id));
2902 -- Calling the procedure change_asgn_schedule that will generate the
2903 -- change schedule for the passed start date and end date
2904 PA_SCHEDULE_PUB.change_asgn_schedule(
2905 p_record_version_number => rec_sch_excp.record_version_number,
2906 p_assignment_id => rec_sch_excp.assignment_id,
2907 p_project_id => rec_sch_excp.project_id,
2908 p_exception_id => null,
2909 x_return_status => l_x_return_status,
2910 x_msg_count => x_msg_count,
2911 x_msg_data => x_msg_data);
2912 END LOOP;
2913 PA_SCHEDULE_UTILS.log_message(1,'End of the change_schedule API ... ');
2914
2915 x_return_status := l_x_return_status;
2916
2917 x_msg_count := FND_MSG_PUB.Count_Msg;
2918 If x_msg_count = 1 THEN
2919 pa_interface_utils_pub.get_messages
2920 (p_encoded => FND_API.G_TRUE ,
2921 p_msg_index => 1,
2922 p_msg_count => x_msg_count ,
2923 p_msg_data => x_msg_data ,
2924 p_data => l_data, -- 4537865 :Replaced x_msg_data with l_data
2925 p_msg_index_out => l_msg_index_out );
2926 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2927 End If;
2928
2929 EXCEPTION
2930 WHEN OTHERS THEN
2931 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_schedule API ..'||sqlerrm);
2932 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2933 x_msg_count := 1;
2934 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : Replaced substr usage with substrb
2935 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
2936 p_procedure_name => 'change_schedule');
2937 If x_msg_count = 1 THEN
2938 pa_interface_utils_pub.get_messages
2939 (p_encoded => FND_API.G_TRUE ,
2940 p_msg_index => 1,
2941 p_msg_count => x_msg_count ,
2942 p_msg_data => x_msg_data ,
2943 p_data => l_data, -- 4537865 :Replaced x_msg_data with l_data
2944 p_msg_index_out => l_msg_index_out );
2945 x_msg_data := l_data ; -- 4537865 : NOCOPY related change
2946 End If;
2947 RAISE; -- This is optional depending on the needs
2948 END change_schedule;
2949
2950
2951
2952 -- Procedure : change_asgn_schedule
2953 -- Purpose : This procedure will be called from each schedule change page via
2954 -- workflow. This procedure will apply the exceptions for the assignment
2955 -- on the assignment schedules.
2956 -- Input parameters
2957 -- Parameters Type Required Description
2958 -- P_Assignment_Id NUMBER YES Assignment id for the changed assignment
2959 -- P_Exception_Id NUMBER YES Exception id for changing ths chedule of the
2960 -- assiciated assignment
2961 -- p_save_to_hist VARCHAR2 NO If TRUE, then the change_approval_status proc.
2962 -- is called and the change is saved to the
2963 -- exceptions history. This is the case when
2964 -- the procedure is called from the UI.
2965 -- If FALSE, the the change_approval_status proc.
2966 -- is not called and the change is not saved to
2967 -- the exceptions history. FALSE should be used in
2968 -- all cases except when called from UI.
2969
2970 PROCEDURE change_asgn_schedule(
2971 p_record_version_number IN NUMBER,
2972 p_assignment_id IN NUMBER,
2973 p_project_id IN NUMBER,
2974 p_exception_id IN NUMBER,
2975 p_save_to_hist IN VARCHAR2 := FND_API.G_TRUE,
2976 p_remove_conflict_flag IN VARCHAR2 := 'N',
2977 p_generate_timeline_flag IN VARCHAR2 := 'Y', --Unilog
2978 p_called_by_proj_party IN VARCHAR2 := 'N', -- Added for Bug 6631033
2979 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
2980 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
2981 x_msg_data OUT NOCOPY VARCHAR2 --File.Sql.39 bug 4440895
2982 )
2983 IS
2984 l_msg_index_out NUMBER;
2985 l_record_version_number NUMBER;
2986
2987 l_data VARCHAR2(2000); -- 4537865
2988 -- jmarques: 1776658: Local variables for storing new duration and
2989 -- old duration.
2990 l_new_start_date DATE := NULL;
2991 l_new_end_date DATE := NULL;
2992 l_old_start_date DATE := NULL;
2993 l_old_end_date DATE := NULL;
2994 l_resource_id NUMBER := NULL;
2995
2996 CURSOR csr_sch_excp IS
2997 SELECT calendar_id,
2998 schedule_exception_id,
2999 assignment_id,
3000 project_id,
3001 status_code,
3002 schedule_type_code,
3003 exception_type_code,
3004 resource_calendar_percent,
3005 non_working_day_flag,
3006 change_hours_type_code,
3007 change_calendar_type_code,
3008 -- change_calendar_name,
3009 change_calendar_id,
3010 duration_shift_type_code,
3011 duration_shift_unit_code,
3012 number_of_shift,
3013 start_date,
3014 end_date,
3015 Monday_hours,
3016 Tuesday_hours,
3017 Wednesday_hours,
3018 Thursday_hours,
3019 Friday_hours,
3020 saturday_hours,
3021 Sunday_hours
3022 FROM pa_schedule_exceptions
3023 WHERE assignment_id = p_assignment_id
3024 AND ((p_exception_id IS NULL) OR
3025 (schedule_exception_id = p_exception_id))
3026 ORDER BY schedule_exception_id;
3027
3028 l_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3029 l_sch_except_record_tab PA_SCHEDULE_GLOB.SchExceptTabTyp;
3030 l_sch_except_rec PA_SCHEDULE_GLOB.SchExceptRecord;
3031 l_chg_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3032 l_out_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3033 l_del_tr_sch_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3034 l_I NUMBER;
3035 l_p_start_id NUMBER;
3036 l_p_end_id NUMBER;
3037 l_apply_schedule_changes BOOLEAN;
3038 l_change_id PA_SCHEDULES_HISTORY.change_id%type;
3039 l_temp_status_code PA_PROJECT_ASSIGNMENTS.status_code%type;
3040
3041 l_save_to_hist VARCHAR2(1); -- Unilog
3042 l_record_version_number_wo_chg NUMBER; -- Unilog
3043 l_exception_type_code VARCHAR2(100); --7663765
3044
3045 BEGIN
3046 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
3047
3048 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_asgn_schedule API ... ');
3049
3050 -- Unilog Begin
3051 l_save_to_hist := p_save_to_hist;
3052 IF p_generate_timeline_flag = 'N' THEN -- It means it is called from WeeklySchedule
3053 l_save_to_hist := FND_API.G_FALSE;
3054 END IF;
3055 -- Also now we should be using l_save_to_hist instead of p_save_to_hist
3056 -- Unilog End
3057
3058 -- Initializing local variables in case next procedure is not called.
3059 l_record_version_number := p_record_version_number;
3060
3061 -- Updates the assignment's approval status to WORKING which
3062 -- copies the history records into the assignment and schedule
3063 -- history tables.
3064 -- This if statement was added so that the approval status is not
3065 -- updated in all situations. For example, the approval status
3066 -- should not be updated when changing the status after failure
3067 -- or success. This is a work around and will be removed when the
3068 -- approval flow is redesigned.
3069 -- Bug 2135616: when this is called by PA_SCHEDULE_PVT.resolve_conflicts to remove
3070 -- conflicts, the approval status should not change.
3071 IF (FND_API.TO_BOOLEAN(NVL(l_save_to_hist,FND_API.G_TRUE))
3072 AND p_remove_conflict_flag = 'N') THEN
3073
3074 pa_assignment_approval_pvt.update_approval_status(
3075 p_assignment_id => p_assignment_id,
3076 p_action_code => PA_ASSIGNMENT_APPROVAL_PUB.g_update_action,
3077 p_record_version_number => p_record_version_number,
3078 x_record_version_number => l_record_version_number,
3079 x_change_id => l_change_id,
3080 x_apprvl_status_code => l_temp_status_code,
3081 x_return_status => l_x_return_status,
3082 x_msg_count => x_msg_count,
3083 x_msg_data => x_msg_data);
3084 ELSE
3085 l_record_version_number := p_record_version_number;
3086 l_change_id := PA_ASSIGNMENT_APPROVAL_PVT.Get_Change_Id(p_assignment_id);
3087 END IF;
3088
3089
3090 l_apply_schedule_changes := FALSE;
3091
3092 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API get_assignment_schedule ....');
3093
3094 -- Calling the PVT API This api will bring the asignment schedule for the passed
3095 -- asignment id and it will store the schedule in tabel of record i.e l_tr_sch_rec_tab.
3096 PA_SCHEDULE_PVT.get_assignment_schedule(p_assignment_id,
3097 l_tr_sch_rec_tab,
3098 l_x_return_status,
3099 x_msg_count,
3100 x_msg_data );
3101
3102 PA_SCHEDULE_UTILS.log_message(1,'START ASSG SCHEDULE ',l_tr_sch_rec_tab );
3103 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API get_assignment_schedule ....');
3104
3105 l_I := 1;
3106
3107 -- Copying the exceptions of the given assignment
3108 FOR rec_sch_excp IN csr_sch_excp LOOP
3109 l_apply_schedule_changes := TRUE;
3110 l_sch_except_record_tab(l_i).calendar_id := rec_sch_excp.calendar_id;
3111 l_sch_except_record_tab(l_i).schedule_exception_id := rec_sch_excp.schedule_exception_id;
3112 l_sch_except_record_tab(l_i).assignment_id := rec_sch_excp.assignment_id;
3113 l_sch_except_record_tab(l_i).project_id := rec_sch_excp.project_id;
3114 l_sch_except_record_tab(l_i).assignment_status_code := rec_sch_excp.status_code;
3115 l_sch_except_record_tab(l_i).schedule_type_code := rec_sch_excp.schedule_type_code;
3116 l_sch_except_record_tab(l_i).exception_type_code := rec_sch_excp.exception_type_code;
3117 l_sch_except_record_tab(l_i).resource_calendar_percent := rec_sch_excp.resource_calendar_percent;
3118 l_sch_except_record_tab(l_i).non_working_day_flag := rec_sch_excp.non_working_day_flag;
3119 l_sch_except_record_tab(l_i).change_hours_type_code := rec_sch_excp.change_hours_type_code;
3120 l_sch_except_record_tab(l_i).change_calendar_type_code := rec_sch_excp.change_calendar_type_code;
3121 --l_sch_except_record_tab(l_i).change_calendar_name := rec_sch_excp.change_calendar_name;
3122 l_sch_except_record_tab(l_i).change_calendar_id := rec_sch_excp.change_calendar_id;
3123 l_sch_except_record_tab(l_i).duration_shift_type_code := rec_sch_excp.duration_shift_type_code;
3124 l_sch_except_record_tab(l_i).duration_shift_unit_code := rec_sch_excp.duration_shift_unit_code;
3125 l_sch_except_record_tab(l_i).number_of_shift := rec_sch_excp.number_of_shift;
3126 l_sch_except_record_tab(l_i).start_date := rec_sch_excp.start_date;
3127 l_sch_except_record_tab(l_i).end_date := rec_sch_excp.end_date;
3128 l_sch_except_record_tab(l_i).Monday_hours := rec_sch_excp.Monday_hours;
3129 l_sch_except_record_tab(l_i).Tuesday_hours := rec_sch_excp.Tuesday_hours;
3130 l_sch_except_record_tab(l_i).Wednesday_hours := rec_sch_excp.Wednesday_hours;
3131 l_sch_except_record_tab(l_i).Thursday_hours := rec_sch_excp.Thursday_hours;
3132 l_sch_except_record_tab(l_i).Friday_hours := rec_sch_excp.Friday_hours;
3133 l_sch_except_record_tab(l_i).saturday_hours := rec_sch_excp.saturday_hours;
3134 l_sch_except_record_tab(l_i).Sunday_hours := rec_sch_excp.sunday_hours;
3135 l_sch_except_rec.assignment_id := rec_sch_excp.assignment_id;
3136 l_sch_except_rec.calendar_id := rec_sch_excp.calendar_id;
3137 l_sch_except_rec.schedule_exception_id := rec_sch_excp.schedule_exception_id;
3138 l_sch_except_rec.project_id := rec_sch_excp.project_id;
3139 l_sch_except_rec.assignment_status_code := rec_sch_excp.status_code;
3140 l_sch_except_rec.schedule_type_code := rec_sch_excp.schedule_type_code;
3141 l_sch_except_rec.exception_type_code := rec_sch_excp.exception_type_code;
3142 l_sch_except_rec.resource_calendar_percent := rec_sch_excp.resource_calendar_percent;
3143 l_sch_except_rec.non_working_day_flag := rec_sch_excp.non_working_day_flag;
3144 l_sch_except_rec.change_hours_type_code := rec_sch_excp.change_hours_type_code;
3145 l_sch_except_rec.change_calendar_type_code := rec_sch_excp.change_calendar_type_code;
3146 --l_sch_except_rec.change_calendar_name := rec_sch_excp.change_calendar_name;
3147 l_sch_except_rec.change_calendar_id := rec_sch_excp.change_calendar_id;
3148 l_sch_except_rec.duration_shift_type_code := rec_sch_excp.duration_shift_type_code;
3149 l_sch_except_rec.duration_shift_unit_code := rec_sch_excp.duration_shift_unit_code;
3150 l_sch_except_rec.number_of_shift := rec_sch_excp.number_of_shift;
3151 l_sch_except_rec.start_date := rec_sch_excp.start_date;
3152 l_sch_except_rec.end_date := rec_sch_excp.end_date;
3153 l_sch_except_rec.Monday_hours := rec_sch_excp.Monday_hours;
3154 l_sch_except_rec.Tuesday_hours := rec_sch_excp.Tuesday_hours;
3155 l_sch_except_rec.Wednesday_hours := rec_sch_excp.Wednesday_hours;
3156 l_sch_except_rec.Thursday_hours := rec_sch_excp.Thursday_hours;
3157 l_sch_except_rec.Friday_hours := rec_sch_excp.Friday_hours;
3158 l_sch_except_rec.saturday_hours := rec_sch_excp.saturday_hours;
3159 l_sch_except_rec.Sunday_hours := rec_sch_excp.sunday_hours;
3160
3161 l_exception_type_code := rec_sch_excp.exception_type_code ; -- 7663765
3162
3163 IF (l_I > 1) THEN
3164 PA_SCHEDULE_UTILS.log_message(1,'Index Value :' || to_char(l_i));
3165 l_tr_sch_rec_tab.delete;
3166
3167
3168 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3169 -- This procedure will copy the schedule record from one table of record to another
3170 PA_SCHEDULE_UTILS.copy_schedule_rec_tab(
3171 l_chg_tr_sch_rec_tab,
3172 l_chg_tr_sch_rec_tab.first,
3173 l_chg_tr_sch_rec_tab.last,
3174 l_tr_sch_rec_tab,
3175 l_x_return_status,
3176 x_msg_count,
3177 x_msg_data
3178 );
3179 END IF;
3180
3181 PA_SCHEDULE_UTILS.log_message(1,'after copy schedule : ',l_tr_sch_rec_tab );
3182 END IF;
3183
3184 IF (rec_sch_excp.exception_type_code = 'CHANGE_DURATION' OR
3185 rec_sch_excp.exception_type_code = 'SHIFT_DURATION' OR rec_sch_excp.exception_type_code = 'DURATION_PATTERN_SHIFT') then -- 7663765
3186 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3187 -- calling PVT API that will change the duration and generate a new schedule
3188 -- on the basis of passed schedule and exception record
3189 PA_SCHEDULE_PVT.apply_change_duration(l_tr_sch_rec_tab,
3190 l_sch_except_rec,
3191 l_out_tr_sch_rec_tab,
3192 l_x_return_status,
3193 x_msg_count,
3194 x_msg_data);
3195
3196 -- jmarques: 1776658: Store new duration.
3197 l_new_start_date := l_sch_except_rec.start_date;
3198 l_new_end_date := l_sch_except_rec.end_date;
3199 END IF;
3200
3201 PA_SCHEDULE_UTILS.log_message(1,'after change_duration : ',l_out_tr_sch_rec_tab );
3202 ELSE
3203
3204 PA_SCHEDULE_UTILS.log_message(1,'after change_duration : ' );
3205
3206 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3207 -- calling PVT API that will apply the changes
3208 PA_SCHEDULE_UTILS.log_message (1,' IN THE ELSE PART AND starting of apply other changes ');
3209 PA_SCHEDULE_UTILS.log_message(1, 'Calling apply_other_changes1 :', l_tr_sch_rec_tab);
3210 --PA_SCHEDULE_UTILS.log_message(1, 'Calling apply_other_changes2 :', l_sch_except_rec);
3211 PA_SCHEDULE_PVT.apply_other_changes(l_tr_sch_rec_tab,
3212 l_sch_except_rec,
3213 l_out_tr_sch_rec_tab,
3214 l_x_return_status,
3215 x_msg_count,
3216 x_msg_data
3217 );
3218 END IF;
3219
3220 PA_SCHEDULE_UTILS.log_message(1,'after change_others : ',l_out_tr_sch_rec_tab );
3221 END IF;
3222
3223 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3224 -- seperating the deleted or non deleted record i.e inserted or updated
3225 PA_SCHEDULE_UTILS.sep_del_sch_rec_tab(l_out_tr_sch_rec_tab,
3226 l_del_tr_sch_rec_tab,
3227 l_chg_tr_sch_rec_tab,
3228 l_x_return_status,
3229 x_msg_count,
3230 x_msg_data
3231 );
3232 END IF;
3233
3234 l_I := l_I + 1;
3235
3236 PA_SCHEDULE_UTILS.log_message(1,'after delete seperate (change ) : ',l_chg_tr_sch_rec_tab );
3237 PA_SCHEDULE_UTILS.log_message(1,'after delete seperate (delete ) : ',l_del_tr_sch_rec_tab );
3238
3239 END LOOP;
3240
3241 PA_SCHEDULE_UTILS.log_message(1,'FINAL (change ) : ',l_chg_tr_sch_rec_tab );
3242 PA_SCHEDULE_UTILS.log_message(1,'FINAL (delete ) : ',l_del_tr_sch_rec_tab );
3243
3244 IF ( l_apply_schedule_changes ) THEN
3245 /* Added below for 7663765 */
3246 if (l_exception_type_code = 'DURATION_PATTERN_SHIFT') then
3247 delete pa_schedules where assignment_id = p_assignment_id;
3248 end if;
3249
3250 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API apply_schedule_change ....');
3251
3252 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3253 -- Calling the PVT api that will change the schedule
3254 PA_SCHEDULE_PVT.apply_schedule_change(l_chg_tr_sch_rec_tab,
3255 l_del_tr_sch_rec_tab,
3256 l_x_return_status,
3257 x_msg_count,
3258 x_msg_data);
3259 END IF;
3260
3261 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API apply_schedule_change ....');
3262
3263 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3264 -- Calling the API PA_SCHEDULE_PVT.apply_assignment_change
3265
3266 -- jmarques: 1776658: Get old duration.
3267 select start_date, end_date, resource_id, record_version_number -- Unilog Selected record_version_number too
3268 into l_old_start_date, l_old_end_date, l_resource_id, l_record_version_number_wo_chg
3269 from pa_project_assignments
3270 where assignment_id = p_assignment_id;
3271
3272 -- Unilog Added this IF condition
3273 IF p_generate_timeline_flag = 'N' THEN
3274 l_record_version_number := l_record_version_number_wo_chg;
3275 END IF;
3276
3277 -- jmarques: 1776658: Fix variables so that no null values are present.
3278 l_new_start_date := NVL(l_new_start_date, l_old_start_date);
3279 l_new_end_date := NVL(l_new_end_date, l_old_end_date);
3280
3281 PA_SCHEDULE_PVT.apply_assignment_change(
3282 p_record_version_number => l_record_version_number,
3283 chg_tr_sch_rec_tab => l_chg_tr_sch_rec_tab,
3284 sch_except_record_tab => l_sch_except_record_tab,
3285 p_called_by_proj_party => p_called_by_proj_party, -- Added for Bug 6631033
3286 x_return_status => l_x_return_status,
3287 x_msg_count => x_msg_count,
3288 x_msg_data => x_msg_data);
3289 END IF;
3290
3291 PA_SCHEDULE_UTILS.log_message(1, 'Before Calling the API delete_rows ....');
3292
3293 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3294 -- Deleting the rows from pa_schedule_exception table
3295 PA_SCH_EXCEPT_PKG.delete_rows(l_sch_except_record_tab,
3296 l_x_return_status,
3297 x_msg_count,
3298 x_msg_data
3299 );
3300 END IF;
3301
3302 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API delete_rows ..');
3303
3304 -- inserting the rows from schedule except history table
3305 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3306 IF (FND_API.TO_BOOLEAN(NVL(l_save_to_hist,FND_API.G_TRUE))) THEN
3307 PA_SCH_EXCEPT_HIST_PKG.insert_rows(
3308 l_sch_except_record_tab,
3309 l_change_id,
3310 l_x_return_status,
3311 x_msg_count,
3312 x_msg_data
3313 );
3314 END IF;
3315 END IF;
3316
3317 PA_SCHEDULE_UTILS.log_message(1, 'After Calling the API insert_rows ....');
3318 END IF;
3319
3320 IF p_generate_timeline_flag = 'Y' THEN --Unilog
3321
3322 -- Calling the Timeline api to create the timeline records
3323 -- for the assignment
3324 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3325 PA_SCHEDULE_UTILS.log_message(1,'Calling Timeline API ..... ');
3326 PA_SCHEDULE_UTILS.log_message(1, 'Num: ' || FND_MSG_PUB.Count_Msg);
3327 PA_TIMELINE_PVT.create_timeline (
3328 p_assignment_id =>p_assignment_id ,
3329 x_return_status =>l_x_return_status ,
3330 x_msg_count =>x_msg_count ,
3331 x_msg_data =>x_msg_data );
3332
3333
3334 -- jmarques: 1776658: If the duration has changed, then create the
3335 -- resource timeline (recalculates availability) for the parts of
3336 -- the old duration which do not overlap the new duration.
3337
3338 IF (l_old_start_date < l_new_start_date AND l_resource_id is not null) THEN
3339 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3340 pa_timeline_pvt.Create_Timeline (
3341 p_start_resource_name => NULL,
3342 p_end_resource_name => NULL,
3343 p_resource_id => l_resource_id,
3344 p_start_date => l_old_start_date,
3345 p_end_date => l_new_start_date,
3346 x_return_status => l_x_return_status,
3347 x_msg_count => x_msg_count,
3348 x_msg_data => x_msg_data);
3349 END IF;
3350 END IF;
3351
3352 IF (l_old_end_date > l_new_end_date AND l_resource_id is not null) THEN
3353 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3354 pa_timeline_pvt.Create_Timeline (
3355 p_start_resource_name => NULL,
3356 p_end_resource_name => NULL,
3357 p_resource_id => l_resource_id,
3358 p_start_date => l_new_end_date,
3359 p_end_date => l_old_end_date,
3360 x_return_status => l_x_return_status,
3361 x_msg_count => x_msg_count,
3362 x_msg_data => x_msg_data);
3363 END IF;
3364 END IF;
3365 END IF;
3366 END IF; -- Unilog
3367
3368 PA_SCHEDULE_UTILS.log_message(1,'End of the change_asgn_schedule API ... ');
3369 x_return_status := l_x_return_status;
3370
3371 x_msg_count := FND_MSG_PUB.Count_Msg;
3372
3373 If x_msg_count = 1 THEN
3374 pa_interface_utils_pub.get_messages
3375 (p_encoded => FND_API.G_TRUE ,
3376 p_msg_index => 1,
3377 p_msg_count => x_msg_count ,
3378 p_msg_data => x_msg_data ,
3379 p_data => l_data, -- 4537865
3380 p_msg_index_out => l_msg_index_out );
3381 x_msg_data := l_data ; -- 4537865
3382 End If;
3383
3384 EXCEPTION
3385 WHEN OTHERS THEN
3386 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_asgn_schedule API ..'
3387 ||sqlerrm);
3388 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3389 x_msg_count := 1;
3390 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : Changed substr to substrb
3391 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
3392 p_procedure_name => 'change_asgn_schedule');
3393 If x_msg_count = 1 THEN
3394 pa_interface_utils_pub.get_messages
3395 (p_encoded => FND_API.G_TRUE ,
3396 p_msg_index => 1,
3397 p_msg_count => x_msg_count ,
3398 p_msg_data => x_msg_data ,
3399 p_data => l_data, -- 4537865
3400 p_msg_index_out => l_msg_index_out );
3401 x_msg_data := l_data ; -- 4537865
3402 End If;
3403 RAISE; -- This is optional depending on the needs
3404 END change_asgn_schedule;
3405
3406 -- Procedure : create_calendar_schedule
3407 -- Purpose : This procedure is called from periodic process for creating calendar schedule
3408 -- . It will generate the new schedule on the basi of passed calendar id
3409 -- Input parameters
3410 -- Parameters Type Required Description
3411 -- P_Calendar_Id NUMBER YES Id for that calendar for which you want to create schedule
3412 --
3413
3414 PROCEDURE create_calendar_schedule ( p_calendar_id IN NUMBER,
3415 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
3416 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
3417 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
3418 IS
3419
3420 l_x_cal_record_tab PA_SCHEDULE_GLOB.CalendarTabTyp;
3421 l_schedule_rec_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3422 l_x_sch_record_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3423 l_x_cal_except_record_tab PA_SCHEDULE_GLOB.calExceptionTabTyp;
3424 l_msg_index_out NUMBER;
3425 l_data varchar2(2000) ;-- 4537865
3426 BEGIN
3427 PA_SCHEDULE_UTILS.log_message(1,'Start of the create_calendar_schedule API ... ');
3428 -- storing the status success to track the error
3429 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
3430
3431 -- Calling the Calendar API that will give the shift assign to the calendar*/
3432 PA_CALENDAR_UTILS.get_calendar_shifts(p_calendar_id,l_x_cal_record_tab,l_x_return_status,x_msg_count,x_msg_data);
3433
3434 IF ( l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3435 PA_CALENDAR_UTILS.gen_calendar_sch(p_calendar_id,l_x_cal_record_tab,l_schedule_rec_tab,l_x_return_status,
3436 x_msg_count,x_msg_data);
3437
3438 END IF;
3439
3440 PA_SCHEDULE_UTILS.log_message(1,'GEN SCH ',l_schedule_rec_tab);
3441 IF ( l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3442 -- Calling the PA_CALENDAR_UTILS API that will take the exception associated with the calendar
3443 PA_CALENDAR_UTILS.get_calendar_except(p_calendar_id,l_x_cal_except_record_tab,l_x_return_status,
3444 x_msg_count,x_msg_data);
3445
3446 END IF;
3447
3448 IF ( l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3449
3450 -- Calling the PA_CALENDAR_UTILS API that will generate the calendar schedule after applying the exception
3451 PA_CALENDAR_UTILS.apply_calendar_except(p_calendar_id,l_x_cal_except_record_tab,l_schedule_rec_tab,
3452 l_x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
3453
3454 END IF;
3455
3456 IF ( l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3457 -- Inserting the records in PA_SCHEDULES table
3458 PA_SCHEDULE_PKG.insert_rows(l_x_sch_record_tab,l_x_return_status,x_msg_count,x_msg_data);
3459
3460 END IF;
3461 /** Added call to update_wp_calendar for all projects **/
3462 -- Start Of Bug No :4666318
3463 --Commented for Bug No:4666318
3464 -- This functionality was originally introduced in FP.K .But It was removed in FP.M.
3465 /* PA_PROJECT_STRUCTURE_PVT1.update_all_wp_calendar
3466 ( p_calendar_id => p_calendar_id
3467 ,x_return_status => x_return_status
3468 ,x_msg_count => x_msg_count
3469 ,x_msg_data => x_msg_data
3470 );*/
3471 -- End Of Bug No : 4666318
3472
3473 PA_SCHEDULE_UTILS.log_message(1,'End of the create_calendar_schedule API ... ');
3474
3475 x_return_status := l_x_return_status;
3476 x_msg_count := FND_MSG_PUB.Count_Msg;
3477 If x_msg_count = 1 THEN
3478 pa_interface_utils_pub.get_messages
3479 (p_encoded => FND_API.G_TRUE ,
3480 p_msg_index => 1,
3481 p_msg_count => x_msg_count ,
3482 p_msg_data => x_msg_data ,
3483 p_data => l_data, -- 4537865
3484 p_msg_index_out => l_msg_index_out );
3485 x_msg_Data := l_data ;-- 4537865
3486 End If;
3487 EXCEPTION
3488 WHEN OTHERS THEN
3489 PA_SCHEDULE_UTILS.log_message(1,'ERROR in create_calendar_schedule API ..'||sqlerrm);
3490 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3491 x_msg_count := 1;
3492 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 changed substr to substrb
3493 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
3494 p_procedure_name => 'create_calendar_schedule');
3495 If x_msg_count = 1 THEN
3496 pa_interface_utils_pub.get_messages
3497 (p_encoded => FND_API.G_TRUE,
3498 p_msg_index => 1,
3499 p_msg_count => x_msg_count,
3500 p_msg_data => x_msg_data,
3501 p_data => l_data, -- 4537865
3502 p_msg_index_out => l_msg_index_out );
3503 x_msg_Data := l_data ;-- 4537865
3504 End If;
3505 RAISE; -- This is optional depending on the needs
3506 END create_calendar_schedule;
3507
3508 -- Procedure : get_proj_calendar_default
3509 -- Purpose : This procedure is called for getting the default calendar for the project.
3510 -- This will be called from projects form
3511 --
3512 -- Input parameters
3513 -- Parameters Type Required Description
3514 -- P_Proj_Organization NUMBER YES project organization
3515 -- P_Project_Id NUMBER YES project id
3516 -- Out parameters
3517 -- X_Calendar_Id NUMBER YES It stores the id for the calendar
3518 -- X_Calendar_Name VARCHAR2 YES It stores name of the calendar
3519 --
3520
3521 PROCEDURE get_proj_calendar_default ( p_proj_organization IN NUMBER,
3522 p_project_id IN NUMBER,
3523 x_calendar_id OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
3524 x_calendar_name OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
3525 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
3526 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
3527 x_msg_data OUT NOCOPY VARCHAR2 ) IS --File.Sql.39 bug 4440895
3528 l_no_calendar_at_org BOOLEAN;
3529 l_temp_calendar_id VARCHAR2(80);
3530 l_null_default_calendar EXCEPTION;
3531 l_invalid_default_calendar EXCEPTION;
3532 l_t_carrying_out_org_id PA_PROJECTS.carrying_out_organization_id%TYPE; -- To store the orgnaization id
3533 L_MSG_INDEX_OUT NUMBER;
3534
3535 l_data varchar2(2000); -- 4537865
3536 BEGIN
3537 PA_SCHEDULE_UTILS.log_message(1,'Start of the get_proj_calendar_default API ... ');
3538
3539 l_x_return_status := FND_API.G_RET_STS_SUCCESS ;
3540 l_no_calendar_at_org := FALSE;
3541
3542 /* Bug2873984
3543 IF (PA_INSTALL.IS_PRM_LICENSED() <> 'Y') THEN
3544 PA_SCHEDULE_UTILS.log_message(1,'PRM is not licensed, so returning null.');
3545 x_calendar_id := null;
3546 x_calendar_name := null;
3547 x_return_status := l_x_return_status;
3548 return;
3549 END IF; */
3550
3551 PA_SCHEDULE_UTILS.log_message(1,'PRM is licensed, so continuing.');
3552
3553 -- Taking out the orgnization id for passing to the get_proj_calendar_default */
3554 IF (p_project_id IS NOT NULL ) THEN
3555 BEGIN
3556 -- Modified to select from PA_PROJECTS_ALL instead of PA_PROJECTS.
3557 SELECT carrying_out_organization_id
3558 INTO l_t_carrying_out_org_id
3559 FROM PA_PROJECTS_ALL
3560 WHERE project_id = p_project_id;
3561
3562 EXCEPTION
3563 WHEN NO_DATA_FOUND THEN
3564 x_return_status := FND_API.G_RET_STS_ERROR;
3565 RAISE;
3566 END;
3567 ELSE
3568 l_t_carrying_out_org_id := p_proj_organization;
3569 END IF;
3570
3571 BEGIN
3572 PA_SCHEDULE_UTILS.log_message(1,'before select on hr_org.... ');
3573
3574 -- Taking the calendar on the basis of organization assigned to the project
3575 -- R12 changes - the calendar is now stored
3576 -- under a new information type - Resource Defaults
3577 -- in a different column
3578
3579 --SELECT TO_NUMBER(hr1.org_information2) ,
3580 SELECT TO_NUMBER(hr1.org_information1) ,
3581 cal1.calendar_name
3582 INTO x_calendar_id ,
3583 x_calendar_name
3584 FROM hr_organization_information hr1,
3585 jtf_calendars_vl cal1
3586 --WHERE cal1.calendar_id = TO_NUMBER(hr1.org_information2) BUG 3530529
3587 -- WHERE TO_CHAR(cal1.calendar_id) = hr1.org_information2
3588 WHERE TO_CHAR(cal1.calendar_id) = hr1.org_information1
3589 AND hr1.organization_id = l_t_carrying_out_org_id
3590 --AND hr1.org_information_context = 'Exp Organization Defaults';
3591 AND hr1.org_information_context = 'Resource Defaults';
3592
3593 PA_SCHEDULE_UTILS.log_message(1,'after select on hr_org.... ');
3594 EXCEPTION
3595 WHEN NO_DATA_FOUND THEN
3596 PA_SCHEDULE_UTILS.log_message(1,'inside no data found for select on hr_org.... ');
3597 l_no_calendar_at_org := TRUE;
3598 WHEN OTHERS THEN
3599 PA_SCHEDULE_UTILS.log_message(1,'ERROR while excuting select on hr_org.... '||sqlerrm);
3600 RAISE;
3601 END;
3602
3603 -- If no calendar is associated with the organization the we will take the calendar which will be
3604 -- assiciated with the PROFILE
3605 IF ( l_no_calendar_at_org ) THEN
3606 FND_PROFILE.GET('PA_PRM_DEFAULT_CALENDAR',l_temp_calendar_id);
3607
3608 IF ( l_temp_calendar_id is NULL ) THEN
3609 /* Commented for bug 2873984
3610 x_msg_data := 'Default Calendar not assigned to profile option PA_PRM_CALENDAR';
3611 RAISE l_null_default_calendar; */
3612 /* Code Addition for bug 2873984 starts */
3613 x_calendar_id := null;
3614 x_calendar_name := null;
3615 /* Code Addition for bug 2873984 ends */
3616 ELSE
3617 PA_SCHEDULE_UTILS.log_message(1,'calendar_id '||l_temp_calendar_id);
3618 BEGIN
3619 SELECT
3620 calendar_name
3621 INTO x_calendar_name
3622 FROM jtf_calendars_vl
3623 WHERE calendar_id = TO_NUMBER(l_temp_calendar_id);
3624
3625 x_calendar_id := TO_NUMBER(l_temp_calendar_id);
3626 EXCEPTION
3627 WHEN NO_DATA_FOUND THEN
3628 x_msg_data := 'Not a valid calendar assigned to profile option ';
3629 PA_SCHEDULE_UTILS.log_message(1,'Not a valid calendar assigned to profile option ');
3630 RAISE l_invalid_default_calendar;
3631 WHEN OTHERS THEN
3632 PA_SCHEDULE_UTILS.log_message(1,'ERROR while excuting select on jtf_calendars_vl.... '||sqlerrm);
3633 RAISE;
3634 END;
3635
3636 END IF;
3637 END IF;
3638
3639 PA_SCHEDULE_UTILS.log_message(1,'End of the get_proj_calendar_default API ... ');
3640 x_return_status := l_x_return_status;
3641
3642 EXCEPTION
3643 WHEN l_invalid_default_calendar THEN
3644 PA_SCHEDULE_UTILS.log_message(1,'ERROR: invalid calendar id at profile option ..');
3645 PA_UTILS.add_message('PA','PA_INVALID_PROFILE_CALENDAR_ID');
3646 x_return_status := FND_API.G_RET_STS_ERROR;
3647 x_msg_data := 'PA_INVALID_PROFILE_CALENDAR_ID';
3648 x_msg_count := FND_MSG_PUB.Count_Msg;
3649
3650 -- RESET other out params also : 4537865
3651 x_calendar_id := NULL ;
3652 x_calendar_name := NULL;
3653
3654 If x_msg_count = 1 THEN
3655 pa_interface_utils_pub.get_messages
3656 (p_encoded => FND_API.G_TRUE,
3657 p_msg_index => 1,
3658 p_msg_count => x_msg_count,
3659 p_msg_data => x_msg_data,
3660 p_data => l_data, -- 4537865
3661 p_msg_index_out => l_msg_index_out );
3662 x_msg_data := l_data ; -- 4537865
3663 End If;
3664 WHEN l_null_default_calendar THEN
3665 PA_SCHEDULE_UTILS.log_message(1,'ERROR: Null calendar id at profile option ..');
3666 PA_UTILS.add_message('PA','PA_INVALID_PROFILE_CALENDAR_ID');
3667 x_return_status := FND_API.G_RET_STS_ERROR;
3668 x_msg_data := 'PA_NULL_PROFILE_CALENDAR_ID';
3669 x_msg_count := FND_MSG_PUB.Count_Msg;
3670
3671 -- RESET other out params also : 4537865
3672 x_calendar_id := NULL ;
3673 x_calendar_name := NULL;
3674
3675 If x_msg_count = 1 THEN
3676 pa_interface_utils_pub.get_messages
3677 (p_encoded => FND_API.G_TRUE,
3678 p_msg_index => 1,
3679 p_msg_count => x_msg_count,
3680 p_msg_data => x_msg_data,
3681 p_data => l_data, -- 4537865
3682 p_msg_index_out => l_msg_index_out );
3683 x_msg_data := l_data ; -- 4537865
3684 End If;
3685 WHEN OTHERS THEN
3686 PA_SCHEDULE_UTILS.log_message(1,'ERROR in get_proj_calendar_default API ..'||sqlerrm);
3687 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3688 x_msg_count := 1;
3689 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : CHANGd substr to substrb
3690
3691 -- RESET other out params also : 4537865
3692 x_calendar_id := NULL ;
3693 x_calendar_name := NULL;
3694
3695 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
3696 p_procedure_name => 'get_proj_calendar_default');
3697 If x_msg_count = 1 THEN
3698 pa_interface_utils_pub.get_messages
3699 (p_encoded => FND_API.G_TRUE,
3700 p_msg_index => 1,
3701 p_msg_count => x_msg_count,
3702 p_msg_data => x_msg_data,
3703 p_data => l_data, -- 4537865
3704 p_msg_index_out => l_msg_index_out );
3705 x_msg_data := l_data ; -- 4537865
3706 End If;
3707 RAISE; -- This is optional depending on the needs
3708 END get_proj_calendar_default;
3709
3710 -- Procedure : create_new_cal_schedules
3711 -- Purpose : This procedure is called for creating the new schedule for the given calendars
3712 -- .
3713 -- Input parameters
3714 -- Parameters Type Required Description
3715 -- P_Start_Calendar_Name VARCHAR2 NO Name of the starting calendar
3716 -- P_End_Calendar_Name VARCHAR2 NO Name of the Ending calendar
3717 --
3718
3719 PROCEDURE create_new_cal_schedules ( p_start_calendar_name IN VARCHAR2,
3720 p_end_calendar_name IN VARCHAR2,
3721 x_return_status OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
3722 x_msg_count OUT NOCOPY NUMBER, --File.Sql.39 bug 4440895
3723 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
3724 IS
3725 l_I NUMBER;
3726 l_code VARCHAR2(50); -- temp variable
3727 l_flag VARCHAR2(1); -- temp variable
3728 l_t_start_calendar_name VARCHAR2(50); -- temp variable to store the calendar start name for creating
3729 -- the new schedule
3730 l_t_end_calendar_name VARCHAR2(50); -- temp variable to store the calendar end name for creating
3731 -- the new schedule
3732
3733 -- This cursor will select only those records which are matching in the start and end calendar name
3734 -- or coming between them
3735 CURSOR C1 IS SELECT calendar_id,calendar_name
3736 FROM JTF_CALENDARS_VL
3737 WHERE calendar_name BETWEEN l_t_start_calendar_name AND l_t_end_calendar_name;
3738 l_msg_index_out NUMBER;
3739 l_exception EXCEPTION;
3740 l_debug_mode VARCHAR2(20) := 'N';
3741 l_counter NUMBER;
3742
3743 l_data varchar2(2000) ; -- 4537865
3744 BEGIN
3745 -- Storing the status for error handling
3746 l_x_return_status := FND_API.G_RET_STS_SUCCESS;
3747
3748 -- 2843435
3749 fnd_profile.get('PA_DEBUG_MODE',l_debug_mode);
3750
3751 -- 4370082
3752 IF l_debug_mode = 'Y' THEN
3753 pa_debug.set_process('PLSQL','LOG',l_debug_mode);
3754 END IF;
3755
3756 -- End of 2843435
3757
3758 -- The passing calendar start name is null then take the lowest one
3759 IF (p_start_calendar_name IS NULL ) THEN
3760
3761 SELECT MIN(calendar_name)
3762 INTO l_t_start_calendar_name
3763 FROM JTF_CALENDARS_VL;
3764 ELSE
3765 l_t_start_calendar_name := p_start_calendar_name;
3766 END IF;
3767
3768 -- The passing calendar start name is null then take the hightest one
3769 IF (p_end_calendar_name IS NULL ) THEN
3770
3771 SELECT MAX(calendar_name)
3772 INTO l_t_end_calendar_name
3773 FROM JTF_CALENDARS_VL;
3774 ELSE
3775 l_t_end_calendar_name := p_end_calendar_name;
3776 END IF;
3777
3778 FOR v_c1 IN C1 LOOP
3779 -- Defining save point
3780 SAVEPOINT bfr_strt_del;
3781
3782 --Locking the JTF_CALENDAR_B table becouse of updation of its record
3783 SELECT 1
3784 INTO l_I
3785 FROM JTF_CALENDARS_B
3786 WHERE calendar_id=v_c1.calendar_id
3787 FOR UPDATE ;
3788
3789 -- Deleting the existing schedule of the calendar and creating the new one
3790 DELETE FROM PA_SCHEDULES
3791 WHERE calendar_id = v_c1.calendar_id
3792 AND schedule_type_code = 'CALENDAR';
3793
3794 -- Creating new schedule for the Calendar Id */
3795 PA_SCHEDULE_PUB.create_calendar_schedule(v_c1.calendar_id,l_x_return_status,x_msg_count,x_msg_data);
3796
3797 PA_SCHEDULE_UTILS.log_message(1,'Calling Timeline API ..... ');
3798 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3799 PA_TIMELINE_PVT.Create_Timeline (p_calendar_id =>v_c1.calendar_id,
3800 x_return_status =>l_x_return_status,
3801 x_msg_count =>x_msg_count,
3802 x_msg_data =>x_msg_data);
3803 END IF;
3804
3805 IF (l_x_return_status = FND_API.G_RET_STS_SUCCESS ) THEN
3806 l_flag := 'S';
3807 l_code := 'PA_SCH_SUCC_CAL_GEN';
3808 COMMIT;
3809 ELSE
3810 l_flag := 'E';
3811 l_code := 'PA_SCH_FAIL_CAL_GEN';
3812 ROLLBACK TO SAVEPOINT bfr_strt_del;
3813 END IF;
3814 -- Inserting the calendars in session level temp table to pupulate the report
3815 INSERT INTO PA_CAL_GEN_STATUS_TEMP(calendar_id,calendar_name,generate_status_flag,message_code)
3816 VALUES(v_c1.calendar_id,v_c1.calendar_name,l_flag,l_code);
3817 COMMIT;
3818
3819 -- 2843435: Need to raise expected error messages and print them to
3820 -- FND_FILE. Currently we don't have the logic to print error messages
3821 -- to the report file. Therefore, we have to raise expected errors.
3822 IF l_x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
3823
3824 IF l_debug_mode = 'Y' THEN
3825 pa_debug.write_file('CREATE_NEW_CAL_SCHEDULES: '||'LOG', 'msg_count = '||FND_MSG_PUB.Count_Msg);
3826 END IF;
3827
3828 FOR l_counter IN 1..FND_MSG_PUB.Count_Msg LOOP
3829 pa_interface_utils_pub.get_messages ( p_encoded => FND_API.G_FALSE
3830 ,p_msg_index => l_counter
3831 ,p_data => x_msg_data
3832 ,p_msg_index_out => l_msg_index_out);
3833 IF l_debug_mode = 'Y' THEN
3834 pa_debug.write_file('CREATE_NEW_CAL_SCHEDULES: '||'LOG', x_msg_data);
3835 END IF;
3836 END LOOP;
3837
3838 RAISE l_exception;
3839
3840 END IF;
3841 -- End of 2843435
3842
3843 END LOOP;
3844
3845 x_return_status := FND_API.G_RET_STS_SUCCESS;
3846 x_msg_count := FND_MSG_PUB.Count_Msg;
3847 If x_msg_count = 1 THEN
3848 pa_interface_utils_pub.get_messages
3849 (p_encoded => FND_API.G_TRUE ,
3850 p_msg_index => 1,
3851 p_msg_count => x_msg_count ,
3852 p_msg_data => x_msg_data ,
3853 p_data => l_data, -- 4537865
3854 p_msg_index_out => l_msg_index_out );
3855 x_msg_data := l_data ; -- 4537865
3856 End If;
3857
3858 EXCEPTION
3859 -- 2843435
3860 WHEN l_exception THEN
3861 RAISE;
3862 -- End of 2843435
3863 WHEN NO_DATA_FOUND THEN
3864 NULL;
3865 WHEN OTHERS THEN
3866 PA_SCHEDULE_UTILS.log_message(1,'ERROR in create_new_cal_schedules API ..'|| sqlerrm);
3867 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3868 x_msg_count := 1;
3869 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : Changed substrb to substr
3870 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
3871 p_procedure_name => 'create_new_cal_schedules');
3872 If x_msg_count = 1 THEN
3873 pa_interface_utils_pub.get_messages
3874 (p_encoded => FND_API.G_TRUE,
3875 p_msg_index => 1,
3876 p_msg_count => x_msg_count,
3877 p_msg_data => x_msg_data,
3878 p_data => l_data, -- 4537865
3879 p_msg_index_out => l_msg_index_out );
3880 x_msg_data := l_data ; -- 4537865
3881 End If;
3882 RAISE; -- This is optional depending on the needs
3883 END create_new_cal_schedules;
3884
3885 -- Unilog Enhancement : BEGIN
3886
3887 -- Procedure : change_work_pattern_duration
3888 -- Purpose : This procedure is called from self service for changing duration and work pattern.
3889 -- : It uses existing change_work_pattern and change_duration procedures to do the job.
3890 -- : While calling change_duartion and change_work_pattern, it passes newly introduced
3891 -- : parameter p_generate_timeline_flag as N, so that they do not call timeline API.
3892 -- : Typically this API will get called for a set of assignments of a resource
3893 -- : (in a loop or from VORowImpl). So it takes two parameters p_prev_call_timeline_st_date
3894 -- : and p_prev_call_timeline_end_date. For first assignment in the loop it will be null.
3895 -- : So x_call_timeline_st_date and x_call_timeline_end_date will have the required date ranges
3896 -- : for which timeline has to be regenerated. For the second assignment p_prev_call_timeline_st_date
3897 -- : and p_prev_call_timeline_end_date will have the first assighnmenmt's x_call_timeline_st_date
3898 -- : and x_call_timeline_end_date correspondingly. Then it will again calculate the timeline start date
3899 -- : and timeline end date for the second assignment. Then it will compare it with
3900 -- : p_prev_call_timeline_st_date and p_prev_call_timeline_end_date and will take
3901 -- : min(new timeline start date, p_prev_call_timeline_st_date) and
3902 -- : max(new timeline end date, p_prev_call_timeline_end_date). Similarly for other assignments....
3903 -- : After this API is called for a set of assignments, you need to call PA_FORECASTITEM_PVT.Create_Forecast_Item
3904 -- : with person_id as paremetrer and with the returned dates x_call_timeline_st_date
3905 -- : and x_call_timeline_end_date
3906 -- Parameters :
3907 -- Note : Note that the p_hours_table should have hours quantity starting at p_start_date and
3908 -- : ending at p_end_date.
3909
3910
3911 PROCEDURE change_work_pattern_duration(
3912 p_record_version_number IN Number ,
3913 p_project_id IN Number ,
3914 p_calendar_id IN Number ,
3915 p_assignment_id IN Number ,
3916 p_resource_id IN Number ,
3917 p_assignment_type IN Varchar2 ,
3918 p_asgn_start_date IN DATE := NULL ,
3919 p_asgn_end_date IN DATE := NULL ,
3920 p_start_date IN date := NULL ,
3921 -- p_end_date IN date := NULL ,
3922 p_assignment_status_code IN varchar2 := NULL ,
3923 p_hours_table IN SYSTEM.PA_NUM_TBL_TYPE ,
3924 p_prev_call_timeline_st_date IN DATE ,
3925 p_prev_call_timeline_end_date IN DATE ,
3926 x_call_timeline_st_date OUT NOCOPY Date , --File.Sql.39 bug 4440895
3927 x_call_timeline_end_date OUT NOCOPY Date , --File.Sql.39 bug 4440895
3928 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
3929 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
3930 x_msg_data OUT NOCOPY VARCHAR2 ) --File.Sql.39 bug 4440895
3931 IS
3932
3933 l_hours_table PA_PLSQL_DATATYPES.IdTabTyp;
3934 l_hours_db_table PA_PLSQL_DATATYPES.IdTabTyp;
3935 l_monday_hours PA_PLSQL_DATATYPES.IdTabTyp;
3936 l_tuesday_hours PA_PLSQL_DATATYPES.IdTabTyp;
3937 l_wednesday_hours PA_PLSQL_DATATYPES.IdTabTyp;
3938 l_thursday_hours PA_PLSQL_DATATYPES.IdTabTyp;
3939 l_friday_hours PA_PLSQL_DATATYPES.IdTabTyp;
3940 l_saturday_hours PA_PLSQL_DATATYPES.IdTabTyp;
3941 l_sunday_hours PA_PLSQL_DATATYPES.IdTabTyp;
3942 l_sch_record_tab PA_SCHEDULE_GLOB.ScheduleTabTyp;
3943 l_date DATE;
3944 l_counter NUMBER := 1;
3945 l_changes_done BOOLEAN := false;
3946 l_call_change_work_pattern BOOLEAN := false;
3947 l_call_change_duration BOOLEAN := false;
3948 l_call_cng_work_patt_out_range BOOLEAN := false;
3949 l_call_second_time BOOLEAN :=false;
3950 l_call_first_time BOOLEAN :=false; --Added for the bug 3421637
3951 l_new_assgn_start_date DATE;
3952 l_new_assgn_end_date DATE;
3953 l_update_work_zero_start_date DATE;
3954 l_update_work_zero_end_date DATE;
3955 l_count NUMBER;
3956 l_global_week_start_day NUMBER; --Added for bug 4068167
3957 l_days_to_inc NUMBER; --Added for bug 4068167
3958 l_actual_days_to_inc NUMBER; --Added for bug 4068167
3959 l_week_day VARCHAR2(10);
3960 l_ch_work_pattern_st_date1 DATE;
3961 l_ch_work_pattern_end_date1 DATE;
3962 l_ch_work_pattern_st_date2 DATE;
3963 l_ch_work_pattern_end_date2 DATE;
3964 l_actual_start_date DATE;
3965 l_actual_end_date DATE;
3966 -- l_exception EXCEPTION;
3967 API_ERROR EXCEPTION;
3968 l_msg_index_out NUMBER;
3969 p_end_date DATE;
3970 l_last_row_flag VARCHAR2(1);
3971
3972 l_data varchar2(2000); -- 4537865
3973 BEGIN
3974
3975 FND_MSG_PUB.initialize;
3976 l_count := p_hours_table.COUNT;
3977 p_end_date := p_start_date+13;
3978
3979 l_global_week_start_day := fnd_profile.value_specific('PA_GLOBAL_WEEK_START_DAY'); --Added for bug 4068167
3980
3981 PA_SCHEDULE_UTILS.log_message(1,'Start of the change_work_pattern_duration API ... ');
3982 PA_SCHEDULE_UTILS.log_message(1,'Parameters ... ');
3983 PA_SCHEDULE_UTILS.log_message(1,'p_record_version_number='||p_record_version_number);
3984 PA_SCHEDULE_UTILS.log_message(1,'p_project_id='||p_project_id);
3985 PA_SCHEDULE_UTILS.log_message(1,'p_calendar_id='||p_calendar_id);
3986 PA_SCHEDULE_UTILS.log_message(1,'p_assignment_id='||p_assignment_id);
3987 PA_SCHEDULE_UTILS.log_message(1,'p_resource_id='||p_resource_id);
3988 PA_SCHEDULE_UTILS.log_message(1,'p_assignment_type='||p_assignment_type);
3989 PA_SCHEDULE_UTILS.log_message(1,'p_asgn_start_date='||p_asgn_start_date);
3990 PA_SCHEDULE_UTILS.log_message(1,'p_asgn_end_date='||p_asgn_end_date);
3991 PA_SCHEDULE_UTILS.log_message(1,'p_start_date='||p_start_date);
3992 PA_SCHEDULE_UTILS.log_message(1,'p_end_date='||p_end_date);
3993 PA_SCHEDULE_UTILS.log_message(1,'p_assignment_status_code='||p_assignment_status_code);
3994 PA_SCHEDULE_UTILS.log_message(1,'Number of records in p_hours_table='||l_count);
3995 PA_SCHEDULE_UTILS.log_message(1,'Week start day l_global_week_start_day='||l_global_week_start_day); --Added for bug 4068167
3996
3997 -- Initialize the out date variables, so that if changes are not required then no need to call
3998 -- create_forecast_items
3999
4000 x_call_timeline_st_date := null;
4001 x_call_timeline_end_date := null;
4002 x_return_status := FND_API.G_RET_STS_SUCCESS;
4003
4004 IF ((p_end_date - p_start_date <> 13) OR (p_end_date < p_start_date)) THEN
4005 PA_SCHEDULE_UTILS.log_message(1,'p_start_date and p_end_date is wrongly passed');
4006 raise API_ERROR;
4007 END IF;
4008
4009 IF l_count <> 14 THEN
4010 PA_SCHEDULE_UTILS.log_message(1,'Number of records in p_hours_table is not 14');
4011 raise API_ERROR;
4012 END IF;
4013 -- Bug 3235656 : Added the below condition to show error
4014 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4015 IF (p_hours_table(i) < 0 OR p_hours_table(i) > 24) THEN
4016 PA_UTILS.Add_Message ('PA', 'PA_SCH_HOURS_OUT_OF_RANGE');
4017 RAISE FND_API.G_EXC_ERROR;
4018 END IF;
4019 END LOOP;
4020
4021 -- We want to calculate the actual start date and actual end date here instead of Java
4022 -- Because it is difficult and error prone to play with Dates in java. Java will pass
4023 -- alwyas the first shown date in work pattern table and last date as p_start_date and
4024 -- p_end_date. And a table of hours p_hours_table with 14 values filled in this. These
4025 -- values may be null, 0 or any value
4026
4027 PA_SCHEDULE_UTILS.log_message(1,'Parameters Detrmination Phase Begin');
4028
4029 -- Parameters Detrmination Phase Begin : In this it will determine the following parameters
4030
4031 -- l_actual_start_date : From which date actually changes starts in work pattern table
4032 -- l_actual_end_date : From which date actually changes ends in work pattern table
4033 -- l_new_assgn_start_date : New extended assignment start date. It will be original assignment start date if assignment is not extended
4034 -- l_new_assgn_start_date : New extended assignment end date. It will be original assignment end date if assignment is not extended
4035 -- l_changes_done : Some changes are done, but not very sure. So needs to determine further
4036 -- l_call_change_duration : Duration has been extended
4037 -- l_call_change_work_pattern : Work pattern has been changed
4038 -- l_call_cng_work_patt_out_range : There is a gap between assignment, so needs to fill this with 0 hours
4039 -- l_update_work_zero_start_date : Start date for the Gap created in the assignment
4040 -- l_update_work_zero_end_date : End date for the Gap created in the assignment
4041 -- x_call_timeline_st_date : The start date from which timeline should be regenerated.
4042 -- x_call_timeline_end_date : The end date till which timeline should be regenerated.
4043
4044 IF ((p_start_date BETWEEN p_asgn_start_date AND p_asgn_end_date) AND (p_end_date BETWEEN p_asgn_start_date AND p_asgn_end_date)) THEN
4045 -- Changes are Within Assignment Date Range
4046 PA_SCHEDULE_UTILS.log_message(1,'Changes are Within Assignment Date Range');
4047 l_actual_start_date := p_start_date;
4048 l_actual_end_date := p_end_date;
4049 l_new_assgn_start_date := p_asgn_start_date;
4050 l_new_assgn_end_date := p_asgn_end_date;
4051 x_call_timeline_st_date := l_actual_start_date;
4052 x_call_timeline_end_date := l_actual_end_date;
4053 --Changes are done, now further it needs to be determined that whether work pattern has changed or not
4054 l_changes_done := true;
4055 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4056 IF p_hours_table(i) IS NULL THEN
4057 l_hours_table(i) := 0;
4058 ELSE
4059 l_hours_table(i) := p_hours_table(i);
4060 END IF;
4061 END LOOP;
4062 ELSIF p_end_date < p_asgn_start_date THEN
4063 -- Moving Backward Totally outside range
4064
4065 PA_SCHEDULE_UTILS.log_message(1,'Moving Backward Totally outside range');
4066
4067 -- Example 1 : assgn start date is 20-Oct-2003 and assgn end date is 10-Nov-2003
4068 -- p_start_date is 01-Oct-2003 and p_end_date is 14-Oct-2003
4069 -- p_hours_table has 0,null,0,8,8,8,8,8,8,8,8,8,8,8
4070
4071 -- Example 2 : assgn start date is 15-Oct-2003 and assgn end date is 10-Nov-2003
4072 -- p_start_date is 01-Oct-2003 and p_end_date is 14-Oct-2003
4073 -- p_hours_table has 0,null,0,8,8,8,8,8,8,8,8,8,8,8
4074
4075 l_actual_end_date := p_end_date;
4076 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4077 IF p_hours_table(i) IS NOT NULL AND p_hours_table(i) <> 0 THEN
4078 l_actual_start_date := p_start_date + (i-1);
4079 exit; -- As soon as find non zero, non null; come out
4080 END IF;
4081 END LOOP;
4082
4083 -- Example 1 Results : l_actual_start_date is 04-Oct-2003, l_actual_end_date is 14-Oct-2003
4084 -- Example 2 Results : l_actual_start_date is 04-Oct-2003, l_actual_end_date is 14-Oct-2003
4085
4086 IF l_actual_start_date IS NULL THEN
4087 -- This will happen when all 0 or null hours are passed
4088 l_changes_done := false;
4089 ELSE
4090 l_changes_done := true;
4091 l_call_change_duration := true;
4092 l_call_change_work_pattern := true;
4093 -- Start of addition for bug 4183479
4094 FOR i IN (l_actual_start_date-p_start_date+1) .. p_hours_table.LAST LOOP
4095 IF p_hours_table(i) IS NULL THEN
4096 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := 0; -- Bug 3234786 : To make sure that it starts from 1
4097 ELSE
4098 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := p_hours_table(i);-- Bug 3234786 : To make sure that it starts from 1
4099 END IF;
4100 END LOOP;
4101 -- End of addition for bug 4183479
4102 END IF;
4103
4104 -- Example 1 Results : l_changes_done, l_call_change_duration, l_call_change_work_pattern are true
4105 -- Example 2 Results : l_changes_done, l_call_change_duration, l_call_change_work_pattern are true
4106
4107 l_new_assgn_start_date := l_actual_start_date;
4108 l_new_assgn_end_date := p_asgn_end_date;
4109 l_update_work_zero_start_date := l_actual_end_date+1;
4110 l_update_work_zero_end_date := p_asgn_start_date-1;
4111 x_call_timeline_st_date := l_actual_start_date;
4112 x_call_timeline_end_date := l_actual_end_date;
4113
4114 IF l_update_work_zero_end_date >= l_update_work_zero_start_date THEN
4115 l_call_cng_work_patt_out_range := true;
4116 x_call_timeline_st_date := l_actual_start_date;
4117 x_call_timeline_end_date := l_update_work_zero_end_date;
4118 END IF;
4119
4120 -- Example 1 Results : l_new_assgn_start_date is 04-Oct-2003 and l_new_assgn_end_date is 10-Nov-2003
4121 -- So now new assignment date is 04-Oct-2003 to 10-Nov-2003 for which change_duration should be called.
4122 -- l_update_work_zero_start_date is 15-Oct-2003 and l_update_work_zero_end_date is 19-Oct-2003
4123 -- for which change_work_pattern should be called with all 0 hours in monday to sunday
4124 -- x_call_timeline_st_date, and x_call_timeline_end_date for which forecast should be regenerated
4125
4126 -- Example 2 Results : l_new_assgn_start_date is 04-Oct-2003 and l_new_assgn_end_date is 10-Nov-2003
4127 -- So now new assignment date is 04-Oct-2003 to 10-Nov-2003 for which change_duration should be called.
4128 -- l_update_work_zero_start_date is 15-Oct-2003 and l_update_work_zero_end_date is 14-Oct-2003
4129 -- so change_work_pattern should not be called with all 0 hours in monday to sunday. Hence
4130 -- l_call_cng_work_patt_out_range will remain false
4131 -- x_call_timeline_st_date, and x_call_timeline_end_date for which forecast should be regenerated
4132
4133 /* Commented and moved above for Bug 4183479
4134 FOR i IN (l_actual_start_date-p_start_date+1) .. p_hours_table.LAST LOOP
4135 IF p_hours_table(i) IS NULL THEN
4136 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := 0; -- Bug 3234786 : To make sure that it starts from 1
4137 ELSE
4138 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := p_hours_table(i);-- Bug 3234786 : To make sure that it starts from 1
4139 END IF;
4140 END LOOP; */
4141
4142 -- Example 1 Results : l_hours_table has 8,8,8,8,8,8,8,8,8,8,8
4143 -- Example 2 Results : l_hours_table has 8,8,8,8,8,8,8,8,8,8,8
4144
4145 ELSIF p_start_date > p_asgn_end_date THEN
4146 -- Moving Forward Totally outside range
4147
4148 PA_SCHEDULE_UTILS.log_message(1,'Moving Forward Totally outside range');
4149
4150 -- Example 1 : assgn start date is 20-Oct-2003 and assgn end date is 10-Nov-2003
4151 -- p_start_date is 15-Nov-2003 and p_end_date is 28-Nov-2003
4152 -- p_hours_table has 8,null,0,8,8,8,8,8,8,8,8,null,null,null
4153
4154 -- Example 2 : assgn start date is 20-Oct-2003 and assgn end date is 14-Nov-2003
4155 -- p_start_date is 15-Nov-2003 and p_end_date is 28-Nov-2003
4156 -- p_hours_table has 8,null,0,8,8,8,8,8,8,8,8,null,null,null
4157
4158 l_actual_start_date := p_start_date;
4159
4160 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4161 IF p_hours_table(i) IS NOT NULL AND p_hours_table(i) <> 0 THEN
4162 l_actual_end_date := p_start_date + (i-1);
4163 END IF;
4164 END LOOP;
4165
4166 -- Example 1 Results : l_actual_start_date is 15-Nov-2003, l_actual_end_date is 25-Nov-2003
4167 -- Example 2 Results : l_actual_start_date is 15-Nov-2003, l_actual_end_date is 25-Nov-2003
4168
4169 IF l_actual_end_date IS NULL THEN
4170 -- This will happen when all 0 or null hours are passed
4171 l_changes_done := false;
4172 ELSE
4173 l_changes_done := true;
4174 l_call_change_duration := true;
4175 l_call_change_work_pattern := true;
4176 -- Start of addition for bug 4183479
4177 FOR i IN p_hours_table.FIRST .. (l_actual_end_date-p_start_date+1) LOOP
4178 IF p_hours_table(i) IS NULL THEN
4179 l_hours_table(i) := 0;
4180 ELSE
4181 l_hours_table(i) := p_hours_table(i);
4182 END IF;
4183 END LOOP;
4184 -- End of addition for bug 4183479
4185 END IF;
4186
4187 -- Example 1 Results : l_changes_done, l_call_change_duration, l_call_change_work_pattern are true
4188 -- Example 2 Results : l_changes_done, l_call_change_duration, l_call_change_work_pattern are true
4189
4190 l_new_assgn_start_date := p_asgn_start_date;
4191 l_new_assgn_end_date := l_actual_end_date;
4192 l_update_work_zero_start_date := p_asgn_end_date+1;
4193 l_update_work_zero_end_date := l_actual_start_date-1;
4194 x_call_timeline_st_date := l_actual_start_date;
4195 x_call_timeline_end_date := l_actual_end_date;
4196
4197 IF l_update_work_zero_end_date >= l_update_work_zero_start_date THEN
4198 l_call_cng_work_patt_out_range := true;
4199 x_call_timeline_st_date := l_update_work_zero_start_date;
4200 x_call_timeline_end_date := l_actual_end_date;
4201 END IF;
4202
4203 -- Example 1 Results : l_new_assgn_start_date is 20-Oct-2003 and l_new_assgn_end_date is 25-Nov-2003
4204 -- So now new assignment date is 20-Oct-2003 to 25-Nov-2003 for which change_duration should be called.
4205 -- l_update_work_zero_start_date is 11-Nov-2003 and l_update_work_zero_end_date is 14-Nov-2003
4206 -- for which change_work_pattern should be called with all 0 hours in monday to sunday
4207
4208 -- Example 2 Results : l_new_assgn_start_date is 20-Oct-2003 and l_new_assgn_end_date is 25-Nov-2003
4209 -- So now new assignment date is 04-Oct-2003 to 10-Nov-2003 for which change_duration should be called.
4210 -- l_update_work_zero_start_date is 15-Nov-2003 and l_update_work_zero_end_date is 14-Nov-2003
4211 -- so change_work_pattern should not be called with all 0 hours in monday to sunday. Hence
4212 -- l_call_cng_work_patt_out_range will remain false
4213
4214 /* Commented and moved above for Bug 4183479
4215 FOR i IN p_hours_table.FIRST .. (l_actual_end_date-p_start_date+1) LOOP
4216 IF p_hours_table(i) IS NULL THEN
4217 l_hours_table(i) := 0;
4218 ELSE
4219 l_hours_table(i) := p_hours_table(i);
4220 END IF;
4221 END LOOP; */
4222
4223 -- Example 1 Results : l_hours_table has 8,0,0,8,8,8,8,8,8,8,8
4224 -- Example 2 Results : l_hours_table has 8,0,0,8,8,8,8,8,8,8,8
4225
4226 ELSIF (p_start_date BETWEEN p_asgn_start_date AND p_asgn_end_date) AND p_end_date > p_asgn_end_date THEN
4227 -- Moving Forward Partially outside range
4228
4229 PA_SCHEDULE_UTILS.log_message(1,'Moving Forward Partially outside range');
4230
4231 --Changes are done, now further it needs to be determined that whether work pattern has changed or not
4232 l_changes_done := true;
4233 l_actual_start_date := p_start_date;
4234 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4235 IF p_hours_table(i) IS NOT NULL AND p_hours_table(i) <> 0 THEN
4236 l_actual_end_date := p_start_date + (i-1);
4237 END IF;
4238 END LOOP;
4239
4240 IF l_actual_end_date IS NULL THEN
4241 l_actual_end_date := p_asgn_end_date;
4242 -- call change duration will remain false in this case
4243 -- But we need to see further that work pattern changed or not
4244 ELSE
4245 IF l_actual_end_date <= p_asgn_end_date THEN -- cut off in assignment is not possible
4246 l_actual_end_date := p_asgn_end_date;
4247 -- call change duration will remain false in this case
4248 -- But we need to see further that work pattern changed or not
4249 ELSE
4250 l_call_change_duration := true;
4251 l_call_change_work_pattern := true;
4252 END IF;
4253 END IF;
4254
4255 -- x_call_timeline_st_date, and x_call_timeline_end_date for which forecast should be regenerated
4256 x_call_timeline_st_date := l_actual_start_date;
4257 x_call_timeline_end_date := l_actual_end_date;
4258 l_new_assgn_start_date := p_asgn_start_date;
4259 l_new_assgn_end_date := l_actual_end_date;
4260 -- l_call_cng_work_patt_out_range will remain false
4261
4262 FOR i IN p_hours_table.FIRST .. (l_actual_end_date-p_start_date+1) LOOP
4263 IF p_hours_table(i) IS NULL THEN
4264 l_hours_table(i) := 0;
4265 ELSE
4266 l_hours_table(i) := p_hours_table(i);
4267 END IF;
4268 END LOOP;
4269 ELSIF (p_end_date BETWEEN p_asgn_start_date AND p_asgn_end_date) AND p_start_date < p_asgn_start_date THEN
4270 -- Moving Backward Partially outside range
4271
4272 PA_SCHEDULE_UTILS.log_message(1,'Moving Backward Partially outside range');
4273
4274 --Changes are done, now further it needs to be determined that whether work pattern has changed or not
4275 l_changes_done := true;
4276 l_actual_end_date := p_end_date;
4277 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4278 IF p_hours_table(i) IS NOT NULL AND p_hours_table(i) <> 0 THEN
4279 l_actual_start_date := p_start_date + (i-1);
4280 exit; -- As soon as find non zero come out
4281 END IF;
4282 END LOOP;
4283
4284 IF l_actual_start_date IS NULL THEN
4285 -- This will happen when all 0 or null hours are passed
4286 l_actual_start_date := p_asgn_start_date;
4287 ELSE
4288 IF l_actual_start_date >= p_asgn_start_date THEN -- cut off in assignment is not possible
4289 l_actual_start_date := p_asgn_start_date;
4290 -- call change duration will remain false in this case
4291 -- But we need to see further that work pattern changed or not
4292 ELSE
4293 l_call_change_duration := true;
4294 l_call_change_work_pattern := true;
4295 END IF;
4296 END IF;
4297
4298 -- x_call_timeline_st_date, and x_call_timeline_end_date for which forecast should be regenerated
4299 l_new_assgn_start_date := l_actual_start_date;
4300 l_new_assgn_end_date := p_asgn_end_date;
4301 x_call_timeline_st_date := l_actual_start_date;
4302 x_call_timeline_end_date := l_actual_end_date;
4303 -- l_call_cng_work_patt_out_range will remain false
4304
4305 FOR i IN (l_actual_start_date-p_start_date+1) .. p_hours_table.LAST LOOP
4306 IF p_hours_table(i) IS NULL THEN
4307 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := 0;-- Bug 3234786 : To make sure that it starts from 1
4308 ELSE
4309 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := p_hours_table(i);-- Bug 3234786 : To make sure that it starts from 1
4310 END IF;
4311 END LOOP;
4312 ELSIF ((p_asgn_start_date BETWEEN p_start_date AND p_end_date) AND (p_asgn_end_date BETWEEN p_start_date AND p_end_date)) THEN
4313 -- Moving Partially Backward and Forward Both outside range
4314
4315 PA_SCHEDULE_UTILS.log_message(1,'Moving Partially Backward and Forward Both outside range');
4316
4317 --Changes are done, now further it needs to be determined that whether work pattern has changed or not
4318 l_changes_done := true;
4319 l_actual_end_date := p_end_date;
4320 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4321 IF p_hours_table(i) IS NOT NULL AND p_hours_table(i) <> 0 THEN
4322 l_actual_start_date := p_start_date + (i-1);
4323 exit; -- As soon as find non zero come out
4324 END IF;
4325 END LOOP;
4326
4327 FOR i IN p_hours_table.FIRST .. p_hours_table.LAST LOOP
4328 IF p_hours_table(i) IS NOT NULL AND p_hours_table(i) <> 0 THEN
4329 l_actual_end_date := p_start_date + (i-1);
4330 END IF;
4331 END LOOP;
4332
4333 IF l_actual_start_date IS NULL THEN
4334 -- This will happen when all 0 or null hours are passed
4335 l_actual_start_date := p_asgn_start_date;
4336 ELSE
4337 IF l_actual_start_date >= p_asgn_start_date THEN -- cut off in assignment is not possible
4338 l_actual_start_date := p_asgn_start_date;
4339 -- call change duration will remain false in this case
4340 -- But we need to see further that work pattern changed or not
4341 ELSE
4342 l_call_change_duration := true;
4343 l_call_change_work_pattern := true;
4344 END IF;
4345 END IF;
4346
4347 IF l_actual_end_date IS NULL THEN
4348 -- This will happen when all 0 or null hours are passed
4349 l_actual_end_date := p_asgn_end_date;
4350 ELSE
4351 IF l_actual_end_date <= p_asgn_end_date THEN -- cut off in assignment is not possible
4352 l_actual_end_date := p_asgn_end_date;
4353 -- call change duration will remain false in this case
4354 -- But we need to see further that work pattern changed or not
4355 ELSE
4356 l_call_change_duration := true;
4357 l_call_change_work_pattern := true;
4358 END IF;
4359 END IF;
4360
4361 -- x_call_timeline_st_date, and x_call_timeline_end_date for which forecast should be regenerated
4362 l_new_assgn_start_date := l_actual_start_date;
4363 l_new_assgn_end_date := l_actual_end_date;
4364 x_call_timeline_st_date := l_actual_start_date;
4365 x_call_timeline_end_date := l_actual_end_date;
4366 -- l_call_cng_work_patt_out_range will remain false
4367
4368 FOR i IN (l_actual_start_date-p_start_date+1) .. (l_actual_end_date-p_start_date+1) LOOP
4369 IF p_hours_table(i) IS NULL THEN
4370 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := 0;-- Bug 3234786 : To make sure that it starts from 1
4371 ELSE
4372 l_hours_table(i-(l_actual_start_date-p_start_date+1)+1) := p_hours_table(i);-- Bug 3234786 : To make sure that it starts from 1
4373 END IF;
4374 END LOOP;
4375
4376
4377 END IF; --(p_start_date BETWEEN p_asgn_start_date AND p_asgn_end_date) AND (p_end_date BETWEEN p_asgn_start_date AND p_asgn_end_date)) THEN
4378
4379 -- Parameters Detrmination Phase Ends
4380 PA_SCHEDULE_UTILS.log_message(1,'Parameters Detrmination Phase Ends');
4381 PA_SCHEDULE_UTILS.log_message(1,'Parameters Are ...');
4382 PA_SCHEDULE_UTILS.log_message(1,'l_actual_start_date='||l_actual_start_date);
4383 PA_SCHEDULE_UTILS.log_message(1,'l_actual_end_date='||l_actual_end_date);
4384 PA_SCHEDULE_UTILS.log_message(1,'l_new_assgn_start_date='||l_new_assgn_start_date);
4385 PA_SCHEDULE_UTILS.log_message(1,'l_new_assgn_end_date='||l_new_assgn_end_date);
4386 PA_SCHEDULE_UTILS.log_message(1,'l_update_work_zero_start_date='||l_update_work_zero_start_date);
4387 PA_SCHEDULE_UTILS.log_message(1,'l_update_work_zero_end_date='||l_update_work_zero_end_date);
4388
4389
4390 IF l_changes_done THEN
4391 PA_SCHEDULE_UTILS.log_message(1,'l_changes_done is true');
4392
4393 -- Initialization of hours table
4394 -- These tables will be used while calling change_work_pattern
4395
4396 FOR i in 1..2 LOOP
4397 l_monday_hours(i):=-99;
4398 l_tuesday_hours(i):=-99;
4399 l_wednesday_hours(i):=-99;
4400 l_thursday_hours(i):=-99;
4401 l_friday_hours(i):=-99;
4402 l_saturday_hours(i):=-99;
4403 l_sunday_hours(i):= -99;
4404 END LOOP;
4405 /*Placed the call here for the bug 3421637*/
4406 IF l_call_change_duration THEN
4407 PA_SCHEDULE_UTILS.log_message(1,'l_call_change_duration is true');
4408
4409 PA_SCHEDULE_UTILS.log_message(1,'Calling change_duration');
4410 PA_SCHEDULE_UTILS.log_message(1,'l_new_assgn_start_date='||l_new_assgn_start_date);
4411 PA_SCHEDULE_UTILS.log_message(1,'l_new_assgn_end_date='||l_new_assgn_end_date);
4412
4413 pa_schedule_pub.change_duration(
4414 p_record_version_number => p_record_version_number,
4415 p_exception_type_code => 'CHANGE_DURATION' ,
4416 p_project_id => p_project_id ,
4417 p_calendar_id => p_calendar_id ,
4418 p_assignment_id => p_assignment_id ,
4419 p_assignment_type => p_assignment_type ,
4420 p_start_date => l_new_assgn_start_date ,
4421 p_end_date => l_new_assgn_end_date ,
4422 p_assignment_status_code => p_assignment_status_code ,
4423 p_asgn_start_date => p_asgn_start_date ,
4424 p_asgn_end_date => p_asgn_end_date ,
4425 p_init_msg_list => FND_API.G_FALSE ,
4426 p_generate_timeline_flag => 'N' ,
4427 x_return_status => x_return_status ,
4428 x_msg_count => x_msg_count ,
4429 x_msg_data => x_msg_data) ;
4430
4431 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4432 raise API_ERROR;
4433 END IF;
4434
4435 -- There is a gap found, so need to fill this with 0 hours
4436 IF l_call_cng_work_patt_out_range THEN
4437 PA_SCHEDULE_UTILS.log_message(1,'l_call_cng_work_patt_out_range is true');
4438
4439 pa_schedule_pub.change_work_pattern(
4440 p_record_version_number => p_record_version_number ,
4441 p_project_id => p_project_id ,
4442 p_calendar_id => p_calendar_id ,
4443 p_assignment_id => p_assignment_id ,
4444 p_assignment_type => p_assignment_type ,
4445 p_start_date => l_update_work_zero_start_date ,
4446 p_end_date => l_update_work_zero_end_date ,
4447 p_monday_hours => 0 ,
4448 p_tuesday_hours => 0 ,
4449 p_wednesday_hours => 0 ,
4450 p_thursday_hours => 0 ,
4451 p_friday_hours => 0 ,
4452 p_saturday_hours => 0 ,
4453 p_sunday_hours => 0 ,
4454 p_asgn_start_date => l_new_assgn_start_date ,
4455 p_asgn_end_date => l_new_assgn_end_date ,
4456 p_init_msg_list => FND_API.G_FALSE ,
4457 p_last_row_flag => 'Y' , --Changed 'N' to 'Y' for Bug 4165970.
4458 p_generate_timeline_flag => 'N' ,
4459 x_return_status => x_return_status ,
4460 x_msg_count => x_msg_count ,
4461 x_msg_data => x_msg_data) ;
4462
4463 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4464 raise API_ERROR;
4465 END IF;
4466 END IF; -- l_call_cng_work_patt_out_range THEN
4467
4468 END IF; -- l_call_change_duration THEN*
4469
4470 PA_SCHEDULE_UTILS.log_message(1,'Calling pa_schedule_pvt.get_assignment_schedule');
4471
4472 pa_schedule_pvt.get_assignment_schedule ( p_assignment_id => p_assignment_id ,
4473 p_start_date => l_actual_start_date ,
4474 p_end_date => l_actual_end_date ,
4475 x_sch_record_tab => l_sch_record_tab ,
4476 x_return_status => x_return_status ,
4477 x_msg_count => x_msg_count ,
4478 x_msg_data => x_msg_data) ;
4479
4480
4481
4482 -- get_assignment_schedule will return 0 records in l_sch_record_tab, if given dates are
4483 -- outside the assignment range. So we need to populate the l_sch_record_tab with one row here
4484
4485 IF l_sch_record_tab.COUNT = 0 THEN
4486 l_sch_record_tab(1).start_date := l_actual_start_date;
4487 l_sch_record_tab(1).end_date := l_actual_end_date;
4488 l_sch_record_tab(1).monday_hours := 0;
4489 l_sch_record_tab(1).tuesday_hours := 0;
4490 l_sch_record_tab(1).wednesday_hours := 0;
4491 l_sch_record_tab(1).thursday_hours := 0;
4492 l_sch_record_tab(1).friday_hours := 0;
4493 l_sch_record_tab(1).saturday_hours := 0;
4494 l_sch_record_tab(1).sunday_hours := 0;
4495 END IF;
4496
4497 PA_SCHEDULE_UTILS.log_message(1,'After calling pa_schedule_pvt.get_assignment_schedule l_sch_record_tab.count='||l_sch_record_tab.count);
4498
4499 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4500 raise API_ERROR;
4501 END IF;
4502
4503
4504 -- Put the monday..sunday hours in the l_hours_db_table table which stores the data base values of the
4505 -- schedule records. Also find out the monday..sunday hours to be passed to change_work_pattern
4506 /* Start of Addition for bug 4068167 */
4507 Begin
4508 select decode(l_global_week_start_day,1,1,2,0,3,6,4,5,5,4,6,3,7,2,0) into l_days_to_inc from dual;
4509 END;
4510 /* End of addition for bug 4068167 */
4511
4512 IF l_sch_record_tab.COUNT > 0 THEN
4513 l_counter := 1;
4514 FOR j IN l_sch_record_tab.FIRST..l_sch_record_tab.LAST LOOP
4515 l_date := l_sch_record_tab(j).start_date;
4516
4517 IF l_sch_record_tab(j).start_date IS NOT NULL AND l_sch_record_tab(j).end_date IS NOT NULL THEN
4518 LOOP
4519 l_week_day := TO_CHAR(l_date, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN');
4520
4521 IF l_week_day = 'MON' THEN
4522 l_hours_db_table(l_counter) := l_sch_record_tab(j).monday_hours;
4523 /*Modified the if condition as below for the bug 3421637*/
4524 --IF l_monday_hours(1) = -99
4525 /* Commented for bug 4068167 IF l_monday_hours(1) = -99 and (l_date = p_start_Date
4526 OR (l_date = p_start_date + 7 and l_actual_start_date > p_start_date+6)) */
4527 -- Start of addition for bug 4068167
4528 l_actual_days_to_inc := l_days_to_inc;
4529 if (l_actual_days_to_inc>6) then
4530 l_actual_days_to_inc := l_actual_days_to_inc - 7 ;
4531 end if ;
4532 IF l_monday_hours(1) = -99 and (l_date = p_start_Date + l_actual_days_to_inc
4533 OR (l_date = p_start_date + l_actual_days_to_inc + 7 and l_actual_start_date > p_start_date+6)) -- End of addition for bug 4068167
4534 THEN
4535 l_monday_hours(1) := l_hours_table(l_counter);
4536 ELSE
4537 l_monday_hours(2) := l_hours_table(l_counter);
4538 END IF;
4539 l_counter := l_counter+1;
4540 ELSIF l_week_day = 'TUE' THEN
4541 l_hours_db_table(l_counter) := l_sch_record_tab(j).tuesday_hours;
4542 /*Modified the if condition as below for the bug 3421637*/
4543 --IF l_tuesday_hours(1) = -99
4544 /* Commented for bug 4068167 IF l_tuesday_hours(1) = -99 AND (l_date = p_start_Date + 1
4545 OR (l_date = p_start_date + 8 and l_actual_start_date > p_start_date+6)) */
4546 -- Start of addition for bug 4068167
4547 l_actual_days_to_inc := l_days_to_inc + 1;
4548 if (l_actual_days_to_inc>6) then
4549 l_actual_days_to_inc := l_actual_days_to_inc - 7 ;
4550 end if ;
4551 IF l_tuesday_hours(1) = -99 AND (l_date = p_start_Date + l_actual_days_to_inc
4552 OR (l_date = p_start_date + l_actual_days_to_inc + 7 and l_actual_start_date > p_start_date+6)) -- End of addition for bug 4068167
4553 THEN
4554 l_tuesday_hours(1) := l_hours_table(l_counter);
4555 ELSE
4556 l_tuesday_hours(2) := l_hours_table(l_counter);
4557 END IF;
4558 l_counter := l_counter+1;
4559 ELSIF l_week_day = 'WED' THEN
4560 l_hours_db_table(l_counter) := l_sch_record_tab(j).wednesday_hours;
4561 /*Modified the if condition as below for the bug 3421637*/
4562 --IF l_wednesday_hours(1) = -99
4563 /*Commented for bug 4068167 IF l_wednesday_hours(1) = -99 AND (l_date = p_start_Date + 2
4564 OR (l_date = p_start_date + 9 and l_actual_start_date > p_start_date+6))*/
4565 -- Start of addition for bug 4068167
4566 l_actual_days_to_inc := l_days_to_inc + 2;
4567 if (l_actual_days_to_inc>6) then
4568 l_actual_days_to_inc := l_actual_days_to_inc - 7 ;
4569 end if ;
4570 IF l_wednesday_hours(1) = -99 AND (l_date = p_start_Date + l_actual_days_to_inc
4571 OR (l_date = p_start_date + l_actual_days_to_inc + 7 and l_actual_start_date > p_start_date+6)) -- End of addition for bug 4068167
4572 THEN
4573 l_wednesday_hours(1) := l_hours_table(l_counter);
4574 ELSE
4575 l_wednesday_hours(2) := l_hours_table(l_counter);
4576 END IF;
4577 l_counter := l_counter+1;
4578 ELSIF l_week_day = 'THU' THEN
4579 l_hours_db_table(l_counter) := l_sch_record_tab(j).thursday_hours;
4580 /* Commented for bug 4068167 Modified the if condition as below for the bug 3421637*/
4581 --IF l_thursday_hours(1) = -99
4582 /*IF l_thursday_hours(1) = -99 AND (l_date = p_start_Date + 3
4583 OR (l_date = p_start_date + 10 and l_actual_start_date > p_start_date+6))*/
4584 -- Start of addition for bug 4068167
4585 l_actual_days_to_inc := l_days_to_inc + 3;
4586 if (l_actual_days_to_inc>6) then
4587 l_actual_days_to_inc := l_actual_days_to_inc - 7 ;
4588 end if ;
4589 IF l_thursday_hours(1) = -99 AND (l_date = p_start_Date + l_actual_days_to_inc
4590 OR (l_date = p_start_date + l_actual_days_to_inc + 7 and l_actual_start_date > p_start_date+6)) -- End of addition for bug 4068167
4591 THEN
4592 l_thursday_hours(1) := l_hours_table(l_counter);
4593 ELSE
4594 l_thursday_hours(2) := l_hours_table(l_counter);
4595 END IF;
4596 l_counter := l_counter+1;
4597 ELSIF l_week_day = 'FRI' THEN
4598 l_hours_db_table(l_counter) := l_sch_record_tab(j).friday_hours;
4599 /*Modified the if condition as below for the bug 3421637*/
4600 --IF l_friday_hours(1) = -99
4601 /* Commented for bug 4068167 IF l_friday_hours(1) = -99 AND (l_date = p_start_Date + 4
4602 OR (l_date = p_start_date + 11 and l_actual_start_date > p_start_date+6)) */
4603 -- Start of addition for bug 4068167
4604 l_actual_days_to_inc := l_days_to_inc + 4;
4605 if (l_actual_days_to_inc>6) then
4606 l_actual_days_to_inc := l_actual_days_to_inc - 7 ;
4607 end if ;
4608 IF l_friday_hours(1) = -99 AND (l_date = p_start_Date + l_actual_days_to_inc
4609 OR (l_date = p_start_date + l_actual_days_to_inc + 7 and l_actual_start_date > p_start_date+6)) -- End of addition for bug 4068167
4610 THEN
4611 l_friday_hours(1) := l_hours_table(l_counter);
4612 ELSE
4613 l_friday_hours(2) := l_hours_table(l_counter);
4614 END IF;
4615 l_counter := l_counter+1;
4616 ELSIF l_week_day = 'SAT' THEN
4617 l_hours_db_table(l_counter) := l_sch_record_tab(j).saturday_hours;
4618 /*Modified the if condition as below for the bug 3421637*/
4619 --IF l_saturday_hours(1) = -99
4620 /* Commented for bug 4068167 IF l_saturday_hours(1) = -99 AND (l_date = p_start_Date + 5
4621 OR (l_date = p_start_date + 12 and l_actual_start_date > p_start_date+6)) */
4622 -- Start of addition for bug 4068167
4623 l_actual_days_to_inc := l_days_to_inc + 5;
4624 if (l_actual_days_to_inc>6) then
4625 l_actual_days_to_inc := l_actual_days_to_inc - 7 ;
4626 end if ;
4627 IF l_saturday_hours(1) = -99 AND (l_date = p_start_Date + l_actual_days_to_inc
4628 OR (l_date = p_start_date + l_actual_days_to_inc + 7 and l_actual_start_date > p_start_date+6)) -- End of addition for bug 4068167
4629 THEN
4630 l_saturday_hours(1) := l_hours_table(l_counter);
4631 ELSE
4632 l_saturday_hours(2) := l_hours_table(l_counter);
4633 END IF;
4634 l_counter := l_counter+1;
4635 ELSIF l_week_day = 'SUN' THEN
4636 l_hours_db_table(l_counter) := l_sch_record_tab(j).sunday_hours;
4637 /*Modified the if condition as below for the bug 3421637*/
4638 --IF l_sunday_hours(1) = -99
4639 /* Commented for bug 4068167 IF l_sunday_hours(1) = -99 AND (l_date = p_start_Date + 6
4640 OR (l_date = p_start_date + 13 and l_actual_start_date > p_start_date+6)) */
4641 -- Start of addition for bug 4068167
4642 l_actual_days_to_inc := l_days_to_inc + 6;
4643 if (l_actual_days_to_inc>6) then
4644 l_actual_days_to_inc := l_actual_days_to_inc - 7 ;
4645 end if ;
4646 IF l_sunday_hours(1) = -99 AND (l_date = p_start_Date + l_actual_days_to_inc
4647 OR (l_date = p_start_date + l_actual_days_to_inc + 7 and l_actual_start_date > p_start_date+6)) -- End of addition for bug 4068167
4648 THEN
4649 l_sunday_hours(1) := l_hours_table(l_counter);
4650 ELSE
4651 l_sunday_hours(2) := l_hours_table(l_counter);
4652 END IF;
4653 l_counter := l_counter+1;
4654 END IF;
4655
4656 l_date := l_date + 1;
4657
4658 EXIT WHEN trunc(l_date) > trunc(l_sch_record_tab(j).end_date);
4659 END LOOP;
4660 END IF; -- l_sch_record_tab(j).start_date IS NOT NULL AND l_sch_record_tab(j).end_date IS NOT NULL THEN
4661 END LOOP; -- j IN l_sch_record_tab.FIRST..l_sch_record_tab.LAST LOOP
4662 END IF; -- l_sch_record_tab.COUNT > 0 THEN
4663
4664 PA_SCHEDULE_UTILS.log_message(1,'After populating the monday..sunday hours tables and l_hours_db_table ');
4665
4666 -- Compare the passed hours with the database values. If no changes then no need to call change_work_pattern
4667 -- if l_call_change_duration then it means work pattern changes will be alwyas there
4668 IF l_call_change_duration = false THEN
4669 FOR i IN l_hours_db_table.FIRST..l_hours_db_table.LAST LOOP
4670 IF l_hours_db_table(i) <> l_hours_table(i) THEN
4671 l_call_change_work_pattern := true;
4672 END IF;
4673 END LOOP;
4674 END IF;
4675
4676 IF l_call_change_duration = false AND l_call_change_work_pattern = false THEN
4677 x_call_timeline_st_date := null;
4678 x_call_timeline_end_date := null;
4679 --x_person_id := null;
4680 --return;
4681 END IF;
4682
4683 -- Now all parameters for calling API's are determined. Now start calling them
4684
4685 -- Returning the person_id back to the calling environment so that it does not have to fetch
4686 --x_person_id := PA_FORECAST_ITEMS_UTILS.get_person_id(p_resource_id);
4687
4688
4689 -- Initialize the monday..sinday hours table with 0 if data is not populated already
4690 -- Note that in First set of hours at least one day will have at least one non -99 value
4691
4692 IF l_monday_hours(1) = -99 THEN
4693 l_monday_hours(1) := 0;
4694 END IF;
4695 IF l_tuesday_hours(1) = -99 THEN
4696 l_tuesday_hours(1) := 0;
4697 END IF;
4698 IF l_wednesday_hours(1) = -99 THEN
4699 l_wednesday_hours(1) := 0;
4700 END IF;
4701 IF l_thursday_hours(1) = -99 THEN
4702 l_thursday_hours(1) := 0;
4703 END IF;
4704 IF l_friday_hours(1) = -99 THEN
4705 l_friday_hours(1) := 0;
4706 END IF;
4707 IF l_saturday_hours(1) = -99 THEN
4708 l_saturday_hours(1) := 0;
4709 END IF;
4710 IF l_sunday_hours(1) = -99 THEN
4711 l_sunday_hours(1) := 0;
4712 END IF;
4713
4714 /*Added for the bug 3421637*/
4715 IF l_monday_hours(2) = -99 THEN
4716 l_monday_hours(2) := 0;
4717 END IF;
4718 IF l_tuesday_hours(2) = -99 THEN
4719 l_tuesday_hours(2) := 0;
4720 END IF;
4721 IF l_wednesday_hours(2) = -99 THEN
4722 l_wednesday_hours(2) := 0;
4723 END IF;
4724 IF l_thursday_hours(2) = -99 THEN
4725 l_thursday_hours(2) := 0;
4726 END IF;
4727 IF l_friday_hours(2) = -99 THEN
4728 l_friday_hours(2) := 0;
4729 END IF;
4730 IF l_saturday_hours(2) = -99 THEN
4731 l_saturday_hours(2) := 0;
4732 END IF;
4733 IF l_sunday_hours(2) = -99 THEN
4734 l_sunday_hours(2) := 0;
4735 END IF;
4736 /*Added till here for the bug 3421637*/
4737 -- If Only 7 days records are passed then no need to call change_work_pattern second time.
4738 -- Otherwise we need to call it two times.
4739
4740 /*Addition for the bug 3421637 starts*/
4741 l_call_second_time := False;
4742
4743 IF (l_actual_start_date - p_start_date) <= 6
4744 AND (l_actual_end_date - p_start_date ) >= 6
4745 THEN
4746 l_call_second_time := True;
4747 END IF;
4748
4749 If l_call_second_time THEN
4750 l_ch_work_pattern_st_date1 := l_actual_start_date;
4751 l_ch_work_pattern_end_date1 := p_start_date + 6; --l_actual_start_date+6;
4752 l_ch_work_pattern_st_date2 := p_start_date + 7; --l_actual_start_date+7;
4753 l_ch_work_pattern_end_date2 := l_actual_end_date;
4754 l_call_first_time := false;
4755 for i in 1 .. (l_ch_work_pattern_end_date1 - l_ch_work_pattern_st_date1) + 1 LOOP
4756 IF l_hours_db_table(i) <> l_hours_table(i) THEN
4757 l_call_first_time := true;
4758 exit;
4759 END IF;
4760 END LOOP;
4761 l_call_second_time := false;
4762 for i in (l_ch_work_pattern_st_date2 - l_ch_work_pattern_st_date1) +1 ..
4763 (l_ch_work_pattern_end_date2 - l_ch_work_pattern_st_date1) + 1 LOOP
4764 IF l_hours_db_table(i) <> l_hours_table(i) THEN
4765 l_call_second_time := true;
4766 exit;
4767 END IF;
4768 END LOOP;
4769
4770 ELSE
4771 l_ch_work_pattern_st_date1 := l_actual_start_date;
4772 l_ch_work_pattern_end_date1 := l_actual_end_date;
4773 l_call_first_time := false;
4774 for i in 1 .. (l_ch_work_pattern_end_date1 - l_ch_work_pattern_st_date1) + 1 LOOP
4775 IF l_hours_db_table(i) <> l_hours_table(i) THEN
4776 l_call_first_time := true;
4777 exit;
4778 END IF;
4779 END LOOP;
4780 END IF;
4781
4782 /*Addition for the bug 3421637 ends*/
4783
4784 /*Commenting the below code for the bug 3421637*/
4785
4786 /* IF (l_actual_end_date - l_actual_start_date) <= 6 THEN
4787 l_ch_work_pattern_st_date1 := l_actual_start_date;
4788 l_ch_work_pattern_end_date1 := l_actual_end_date;
4789 l_call_second_time := false;
4790 ELSE
4791 l_ch_work_pattern_st_date1 := l_actual_start_date;
4792 l_ch_work_pattern_end_date1 := l_actual_start_date+6;
4793 l_ch_work_pattern_st_date2 := l_actual_start_date+7;
4794 l_ch_work_pattern_end_date2 := l_actual_end_date;
4795 l_call_second_time := true;
4796
4797 -- If need to call second time then Initialize the second set of monday..sunday hours
4798 -- table with 0 if data is not populated already
4799 IF l_monday_hours(2) = -99 THEN
4800 l_monday_hours(2) := 0;
4801 END IF;
4802 IF l_tuesday_hours(2) = -99 THEN
4803 l_tuesday_hours(2) := 0;
4804 END IF;
4805 IF l_wednesday_hours(2) = -99 THEN
4806 l_wednesday_hours(2) := 0;
4807 END IF;
4808 IF l_thursday_hours(2) = -99 THEN
4809 l_thursday_hours(2) := 0;
4810 END IF;
4811 IF l_friday_hours(2) = -99 THEN
4812 l_friday_hours(2) := 0;
4813 END IF;
4814 IF l_saturday_hours(2) = -99 THEN
4815 l_saturday_hours(2) := 0;
4816 END IF;
4817 IF l_sunday_hours(2) = -99 THEN
4818 l_sunday_hours(2) := 0;
4819 END IF;
4820 END IF; -- (l_actual_end_date - l_actual_start_date) <= 6 THEN*/
4821 /*Commenting till here for the bug 3421637*/
4822
4823
4824 /*Moved the below call above */
4825 /* IF l_call_change_duration THEN
4826 PA_SCHEDULE_UTILS.log_message(1,'l_call_change_duration is true');
4827
4828 PA_SCHEDULE_UTILS.log_message(1,'Calling change_duration');
4829 PA_SCHEDULE_UTILS.log_message(1,'l_new_assgn_start_date='||l_new_assgn_start_date);
4830 PA_SCHEDULE_UTILS.log_message(1,'l_new_assgn_end_date='||l_new_assgn_end_date);
4831
4832 pa_schedule_pub.change_duration(
4833 p_record_version_number => p_record_version_number,
4834 p_exception_type_code => 'CHANGE_DURATION' ,
4835 p_project_id => p_project_id ,
4836 p_calendar_id => p_calendar_id ,
4837 p_assignment_id => p_assignment_id ,
4838 p_assignment_type => p_assignment_type ,
4839 p_start_date => l_new_assgn_start_date ,
4840 p_end_date => l_new_assgn_end_date ,
4841 p_assignment_status_code => p_assignment_status_code ,
4842 p_asgn_start_date => p_asgn_start_date ,
4843 p_asgn_end_date => p_asgn_end_date ,
4844 p_init_msg_list => FND_API.G_FALSE ,
4845 p_generate_timeline_flag => 'N' ,
4846 x_return_status => x_return_status ,
4847 x_msg_count => x_msg_count ,
4848 x_msg_data => x_msg_data) ;
4849
4850 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4851 raise API_ERROR;
4852 END IF;
4853
4854 -- There is a gap found, so need to fill this with 0 hours
4855 IF l_call_cng_work_patt_out_range THEN
4856 PA_SCHEDULE_UTILS.log_message(1,'l_call_cng_work_patt_out_range is true');
4857
4858 pa_schedule_pub.change_work_pattern(
4859 p_record_version_number => p_record_version_number ,
4860 p_project_id => p_project_id ,
4861 p_calendar_id => p_calendar_id ,
4862 p_assignment_id => p_assignment_id ,
4863 p_assignment_type => p_assignment_type ,
4864 p_start_date => l_update_work_zero_start_date ,
4865 p_end_date => l_update_work_zero_end_date ,
4866 p_monday_hours => 0 ,
4867 p_tuesday_hours => 0 ,
4868 p_wednesday_hours => 0 ,
4869 p_thursday_hours => 0 ,
4870 p_friday_hours => 0 ,
4871 p_saturday_hours => 0 ,
4872 p_sunday_hours => 0 ,
4873 p_asgn_start_date => l_new_assgn_start_date ,
4874 p_asgn_end_date => l_new_assgn_end_date ,
4875 p_init_msg_list => FND_API.G_FALSE ,
4876 p_last_row_flag => 'N' ,
4877 p_generate_timeline_flag => 'N' ,
4878 x_return_status => x_return_status ,
4879 x_msg_count => x_msg_count ,
4880 x_msg_data => x_msg_data) ;
4881
4882 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4883 raise API_ERROR;
4884 END IF;
4885 END IF; -- l_call_cng_work_patt_out_range THEN
4886
4887 END IF; -- l_call_change_duration THEN*/
4888
4889 IF l_call_change_work_pattern THEN
4890
4891 PA_SCHEDULE_UTILS.log_message(1,'l_call_change_work_pattern is true');
4892 PA_SCHEDULE_UTILS.log_message(1,'Calling change_work_pattern first time');
4893 PA_SCHEDULE_UTILS.log_message(1,'l_ch_work_pattern_st_date1='||l_ch_work_pattern_st_date1);
4894 PA_SCHEDULE_UTILS.log_message(1,'l_ch_work_pattern_end_date1='||l_ch_work_pattern_end_date1);
4895
4896 -- Call change_work_pattern for the first 7 days
4897 IF l_call_second_time THEN
4898 l_last_row_flag := 'N';
4899 ELSE
4900 l_last_row_flag := 'Y';
4901 END IF;
4902
4903 If l_call_first_time THEN
4904 pa_schedule_pub.change_work_pattern(
4905 p_record_version_number => p_record_version_number ,
4906 p_project_id => p_project_id ,
4907 p_calendar_id => p_calendar_id ,
4908 p_assignment_id => p_assignment_id ,
4909 p_assignment_type => p_assignment_type ,
4910 p_start_date => l_ch_work_pattern_st_date1 ,
4911 p_end_date => l_ch_work_pattern_end_date1 ,
4912 p_monday_hours => l_monday_hours(1) ,
4913 p_tuesday_hours => l_tuesday_hours(1) ,
4914 p_wednesday_hours => l_wednesday_hours(1) ,
4915 p_thursday_hours => l_thursday_hours(1) ,
4916 p_friday_hours => l_friday_hours(1) ,
4917 p_saturday_hours => l_saturday_hours(1) ,
4918 p_sunday_hours => l_sunday_hours(1) ,
4919 p_asgn_start_date => l_new_assgn_start_date ,
4920 p_asgn_end_date => l_new_assgn_end_date ,
4921 p_init_msg_list => FND_API.G_FALSE ,
4922 p_last_row_flag => l_last_row_flag ,
4923 p_generate_timeline_flag => 'N' ,
4924 x_return_status => x_return_status ,
4925 x_msg_count => x_msg_count ,
4926 x_msg_data => x_msg_data) ;
4927
4928 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4929 raise API_ERROR;
4930 END IF;
4931 END IF;
4932
4933 IF l_call_second_time THEN
4934 PA_SCHEDULE_UTILS.log_message(1,'Calling change_work_pattern second time');
4935 PA_SCHEDULE_UTILS.log_message(1,'l_ch_work_pattern_st_date2='||l_ch_work_pattern_st_date2);
4936 PA_SCHEDULE_UTILS.log_message(1,'l_ch_work_pattern_end_date2='||l_ch_work_pattern_end_date2);
4937
4938 pa_schedule_pub.change_work_pattern(
4939 p_record_version_number => p_record_version_number ,
4940 p_project_id => p_project_id ,
4941 p_calendar_id => p_calendar_id ,
4942 p_assignment_id => p_assignment_id ,
4943 p_assignment_type => p_assignment_type ,
4944 p_start_date => l_ch_work_pattern_st_date2 ,
4945 p_end_date => l_ch_work_pattern_end_date2 ,
4946 p_monday_hours => l_monday_hours(2) ,
4947 p_tuesday_hours => l_tuesday_hours(2) ,
4948 p_wednesday_hours => l_wednesday_hours(2) ,
4949 p_thursday_hours => l_thursday_hours(2) ,
4950 p_friday_hours => l_friday_hours(2) ,
4951 p_saturday_hours => l_saturday_hours(2) ,
4952 p_sunday_hours => l_sunday_hours(2) ,
4953 p_asgn_start_date => l_new_assgn_start_date ,
4954 p_asgn_end_date => l_new_assgn_end_date ,
4955 p_init_msg_list => FND_API.G_FALSE ,
4956 p_last_row_flag => 'Y' ,
4957 p_generate_timeline_flag => 'N' ,
4958 x_return_status => x_return_status ,
4959 x_msg_count => x_msg_count ,
4960 x_msg_data => x_msg_data) ;
4961
4962 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4963 raise API_ERROR;
4964 END IF;
4965 END IF;--l_call_second_time THEN
4966 END IF; --l_call_change_work_pattern THEN
4967
4968 -- Calling create_timeline is important instead of create_forecast_item as
4969 -- assignment_effort also has to be updated.
4970 -- For performance we can call create_forecast_item, but we need to add/subtract
4971 -- the extra effort. This can be done later.
4972
4973 IF ((l_call_change_work_pattern = true) OR(l_call_change_duration = true)) THEN
4974 PA_TIMELINE_PVT.Create_Timeline(
4975 p_assignment_id => p_assignment_id ,
4976 x_return_status => x_return_status ,
4977 x_msg_count => x_msg_count ,
4978 x_msg_data => x_msg_data) ;
4979
4980 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
4981 raise API_ERROR;
4982 END IF;
4983 END IF;
4984
4985 END IF; --l_changes_done THEN
4986
4987 -- The following section should be outside beacuse for the previous assignment
4988 -- there may be changes and some values are there in prev variables.
4989 IF p_prev_call_timeline_st_date IS NOT NULL AND p_prev_call_timeline_st_date < NVL(x_call_timeline_st_date, p_prev_call_timeline_st_date+1) THEN
4990 x_call_timeline_st_date := p_prev_call_timeline_st_date;
4991 END IF;
4992
4993 IF p_prev_call_timeline_end_date IS NOT NULL AND p_prev_call_timeline_end_date > NVL(x_call_timeline_end_date, p_prev_call_timeline_end_date-1) THEN
4994 x_call_timeline_end_date := p_prev_call_timeline_end_date;
4995 END IF;
4996
4997 PA_SCHEDULE_UTILS.log_message(1,'End of change_work_pattern_duration');
4998
4999 -- Note : The calling environment should call the following API if x_call_timeline_st_date and x_call_timeline_end_date is not null
5000 -- PA_FORECASTITEM_PVT.Create_Forecast_Item (
5001 -- p_resource_id => p_resource_id,
5002 -- p_start_date => x_call_timeline_st_date,
5003 -- p_end_date => x_call_timeline_end_date,
5004 -- p_process_mode => 'GENERATE',
5005 -- x_return_status => x_return_status,
5006 -- x_msg_count => x_msg_count,
5007 -- x_msg_data => x_msg_data);
5008
5009
5010
5011 EXCEPTION
5012 WHEN FND_API.G_EXC_ERROR THEN -- Added for Bug 3235656
5013 x_return_status := FND_API.G_RET_STS_ERROR;
5014 x_msg_count := FND_MSG_PUB.Count_Msg;
5015
5016 -- 4537865 : RESET other out params also.
5017 x_call_timeline_st_date := NULL ;
5018 x_call_timeline_end_date := NULL ;
5019
5020 IF x_msg_count = 1 THEN
5021 pa_interface_utils_pub.get_messages
5022 (p_encoded => FND_API.G_TRUE,
5023 p_msg_index => 1,
5024 p_data => x_msg_data,
5025 p_msg_index_out => l_msg_index_out );
5026 END IF;
5027 WHEN API_ERROR THEN
5028 PA_SCHEDULE_UTILS.log_message(1,'User Defined Exception in change_work_pattern_duration API ..');
5029 x_return_status := 'E';
5030 IF x_msg_count = 0 THEN
5031 x_msg_count := 1;
5032 x_msg_data := 'User Defined Exception in change_work_pattern_duration API ..';
5033 END IF;
5034
5035 -- 4537865 : RESET other out params also.
5036 x_call_timeline_st_date := NULL ;
5037 x_call_timeline_end_date := NULL ;
5038
5039 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
5040 p_procedure_name => 'change_work_pattern_duration');
5041 IF x_msg_count = 1 THEN
5042 pa_interface_utils_pub.get_messages
5043 (p_encoded => FND_API.G_TRUE,
5044 p_msg_index => 1,
5045 p_msg_count => x_msg_count,
5046 p_msg_data => x_msg_data,
5047 p_data => l_data, -- 4537865
5048 p_msg_index_out => l_msg_index_out );
5049 x_msg_data := l_data ; -- 4537865
5050 END IF;
5051
5052 WHEN OTHERS THEN
5053 PA_SCHEDULE_UTILS.log_message(1,'ERROR in change_work_pattern_duration API ..'|| sqlerrm);
5054 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5055 x_msg_count := 1;
5056 x_msg_data := substrb(SQLERRM,1,240); -- 4537865 : Chnaged substr to substrb
5057 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
5058 p_procedure_name => 'change_work_pattern_duration');
5059
5060 -- 4537865 : RESET other out params also.
5061 x_call_timeline_st_date := NULL ;
5062 x_call_timeline_end_date := NULL ;
5063
5064 IF x_msg_count = 1 THEN
5065 pa_interface_utils_pub.get_messages
5066 (p_encoded => FND_API.G_TRUE,
5067 p_msg_index => 1,
5068 p_msg_count => x_msg_count,
5069 p_msg_data => x_msg_data,
5070 p_data => l_data, -- 4537865
5071 p_msg_index_out => l_msg_index_out );
5072 x_msg_data := l_data ; -- 4537865
5073 END IF;
5074 RAISE;
5075 END change_work_pattern_duration;
5076
5077 -- Procedure : populate_work_pattern_table
5078 -- Purpose : This procedure is called from self service for populating the global temp table
5079 -- : pa_work_pattern_temp_table for the given assignment start date and assignment
5080 -- : end date. The data will be populated for 14 days starting with Global week start day
5081 -- : <= p_display_start_date. p_status_code is optional, if it is not given then it will
5082 -- : fetch all the assignments irrespective of the assignment schedule status.
5083 -- : Finally it returns the actual start date depending on the global week start date
5084 -- Parameters :
5085 --
5086
5087 PROCEDURE Populate_work_pattern_table (
5088 p_resource_id_tbl IN SYSTEM.PA_NUM_TBL_TYPE ,
5089 p_assgn_range_start_date IN DATE := NULL ,
5090 p_assgn_range_end_date IN DATE := NULL ,
5091 p_display_start_date IN DATE ,
5092 p_status_code IN VARCHAR2 := NULL ,
5093 p_delete_flag IN VARCHAR2 := 'Y' ,
5094 x_show_start_date OUT NOCOPY DATE , --File.Sql.39 bug 4440895
5095 x_return_status OUT NOCOPY VARCHAR2 , --File.Sql.39 bug 4440895
5096 x_msg_count OUT NOCOPY NUMBER , --File.Sql.39 bug 4440895
5097 x_msg_data OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
5098 AS
5099
5100 l_work_pattern_table WORK_PATTERN_TAB_TYPE;
5101 l_resource_id_tbl PA_PLSQL_DATATYPES.IdTabTyp;
5102 l_actual_display_start_date DATE;
5103 l_count NUMBER;
5104 l_where_to_place_counter NUMBER;
5105 l_current_date DATE;
5106 l_qty NUMBER;
5107 l_global_week_start_day NUMBER;
5108 l_global_week_start_day_new NUMBER; /* Added for Bug 5622389 */
5109 l_msg_index_out NUMBER;
5110 l_capacity_label VARCHAR2(80);
5111 l_availability_label VARCHAR2(80);
5112 l_display_start_day NUMBER; --Added for the bug 3648827
5113
5114 l_data varchar2(2000) ; -- 4537865
5115 l_counter_mod NUMBER ; /* Added for Bug 6176678 */
5116 -- This cursor fetches all the assignments for the given filer conditions
5117
5118 CURSOR C_ASSIGNMENTS(l_res_id number) IS
5119 SELECT
5120 project_id,
5121 project_name,
5122 assignment_name,
5123 start_date,
5124 end_date,
5125 status_name,
5126 assignment_id,
5127 resource_id,
5128 status_code,
5129 record_version_number,
5130 assignment_type,
5131 calendar_id,
5132 calendar_type,
5133 project_role_name,
5134 apprvl_status_name,
5135 assignment_effort,
5136 assignment_duration,
5137 project_system_status_code,
5138 --decode(decode(assignment_type, 'STAFFED_ASSIGNMENT', pa_security_pvt.check_user_privilege
5139 --('PA_ASN_SCHEDULE_ED', 'PA_PROJECTS', project_id), 'STAFFED_ADMIN_ASSIGNMENT',
5140 -- pa_security_pvt.check_user_privilege('PA_ADM_ASN_SCHEDULE_ED', 'PA_PROJECTS',project_id)),'Y',1,0) read_only_flag
5141 -- 1 read_only_flag -- Here we are selecting read_only_flag as 0, actual value will be poulated Java side bcoz it does caching
5142 DECODE(mass_wf_in_progress_flag, 'Y', 1,
5143 DECODE(pending_approval_flag, 'Y', 1,
5144 DECODE(apprvl_status_code, 'ASGMT_APPRVL_CANCELED', 1, -- Bug 3235731
5145 DECODE(status_code, null, 0, -- 3235675 This is needed as is_asgmt_allow_stus_ctl_check returns N if status_code is null
5146 DECODE(pa_assignment_utils.is_asgmt_allow_stus_ctl_check(status_code, project_id, 'N'), 'N', 1, 0))))) read_only_flag
5147 FROM pa_project_assignments_v asgn
5148 WHERE asgn.resource_id = l_res_id
5149 AND (
5150 ((p_assgn_range_start_date IS NOT NULL AND p_assgn_range_end_date IS NOT NULL)
5151 AND
5152 (((asgn.start_date between p_assgn_range_start_date AND p_assgn_range_end_date)OR(asgn.end_date between p_assgn_range_start_date AND p_assgn_range_end_date))
5153 OR
5154 ((p_assgn_range_start_date between asgn.start_date AND asgn.end_date)OR(p_assgn_range_end_date between asgn.start_date AND asgn.end_date))
5155 )
5156 )
5157 OR -- Get all assignments excpet those who are end dated before p_assgn_range_start_date
5158 ( p_assgn_range_start_date IS NOT NULL AND p_assgn_range_end_date IS NULL AND asgn.end_date >= p_assgn_range_start_date
5159 )
5160 OR -- Get all assignments excpet those who are started after p_assgn_range_end_date
5161 ( p_assgn_range_start_date IS NULL AND p_assgn_range_end_date IS NOT NULL AND asgn.start_date <= p_assgn_range_end_date
5162 )
5163 )
5164 --AND asgn.status_code=nvl(p_status_code, asgn.status_code) 3235675 This is not needed, Also this is incorrect if status_code is null
5165 AND 'STAFFED_ASGMT_CANCEL' <> nvl(project_system_status_code, 'XYZ') -- Bug 3235731
5166 ORDER BY resource_id, assignment_id; -- This is very important. Logic is woven depending on this order
5167
5168
5169 -- This cursor fetches all the forecast_items for the resource and assignments for the given filer conditions
5170 -- First part before UNION is for resource capacity and next part is for assignment's forecast items
5171
5172 CURSOR c_quantity_cursor(l_res_id number) IS
5173 SELECT
5174 item_date,
5175 capacity_quantity quantity,
5176 --capacity_quantity-(decode(availability_flag,
5177 -- 'Y', decode(sign(capacity_quantity-availability_quantity), 1, 0, availability_quantity),
5178 -- 'N', decode(sign(capacity_quantity-overcommitment_quantity), 1, 0, overcommitment_quantity))) quantity,
5179 resource_id,
5180 forecast_item_type,
5181 -1 assignment_id
5182 FROM pa_forecast_items
5183 WHERE resource_id = l_res_id
5184 AND forecast_item_type = 'U'
5185 AND item_date between l_actual_display_start_date and l_actual_display_start_date+14
5186 AND delete_flag = 'N'
5187 UNION ALL
5188 SELECT
5189 fi.item_date,
5190 fi.item_quantity quantity,
5191 fi.resource_id,
5192 fi.forecast_item_type,
5193 asgn.assignment_id
5194 FROM pa_project_assignments asgn,
5195 pa_forecast_items fi
5196 WHERE asgn.resource_id = l_res_id
5197 AND fi.resource_id = l_res_id
5198 AND fi.delete_flag = 'N'
5199 AND fi.item_date between l_actual_display_start_date and l_actual_display_start_date+13
5200 AND fi.forecast_item_type = 'A'
5201 AND fi.assignment_id = asgn.assignment_id
5202 AND (
5203 ((p_assgn_range_start_date IS NOT NULL AND p_assgn_range_end_date IS NOT NULL)
5204 AND
5205 (((asgn.start_date between p_assgn_range_start_date AND p_assgn_range_end_date)OR(asgn.end_date between p_assgn_range_start_date AND p_assgn_range_end_date))
5206 OR
5207 ((p_assgn_range_start_date between asgn.start_date AND asgn.end_date)OR(p_assgn_range_end_date between asgn.start_date AND asgn.end_date))
5208 )
5209 )
5210 OR -- Get all assignments excpet those who are end dated before p_assgn_range_start_date
5211 ( p_assgn_range_start_date IS NOT NULL AND p_assgn_range_end_date IS NULL AND asgn.end_date >= p_assgn_range_start_date
5212 )
5213 OR -- Get all assignments excpet those who are started after p_assgn_range_end_date
5214 ( p_assgn_range_start_date IS NULL AND p_assgn_range_end_date IS NOT NULL AND asgn.start_date <= p_assgn_range_end_date
5215 )
5216 )
5217 --AND asgn.status_code=nvl(p_status_code, asgn.status_code) 3235675 This is not needed, Also this is incorrect if status_code is null
5218 ORDER BY resource_id, assignment_id, item_date, forecast_item_type desc;
5219
5220 BEGIN
5221 FND_MSG_PUB.initialize;
5222 PA_SCHEDULE_UTILS.log_message(1,'Start of the Populate_work_pattern_table API ... ');
5223 PA_SCHEDULE_UTILS.log_message(1,'Parameters ... ');
5224 PA_SCHEDULE_UTILS.log_message(1,'p_assgn_range_start_date='||p_assgn_range_start_date);
5225 PA_SCHEDULE_UTILS.log_message(1,'p_assgn_range_end_date='||p_assgn_range_end_date);
5226 PA_SCHEDULE_UTILS.log_message(1,'p_display_start_date='||p_display_start_date);
5227 PA_SCHEDULE_UTILS.log_message(1,'p_status_code='||p_status_code);
5228 PA_SCHEDULE_UTILS.log_message(1,'p_delete_flag='||p_delete_flag);
5229 PA_SCHEDULE_UTILS.log_message(1,'p_resource_id_tbl.count='||p_resource_id_tbl.count);
5230
5231
5232 x_return_status := FND_API.G_RET_STS_SUCCESS;
5233 l_global_week_start_day := fnd_profile.value_specific('PA_GLOBAL_WEEK_START_DAY');
5234
5235 /* Code added for Bug 5622389 */
5236 /* To incorporate the difference between PA weekday numbers and */
5237 /* session parameter dependent weekday numbers.*/
5238 Select (to_number(to_char((to_date('01-01-1950','dd-mm-yyyy')+(l_global_week_start_day - 1)),'D')))
5239 into l_global_week_start_day_new
5240 from dual;
5241 /* Code ends for Bug 5622389 */
5242
5243 -- Get the next_day-7 for the given date
5244
5245 BEGIN
5246 /*Commented for the bug 3648827
5247 SELECT next_day(p_display_start_date,decode(l_global_week_start_day,1,'SUNDAY',2,'MONDAY',3,'TUESDAY',4,'WEDNESDAY',5,'THURSDAY',6,'FRIDAY',7,'SATURDAY'))-7
5248 INTO l_actual_display_start_date
5249 FROM dual;*/
5250 /*Added the below code for bug 3648827*/
5251 SELECT to_char(p_display_start_date,'D') INTO l_display_start_day FROM dual;
5252 END;
5253
5254 /*Added the code for the bug 3648827*/
5255 /* Changed l_global_week_start_day to l_global_week_start_day_new for Bug 5622389*/
5256 IF l_global_week_start_day_new > l_display_start_day THEN
5257 l_actual_display_start_date := p_display_start_date - 7 + l_global_week_start_day_new - l_display_start_day;
5258 ELSE
5259 l_actual_display_start_date := p_display_start_date + l_global_week_start_day_new - l_display_start_day ;
5260 END IF;
5261 --IF l_global_week_start_day > l_display_start_day THEN
5262 -- l_actual_display_start_date := p_display_start_date - 7 + l_global_week_start_day - l_display_start_day;
5263 --ELSE
5264 -- l_actual_display_start_date := p_display_start_date + l_global_week_start_day - l_display_start_day ;
5265 --END IF;
5266 /*Commented for the bug 3648827
5267 IF ((p_display_start_date - l_actual_display_start_date)=7) THEN
5268 -- It means already the given date is falling on right global start week day
5269 l_actual_display_start_date := p_display_start_date;
5270 END IF;
5271 */
5272
5273 x_show_start_date := l_actual_display_start_date;
5274
5275 IF p_delete_flag = 'Y' then
5276 DELETE FROM pa_work_pattern_temp_table;
5277 END IF;
5278
5279 --If more than 25 resources than raise error. In phase2 we plan to have this for multiple resources
5280 l_count := p_resource_id_tbl.COUNT;
5281 IF l_count > 25 THEN
5282 null;
5283 END IF;
5284
5285 IF l_count > 0 THEN
5286 FOR i IN p_resource_id_tbl.FIRST .. p_resource_id_tbl.LAST LOOP -- 25 is the limit, later for multiple resources we can keep this in loop
5287 l_resource_id_tbl(i) := p_resource_id_tbl(i);
5288 END LOOP;
5289 END IF;
5290
5291 -- First it makes the plsql table l_work_pattern_table with two rows capacity and availbility/overcommitment
5292 -- These two row's qty fields are initialized with 0 initially in the Initialization part of the code.
5293 -- Then it creates rows for all the assignments for the given filter conditions. It initializes these
5294 -- assignment row's qty fields with 0 or null depending on whether corresponding date is falling in assignment
5295 -- date range or not.
5296 -- After the initialization part, it fethes the forecast items and then loops thru this plsql table
5297 -- and populate the qty fields with respective capacity_quantity(for Capacity row) or item_quantity(for assignment rows).
5298
5299 -- Initialization Part Begin
5300 PA_SCHEDULE_UTILS.log_message(1,'Initialization Begin');
5301
5302 BEGIN
5303 SELECT meaning into l_capacity_label from pa_lookups where lookup_type='PA_CAPC_AVL_LABELS' and lookup_code ='CAPACITY';
5304 SELECT meaning into l_availability_label from pa_lookups where lookup_type='PA_CAPC_AVL_LABELS' and lookup_code ='AVAILABILITY';
5305 END;
5306
5307 l_where_to_place_counter := 0;
5308 l_current_date := l_actual_display_start_date;
5309 FOR i IN l_resource_id_tbl.FIRST .. l_resource_id_tbl.LAST LOOP
5310 -- Initialize the First two rows with 0. These two rows are for Capacity and Availability/Overcommitment
5311 FOR j in 1 .. 2 LOOP
5312 l_current_date := l_actual_display_start_date;
5313 l_where_to_place_counter := l_where_to_place_counter+1;
5314 l_work_pattern_table(l_where_to_place_counter).l_resource_id := l_resource_id_tbl(i);
5315 IF j = 1 THEN
5316 l_work_pattern_table(l_where_to_place_counter).l_assignment_id := -98;
5317 ELSE
5318 l_work_pattern_table(l_where_to_place_counter).l_assignment_id := -99;
5319 END IF;
5320 l_work_pattern_table(l_where_to_place_counter).l_project_role_name := null;
5321 l_work_pattern_table(l_where_to_place_counter).l_project_id := null;
5322 l_work_pattern_table(l_where_to_place_counter).l_status_name := null;
5323 l_work_pattern_table(l_where_to_place_counter).l_read_only_flag := 1;
5324 IF j = 1 THEN
5325 l_work_pattern_table(l_where_to_place_counter).l_assignment_name := l_capacity_label;
5326 ELSE
5327 l_work_pattern_table(l_where_to_place_counter).l_assignment_name := l_availability_label;
5328 END IF;
5329 l_work_pattern_table(l_where_to_place_counter).l_day1 := l_current_date;
5330 l_work_pattern_table(l_where_to_place_counter).l_qty1 := 0;
5331 l_current_date := l_current_date+1;
5332 l_work_pattern_table(l_where_to_place_counter).l_day2 := l_current_date;
5333 l_work_pattern_table(l_where_to_place_counter).l_qty2 := 0;
5334 l_current_date := l_current_date+1;
5335 l_work_pattern_table(l_where_to_place_counter).l_day3 := l_current_date;
5336 l_work_pattern_table(l_where_to_place_counter).l_qty3 := 0;
5337 l_current_date := l_current_date+1;
5338 l_work_pattern_table(l_where_to_place_counter).l_day4 := l_current_date;
5339 l_work_pattern_table(l_where_to_place_counter).l_qty4 := 0;
5340 l_current_date := l_current_date+1;
5341 l_work_pattern_table(l_where_to_place_counter).l_day5 := l_current_date;
5342 l_work_pattern_table(l_where_to_place_counter).l_qty5 := 0;
5343 l_current_date := l_current_date+1;
5344 l_work_pattern_table(l_where_to_place_counter).l_day6 := l_current_date;
5345 l_work_pattern_table(l_where_to_place_counter).l_qty6 := 0;
5346 l_current_date := l_current_date+1;
5347 l_work_pattern_table(l_where_to_place_counter).l_day7 := l_current_date;
5348 l_work_pattern_table(l_where_to_place_counter).l_qty7 := 0;
5349 l_current_date := l_current_date+1;
5350 l_work_pattern_table(l_where_to_place_counter).l_day8 := l_current_date;
5351 l_work_pattern_table(l_where_to_place_counter).l_qty8 := 0;
5352 l_current_date := l_current_date+1;
5353 l_work_pattern_table(l_where_to_place_counter).l_day9 := l_current_date;
5354 l_work_pattern_table(l_where_to_place_counter).l_qty9 := 0;
5355 l_current_date := l_current_date+1;
5356 l_work_pattern_table(l_where_to_place_counter).l_day10 := l_current_date;
5357 l_work_pattern_table(l_where_to_place_counter).l_qty10 := 0;
5358 l_current_date := l_current_date+1;
5359 l_work_pattern_table(l_where_to_place_counter).l_day11 := l_current_date;
5360 l_work_pattern_table(l_where_to_place_counter).l_qty11 := 0;
5361 l_current_date := l_current_date+1;
5362 l_work_pattern_table(l_where_to_place_counter).l_day12 := l_current_date;
5363 l_work_pattern_table(l_where_to_place_counter).l_qty12 := 0;
5364 l_current_date := l_current_date+1;
5365 l_work_pattern_table(l_where_to_place_counter).l_day13 := l_current_date;
5366 l_work_pattern_table(l_where_to_place_counter).l_qty13 := 0;
5367 l_current_date := l_current_date+1;
5368 l_work_pattern_table(l_where_to_place_counter).l_day14 := l_current_date;
5369 l_work_pattern_table(l_where_to_place_counter).l_qty14 := 0;
5370 l_work_pattern_table(l_where_to_place_counter).l_row_type_code := j ; --1:Capacity, 2:Availability/Overcommitment
5371 END LOOP; -- j in 1..2
5372
5373 -- Initialize the next rows with all the assignments with given filter condition
5374
5375 FOR l_asgn IN c_assignments(l_resource_id_tbl(i)) LOOP
5376 /* Added for Bug 6176678 */
5377 /* Now on, if there are any assignments to be displayed, then we will again set both
5378 the (10K+1)th and (10K+2)th rows for Capacity and Availability/Overcommitment
5379 This value 10 is the 'Records Displayed' property of WorkPatternTable item in
5380 WeeklyScheduleRN.xml that we are using to display the records
5381 */
5382
5383 SELECT MOD(l_where_to_place_counter,10)
5384 INTO l_counter_mod
5385 FROM dual;
5386
5387 IF (l_counter_mod = 0 ) THEN
5388
5389 FOR j in 1 .. 2 LOOP
5390 l_current_date := l_actual_display_start_date;
5391 l_where_to_place_counter := l_where_to_place_counter+1;
5392 l_work_pattern_table(l_where_to_place_counter).l_resource_id :=l_resource_id_tbl(i);
5393 IF j = 1 THEN
5394 l_work_pattern_table(l_where_to_place_counter).l_assignment_id := -98;
5395 ELSE
5396 l_work_pattern_table(l_where_to_place_counter).l_assignment_id := -99;
5397 END IF;
5398 l_work_pattern_table(l_where_to_place_counter).l_project_role_name := null;
5399 l_work_pattern_table(l_where_to_place_counter).l_project_id := null;
5400 l_work_pattern_table(l_where_to_place_counter).l_status_name := null;
5401 l_work_pattern_table(l_where_to_place_counter).l_read_only_flag := 1;
5402 IF j = 1 THEN
5403 l_work_pattern_table(l_where_to_place_counter).l_assignment_name := l_capacity_label;
5404 ELSE
5405 l_work_pattern_table(l_where_to_place_counter).l_assignment_name := l_availability_label;
5406 END IF;
5407 l_work_pattern_table(l_where_to_place_counter).l_day1 := l_current_date;
5408 l_work_pattern_table(l_where_to_place_counter).l_qty1 := 0;
5409 l_current_date := l_current_date+1;
5410 l_work_pattern_table(l_where_to_place_counter).l_day2 := l_current_date;
5411 l_work_pattern_table(l_where_to_place_counter).l_qty2 := 0;
5412 l_current_date := l_current_date+1;
5413 l_work_pattern_table(l_where_to_place_counter).l_day3 := l_current_date;
5414 l_work_pattern_table(l_where_to_place_counter).l_qty3 := 0;
5415 l_current_date := l_current_date+1;
5416 l_work_pattern_table(l_where_to_place_counter).l_day4 := l_current_date;
5417 l_work_pattern_table(l_where_to_place_counter).l_qty4 := 0;
5418 l_current_date := l_current_date+1;
5419 l_work_pattern_table(l_where_to_place_counter).l_day5 := l_current_date;
5420 l_work_pattern_table(l_where_to_place_counter).l_qty5 := 0;
5421 l_current_date := l_current_date+1;
5422 l_work_pattern_table(l_where_to_place_counter).l_day6 := l_current_date;
5423 l_work_pattern_table(l_where_to_place_counter).l_qty6 := 0;
5424 l_current_date := l_current_date+1;
5425 l_work_pattern_table(l_where_to_place_counter).l_day7 := l_current_date;
5426 l_work_pattern_table(l_where_to_place_counter).l_qty7 := 0;
5427 l_current_date := l_current_date+1;
5428 l_work_pattern_table(l_where_to_place_counter).l_day8 := l_current_date;
5429 l_work_pattern_table(l_where_to_place_counter).l_qty8 := 0;
5430 l_current_date := l_current_date+1;
5431 l_work_pattern_table(l_where_to_place_counter).l_day9 := l_current_date;
5432 l_work_pattern_table(l_where_to_place_counter).l_qty9 := 0;
5433 l_current_date := l_current_date+1;
5434 l_work_pattern_table(l_where_to_place_counter).l_day10 := l_current_date;
5435 l_work_pattern_table(l_where_to_place_counter).l_qty10 := 0;
5436 l_current_date := l_current_date+1;
5437 l_work_pattern_table(l_where_to_place_counter).l_day11 := l_current_date;
5438 l_work_pattern_table(l_where_to_place_counter).l_qty11 := 0;
5439 l_current_date := l_current_date+1;
5440 l_work_pattern_table(l_where_to_place_counter).l_day12 := l_current_date;
5441 l_work_pattern_table(l_where_to_place_counter).l_qty12 := 0;
5442 l_current_date := l_current_date+1;
5443 l_work_pattern_table(l_where_to_place_counter).l_day13 := l_current_date;
5444 l_work_pattern_table(l_where_to_place_counter).l_qty13 := 0;
5445 l_current_date := l_current_date+1;
5446 l_work_pattern_table(l_where_to_place_counter).l_day14 := l_current_date;
5447 l_work_pattern_table(l_where_to_place_counter).l_qty14 := 0;
5448 l_work_pattern_table(l_where_to_place_counter).l_row_type_code := j ; --1:Capacity, 2:Availability/Overcommitment
5449 END LOOP; -- j in 1..2
5450
5451 END IF ; --IF (l_counter_mod = 0 ) THEN
5452 /* Changes end for Bug 6176678 */
5453
5454 l_current_date := l_actual_display_start_date;
5455 l_where_to_place_counter := l_where_to_place_counter+1;
5456 l_work_pattern_table(l_where_to_place_counter).l_resource_id := l_asgn.resource_id;
5457 l_work_pattern_table(l_where_to_place_counter).l_assignment_id := l_asgn.assignment_id;
5458 l_work_pattern_table(l_where_to_place_counter).l_project_id := l_asgn.project_id;
5459 l_work_pattern_table(l_where_to_place_counter).l_project_name := l_asgn.project_name;
5460 l_work_pattern_table(l_where_to_place_counter).l_assignment_name := l_asgn.assignment_name;
5461 l_work_pattern_table(l_where_to_place_counter).l_start_date := l_asgn.start_date;
5462 l_work_pattern_table(l_where_to_place_counter).l_end_date := l_asgn.end_date;
5463 l_work_pattern_table(l_where_to_place_counter).l_status_name := l_asgn.status_name;
5464 l_work_pattern_table(l_where_to_place_counter).l_status_code := l_asgn.status_code;
5465 l_work_pattern_table(l_where_to_place_counter).l_record_version_number := l_asgn.record_version_number;
5466 l_work_pattern_table(l_where_to_place_counter).l_assignment_type := l_asgn.assignment_type;
5467 l_work_pattern_table(l_where_to_place_counter).l_calendar_id := l_asgn.calendar_id;
5468 l_work_pattern_table(l_where_to_place_counter).l_calendar_type := l_asgn.calendar_type;
5469 l_work_pattern_table(l_where_to_place_counter).l_project_role_name := l_asgn.project_role_name;
5470 l_work_pattern_table(l_where_to_place_counter).l_apprvl_status_name := l_asgn.apprvl_status_name;
5471 l_work_pattern_table(l_where_to_place_counter).l_assignment_effort := l_asgn.assignment_effort;
5472 l_work_pattern_table(l_where_to_place_counter).l_assignment_duration := l_asgn.assignment_duration;
5473 l_work_pattern_table(l_where_to_place_counter).l_project_system_status_code := l_asgn.project_system_status_code;
5474 l_work_pattern_table(l_where_to_place_counter).l_read_only_flag := l_asgn.read_only_flag;
5475 l_work_pattern_table(l_where_to_place_counter).l_day1 := l_current_date;
5476
5477 -- If l_current_date goes outside the assignment date ranges then the qty field should be bull
5478
5479 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5480 l_qty:=null;
5481 ELSE
5482 l_qty:=0;
5483 END IF;
5484 l_work_pattern_table(l_where_to_place_counter).l_qty1 := l_qty;
5485 l_current_date := l_current_date+1;
5486 l_work_pattern_table(l_where_to_place_counter).l_day2 := l_current_date;
5487 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5488 l_qty:=null;
5489 ELSE
5490 l_qty:=0;
5491 END IF;
5492 l_work_pattern_table(l_where_to_place_counter).l_qty2 := l_qty;
5493 l_current_date := l_current_date+1;
5494 l_work_pattern_table(l_where_to_place_counter).l_day3 := l_current_date;
5495 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5496 l_qty:=null;
5497 ELSE
5498 l_qty:=0;
5499 END IF;
5500 l_work_pattern_table(l_where_to_place_counter).l_qty3 := l_qty;
5501 l_current_date := l_current_date+1;
5502 l_work_pattern_table(l_where_to_place_counter).l_day4 := l_current_date;
5503 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5504 l_qty:=null;
5505 ELSE
5506 l_qty:=0;
5507 END IF;
5508 l_work_pattern_table(l_where_to_place_counter).l_qty4 := l_qty;
5509 l_current_date := l_current_date+1;
5510 l_work_pattern_table(l_where_to_place_counter).l_day5 := l_current_date;
5511 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5512 l_qty:=null;
5513 ELSE
5514 l_qty:=0;
5515 END IF;
5516 l_work_pattern_table(l_where_to_place_counter).l_qty5 := l_qty;
5517 l_current_date := l_current_date+1;
5518 l_work_pattern_table(l_where_to_place_counter).l_day6 := l_current_date;
5519 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5520 l_qty:=null;
5521 ELSE
5522 l_qty:=0;
5523 END IF;
5524 l_work_pattern_table(l_where_to_place_counter).l_qty6 := l_qty;
5525 l_current_date := l_current_date+1;
5526 l_work_pattern_table(l_where_to_place_counter).l_day7 := l_current_date;
5527 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5528 l_qty:=null;
5529 ELSE
5530 l_qty:=0;
5531 END IF;
5532 l_work_pattern_table(l_where_to_place_counter).l_qty7 := l_qty;
5533 l_current_date := l_current_date+1;
5534 l_work_pattern_table(l_where_to_place_counter).l_day8 := l_current_date;
5535 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5536 l_qty:=null;
5537 ELSE
5538 l_qty:=0;
5539 END IF;
5540 l_work_pattern_table(l_where_to_place_counter).l_qty8 := l_qty;
5541 l_current_date := l_current_date+1;
5542 l_work_pattern_table(l_where_to_place_counter).l_day9 := l_current_date;
5543 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5544 l_qty:=null;
5545 ELSE
5546 l_qty:=0;
5547 END IF;
5548 l_work_pattern_table(l_where_to_place_counter).l_qty9 := l_qty;
5549 l_current_date := l_current_date+1;
5550 l_work_pattern_table(l_where_to_place_counter).l_day10 := l_current_date;
5551 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5552 l_qty:=null;
5553 ELSE
5554 l_qty:=0;
5555 END IF;
5556 l_work_pattern_table(l_where_to_place_counter).l_qty10 := l_qty;
5557 l_current_date := l_current_date+1;
5558 l_work_pattern_table(l_where_to_place_counter).l_day11 := l_current_date;
5559 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5560 l_qty:=null;
5561 ELSE
5562 l_qty:=0;
5563 END IF;
5564 l_work_pattern_table(l_where_to_place_counter).l_qty11 := l_qty;
5565 l_current_date := l_current_date+1;
5566 l_work_pattern_table(l_where_to_place_counter).l_day12 := l_current_date;
5567 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5568 l_qty:=null;
5569 ELSE
5570 l_qty:=0;
5571 END IF;
5572 l_work_pattern_table(l_where_to_place_counter).l_qty12 := l_qty;
5573 l_current_date := l_current_date+1;
5574 l_work_pattern_table(l_where_to_place_counter).l_day13 := l_current_date;
5575 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5576 l_qty:=null;
5577 ELSE
5578 l_qty:=0;
5579 END IF;
5580 l_work_pattern_table(l_where_to_place_counter).l_qty13 := l_qty;
5581 l_current_date := l_current_date+1;
5582 l_work_pattern_table(l_where_to_place_counter).l_day14 := l_current_date;
5583 IF l_current_date > l_asgn.END_DATE OR l_current_date < l_asgn.START_DATE THEN
5584 l_qty:=null;
5585 ELSE
5586 l_qty:=0;
5587 END IF;
5588 l_work_pattern_table(l_where_to_place_counter).l_qty14 := l_qty;
5589 l_work_pattern_table(l_where_to_place_counter).l_row_type_code := 3 ; --Assignments
5590 END LOOP; -- l_asgn IN c_assignments
5591 END LOOP; -- l_resource_id_tbl.FIRST .. l_resource_id_tbl.LAST
5592
5593 -- Initialization Part End
5594 PA_SCHEDULE_UTILS.log_message(1,'Initialization End');
5595
5596 -- Now loop thru the forecast items and populate the corresponding qty fields in
5597 -- l_work_pattern_table
5598
5599 /* Changes for Bug 6176678
5600 Now, for populating the Capacity rows (that is , l_row_type_code = 1),
5601 we will NOT exit after each IF check.
5602 */
5603
5604 FOR i IN l_resource_id_tbl.FIRST .. l_resource_id_tbl.LAST LOOP
5605 FOR l_temp IN c_quantity_cursor(l_resource_id_tbl(i)) LOOP
5606 FOR j IN l_work_pattern_table.FIRST .. l_work_pattern_table.LAST LOOP
5607 IF l_work_pattern_table(j).l_row_type_code = 1 AND l_temp.resource_id = l_work_pattern_table(j).l_resource_id AND l_temp.forecast_item_type='U' THEN
5608 IF l_temp.item_date = l_work_pattern_table(j).l_day1 THEN
5609 l_work_pattern_table(j).l_qty1 := l_temp.quantity;
5610 --exit;
5611 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day2 THEN
5612 l_work_pattern_table(j).l_qty2 := l_temp.quantity;
5613 --exit;
5614 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day3 THEN
5615 l_work_pattern_table(j).l_qty3 := l_temp.quantity;
5616 --exit;
5617 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day4 THEN
5618 l_work_pattern_table(j).l_qty4 := l_temp.quantity;
5619 --exit;
5620 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day5 THEN
5621 l_work_pattern_table(j).l_qty5 := l_temp.quantity;
5622 --exit;
5623 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day6 THEN
5624 l_work_pattern_table(j).l_qty6 := l_temp.quantity;
5625 --exit;
5626 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day7 THEN
5627 l_work_pattern_table(j).l_qty7 := l_temp.quantity;
5628 --exit;
5629 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day8 THEN
5630 l_work_pattern_table(j).l_qty8 := l_temp.quantity;
5631 --exit;
5632 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day9 THEN
5633 l_work_pattern_table(j).l_qty9 := l_temp.quantity;
5634 --exit;
5635 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day10 THEN
5636 l_work_pattern_table(j).l_qty10 := l_temp.quantity;
5637 --exit;
5638 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day11 THEN
5639 l_work_pattern_table(j).l_qty11 := l_temp.quantity;
5640 --exit;
5641 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day12 THEN
5642 l_work_pattern_table(j).l_qty12 := l_temp.quantity;
5643 --exit;
5644 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day13 THEN
5645 l_work_pattern_table(j).l_qty13 := l_temp.quantity;
5646 --exit;
5647 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day14 THEN
5648 l_work_pattern_table(j).l_qty14 := l_temp.quantity;
5649 --exit;
5650 END IF; -- l_temp.item_date = l_work_pattern_table(j).l_day1 THEN
5651 ELSIF l_work_pattern_table(j).l_row_type_code = 3 AND l_temp.resource_id = l_work_pattern_table(j).l_resource_id AND l_temp.assignment_id=l_work_pattern_table(j).l_assignment_id AND l_temp.forecast_item_type='A' THEN
5652 IF l_temp.item_date = l_work_pattern_table(j).l_day1 THEN
5653 l_work_pattern_table(j).l_qty1 := l_temp.quantity;
5654 exit;
5655 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day2 THEN
5656 l_work_pattern_table(j).l_qty2 := l_temp.quantity;
5657 exit;
5658 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day3 THEN
5659 l_work_pattern_table(j).l_qty3 := l_temp.quantity;
5660 exit;
5661 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day4 THEN
5662 l_work_pattern_table(j).l_qty4 := l_temp.quantity;
5663 exit;
5664 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day5 THEN
5665 l_work_pattern_table(j).l_qty5 := l_temp.quantity;
5666 exit;
5667 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day6 THEN
5668 l_work_pattern_table(j).l_qty6 := l_temp.quantity;
5669 exit;
5670 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day7 THEN
5671 l_work_pattern_table(j).l_qty7 := l_temp.quantity;
5672 exit;
5673 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day8 THEN
5674 l_work_pattern_table(j).l_qty8 := l_temp.quantity;
5675 exit;
5676 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day9 THEN
5677 l_work_pattern_table(j).l_qty9 := l_temp.quantity;
5678 exit;
5679 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day10 THEN
5680 l_work_pattern_table(j).l_qty10 := l_temp.quantity;
5681 exit;
5682 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day11 THEN
5683 l_work_pattern_table(j).l_qty11 := l_temp.quantity;
5684 exit;
5685 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day12 THEN
5686 l_work_pattern_table(j).l_qty12 := l_temp.quantity;
5687 exit;
5688 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day13 THEN
5689 l_work_pattern_table(j).l_qty13 := l_temp.quantity;
5690 exit;
5691 ELSIF l_temp.item_date = l_work_pattern_table(j).l_day14 THEN
5692 l_work_pattern_table(j).l_qty14 := l_temp.quantity;
5693 exit;
5694 END IF; -- l_temp.item_date = l_work_pattern_table(j).l_day1 THEN
5695 END IF;--l_work_pattern_table(j).l_row_type_code = 1 AND l_temp.resource_id = l_work_pattern_table(j).l_resource_id AND l_temp.forecast_item_type='U' THEN
5696 END LOOP; -- j IN l_work_pattern_table.FIRST .. l_work_pattern_table.LAST LOOP
5697 END LOOP;-- l_temp IN c_quantity_cursor(l_resource_id_tbl(i)) LOOP
5698 END LOOP;--i IN l_resource_id_tbl.FIRST .. l_resource_id_tbl.LAST LOOP
5699
5700 PA_SCHEDULE_UTILS.log_message(1,'Inserting data in pa_work_pattern_temp_table');
5701
5702 FOR j IN l_work_pattern_table.FIRST .. l_work_pattern_table.LAST LOOP
5703 INSERT INTO pa_work_pattern_temp_table
5704 (
5705 PROJECT_ID ,
5706 PROJECT_NAME,
5707 ASSIGNMENT_NAME,
5708 START_DATE,
5709 END_DATE,
5710 STATUS_NAME,
5711 ASSIGNMENT_ID,
5712 RESOURCE_ID,
5713 STATUS_CODE,
5714 RECORD_VERSION_NUMBER,
5715 ASSIGNMENT_TYPE,
5716 CALENDAR_ID,
5717 CALENDAR_TYPE,
5718 PROJECT_ROLE_NAME,
5719 APPRVL_STATUS_NAME,
5720 ASSIGNMENT_EFFORT,
5721 ASSIGNMENT_DURATION,
5722 PROJECT_SYSTEM_STATUS_CODE,
5723 DAY1,
5724 DAY2,
5725 DAY3,
5726 DAY4,
5727 DAY5,
5728 DAY6,
5729 DAY7,
5730 DAY8,
5731 DAY9,
5732 DAY10,
5733 DAY11,
5734 DAY12,
5735 DAY13,
5736 DAY14,
5737 QTY1,
5738 QTY2,
5739 QTY3,
5740 QTY4,
5741 QTY5,
5742 QTY6,
5743 QTY7,
5744 QTY8,
5745 QTY9,
5746 QTY10,
5747 QTY11,
5748 QTY12,
5749 QTY13,
5750 QTY14,
5751 row_type_code,
5752 read_only_flag)
5753 values
5754 (
5755 l_work_pattern_table(j).l_PROJECT_ID ,
5756 l_work_pattern_table(j).l_PROJECT_NAME,
5757 l_work_pattern_table(j).l_ASSIGNMENT_NAME,
5758 l_work_pattern_table(j).l_START_DATE,
5759 l_work_pattern_table(j).l_END_DATE,
5760 l_work_pattern_table(j).l_STATUS_NAME,
5761 l_work_pattern_table(j).l_ASSIGNMENT_ID,
5762 l_work_pattern_table(j).l_RESOURCE_ID,
5763 l_work_pattern_table(j).l_STATUS_CODE,
5764 l_work_pattern_table(j).l_RECORD_VERSION_NUMBER,
5765 l_work_pattern_table(j).l_ASSIGNMENT_TYPE,
5766 l_work_pattern_table(j).l_CALENDAR_ID,
5767 l_work_pattern_table(j).l_CALENDAR_TYPE,
5768 l_work_pattern_table(j).l_PROJECT_ROLE_NAME,
5769 l_work_pattern_table(j).l_APPRVL_STATUS_NAME,
5770 l_work_pattern_table(j).l_ASSIGNMENT_EFFORT,
5771 l_work_pattern_table(j).l_ASSIGNMENT_DURATION,
5772 l_work_pattern_table(j).l_PROJECT_SYSTEM_STATUS_CODE,
5773 l_work_pattern_table(j).l_DAY1,
5774 l_work_pattern_table(j).l_DAY2,
5775 l_work_pattern_table(j).l_DAY3,
5776 l_work_pattern_table(j).l_DAY4,
5777 l_work_pattern_table(j).l_DAY5,
5778 l_work_pattern_table(j).l_DAY6,
5779 l_work_pattern_table(j).l_DAY7,
5780 l_work_pattern_table(j).l_DAY8,
5781 l_work_pattern_table(j).l_DAY9,
5782 l_work_pattern_table(j).l_DAY10,
5783 l_work_pattern_table(j).l_DAY11,
5784 l_work_pattern_table(j).l_DAY12,
5785 l_work_pattern_table(j).l_DAY13,
5786 l_work_pattern_table(j).l_DAY14,
5787 l_work_pattern_table(j).l_QTY1,
5788 l_work_pattern_table(j).l_QTY2,
5789 l_work_pattern_table(j).l_QTY3,
5790 l_work_pattern_table(j).l_QTY4,
5791 l_work_pattern_table(j).l_QTY5,
5792 l_work_pattern_table(j).l_QTY6,
5793 l_work_pattern_table(j).l_QTY7,
5794 l_work_pattern_table(j).l_QTY8,
5795 l_work_pattern_table(j).l_QTY9,
5796 l_work_pattern_table(j).l_QTY10,
5797 l_work_pattern_table(j).l_QTY11,
5798 l_work_pattern_table(j).l_QTY12,
5799 l_work_pattern_table(j).l_QTY13,
5800 l_work_pattern_table(j).l_QTY14,
5801 l_work_pattern_table(j).l_row_type_code,
5802 l_work_pattern_table(j).l_read_only_flag) ;
5803 END LOOP;
5804
5805 PA_SCHEDULE_UTILS.log_message(1,'End of Populate_work_pattern_table');
5806 EXCEPTION
5807 WHEN OTHERS THEN
5808 PA_SCHEDULE_UTILS.log_message(1,'ERROR in Populate_work_pattern_table API ..'|| sqlerrm);
5809 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5810 x_msg_count := 1;
5811 x_msg_data := substrb(SQLERRM,1,240); -- 4537865
5812 -- RESET x_show_start_date also
5813 x_show_start_date := NULL ;
5814
5815 FND_MSG_PUB.add_exc_msg( p_pkg_name => 'PA_SCHEDULE_PUB',
5816 p_procedure_name => 'Populate_work_pattern_table');
5817 IF x_msg_count = 1 THEN
5818 pa_interface_utils_pub.get_messages
5819 (p_encoded => FND_API.G_TRUE,
5820 p_msg_index => 1,
5821 p_msg_count => x_msg_count,
5822 p_msg_data => x_msg_data,
5823 p_data => l_data, -- 4537865
5824 p_msg_index_out => l_msg_index_out );
5825 x_msg_data := l_data ; -- 4537865
5826 END IF;
5827 RAISE;
5828
5829 END Populate_work_pattern_table;
5830
5831 -- Unilog Enhancement END
5832
5833 END PA_SCHEDULE_PUB;