1 PACKAGE BODY AHL_UMP_PROCESSUNIT_PVT AS
2 /* $Header: AHLVUMUB.pls 120.35.12020000.3 2013/04/01 02:58:59 sracha ship $ */
3
4 G_PKG_NAME CONSTANT VARCHAR2(30) := 'AHL_UMP_ProcessUnit_PVT';
5 G_DEBUG VARCHAR2(1) := AHL_DEBUG_PUB.is_log_enabled;
6 G_IS_PM_INSTALLED CONSTANT VARCHAR2(1) := AHL_UTIL_PKG.IS_PM_INSTALLED;
7
8 G_CONCURRENT_FLAG VARCHAR2(1);
9
10 -- added to debug concurrent worker pgms failure.
11 G_DEBUG_LINE_NUM NUMBER;
12
13 -- This variable is populated based on the AHL_APPLN_USAGE profile value.
14 -- 11.5.10 enhancement.
15 G_application_usg_code VARCHAR2(30) := fnd_profile.value('AHL_APPLN_USAGE');
16
17 ----------------------------------------------------------------
18 -- Define local record structures used by Process Unit Procedure.
19 ----------------------------------------------------------------
20 -- To hold the counter rules.
21 TYPE counter_rules_rec_type IS RECORD(
22 UOM_CODE VARCHAR2(3),
23 RATIO NUMBER);
24
25 -- To hold the applicable MRs table record.
26 TYPE applicable_mrs_rec_type IS RECORD(
27 CSI_ITEM_INSTANCE_ID NUMBER,
28 MR_HEADER_ID NUMBER,
29 TITLE AHL_MR_HEADERS_VL.TITLE%TYPE,
30 VERSION_NUMBER NUMBER,
31 REPETITIVE_FLAG VARCHAR2(1),
32 SHOW_REPETITIVE_CODE VARCHAR2(30),
33 IMPLEMENT_STATUS_CODE VARCHAR2(30),
34 COPY_ACCOMPLISHMENT_CODE VARCHAR2(30),
35 PRECEDING_MR_HEADER_ID NUMBER,
36 DESCENDENT_COUNT NUMBER,
37 WHICHEVER_FIRST_CODE VARCHAR2(30),
38 PROGRAM_MR_HEADER_ID NUMBER,
39 SERVICE_LINE_ID NUMBER, -- from service contracts for PM installation.
40 PM_SCHEDULE_EXISTS VARCHAR2(1), -- used only for PM installation.
41 CONTRACT_START_DATE DATE, -- used only for PM installation.
42 CONTRACT_END_DATE DATE, -- used only for PM installation.
43 PROGRAM_END_DATE DATE, -- used only for PM installation.
44 COVERAGE_IMP_LEVEL NUMBER, -- used only for PM installation.
45 EFFECTIVE_TO DATE,
46 EFFECTIVE_FROM DATE,
47 -- added for 9263774
48 EXPIRED_MR_FLAG VARCHAR2(1),
49 -- added for SB Enh
50 TERMINATE_TRIGGER_CHECK VARCHAR2(1),
51 ACCOMPLISH_TRIGGER_TYPE VARCHAR2(30),
52 LOOP_CHAIN_SEQ_NUM NUMBER);
53
54 -- To hold the forecast details.
55 TYPE forecast_details_rec_type IS RECORD(
56 START_DATE DATE,
57 END_DATE DATE,
58 UOM_CODE VARCHAR2(3),
59 USAGE_PER_DAY NUMBER,
60 -- JKJain, NR Analysis and Forecasting
61 UTILIZATION_TYPE VARCHAR2(10));
62
63 -- To hold the ahl unit effectivity record details.
64 TYPE unit_effectivity_rec_type IS RECORD(
65 UNIT_EFFECTIVITY_ID NUMBER,
66 STATUS_CODE VARCHAR2(30),
67 DUE_DATE DATE,
68 FORECAST_SEQUENCE NUMBER,
69 RELATED_UE_ID NUMBER,
70 ORIGINATOR_UE_ID NUMBER,
71 VISIT_ASSIGN_FLAG VARCHAR2(1),
72 VISIT_END_DATE DATE,
73 -- added for 9263774
74 PRIOR_MR_HEADER_ID NUMBER);
75
76 -- To hold the calculated next due details.
77 TYPE next_due_date_rec_type IS RECORD(
78 MR_EFFECTIVITY_ID NUMBER,
79 MR_INTERVAL_ID NUMBER,
80 DUE_DATE DATE,
81 DUE_AT_COUNTER_VALUE NUMBER,
82 CURRENT_CTR_VALUE NUMBER,
83 LAST_CTR_VALUE NUMBER,
84 MESSAGE_CODE VARCHAR2(30),
85 TOLERANCE_AFTER NUMBER,
86 TOLERANCE_BEFORE NUMBER,
87 TOLERANCE_FLAG VARCHAR2(1),
88 CTR_UOM_CODE VARCHAR2(3),
89 EARLIEST_DUE_DATE DATE,
90 LATEST_DUE_DATE DATE,
91 COUNTER_ID NUMBER,
92 -- Added to fix bug# 4224867.
93 COUNTER_REMAIN NUMBER,
94 -- JKJain, NR Analysis and Forecasting
95 FLEET_HEADER_ID NUMBER,
96 FLEET_ASSO_REJECTED VARCHAR2(1));
97
98 /*TYPE MR_RELATIONSHIP_REC IS RECORD (
99 MR_HEADER_ID NUMBER,
100 RELATED_MR_HEADER_ID NUMBER,
101 RELATIONSHIP_CODE VARCHAR2(30)); */
102
103 -- To hold the PM program details.
104 TYPE PMprogram_rec_type IS RECORD(
105 PROGRAM_MR_HEADER_ID NUMBER,
106 MR_EFFECTIVITY_ID NUMBER);
107
108 -- Added for Service Bulletin Enhancement
109 TYPE loop_chain_rec_type IS RECORD(
110 MR_HEADER_ID NUMBER,
111 LOOP_CHAIN_SEQ_NUM NUMBER,
112 ACCOMPLISHED_UE_ID NUMBER,
113 ACCOMPLISHMENT_EXISTS VARCHAR2(1),
114 MR_TITLE ahl_mr_headers_b.title%TYPE
115 );
116
117 -- Begin -- Added for performance fix bug# 6893404.
118 -- number table.
119 TYPE nbr_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
120
121 -- varchar2 table.
122 TYPE vchar_tbl_type IS TABLE OF VARCHAR2(400) INDEX BY BINARY_INTEGER;
123
124 -- date table.
125 TYPE date_tbl_type IS TABLE OF DATE INDEX BY BINARY_INTEGER;
126 -- End -- Added for performance fix bug# 6893404.
127
128 ----------------------------------------------
129 -- Define Table Types for record structures --
130 ----------------------------------------------
131 TYPE unit_effectivity_tbl_type IS TABLE OF unit_effectivity_rec_type INDEX BY BINARY_INTEGER;
132 TYPE counter_rules_tbl_type IS TABLE OF counter_rules_rec_type INDEX BY BINARY_INTEGER;
133 TYPE forecast_details_tbl_type IS TABLE OF forecast_details_rec_type INDEX BY BINARY_INTEGER;
134
135 --TYPE MR_RELATIONSHIP_TBL IS TABLE OF MR_RELATIONSHIP_REC INDEX BY BINARY_INTEGER;
136
137 TYPE PMprogram_tbl_type IS TABLE OF PMprogram_rec_type INDEX BY BINARY_INTEGER;
138
139 TYPE loop_chain_MR_tbl_type IS TABLE OF loop_chain_rec_type INDEX BY BINARY_INTEGER;
140 ------------------------------
141 -- Declare Local Procedures --
142 ------------------------------
143 -- To get the unit and master configurations IDs for the input item instance.
144 PROCEDURE Get_Unit_Master_ConfigIDs (p_csi_item_instance_id IN NUMBER,
145 x_uc_header_id OUT NOCOPY NUMBER,
146 x_master_config_id OUT NOCOPY NUMBER);
147
148 -- To get the root item instance for the input item instance if exists.
149 FUNCTION Get_RootInstanceID(p_csi_item_instance_id IN NUMBER)
150 RETURN NUMBER;
151
152 -- Validate the input item instance.
153 PROCEDURE Validate_Item_Instance (p_csi_item_instance_id IN NUMBER,
154 x_inventory_item_id OUT NOCOPY NUMBER,
155 x_inv_master_organization_id OUT NOCOPY NUMBER,
156 x_expired_flag OUT NOCOPY VARCHAR2);
157
158 -- Build the item instance tree containing root nodes and its components.
159 PROCEDURE Build_Config_Tree(p_csi_root_instance_id IN NUMBER,
160 p_master_config_id IN NUMBER,
161 x_config_node_tbl OUT NOCOPY AHL_UMP_PROCESSUNIT_PVT.config_node_tbl_type);
162
163
164 -- To get the last day of the rolling window from profile values.
165 FUNCTION Get_Rolling_Window_Date RETURN DATE;
166
167 -- Procedure to build unit effectivity for ASO Installation.
168 -- Called from Process_Unit API. This procedure uses the global variables
169 -- set in 'Process Unit' API for processing.
170 PROCEDURE Process_ASO_Unit;
171
172 -- Get the utilization forecast applicable to the input item instance/unit.
173 PROCEDURE Get_Utilization_Forecast (p_csi_item_instance_id IN NUMBER,
174 p_uc_header_id IN NUMBER,
175 p_inventory_item_id IN NUMBER,
176 p_inventory_org_id IN NUMBER,
177 x_forecast_details_tbl OUT NOCOPY forecast_details_tbl_type);
178
179 -- Lock all existing unit effectivity records.
180 PROCEDURE Lock_UnitEffectivity_Records(x_ret_code OUT NOCOPY VARCHAR2);
181
182 -- Build the counter ratio that needs to be applied to the item instance based
183 -- on its master configuration position. Input is the item instance.
184 PROCEDURE build_Counter_Ratio(p_position_reference IN VARCHAR2,
185 p_csi_item_instance_id IN NUMBER,
186 p_master_config_id IN NUMBER,
187 x_counter_rules_tbl OUT NOCOPY counter_rules_tbl_type);
188
189 -- Build the current usage on the item instance's counters based on counters attached
190 -- to the item instance.
191 PROCEDURE get_Current_Usage ( p_csi_item_instance_id IN NUMBER,
192 x_current_usage_tbl OUT NOCOPY counter_values_tbl_type );
193
194 -- Get accomplishment details for an MR.
195 -- Added parameter x_no_forecast to fix bug# 6711228
196 -- Added parameter x_accomplished_ue_id to fix bug# 8994566
197 PROCEDURE get_accomplishment_details (p_applicable_mrs_rec IN applicable_mrs_rec_type,
198 p_current_usage_tbl IN counter_values_tbl_type,
199 p_counter_rules_tbl IN counter_rules_tbl_type,
200 x_accomplishment_date OUT NOCOPY DATE,
201 x_last_acc_counter_val_tbl OUT NOCOPY counter_values_tbl_type,
202 x_one_time_mr_flag OUT NOCOPY BOOLEAN,
203 x_dependent_mr_flag OUT NOCOPY BOOLEAN,
204 x_get_preceding_next_due OUT NOCOPY BOOLEAN,
205 x_mr_accomplish_exists OUT NOCOPY BOOLEAN,
206 x_no_forecast_flag OUT NOCOPY BOOLEAN,
207 x_accomplished_ue_id OUT NOCOPY NUMBER);
208
209
210 -- Build unit effectivity for a given item instance and a maintenance requirement.
211 -- The unit effectivities created here will be written into a temporary table.
212 PROCEDURE Build_Effectivity ( p_applicable_mrs_rec IN applicable_mrs_rec_type,
213 p_current_usage_tbl IN counter_values_tbl_type,
214 p_counter_rules_tbl IN counter_rules_tbl_type);
215
216 -- Calculate due date for the item instance and mr using current usage, counter rules,
217 -- last accomplishment counters and forecast (defined in global variable).
218 -- Added parameter p_dependent_mr_flag to fix bug# 6711228.
219 -- Added parameters p_mr_accomplish_exists and p_last_due_mr_interval_id to fix bug# 6858788.
220 PROCEDURE Calculate_Due_Date ( p_repetivity_flag IN VARCHAR2 := 'Y',
221 p_applicable_mrs_rec IN applicable_mrs_rec_type,
222 p_current_usage_tbl IN counter_values_tbl_type,
223 p_counter_rules_tbl IN counter_rules_tbl_type,
224 p_last_due_date IN DATE,
225 p_last_due_counter_val_tbl IN counter_values_tbl_type,
226 p_dependent_mr_flag IN BOOLEAN := FALSE,
227 p_mr_accomplish_exists IN BOOLEAN,
228 p_last_due_mr_interval_id IN NUMBER := NULL,
229 x_next_due_date_rec OUT NOCOPY next_due_date_rec_type);
230
231
232 -- Calculate due at counter values for a given due due from last due date and last due counters using
233 -- counter rules and forecast (defined in global variable).
234 PROCEDURE Get_Due_At_Counter_Values ( p_last_due_date IN DATE,
235 p_last_due_counter_val_tbl IN counter_values_tbl_type,
236 p_due_date IN DATE,
237 p_counter_rules_tbl IN counter_rules_tbl_type,
238 x_due_at_counter_val_tbl OUT NOCOPY counter_values_tbl_type,
239 x_return_value OUT NOCOPY BOOLEAN);
240
241 -- Calculates the due date for the counter_remain from a given start date using forecast, counter rules
242 -- and counter uom.
243 PROCEDURE Get_Date_from_UF ( p_counter_remain IN NUMBER,
244 p_counter_uom_code IN VARCHAR2,
245 p_counter_rules_tbl IN counter_rules_tbl_type,
246 p_start_date IN DATE := NULL,
247 x_due_date OUT NOCOPY DATE);
248
249 -- Apply the counter ratio factor to convert a given counter value at a component level to the
250 -- root instance. This is needed as forecast is only defined at root instance.
251 FUNCTION Apply_Counter_Ratio ( p_counter_remain IN NUMBER,
252 p_counter_uom_code IN VARCHAR2,
253 p_counter_rules_tbl IN counter_rules_tbl_type)
254 RETURN NUMBER;
255
256 -- Apply the counter ratio factor to convert a given counter value at a root instance level to the
257 -- component. This is needed as forecast is only defined at root instance.
258 FUNCTION Apply_ReverseCounter_Ratio ( p_counter_remain IN NUMBER,
259 p_counter_uom_code IN VARCHAR2,
260 p_counter_rules_tbl IN counter_rules_tbl_type)
261 RETURN NUMBER;
262
263 -- This will return the adjusted interval value if the next due counter value overlaps two intervals.
264 -- It will be used where the overflow condition occurs based on the interval's start value and stop value.
265 PROCEDURE Adjust_Interval_Value ( p_mr_effectivity_id IN NUMBER,
266 p_counter_id IN NUMBER,
267 p_counter_value IN NUMBER,
268 p_interval_value IN NUMBER,
269 p_stop_value IN NUMBER,
270 x_adjusted_int_value OUT NOCOPY NUMBER,
271 x_nxt_interval_found OUT NOCOPY BOOLEAN);
272
273 -- This will return the adjusted due date if the next due date overlaps two intervals.
274 -- It will be used where the overflow condition occurs based on the interval's start date and stop date.
275 PROCEDURE Adjust_Due_Date ( p_mr_effectivity_id IN NUMBER,
276 p_start_counter_rec IN counter_values_rec_type,
277 p_start_due_date IN DATE,
278 p_counter_rules_tbl IN counter_rules_tbl_type,
279 p_interval_value IN NUMBER,
280 p_stop_date IN DATE,
281 p_due_date IN DATE,
282 x_adjusted_due_date OUT NOCOPY DATE,
283 x_adjusted_due_ctr OUT NOCOPY NUMBER,
284 x_nxt_interval_found OUT NOCOPY BOOLEAN);
285
286 -- This procedure will return due date based on the next interval(if exists), whenever an interval
287 -- is not found for the current start/stop values or dates.
288 -- Added parameter p_dependent_mr_flag to fix bug# 6711228.
289 -- Added parameter p_mr_accomplish_exists and p_last_due_mr_interval_id to fix bug# 6858788. Commented
290 -- p_last_accomplishment_date and will instead use p_mr_accomplish_exists.
291 PROCEDURE Get_DueDate_from_NxtInterval(p_applicable_mrs_rec IN applicable_mrs_rec_type,
292 p_repetivity_flag IN VARCHAR2,
293 p_mr_effectivity_id IN NUMBER,
294 p_current_ctr_rec IN Counter_values_rec_type,
295 p_current_ctr_at_date IN DATE,
296 p_counter_rules_tbl IN Counter_rules_tbl_type,
297 p_start_int_match_at_ctr IN NUMBER,
298 p_last_accomplish_ctr_val IN NUMBER,
299 --p_last_accomplishment_date IN DATE,
300 p_dependent_mr_flag IN BOOLEAN,
301 p_mr_accomplish_exists IN BOOLEAN,
302 p_last_due_mr_interval_id IN NUMBER,
303 x_next_due_date_rec OUT NOCOPY next_due_date_rec_type,
304 x_mr_interval_found OUT NOCOPY BOOLEAN,
305 x_return_val OUT NOCOPY BOOLEAN);
306
307 -- To write a record into ahl_temp_unit_effectivities.
308 PROCEDURE Create_temp_unit_effectivity (X_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE);
309
310 -- To process the decendents in case the mr is a group MR.
311 PROCEDURE Process_GroupMR (p_applicable_mrs_rec IN applicable_mrs_rec_type,
312 p_new_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE,
313 p_unit_effectivity_tbl IN unit_effectivity_tbl_type,
314 p_old_UE_forecast_sequence IN NUMBER := -1);
315
316 -- To process the dependent MRs based on the value of preceding MR.
317 PROCEDURE Process_PrecedingMR (p_applicable_mrs_rec IN applicable_mrs_rec_type,
318 p_counter_rules_tbl IN counter_rules_tbl_type,
319 p_current_usage_tbl IN counter_values_tbl_type);
320
321
322 -- To update the preceding_check_flag in the temporary unit effectivities table.
323 PROCEDURE Update_check_flag (p_applicable_mrs_rec IN applicable_mrs_rec_type,
324 p_dependent_mr_flag IN BOOLEAN,
325 p_next_due_date_rec IN next_due_date_rec_type);
326
327 -- To log error messages into a log file if called from concurrent process.
328 PROCEDURE log_error_messages;
329
330
331 -------------------------------------------------
332 -- Procedures for Preventive Maintenance Logic --
333 -------------------------------------------------
334 -- Populate applicable MRs temporary table from the output of FMP API.
335 PROCEDURE PopulatePM_Appl_MRs (p_csi_ii_id IN NUMBER,
336 x_return_status OUT NOCOPY VARCHAR2,
337 x_msg_count OUT NOCOPY NUMBER,
338 x_msg_data OUT NOCOPY VARCHAR2,
339 x_UnSch_programs_tbl OUT NOCOPY PMprogram_tbl_type);
340
341 -- Procedure to build instance level effectivity for PM installation
342 -- using service contracts.
343 -- Called from Process_Unit API.
344 PROCEDURE Process_PM_Unit(p_csi_item_instance_id IN NUMBER,
345 p_UnSch_programs_tbl IN PMprogram_tbl_type);
346
347
348 -- Calculate program end date for all MR's where contract is not scheduled.
349 PROCEDURE Calc_program_end_dates (p_UnSch_programs_tbl IN PMprogram_tbl_type,
350 p_current_usage_tbl IN counter_values_tbl_type);
351
352 -- Process records with contract dates scheduled.
353 PROCEDURE Process_PMSch_Activities;
354
355 -- Process records with no contract dates.
356 PROCEDURE Process_PMUnSch_Activities(p_current_usage_tbl IN counter_values_tbl_type);
357
358 -- Procedure to find the service_line_id and program for a calculated due_date.
359 -- The calculated due_date may be overridden by the contract/program dates.
360 -- Also the earliest due and latest due date will get adjusted if they are not
361 -- within the contract and program start/end dates.
362 PROCEDURE Get_PMprogram(p_csi_item_instance_id IN NUMBER,
363 p_mr_header_id IN NUMBER,
364 p_last_due_date IN DATE,
365 p_due_date IN DATE,
366 p_earliest_due IN DATE,
367 p_latest_due IN DATE,
368 x_program_mr_header_id OUT NOCOPY NUMBER,
369 x_service_line_id OUT NOCOPY NUMBER,
370 x_contract_override_due_date OUT NOCOPY DATE,
371 x_cont_override_earliest_due OUT NOCOPY DATE,
372 x_cont_override_latest_due OUT NOCOPY DATE,
373 x_contract_found_flag OUT NOCOPY BOOLEAN);
374
375 -- After creation of all maintenance requirements for the instance in the temporary table,
376 -- assign unit effectivity IDs from existing un-accomplished maintenance requirements
377 -- from ahl_unit_effectivities_b.
378 PROCEDURE Assign_Unit_effectivity_IDs;
379
380 -- Fix for Prev. Maint. performance bug# 5093064.
381 -- instead of calling procedure AHL_FMP_PVT.GET_MR_AFFECTED_ITEMS,
382 -- write PM effectivity logic in this procedure.
383 PROCEDURE Process_PM_MR_Affected_Items(p_commit IN VARCHAR2 := FND_API.G_FALSE,
384 x_msg_count OUT NOCOPY NUMBER,
385 x_msg_data OUT NOCOPY VARCHAR2,
386 x_return_status OUT NOCOPY VARCHAR2,
387 p_mr_header_id IN NUMBER,
388 p_old_mr_header_id IN NUMBER := NULL,
389 p_concurrent_flag IN VARCHAR2 := 'N',
390 p_num_of_workers IN NUMBER := 10);
391
392 --------------------------------------------------------------------
393 -- Following procedures have been added for 11.5.10 Enhancements. --
394 --------------------------------------------------------------------
395 -- Get the latest recorded counter reading for a given date.
396 PROCEDURE get_ctr_reading_for_date (p_csi_item_instance_id IN NUMBER,
397 p_counter_id IN NUMBER,
398 p_reading_date IN DATE,
399 x_net_reading OUT NOCOPY NUMBER);
400
401 -- Get the earliest date on which a given reading was recorded.
402 PROCEDURE get_ctr_date_for_reading (p_csi_item_instance_id IN NUMBER,
403 p_counter_id IN NUMBER,
404 p_counter_value IN NUMBER,
405 x_ctr_record_date OUT NOCOPY DATE,
406 x_return_val OUT NOCOPY BOOLEAN);
407
408 -- Calculate due date all deferred unit effectivities.
409 PROCEDURE Process_Deferred_UE (p_csi_item_instance_id IN NUMBER,
410 p_current_usage_tbl IN counter_values_tbl_type,
411 p_counter_rules_tbl IN counter_rules_tbl_type);
412
413 -- Explode SR's having MRs for calculating MR due dates.
414 PROCEDURE Process_SR_UE (p_csi_item_instance_id IN NUMBER);
415
416 -- Match if current UE group MR matches the applicable group MR.
417 PROCEDURE Match_Group_MR (p_orig_csi_item_instance_id IN NUMBER,
418 p_orig_mr_header_id IN NUMBER,
419 p_unit_effectivity_id IN NUMBER,
420 x_group_match_flag OUT NOCOPY VARCHAR2);
421
422 -----------------------------------------------------------------------------------
423 -- Following procedures have been added for 11.5.10+ Transit Check Enhancements. --
424 -----------------------------------------------------------------------------------
425
426 -- Validate applicability for Unplanned MRs (MRs directly planned into a Visit from FMP).
427 PROCEDURE Process_Unplanned_UE(p_csi_item_instance_id IN NUMBER,
428 p_current_usage_tbl IN counter_values_tbl_type,
429 p_counter_rules_tbl IN counter_rules_tbl_type);
430
431 ---------------------------------------
432 -- added to fix performance bug 5093064.
433 ---------------------------------------
434 -- Split instances based on instance count.
435 PROCEDURE Instance_Split_BTree(p_csi_max_id in NUMBER,
436 p_csi_min_id IN NUMBER,
437 p_num_workers IN NUMBER,
438 p_mr_header_id IN NUMBER,
439 p_total_inst_count IN NUMBER);
440
441
442 -- Split instance range into blocks based on instance IDs.
443 PROCEDURE Instance_Split_Sequential(p_csi_max_id in NUMBER,
444 p_csi_min_id IN NUMBER,
445 p_num_workers IN NUMBER,
446 p_mr_header_id IN NUMBER);
447
448 ----------------------------------------------
449 -- Following procedures have been added R12 --
450 ----------------------------------------------
451 -- Added to fix bug# 4224867.
452 -- find usage forecast for a given date.
453 PROCEDURE get_usage_for_date(p_due_date IN DATE,
454 p_counter_uom_code IN VARCHAR2,
455 p_counter_rules_tbl IN Counter_rules_tbl_type,
456 x_usage_per_day OUT NOCOPY NUMBER);
457
458 -- Added to fix bug# 6875650.
459 -- Get the latest recorded counter reading for a given date-time.
460 PROCEDURE get_ctr_reading_for_datetime (p_csi_item_instance_id IN NUMBER,
461 p_counter_id IN NUMBER,
462 p_reading_date IN DATE,
463 x_net_reading OUT NOCOPY NUMBER);
464
465
466 ----------------------------------------------------------------
467 -- Following procedures were added for performance bug# 6893404.
468 ----------------------------------------------------------------
469 -- Identify affected units and process or launch concurrent workers for AHL processing.
470 PROCEDURE Split_Process_All_Instances(p_concurrent_flag IN VARCHAR2,
471 p_commit_flag IN VARCHAR2,
472 p_num_of_workers IN NUMBER,
473 p_mr_header_id IN NUMBER,
474 p_mtl_category_id IN NUMBER,
475 p_process_option IN VARCHAR2,
476 x_msg_count OUT NOCOPY NUMBER,
477 x_msg_data OUT NOCOPY NUMBER,
478 x_return_status OUT NOCOPY VARCHAR2);
479
480 -- Write into BUE worker table when processing all units.
481 PROCEDURE Populate_BUE_Worker(p_conc_request_id IN NUMBER,
482 p_concurrent_flag IN VARCHAR2,
483 p_mtl_category_id IN NUMBER,
484 p_process_option IN VARCHAR2,
485 errbuf OUT NOCOPY VARCHAR2,
486 x_return_status OUT NOCOPY VARCHAR2);
487
488
489 -- Write into BUE worker table when processing for a MR.
490 PROCEDURE Populate_BUE_Worker_for_MR(p_conc_request_id IN NUMBER,
491 p_mr_header_id IN NUMBER,
492 p_concurrent_flag IN VARCHAR2,
493 p_mtl_category_id IN NUMBER,
494 p_process_option IN VARCHAR2,
495 x_return_status OUT NOCOPY VARCHAR2);
496
497 -- get next instance from BUE worker table to process.
498 PROCEDURE Get_Next_BUE_Row(p_parent_conc_pgm_id IN NUMBER,
499 p_conc_child_req_id IN NUMBER,
500 x_return_status OUT NOCOPY VARCHAR2,
501 errbuf OUT NOCOPY VARCHAR2,
502 x_item_instance_id OUT NOCOPY NUMBER);
503
504
505 -- cleanup worker table
506 -- added x_return_status and x_errbuf to fix bug# 10185468
507 PROCEDURE Cleanup_BUE_Worker(p_parent_conc_request_id IN NUMBER,
508 p_child_conc_request_id IN NUMBER,
509 x_return_status OUT NOCOPY VARCHAR2,
510 x_errbuf OUT NOCOPY VARCHAR2);
511
512
513 -------------------------------------------------------
514 -- Following procedures were added to fix bug# 6907562.
515 -------------------------------------------------------
516 -- function that compares previous due date and uom remain with current values
517 -- and return Y is the current due date replaces the prev one.
518 FUNCTION validate_for_duedate_reset(p_due_date IN DATE,
519 p_uom_remain IN NUMBER,
520 p_prev_due_date IN DATE,
521 p_prev_counter_id IN NUMBER,
522 p_prev_uom_remain IN NUMBER) RETURN VARCHAR2;
523
524 -- procedure checks forecast and adds zero forecast row if missing forecast.
525 PROCEDURE validate_uf_for_ctr(p_current_usage_tbl IN counter_values_tbl_type,
526 p_x_forecast_details_tbl IN OUT NOCOPY forecast_details_tbl_type);
527
528 -------------------------------------------------------
529 -- Following procedures were added to fix bug# 9263774.
530 -------------------------------------------------------
531 -- To process prior revision of a MR.
532 PROCEDURE Process_Prior_MR_Version (p_applicable_mrs_rec IN applicable_mrs_rec_type,
533 p_new_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE,
534 p_unit_effectivity_tbl IN unit_effectivity_tbl_type,
535 p_old_UE_forecast_sequence IN NUMBER);
536
537 -- Get applicability for expired MRs.
538 PROCEDURE Process_Appl_Expired_MRs;
539
540 ----------------------------------------------------------
541 -- Following procedures were added for Service Bulletin ER
542 ----------------------------------------------------------
543 -- If MR has a accomplishment trigger of 'terminated_by' then check if parent MRs are processed
544 -- and if not, process them.
545 PROCEDURE Process_Terminating_Parent_MRs(p_applicable_mrs_rec IN applicable_mrs_rec_type,
546 p_current_usage_tbl IN counter_values_tbl_type,
547 p_counter_rules_tbl IN counter_rules_tbl_type,
548 x_mr_termination_date OUT NOCOPY DATE);
549
550 -- initialization procedure for loops
551 PROCEDURE Process_Loop_Init(p_applicable_mrs_rec IN applicable_mrs_rec_type,
552 p_current_usage_tbl IN counter_values_tbl_type,
553 p_counter_rules_tbl IN counter_rules_tbl_type,
554 x_loop_chain_MR_tbl OUT NOCOPY loop_chain_MR_tbl_type,
555 x_next_due_skip_flag OUT NOCOPY VARCHAR2,
556 x_loop_last_due_date OUT NOCOPY DATE,
557 x_loop_last_counter_val_tbl OUT NOCOPY counter_values_tbl_type);
558
559
560 -- initialization procedure for chains
561 PROCEDURE Process_Chain_Init(p_applicable_mrs_rec IN applicable_mrs_rec_type,
562 p_current_usage_tbl IN counter_values_tbl_type,
563 p_counter_rules_tbl IN counter_rules_tbl_type,
564 x_loop_chain_MR_tbl OUT NOCOPY loop_chain_MR_tbl_type);
565
566
567 -- process child MRs in a loop or chain
568 PROCEDURE Process_Loop_Chain_MRs (p_item_instance_id IN NUMBER,
569 p_new_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE,
570 p_repetivity_flag IN VARCHAR2 := 'Y',
571 p_current_usage_tbl IN counter_values_tbl_type,
572 p_counter_rules_tbl IN counter_rules_tbl_type,
573 p_last_due_date IN DATE,
574 p_last_due_counter_val_tbl IN counter_values_tbl_type,
575 p_loop_chain_MR_tbl IN loop_chain_MR_tbl_type,
576 x_loop_due_date OUT NOCOPY DATE,
577 x_loop_last_due_date OUT NOCOPY DATE,
578 x_loop_last_counter_val_tbl OUT NOCOPY counter_values_tbl_type);
579
580 -- get instance counter values for instance, accomplishment date or unit effectivity
581 PROCEDURE get_instance_ctr_for_date (p_item_instance_id IN NUMBER,
582 p_last_accomplishment_date IN DATE,
583 p_deferral_flag IN VARCHAR2,
584 p_unit_effectivity_id IN NUMBER,
585 p_current_usage_tbl IN counter_values_tbl_type,
586 p_counter_rules_tbl IN counter_rules_tbl_type,
587 x_no_forecast_flag OUT NOCOPY BOOLEAN,
588 x_last_acc_counter_val_tbl OUT NOCOPY counter_values_tbl_type);
589
590 -- added for Complex Assembly Enh: To calculate due date for nonroutine when UE status is init-due.
591 PROCEDURE Calculate_NR_due_date(p_unit_effectivity_id IN NUMBER,
592 x_due_date OUT NOCOPY DATE,
593 x_due_counter_value OUT NOCOPY NUMBER,
594 x_counter_id OUT NOCOPY NUMBER);
595
596 ------------------------------
597 -- Declare global variables --
598 ------------------------------
599 G_config_node_tbl AHL_UMP_PROCESSUNIT_PVT.config_node_tbl_type;
600 -- This variable holds all the item instances that are contained in a configuration.
601 -- For AHL installation, this will hold the top node and all of its components.
602 -- For PM installation, this will contain only one item instance, because each
603 -- component of a configuration is processed as a unit for this case.
604
605 G_forecast_details_tbl forecast_details_tbl_type;
606 -- This variable holds the forecast information for the unit that is being
607 -- processed. This variable is set in procedure Process_Unit.
608
609 G_last_day_of_window DATE;
610 -- This variable holds the last day of the rolling window, calculated based on
611 -- the profile values set. This is set in procedure Process_Unit.
612
613 G_master_config_id NUMBER;
614 -- This variable holds the Master config ID if configuration has a master Configuration.
615 -- Not Applicable for PM installation.
616
617 -- JKJain, NR Analysis and Forecasting
618 G_SIMULATION_PLAN_ID NUMBER := NULL;
619 -- This variable holds the SIMULATION_PLAN_ID if SIMULATION_PLAN_ID is passed to Process (ALL) Unit API.
620
621 G_PRIMARY_PLAN VARCHAR2(1) := 'Y';
622 -- This variable will be Y if SIMULATION_PLAN_ID passed to Process (ALL) Unit API is NULL. Else it will be N.
623
624 G_UC_HEADER_ID NUMBER ;
625 -- This variable holds the Unit config header ID if configuration has a unit Configuration.
626
627 -----------------------
628 -- Define Procedures --
629 -----------------------
630
631 -- Start of Comments --
632 -- Procedure name : Process_Unit
633 -- Type : Private
634 -- Function : Manages Create/Modify/Delete operations of applicable maintenance
635 -- requirements on a unit.
636 -- Pre-reqs :
637 -- Parameters :
638 --
639 -- Standard OUT Parameters :
640 -- x_return_status OUT VARCHAR2 Required
641 -- x_msg_count OUT NUMBER Required
642 -- x_msg_data OUT VARCHAR2 Required
643 --
644 -- Process_Unit Parameters :
645 -- Unit's Effectivity will be built for the input item instance.
646 --
647
648 PROCEDURE Process_Unit (
649 p_commit IN VARCHAR2 := FND_API.G_FALSE,
650 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
651 x_msg_count OUT NOCOPY NUMBER,
652 x_msg_data OUT NOCOPY VARCHAR2,
653 x_return_status OUT NOCOPY VARCHAR2,
654 p_csi_item_instance_id IN NUMBER,
655 p_concurrent_flag IN VARCHAR2 := 'N',
656 -- JKJain, NR Analysis and Forecasting
657 p_simulation_plan_id IN NUMBER := NULL)
658
659 IS
660
661 l_inventory_item_id NUMBER;
662 l_inv_master_organization_id NUMBER;
663
664 l_uc_header_id NUMBER;
665 -- This variable holds the Unit config ID if configuration is a Unit Configuration.
666 -- Not Applicable for PM installation.
667
668 l_csi_item_instance_id NUMBER;
669 -- This variable holds the Root item instance id.
670 -- For AHL installation, this is the root item instance of the input parameter p_csi_item_instance_id
671 -- For PM installation, this is the item instance input to this procedure(i.e p_csi_item_instance_id).
672
673 l_config_node_tbl AHL_UMP_PROCESSUNIT_PVT.config_node_tbl_type;
674 l_forecast_details_tbl forecast_details_tbl_type;
675
676 l_UnSch_programs_tbl PMprogram_tbl_type;
677 -- contains programs and their effectivities.
678
679 l_ret_code VARCHAR2(30);
680 l_expired_flag VARCHAR2(1);
681
682 BEGIN
683
684 -- Standard start of API savepoint
685 SAVEPOINT Process_Unit_PVT;
686
687 -- Initialize message list if p_init_msg_list is set to TRUE
688 IF FND_API.To_Boolean(p_init_msg_list) THEN
689 FND_MSG_PUB.Initialize;
690 END IF;
691
692 -- Initialize Procedure return status to success
693 x_return_status := FND_API.G_RET_STS_SUCCESS;
694
695 -- Enable Debug.
696 IF G_DEBUG = 'Y' THEN
697 AHL_DEBUG_PUB.enable_debug;
698 END IF;
699
700 -- Add debug mesg.
701 IF G_DEBUG = 'Y' THEN
702 AHL_DEBUG_PUB.debug('Begin private API:' || G_PKG_NAME || '.' || 'ProcessUnit');
703
704 -- Dump input parameters.
705 AHL_DEBUG_PUB.debug(' Csi Item instance ID:' || p_csi_item_instance_id);
706 AHL_DEBUG_PUB.debug(' p_concurrent_flag:' || p_concurrent_flag );
707 AHL_DEBUG_PUB.debug(' p_commit:' || p_commit);
708 AHL_DEBUG_PUB.debug(' p_simulation_plan_id :' || p_simulation_plan_id);
709 END IF;
710
711 G_concurrent_flag := p_concurrent_flag;
712
713 -- JKJain, NR Analysis and Forecasting
714 IF(p_simulation_plan_id IS NULL) THEN
715 G_PRIMARY_PLAN := 'Y';
716 G_SIMULATION_PLAN_ID := NULL;
717 ELSE
718 G_PRIMARY_PLAN := 'N';
719 G_SIMULATION_PLAN_ID := p_simulation_plan_id;
720 END IF;
721
722 IF (p_concurrent_flag = 'Y') THEN
723 fnd_file.put_line(fnd_file.log, 'Starting Process Unit for item instance: '|| p_csi_item_instance_id);
724 --fnd_file.put_line(fnd_file.log, 'G_IS_PM_INSTALLED: '|| G_IS_PM_INSTALLED);
725 END IF;
726
727 -- Initialize temporary tables.
728
729 DELETE FROM AHL_TEMP_UNIT_EFFECTIVITIES;
730 DELETE FROM AHL_TEMP_UNIT_SR_DEFERRALS;
731
732 /* this validation will be done after getting root instance.
733 -- validate item instance.
734 Validate_item_instance(p_csi_item_instance_id, l_inventory_item_id,
735 l_inv_master_organization_id);
736
737 IF FND_MSG_PUB.Count_msg > 0 THEN
738 RAISE FND_API.G_EXC_ERROR;
739 END IF;
740
741 -- Log success message if called by concurrent program.
742 IF (p_concurrent_flag = 'Y') THEN
743 fnd_file.put_line (FND_FILE.LOG, 'Validated Instance:'||p_csi_item_instance_id);
744 END IF;
745 */
746
747 -- set instance variable.
748 l_csi_item_instance_id := p_csi_item_instance_id;
749
750
751 -- Set configuration variables based on installation type.
752 IF (G_IS_PM_INSTALLED = 'N') THEN
753 -- Only for AHL installation.
754
755 -- If item instance is not top node, find the root item instance.
756 l_csi_item_instance_id := Get_RootInstanceID(l_csi_item_instance_id);
757
758 -- validate item instance.
759 Validate_item_instance(l_csi_item_instance_id, l_inventory_item_id,
760 l_inv_master_organization_id, l_expired_flag);
761
762 IF FND_MSG_PUB.Count_msg > 0 THEN
763 RAISE FND_API.G_EXC_ERROR;
764 END IF;
765
766 -- Log success message if called by concurrent program.
767 IF (p_concurrent_flag = 'Y') THEN
768 fnd_file.put_line (FND_FILE.LOG, 'Validated Instance:'||l_csi_item_instance_id);
769 END IF;
770
771 -- Get master and unit configuration IDs if they exist for this item instance.
772 Get_Unit_Master_ConfigIDs (l_csi_item_instance_id,
773 l_uc_header_id, G_master_config_id);
774
775 -- JKJain, NR Analysis and Forecasting
776 G_UC_HEADER_ID := l_uc_header_id;
777
778 -- Check for errors.
779 IF FND_MSG_PUB.Count_msg > 0 THEN
780 RAISE FND_API.G_EXC_ERROR;
781 END IF;
782
783 -- Build the Configuration tree structure.(G_config_node_tbl).
784 Build_Config_Tree(l_csi_item_instance_id, G_master_config_id, G_CONFIG_NODE_TBL);
785
786 ELSE
787 -- For PM installation.
788
789 -- validate item instance.
790 Validate_item_instance(p_csi_item_instance_id, l_inventory_item_id,
791 l_inv_master_organization_id, l_expired_flag);
792
793 IF FND_MSG_PUB.Count_msg > 0 THEN
794 RAISE FND_API.G_EXC_ERROR;
795 END IF;
796
797 -- Log success message if called by concurrent program.
798 IF (p_concurrent_flag = 'Y') THEN
799 fnd_file.put_line (FND_FILE.LOG, 'Validated Instance:'||p_csi_item_instance_id);
800 END IF;
801
802 -- Intialize config node table consisting of the input item instance.
803 G_config_node_tbl(1).csi_item_instance_id := p_csi_item_instance_id;
804
805 END IF; -- pm_install check
806
807 -- Add debug mesg.
808 IF G_DEBUG = 'Y' THEN
809 AHL_DEBUG_PUB.debug(' Count on Config Node Tbl:' || G_config_node_tbl.COUNT);
810 AHL_DEBUG_PUB.debug(' Root Node:' || l_csi_item_instance_id );
811 AHL_DEBUG_PUB.debug(' Unit Config ID:' || l_uc_header_id);
812 AHL_DEBUG_PUB.debug(' Master Config ID:' || G_master_config_id);
813 AHL_DEBUG_PUB.debug(' l_expired_flag:' || l_expired_flag);
814 END IF;
815
816 -- Get rolling window end date.
817 G_last_day_of_window := Get_Rolling_Window_Date;
818
819 IF (l_expired_flag = 'Y') THEN
820 GOTO process_cleanup;
821 END IF;
822
823 -- Call FMP to get applicable MRs.
824 IF (G_IS_PM_INSTALLED = 'N') THEN
825 -- Only for AHL installation.
826
827 IF G_DEBUG = 'Y' THEN
828 AHL_DEBUG_PUB.debug('AHL Installation processing');
829 END IF;
830
831 -- Call FMP api to build applicable MRs for the unit.
832 AHL_UMP_UTIL_PKG.Populate_Appl_MRs ( p_csi_ii_id => l_csi_item_instance_id,
833 --p_include_doNotImplmt => 'N',
834 p_include_doNotImplmt => 'Y',
835 x_return_status => x_return_status,
836 x_msg_count => x_msg_count,
837 x_msg_data => x_msg_data );
838
839 IF (x_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
840 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
841 ELSIF (x_return_status = FND_API.G_RET_STS_ERROR) THEN
842 RAISE FND_API.G_EXC_ERROR;
843 END IF;
844
845 -- Build applicability for group MRs.
846 AHL_UMP_UTIL_PKG.Process_Group_MRs;
847
848 ELSE -- for PM installation.
849 IF G_DEBUG = 'Y' THEN
850 AHL_DEBUG_PUB.debug('PM Installation processing');
851 END IF;
852
853 -- Call FMP-PM api to build applicable MRs for an instance.
854 PopulatePM_Appl_MRs (p_csi_ii_id => l_csi_item_instance_id,
855 x_return_status => x_return_status,
856 x_msg_count => x_msg_count,
857 x_msg_data => x_msg_data,
858 x_UnSch_programs_tbl => l_UnSch_programs_tbl);
859
860 IF (x_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
861 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
862 ELSIF (x_return_status = FND_API.G_RET_STS_ERROR) THEN
863 RAISE FND_API.G_EXC_ERROR;
864 END IF;
865
866 END IF; -- pm_install check.
867
868 IF G_DEBUG = 'Y' THEN
869 AHL_DEBUG_PUB.debug('After calling FMP API and process group MRs');
870 END IF;
871
872 -- Read applicable utilization forecast for the configuration.
873 Get_Utilization_Forecast (l_csi_item_instance_id,
874 l_uc_header_id,
875 l_inventory_item_id,
876 l_inv_master_organization_id,
877 G_forecast_details_tbl);
878
879
880 -- Lock records.
881 FOR i IN 1..4 LOOP
882 Lock_UnitEffectivity_Records(x_ret_code => l_ret_code);
883 EXIT WHEN (l_ret_code <> '-54');
884 DBMS_LOCK.SLEEP(30);
885 END LOOP;
886
887 IF (l_ret_code = -54) THEN
888 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_ALREADY_RUNNING');
889 FND_MSG_PUB.ADD;
890 RAISE FND_API.G_EXC_ERROR;
891 END IF;
892
893 /*
894 -- Log success message if called by concurrent program.
895 IF (p_concurrent_flag = 'Y') THEN
896 fnd_file.put_line (FND_FILE.LOG, 'G Config Tbl:' || G_config_node_tbl.COUNT);
897 fnd_file.put_line (FND_FILE.LOG, 'G_forecast_details_tbl:' || G_forecast_details_tbl.count);
898 fnd_file.put_line (FND_FILE.LOG, 'Last Day window:' || G_last_day_of_window);
899 fnd_file.put_line (FND_FILE.LOG, 'UC Header ID:' || l_uc_header_id);
900 END IF;
901 */
902
903 -- Note: Both of the procedures Process_ASO_Unit and Process_PM_Unit use global variables
904 -- set by this procedure in addition to any input parameters.
905 IF (G_IS_PM_INSTALLED = 'N') THEN
906 Process_ASO_Unit;
907 ELSE
908 Process_PM_Unit(p_csi_item_instance_id => l_csi_item_instance_id,
909 p_UnSch_programs_tbl => l_UnSch_programs_tbl);
910 END IF;
911
912 <<process_cleanup>>
913 -- JKJain, NR Analysis and Forecasting
914 --IF p_simulation_plan_id is null, then flush to UE table else, flush to simulated UE table
915 IF (G_PRIMARY_PLAN = 'Y') THEN
916 -- Flush from temporary table to ahl_unit_effectivities.
917 AHL_UMP_PROCESSUNIT_EXTN_PVT.Flush_From_Temp_Table(G_config_node_tbl,G_UC_HEADER_ID);
918 ELSE
919 AHL_UMP_PROCESSUNIT_EXTN_PVT.Flush_To_Sim_Ue_Table(G_config_node_tbl,p_simulation_plan_id,G_UC_HEADER_ID);
920 END IF;
921
922 -- Check for errors.
923 IF FND_MSG_PUB.Count_msg > 0 THEN
924 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
925 END IF;
926
927 /* -- commented for performance fix - bug# 6893404
928 IF (G_IS_PM_INSTALLED = 'N') THEN
929 -- Only for AHL installation.
930
931 --call for material requirement forecst
932 AHL_UMP_FORECAST_REQ_PVT.process_mrl_req_forecast
933 (
934 p_api_version => 1.0,
935 p_init_msg_list => FND_API.G_TRUE,
936 p_commit => FND_API.G_FALSE,
937 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
938 x_return_status => x_return_status,
939 x_msg_count => x_msg_count,
940 x_msg_data => x_msg_data,
941 p_applicable_instances_tbl => G_config_node_tbl
942 );
943
944 -- Check for errors.
945 IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
946 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
947 END IF;
948
949 END IF;
950 */
951
952 -- Standard check of p_commit
953 IF FND_API.TO_BOOLEAN(p_commit) THEN
954 COMMIT WORK;
955 END IF;
956
957 -- Log success message if called by concurrent program.
958 IF (p_concurrent_flag = 'Y') THEN
959 fnd_file.put_line (FND_FILE.LOG, 'Message-Successfully processed:'||p_csi_item_instance_id);
960 END IF;
961
962 -- Standard call to get message count and if count is 1, get message info
963 FND_MSG_PUB.Count_And_Get
964 ( p_count => x_msg_count,
965 p_data => x_msg_data,
966 p_encoded => fnd_api.g_false
967 );
968
969 --
970 EXCEPTION
971 WHEN FND_API.G_EXC_ERROR THEN
972 x_return_status := FND_API.G_RET_STS_ERROR;
973 Rollback to Process_Unit_PVT;
974 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
975 p_data => x_msg_data,
976 p_encoded => fnd_api.g_false);
977
978 IF (p_concurrent_flag = 'Y') THEN
979
980 fnd_file.put_line(fnd_file.log, 'Process Unit failed for item instance: '|| p_csi_item_instance_id);
981 log_error_messages;
982 END IF;
983
984 -- Disable debug
985 AHL_DEBUG_PUB.disable_debug;
986
987 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
988 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
989 Rollback to Process_Unit_PVT;
990 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
991 p_data => x_msg_data,
992 p_encoded => fnd_api.g_false);
993
994 IF (p_concurrent_flag = 'Y') THEN
995 fnd_file.put_line(fnd_file.log, 'Process Unit failed for item instance: '|| p_csi_item_instance_id);
996 log_error_messages;
997 END IF;
998
999 -- Disable debug
1000 AHL_DEBUG_PUB.disable_debug;
1001
1002 WHEN OTHERS THEN
1003
1004 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1005 Rollback to Process_Unit_PVT;
1006 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
1007 fnd_msg_pub.add_exc_msg(p_pkg_name => G_PKG_NAME,
1008 p_procedure_name => 'Process_Unit_PVT',
1009 p_error_text => SUBSTR(SQLERRM,1,240));
1010 END IF;
1011 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1012 p_data => x_msg_data,
1013 p_encoded => fnd_api.g_false);
1014
1015
1016 IF (p_concurrent_flag = 'Y') THEN
1017 fnd_file.put_line(fnd_file.log, 'Process Unit failed for item instance: '|| p_csi_item_instance_id);
1018 log_error_messages;
1019 END IF;
1020
1021 -- Disable debug
1022 AHL_DEBUG_PUB.disable_debug;
1023
1024 END Process_Unit;
1025
1026 -------------------------------------------------------------------------------
1027 -- Start of Comments --
1028 -- Procedure name : Process_MRAffected_Units
1029 -- Type : Private
1030 -- Function : Processes all units that are affected for a Maintenance requirement.
1031 -- Pre-reqs :
1032 -- Parameters :
1033 --
1034 -- Process_MR_Affected_Units Parameters :
1035 -- Effectivity will be built for all units having p_mr_id as a maintenance requirement.
1036 -- This procedure will also be called from terminate_MRs; in which case p_old_mr_header_id
1037 -- will also be passed.p_old_mr_header_id is the MR that was terminated. Effectivity will
1038 -- be re-build for all units that had p_old_mr_header_id as applicability.
1039 --
1040 -- p_concurrent_flag IN VARCHAR2
1041 -- This flag will be 'Y' if called from a concurrent program. Based on this flag, the error
1042 -- and informational messages will be logged into the log file.
1043 --
1044
1045 PROCEDURE Process_MRAffected_Units (
1046 p_commit IN VARCHAR2 := FND_API.G_FALSE,
1047 x_msg_count OUT NOCOPY NUMBER,
1048 x_msg_data OUT NOCOPY VARCHAR2,
1049 x_return_status OUT NOCOPY VARCHAR2,
1050 p_mr_header_id IN NUMBER,
1051 p_old_mr_header_id IN NUMBER := NULL,
1052 p_concurrent_flag IN VARCHAR2 := 'N',
1053 p_num_of_workers IN NUMBER := 1,
1054 p_mtl_category_id IN NUMBER := NULL,
1055 p_process_option IN VARCHAR2 := NULL)
1056
1057
1058 IS
1059
1060 l_commit VARCHAR2(1) := p_commit;
1061
1062 l_conc_request_id NUMBER;
1063 l_req_id NUMBER;
1064 l_instance_id NUMBER;
1065 l_num_of_workers NUMBER;
1066
1067 -- added for bug# 10185468
1068 l_err_mesg VARCHAR2(4000);
1069 l_return_status VARCHAR2(1);
1070
1071 BEGIN
1072
1073 -- Initialize Procedure return status to success
1074 x_return_status := FND_API.G_RET_STS_SUCCESS;
1075
1076 -- Enable Debug.
1077 IF G_DEBUG = 'Y' THEN
1078 AHL_DEBUG_PUB.enable_debug;
1079 END IF;
1080
1081 -- Add debug mesg.
1082 IF G_DEBUG = 'Y' THEN
1083 AHL_DEBUG_PUB.debug('Begin private API:' || G_PKG_NAME || '.' || 'Process_MRAffected_Units');
1084 AHL_DEBUG_PUB.debug('Application Usage Profile:' || fnd_profile.value('AHL_APPLN_USAGE'));
1085 END IF;
1086
1087 IF (p_concurrent_flag = 'Y') THEN
1088 l_commit := FND_API.G_TRUE;
1089 l_conc_request_id := fnd_global.conc_request_id;
1090 IF (l_conc_request_id = -1) OR (l_conc_request_id IS NULL) OR (l_conc_request_id <= 0) THEN
1091 -- this will happen only when called from UMP Terminate_MR_Instances api.
1092 l_conc_request_id := fnd_global.login_id;
1093 END IF;
1094 ELSE
1095 l_conc_request_id := fnd_global.session_id;
1096 END IF;
1097
1098 -- validate p_num_of_workers.
1099 l_num_of_workers := trunc(p_num_of_workers);
1100
1101 IF (l_num_of_workers IS NULL OR l_num_of_workers <= 0) THEN
1102 l_num_of_workers := 1;
1103 ELSIF l_num_of_workers > 30 THEN
1104 l_num_of_workers := 30;
1105 END IF;
1106
1107 -- Set FMP parameter based on PM installation.
1108 IF (G_IS_PM_INSTALLED = 'Y') THEN
1109 -- PM processing(fix for performance bug# 5093064).
1110 Process_PM_MR_Affected_Items(
1111 p_commit => l_commit,
1112 x_msg_count => x_msg_count,
1113 x_msg_data => x_msg_data,
1114 x_return_status => x_return_status,
1115 p_mr_header_id => p_mr_header_id,
1116 p_old_mr_header_id => p_old_mr_header_id,
1117 p_concurrent_flag => p_concurrent_flag,
1118 p_num_of_workers => l_num_of_workers);
1119 ELSE
1120
1121 Populate_BUE_Worker_for_MR(p_conc_request_id => l_conc_request_id,
1122 p_mr_header_id => p_mr_header_id,
1123 p_concurrent_flag => p_concurrent_flag,
1124 p_mtl_category_id => p_mtl_category_id,
1125 p_process_option => p_process_option,
1126 x_return_status => x_return_status);
1127
1128 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1129 RETURN;
1130 END IF;
1131
1132 IF (p_old_mr_header_id IS NOT NULL AND p_old_mr_header_id <> FND_API.G_MISS_NUM) THEN
1133 -- Call FMP API to get all items instances which have old mr_id in its applicability.
1134 Populate_BUE_Worker_for_MR(p_conc_request_id => l_conc_request_id,
1135 p_mr_header_id => p_old_mr_header_id,
1136 p_concurrent_flag => p_concurrent_flag,
1137 p_mtl_category_id => p_mtl_category_id,
1138 p_process_option => p_process_option,
1139 x_return_status => x_return_status);
1140 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1141 RETURN;
1142 END IF;
1143 END IF; -- p_old_mr_header_id I
1144
1145 IF (p_concurrent_flag = 'Y') THEN
1146 -- submit worker programs to process units.
1147 FOR i IN 1..l_num_of_workers LOOP
1148 l_req_id := fnd_request.submit_request('AHL','AHLWUEFF',NULL,NULL,FALSE, l_conc_request_id);
1149 IF (l_req_id = 0 OR l_req_id IS NULL) THEN
1150 IF G_debug = 'Y' THEN
1151 AHL_DEBUG_PUB.debug('Tried to submit concurrent request but failed');
1152 END IF;
1153 fnd_file.put_line(FND_FILE.LOG, 'Failed submit concurrent request');
1154 fnd_file.new_line(FND_FILE.LOG,1);
1155 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1156 EXIT; -- abort and return to calling pgm.
1157
1158 ELSE
1159 fnd_file.put_line(FND_FILE.LOG, 'Concurrent request ID:' || l_req_id);
1160 IF G_debug = 'Y' THEN
1161 AHL_DEBUG_PUB.debug('Concurrent request ID:' || l_req_id );
1162 END IF;
1163 END IF; -- l_req_id = 0 OR ..
1164
1165 END LOOP;
1166
1167 -- call cleanup BUE for previously failed deletes.
1168 Cleanup_BUE_Worker(p_parent_conc_request_id => l_conc_request_id,
1169 p_child_conc_request_id => NULL,
1170 x_return_status => l_return_status,
1171 x_errbuf => l_err_mesg);
1172 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1173 -- ignore error returned from this procedure
1174 -- log message in concurrent request log.
1175 fnd_file.put_line(FND_FILE.LOG, 'Warning: Error from Cleanup_BUE_Worker:' || l_err_mesg);
1176 END IF;
1177
1178 ELSE
1179 LOOP
1180 -- initialize return status.
1181 x_return_status := FND_API.G_RET_STS_SUCCESS;
1182
1183 -- process each unit from worker table.
1184 Get_Next_BUE_Row(p_parent_conc_pgm_id => l_conc_request_id,
1185 p_conc_child_req_id => l_conc_request_id,
1186 errbuf => x_msg_data,
1187 x_return_status => x_return_status,
1188 x_item_instance_id => l_instance_id);
1189
1190 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1191 EXIT; -- abort and return to calling pgm.
1192 END IF;
1193
1194 EXIT WHEN (l_instance_id IS NULL);
1195
1196 IF G_DEBUG = 'Y' THEN
1197 AHL_DEBUG_PUB.debug('Now processing..:' || l_instance_id);
1198 END IF;
1199
1200 -- Call Process Unit for the item instance.
1201 Process_Unit (
1202 p_commit => l_commit,
1203 p_init_msg_list => FND_API.G_TRUE,
1204 x_msg_count => x_msg_count,
1205 x_msg_data => x_msg_data,
1206 x_return_status => x_return_status,
1207 p_csi_item_instance_id => l_instance_id,
1208 p_concurrent_flag => p_concurrent_flag);
1209
1210 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1211 EXIT; -- abort and return to calling pgm.
1212 END IF;
1213
1214 END LOOP;
1215
1216 -- cleanup worker table after processing.
1217 Cleanup_BUE_Worker(p_parent_conc_request_id => l_conc_request_id,
1218 p_child_conc_request_id => l_conc_request_id,
1219 x_return_status => l_return_status,
1220 x_errbuf => l_err_mesg);
1221 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1222 -- ignore error returned from this procedure
1223 IF G_DEBUG = 'Y' THEN
1224 AHL_DEBUG_PUB.debug('Warning: Error from Cleanup_BUE_Worker:' || l_err_mesg);
1225 END IF;
1226 END IF;
1227
1228 END IF; -- p_concurrent_flag
1229
1230 END IF; -- G_IS_PM_INSTALLED.
1231
1232 END Process_MRAffected_Units;
1233
1234 -- Tamal: Bug #4207212, #4114368: Begin
1235 ------------------------------------------------------------------------------
1236 -- Start of Comments --
1237 -- Procedure name : Process_PM_Contracts
1238 -- Type : Private
1239 -- Function : Retrieves all instances for a contract and calls Process_Unit for each unit.
1240 -- Pre-reqs :
1241 -- Parameters :
1242 --
1243 -- p_concurrent_flag IN VARCHAR2
1244 -- This flag will be 'Y' if called from a concurrent program. Based on this flag, the error
1245 -- and informational messages will be logged into the log file.
1246 -- p_contract_number IN VARCHAR2
1247 -- The contract number for which want to process csi_item_instances entitlement
1248 -- p_contract_number IN VARCHAR2
1249 -- The contract number modifier for above contract number
1250
1251 PROCEDURE Process_PM_Contracts
1252 (
1253 p_commit IN VARCHAR2 := FND_API.G_FALSE,
1254 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
1255 x_msg_count OUT NOCOPY NUMBER,
1256 x_msg_data OUT NOCOPY VARCHAR2,
1257 x_return_status OUT NOCOPY VARCHAR2,
1258 p_contract_number IN VARCHAR2 := NULL,
1259 p_contract_modifier IN VARCHAR2 := NULL,
1260 p_concurrent_flag IN VARCHAR2 := 'N'
1261 )
1262 IS
1263 l_msg_count number;
1264 l_commit varchar2(1) := p_commit;
1265
1266 l_inp_cont_rec OKS_ENTITLEMENTS_PUB.inp_cont_rec;
1267 l_ent_cont_tbl OKS_ENTITLEMENTS_PUB.ent_cont_tbl;
1268
1269 -- Fix for bug# 5639852.
1270 CURSOR get_oks_line_end_dt1(p_contract_number IN VARCHAR2,
1271 p_contract_modifier IN VARCHAR2)
1272 IS
1273 SELECT trunc(min(okl.end_date)), trunc(okh.start_date)
1274 FROM okc_k_headers_b okh, okc_k_lines_b okl
1275 WHERE OKL.DNZ_CHR_ID = OKH.ID
1276 AND OKH.CONTRACT_NUMBER = p_contract_number
1277 AND OKH.CONTRACT_NUMBER_MODIFIER = p_contract_modifier
1278 GROUP BY OKH.ID, OKH.start_date;
1279
1280 CURSOR get_oks_line_end_dt2(p_contract_number IN VARCHAR2)
1281 IS
1282 SELECT trunc(min(okl.end_date)), trunc(okh.start_date)
1283 FROM okc_k_headers_b okh, okc_k_lines_b okl
1284 WHERE OKL.DNZ_CHR_ID = OKH.ID
1285 AND OKH.CONTRACT_NUMBER = p_contract_number
1286 GROUP BY OKH.ID, OKH.start_date;
1287
1288 l_end_date DATE;
1289 l_start_date DATE;
1290
1291 BEGIN
1292 -- Standard start of API savepoint
1293 SAVEPOINT Process_PM_Contracts_PVT;
1294
1295 -- Initialize message list if p_init_msg_list is set to TRUE
1296 IF FND_API.To_Boolean(p_init_msg_list) THEN
1297 FND_MSG_PUB.Initialize;
1298 END IF;
1299
1300 -- Initialize Procedure return status to success
1301 x_return_status := FND_API.G_RET_STS_SUCCESS;
1302
1303 -- Enable Debug.
1304 IF G_DEBUG = 'Y' THEN
1305 AHL_DEBUG_PUB.enable_debug;
1306 END IF;
1307
1308 -- Add debug mesg.
1309 IF G_DEBUG = 'Y' THEN
1310 AHL_DEBUG_PUB.debug('Begin private API:' || G_PKG_NAME || '.' || 'Process_PM_Contracts');
1311 -- Dump input parameters.
1312 AHL_DEBUG_PUB.debug('Contract Number:' || p_contract_number );
1313 AHL_DEBUG_PUB.debug('Contract Modifier:' || p_contract_modifier );
1314 AHL_DEBUG_PUB.debug('p_concurrent_flag:' || p_concurrent_flag );
1315 AHL_DEBUG_PUB.debug('p_commit:' || p_commit );
1316 END IF;
1317
1318 IF (p_concurrent_flag = 'Y') THEN
1319 fnd_file.put_line(fnd_file.log, 'Starting processing for contract Number '|| p_contract_number || ' and contract modifier' || p_contract_modifier);
1320 -- If the call is from concurrent program, then commit should default to TRUE
1321 l_commit := FND_API.G_TRUE;
1322 END IF;
1323
1324 l_inp_cont_rec.contract_number := p_contract_number;
1325 l_inp_cont_rec.contract_number_modifier := p_contract_modifier;
1326 l_inp_cont_rec.validate_flag := 'Y';
1327
1328 -- Fix for bug# 5639852 -- Begin.
1329 l_inp_cont_rec.request_date := NULL; -- defaults to sysdate.
1330
1331 -- For signed contracts we need to send a future date.
1332 -- find out the minimum end date for the contract lines to ensure date
1333 -- coverage for all service lines.
1334 IF (p_contract_modifier IS NULL) THEN
1335 OPEN get_oks_line_end_dt2(p_contract_number);
1336 FETCH get_oks_line_end_dt2 INTO l_end_date, l_start_date;
1337 CLOSE get_oks_line_end_dt2;
1338 ELSE
1339 OPEN get_oks_line_end_dt1(p_contract_number, p_contract_modifier);
1340 FETCH get_oks_line_end_dt1 INTO l_end_date, l_start_date;
1341 CLOSE get_oks_line_end_dt1;
1342 END IF;
1343
1344 IF (l_start_date > trunc(sysdate)) THEN
1345 IF (l_end_date IS NOT NULL) THEN
1346 l_inp_cont_rec.request_date := l_end_date;
1347 END IF;
1348 END IF;
1349 -- Fix for bug# 5639852 -- End.
1350
1351 OKS_ENTITLEMENTS_PUB.get_contracts
1352 (
1353 p_api_version => 1.0,
1354 p_init_msg_list => FND_API.G_FALSE,
1355 p_inp_rec => l_inp_cont_rec,
1356 x_return_status => x_return_status,
1357 x_msg_count => x_msg_count,
1358 x_msg_data => x_msg_data,
1359 x_ent_contracts => l_ent_cont_tbl
1360 );
1361
1362 -- Check Error Message stack.
1363 l_msg_count := FND_MSG_PUB.count_msg;
1364 IF (l_msg_count > 0 or x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1365 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1366 END IF;
1367
1368 IF (l_ent_cont_tbl.count > 0)
1369 THEN
1370 FOR i IN l_ent_cont_tbl.FIRST..l_ent_cont_tbl.LAST
1371 LOOP
1372 IF (l_ent_cont_tbl(i).coverage_level_code = 'COVER_PROD')
1373 THEN
1374 IF (p_concurrent_flag = 'Y') THEN
1375 fnd_file.put_line(fnd_file.log, 'Calling Process_Unit for instance: ' || l_ent_cont_tbl(i).coverage_level_id);
1376 END IF;
1377 AHL_UMP_ProcessUnit_PVT.Process_Unit
1378 (
1379 p_commit => l_commit,
1380 x_msg_count => x_msg_count,
1381 x_msg_data => x_msg_data,
1382 x_return_status => x_return_status,
1383 p_csi_item_instance_id => l_ent_cont_tbl(i).coverage_level_id,
1384 p_concurrent_flag => p_concurrent_flag
1385 );
1386 IF (p_concurrent_flag = 'Y' and (FND_MSG_PUB.count_msg > 0 or x_return_status <> FND_API.G_RET_STS_SUCCESS)) THEN
1387 fnd_file.put_line(fnd_file.log, 'Process_Unit failed for instance: ' || l_ent_cont_tbl(i).coverage_level_id);
1388 END IF;
1389 END IF;
1390 END LOOP;
1391 END IF;
1392
1393 -- Check Error Message stack.
1394 l_msg_count := FND_MSG_PUB.count_msg;
1395 IF (l_msg_count > 0 or x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1396 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1397 END IF;
1398
1399 -- Standard check of p_commit
1400 IF FND_API.TO_BOOLEAN(p_commit) THEN
1401 COMMIT WORK;
1402 END IF;
1403
1404 -- Log success message if called by concurrent program.
1405 IF (p_concurrent_flag = 'Y') THEN
1406 fnd_file.put_line(fnd_file.log, 'Message-Successfully processed: contract Number '|| p_contract_number || ' and contract modifier' || p_contract_modifier);
1407 END IF;
1408
1409 -- Standard call to get message count and if count is 1, get message info
1410 FND_MSG_PUB.Count_And_Get
1411 (
1412 p_count => x_msg_count,
1413 p_data => x_msg_data,
1414 p_encoded => fnd_api.g_false
1415 );
1416
1417 EXCEPTION
1418 WHEN FND_API.G_EXC_ERROR THEN
1419 x_return_status := FND_API.G_RET_STS_ERROR;
1420 Rollback to Process_PM_Contracts_PVT;
1421 FND_MSG_PUB.count_and_get
1422 (
1423 p_count => x_msg_count,
1424 p_data => x_msg_data,
1425 p_encoded => fnd_api.g_false
1426 );
1427 IF (p_concurrent_flag = 'Y') THEN
1428 fnd_file.put_line(fnd_file.log, 'Process_PM_Contracts failed for: contract Number '|| p_contract_number || ' and contract modifier' || p_contract_modifier);
1429 log_error_messages;
1430 END IF;
1431 AHL_DEBUG_PUB.disable_debug;
1432
1433 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1434 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1435 Rollback to Process_PM_Contracts_PVT;
1436 FND_MSG_PUB.count_and_get
1437 (
1438 p_count => x_msg_count,
1439 p_data => x_msg_data,
1440 p_encoded => fnd_api.g_false
1441 );
1442 IF (p_concurrent_flag = 'Y') THEN
1443 fnd_file.put_line(fnd_file.log, 'Process_PM_Contracts failed for: contract Number '|| p_contract_number || ' and contract modifier' || p_contract_modifier);
1444 log_error_messages;
1445 END IF;
1446 AHL_DEBUG_PUB.disable_debug;
1447
1448 WHEN OTHERS THEN
1449 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1450 Rollback to Process_PM_Contracts_PVT;
1451 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
1452 fnd_msg_pub.add_exc_msg
1453 (
1454 p_pkg_name => G_PKG_NAME,
1455 p_procedure_name => 'Process_PM_Contracts',
1456 p_error_text => SUBSTR(SQLERRM,1,240)
1457 );
1458 END IF;
1459 FND_MSG_PUB.count_and_get
1460 (
1461 p_count => x_msg_count,
1462 p_data => x_msg_data,
1463 p_encoded => fnd_api.g_false
1464 );
1465 IF (p_concurrent_flag = 'Y') THEN
1466 fnd_file.put_line(fnd_file.log, 'Process_PM_Contracts failed for: contract Number '|| p_contract_number || ' and contract modifier' || p_contract_modifier);
1467 log_error_messages;
1468 END IF;
1469 AHL_DEBUG_PUB.disable_debug;
1470 END Process_PM_Contracts;
1471 -- Tamal: Bug #4207212, #4114368: End
1472
1473 ------------------------------------------------------------------------------
1474 -- Start of Comments --
1475 -- Procedure name : Process_All_Units
1476 -- Type : Private
1477 -- Function : Loops through all units and calls Process_Unit for each unit.
1478 -- Pre-reqs :
1479 -- Parameters :
1480 --
1481 -- p_concurrent_flag IN VARCHAR2
1482 -- This flag will be 'Y' if called from a concurrent program. Based on this flag, the error
1483 -- and informational messages will be logged into the log file by Process_Unit.
1484
1485 PROCEDURE Process_All_Units (
1486 p_commit IN VARCHAR2 := FND_API.G_FALSE,
1487 x_msg_count OUT NOCOPY NUMBER,
1488 x_msg_data OUT NOCOPY VARCHAR2,
1489 x_return_status OUT NOCOPY VARCHAR2,
1490 p_concurrent_flag IN VARCHAR2 := 'N',
1491 p_num_of_workers IN NUMBER := 1,
1492 p_mtl_category_id IN NUMBER := NULL,
1493 p_process_option IN VARCHAR2 := NULL,
1494 -- JKJain, NR Analysis and Forecasting
1495 p_simulation_plan_id IN NUMBER := NULL)
1496
1497 IS
1498
1499 -- uncommented query to fix performance issue 6893404
1500 -- declare cursor to retrieve min/max instances from Installed Base for PM installation.
1501 CURSOR csi_pm_instance_csr IS
1502 SELECT min(instance_id), max(instance_id)
1503 FROM csi_item_instances csi,
1504 (select me.inventory_item_id
1505 from ahl_mr_effectivities me, ahl_mr_headers_app_v mr
1506 where mr.mr_header_id = me.mr_header_id
1507 and mr.type_code = 'PROGRAM') mre
1508 WHERE trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate) AND
1509 trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1))
1510 AND mre.inventory_item_id = csi.inventory_item_id;
1511
1512
1513 l_commit VARCHAR2(1) := p_commit;
1514
1515 l_min_csi_id NUMBER;
1516 l_max_csi_id NUMBER;
1517
1518 BEGIN
1519
1520 -- Initialize Procedure return status to success
1521 x_return_status := FND_API.G_RET_STS_SUCCESS;
1522
1523 -- Enable Debug.
1524 -- Add api start debug mesg.
1525 IF G_DEBUG = 'Y' THEN
1526 AHL_DEBUG_PUB.enable_debug;
1527 AHL_DEBUG_PUB.debug('Begin private API:' || G_PKG_NAME || '.' || 'Process_All_Units');
1528 END IF;
1529
1530 -- For concurrent program.
1531 IF (p_concurrent_flag = 'Y') THEN
1532 l_commit := FND_API.G_TRUE;
1533 END IF;
1534
1535 -- JKJain, NR Analysis and Forecasting
1536 IF(p_simulation_plan_id IS NULL) THEN
1537 G_PRIMARY_PLAN := 'Y';
1538 G_SIMULATION_PLAN_ID := NULL;
1539 ELSE
1540 G_PRIMARY_PLAN := 'N';
1541 G_SIMULATION_PLAN_ID := p_simulation_plan_id;
1542
1543 --Delete sim UEs belonging to unit which are not not present in the sim plan now or are expired
1544 DELETE FROM AHL_UE_SIMULATIONS
1545 WHERE SIMULATION_PLAN_ID = p_simulation_plan_id
1546 AND UNIT_CONFIG_HEADER_ID NOT IN
1547 (SELECT DISTINCT FU.UNIT_CONFIG_HEADER_ID
1548 FROM AHL_FLEET_UNIT_ASSOCS FU,
1549 AHL_UNIT_CONFIG_HEADERS UC
1550 WHERE SIMULATION_PLAN_ID = p_simulation_plan_id
1551 AND UC.UNIT_CONFIG_HEADER_ID = FU.UNIT_CONFIG_HEADER_ID
1552 AND ahl_util_uc_pkg.get_uc_status_code(UC.UNIT_CONFIG_HEADER_ID) NOT IN ('DRAFT', 'EXPIRED')
1553 );
1554 END IF;
1555
1556 IF (G_IS_PM_INSTALLED = 'N') THEN
1557 -- AHL processing.
1558 Split_Process_All_Instances(p_concurrent_flag => p_concurrent_flag,
1559 p_commit_flag => l_commit,
1560 p_num_of_workers => p_num_of_workers,
1561 p_mr_header_id => null,
1562 p_mtl_category_id => p_mtl_category_id,
1563 p_process_option => p_process_option,
1564 x_msg_count => x_msg_count,
1565 x_msg_data => x_msg_data,
1566 x_return_status => x_return_status);
1567
1568 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1569 RETURN;
1570 END IF;
1571
1572 ELSE
1573 -- PM processing.
1574 OPEN csi_pm_instance_csr;
1575 FETCH csi_pm_instance_csr INTO l_min_csi_id, l_max_csi_id;
1576 CLOSE csi_pm_instance_csr;
1577
1578 Instance_Split_Sequential(p_csi_max_id => l_max_csi_id,
1579 p_csi_min_id => l_min_csi_id,
1580 p_num_workers => p_num_of_workers,
1581 p_mr_header_id => null);
1582 END IF; -- pm installation check.
1583
1584 END Process_All_Units;
1585
1586 --------------------------------------------------------------------------
1587 PROCEDURE Validate_Item_Instance (p_csi_item_instance_id IN NUMBER,
1588 x_inventory_item_id OUT NOCOPY NUMBER,
1589 x_inv_master_organization_id OUT NOCOPY NUMBER,
1590 x_expired_flag OUT NOCOPY VARCHAR2)
1591 IS
1592
1593 -- To validate instance.
1594 CURSOR csi_item_instances_csr(p_csi_item_instance_id IN NUMBER) IS
1595 SELECT instance_number, active_end_date,
1596 inventory_item_id,
1597 inv_master_organization_id
1598 FROM csi_item_instances
1599 WHERE instance_id = p_csi_item_instance_id;
1600
1601 l_inventory_item_id NUMBER;
1602 l_inv_master_organization_id NUMBER;
1603 l_instance_number csi_item_instances.instance_number%TYPE;
1604 l_active_end_date DATE;
1605 l_expired_flag VARCHAR2(1);
1606
1607 BEGIN
1608
1609 IF G_DEBUG = 'Y' THEN
1610 AHL_DEBUG_PUB.debug('Start Validate Item Instance');
1611 END IF;
1612
1613 -- added to fix bug# 8567880.
1614 l_expired_flag := 'N';
1615
1616 -- Validate csi_item_instance_id.
1617 IF (p_csi_item_instance_id IS NOT NULL) THEN
1618 OPEN csi_item_instances_csr (p_csi_item_instance_id);
1619 FETCH csi_item_instances_csr INTO l_instance_number, l_active_end_date,
1620 l_inventory_item_id, l_inv_master_organization_id;
1621 IF (csi_item_instances_csr%NOTFOUND) THEN
1622 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_INSTID_NOTFOUND');
1623 FND_MESSAGE.Set_Token('INST_ID', p_csi_item_instance_id);
1624 FND_MSG_PUB.ADD;
1625 CLOSE csi_item_instances_csr;
1626 --dbms_output.put_line('Instance not found');
1627 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1628 ELSIF l_active_end_date <= sysdate THEN
1629 /* Bypass error to fix bug# 8567880. For expired
1630 instances we will delete open UMPs.
1631 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_INST_EXPIRED');
1632 FND_MESSAGE.Set_Token('NUMBER', l_instance_number);
1633 FND_MSG_PUB.ADD;
1634 --dbms_output.put_line('Instance has expired');
1635 */
1636 l_expired_flag := 'Y';
1637 END IF;
1638
1639 CLOSE csi_item_instances_csr;
1640 END IF;
1641
1642 x_inventory_item_id := l_inventory_item_id;
1643 x_inv_master_organization_id := l_inv_master_organization_id;
1644 x_expired_flag := l_expired_flag;
1645
1646 IF G_DEBUG = 'Y' THEN
1647 AHL_DEBUG_PUB.debug('End Validate Item Instance');
1648 END IF;
1649
1650 END Validate_Item_Instance;
1651
1652 -----------------------------------------------------------------------------
1653 -- To get the unit and master configurations IDs for the input item instance.
1654
1655 PROCEDURE Get_Unit_Master_ConfigIDs (p_csi_item_instance_id IN NUMBER,
1656 x_uc_header_id OUT NOCOPY NUMBER,
1657 x_master_config_id OUT NOCOPY NUMBER)
1658 IS
1659
1660 -- To get unit config id.
1661 CURSOR ahl_unit_config_header_csr (p_item_instance_id IN NUMBER) IS
1662 SELECT name, active_start_date, active_end_date, master_config_id, unit_config_header_id,
1663 unit_config_status_code
1664 FROM ahl_unit_config_headers
1665 WHERE csi_item_instance_id = p_item_instance_id
1666 --AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate) AND
1667 -- trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
1668 AND parent_uc_header_id IS NULL;
1669
1670 l_name ahl_unit_config_headers.name%TYPE;
1671 l_active_start_date DATE;
1672 l_active_end_date DATE;
1673 l_master_config_id NUMBER;
1674 l_unit_config_header_id NUMBER;
1675 l_config_status_code fnd_lookup_values_vl.lookup_code%TYPE;
1676
1677 BEGIN
1678
1679 IF G_DEBUG = 'Y' THEN
1680 AHL_DEBUG_PUB.debug('Start Get_Unit_Master_ConfigIDs');
1681 END IF;
1682
1683 x_uc_header_id := null;
1684 x_master_config_id := null;
1685
1686 IF (p_csi_item_instance_id IS NOT NULL) THEN
1687 OPEN ahl_unit_config_header_csr (p_csi_item_instance_id);
1688 FETCH ahl_unit_config_header_csr INTO l_name, l_active_start_date,
1689 l_active_end_date, l_master_config_id,
1690 l_unit_config_header_id,
1691 l_config_status_code;
1692 IF (ahl_unit_config_header_csr%FOUND) THEN
1693 --IF (l_config_status_code <> 'COMPLETE' AND l_config_status_code <> 'INCOMPLETE') THEN
1694 --modified for quaratine statuses.
1695 IF (l_config_status_code = 'DRAFT') THEN
1696 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_STATUS_INVALID');
1697 FND_MESSAGE.Set_Token('NAME',l_name);
1698 FND_MSG_PUB.ADD;
1699 --dbms_output.put_line('UC is in draft status');
1700 ELSE
1701 x_uc_header_id := l_unit_config_header_id;
1702 x_master_config_id := l_master_config_id;
1703 END IF;
1704 END IF;
1705 CLOSE ahl_unit_config_header_csr;
1706 END IF;
1707
1708 IF (G_concurrent_flag = 'Y') THEN
1709 fnd_file.put_line (FND_FILE.LOG, 'Unit Config Name:' || l_name);
1710 END IF;
1711
1712 IF G_DEBUG = 'Y' THEN
1713 AHL_DEBUG_PUB.debug('Unit Config ID:' || x_uc_header_id);
1714 AHL_DEBUG_PUB.debug('Master Config ID:' || x_master_config_id);
1715 AHL_DEBUG_PUB.debug('End Get_Unit_Master_ConfigIDs');
1716 END IF;
1717
1718 END Get_Unit_Master_ConfigIDs;
1719
1720 -----------------------------------------------------------------------
1721 -- To get the root item instance for the input item instance if exists.
1722
1723 FUNCTION Get_RootInstanceID(p_csi_item_instance_id IN NUMBER)
1724 RETURN NUMBER
1725 IS
1726
1727 CURSOR csi_root_instance_csr (p_instance_id IN NUMBER) IS
1728 SELECT root.object_id
1729 FROM csi_ii_relationships root
1730 WHERE NOT EXISTS (SELECT 'x'
1731 FROM csi_ii_relationships
1732 WHERE subject_id = root.object_id
1733 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1))
1734 )
1735 START WITH root.subject_id = p_instance_id
1736 AND root.relationship_type_code = 'COMPONENT-OF'
1737 AND trunc(nvl(root.active_start_date,sysdate)) <= trunc(sysdate)
1738 AND trunc(sysdate) < trunc(nvl(root.active_end_date, sysdate+1))
1739 CONNECT BY PRIOR root.object_id = root.subject_id
1740 AND root.relationship_type_code = 'COMPONENT-OF'
1741 AND trunc(nvl(root.active_start_date,sysdate)) <= trunc(sysdate)
1742 AND trunc(sysdate) < trunc(nvl(root.active_end_date, sysdate+1));
1743
1744 l_csi_instance_id NUMBER;
1745
1746 BEGIN
1747
1748 -- get root instance given an item instance_id.
1749 OPEN csi_root_instance_csr (p_csi_item_instance_id);
1750 FETCH csi_root_instance_csr INTO l_csi_instance_id;
1751 IF (csi_root_instance_csr%NOTFOUND) THEN
1752 -- input id is root instance.
1753 l_csi_instance_id := p_csi_item_instance_id;
1754 END IF;
1755 CLOSE csi_root_instance_csr;
1756 --dbms_output.put_line ('root instance' || l_csi_instance_id);
1757
1758 RETURN l_csi_instance_id;
1759
1760 END Get_RootInstanceID;
1761
1762 -------------------------------------------------------------
1763 -- Validate the input item instance.
1764
1765 PROCEDURE Build_Config_Tree(p_csi_root_instance_id IN NUMBER,
1766 p_master_config_id IN NUMBER,
1767 x_config_node_tbl OUT NOCOPY AHL_UMP_PROCESSUNIT_PVT.config_node_tbl_type)
1768
1769 IS
1770
1771 CURSOR csi_config_tree_csr ( p_csi_root_instance_id IN NUMBER) IS
1772 SELECT subject_id , object_id, position_reference
1773 FROM csi_ii_relationships
1774 START WITH object_id = p_csi_root_instance_id
1775 AND relationship_type_code = 'COMPONENT-OF'
1776 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1777 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1))
1778 CONNECT BY PRIOR subject_id = object_id
1779 AND relationship_type_code = 'COMPONENT-OF'
1780 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1781 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1))
1782 ORDER BY level;
1783
1784 i NUMBER;
1785 l_config_node_tbl AHL_UMP_PROCESSUNIT_PVT.config_node_tbl_type := x_config_node_tbl;
1786
1787 -- added for perf fix for bug# 6893404.
1788 l_buffer_limit number := 1000;
1789
1790 l_subj_id_tbl nbr_tbl_type;
1791 l_obj_id_tbl nbr_tbl_type;
1792 l_posn_ref_tbl vchar_tbl_type;
1793
1794 BEGIN
1795
1796 IF G_DEBUG = 'Y' THEN
1797 AHL_DEBUG_PUB.debug('Start Build_Config_Tree');
1798 END IF;
1799
1800 -- For top node.
1801 l_config_node_tbl(1).csi_item_instance_id := p_csi_root_instance_id;
1802
1803 -- For position reference.
1804 IF (p_master_config_id IS NOT NULL) THEN
1805 l_config_node_tbl(1).position_reference := to_char(p_master_config_id);
1806 END IF;
1807
1808 i := 1;
1809
1810 -- add child nodes.
1811 -- added for perf fix for bug# 6893404.
1812 OPEN csi_config_tree_csr(p_csi_root_instance_id);
1813 LOOP
1814 FETCH csi_config_tree_csr BULK COLLECT INTO l_subj_id_tbl, l_obj_id_tbl, l_posn_ref_tbl
1815 LIMIT l_buffer_limit;
1816
1817 EXIT WHEN (l_subj_id_tbl.count = 0);
1818
1819 FOR j IN l_subj_id_tbl.FIRST..l_subj_id_tbl.LAST LOOP
1820
1821 -- Loop through to get all components of the configuration.
1822 -- FOR node_rec IN csi_config_tree_csr(p_csi_root_instance_id) LOOP
1823 i := i + 1;
1824
1825 --l_config_node_tbl(i).csi_item_instance_id := node_rec.subject_id;
1826 --l_config_node_tbl(i).object_id := node_rec.object_id;
1827 --l_config_node_tbl(i).position_reference := node_rec.position_reference;
1828
1829 l_config_node_tbl(i).csi_item_instance_id := l_subj_id_tbl(j);
1830 l_config_node_tbl(i).object_id := l_obj_id_tbl(j);
1831 l_config_node_tbl(i).position_reference := l_posn_ref_tbl(j);
1832
1833 END LOOP; -- l_subj_id_tbl.FIRST
1834
1835 -- reset tables and get the next batch of nodes.
1836 l_subj_id_tbl.DELETE;
1837 l_obj_id_tbl.DELETE;
1838 l_posn_ref_tbl.DELETE;
1839
1840 END LOOP; -- FETCH csi_config_tree_csr
1841 CLOSE csi_config_tree_csr;
1842
1843 X_CONFIG_NODE_TBL := l_config_node_tbl;
1844
1845 IF G_DEBUG = 'Y' THEN
1846 AHL_DEBUG_PUB.debug('End Build_Config_Tree');
1847 AHL_DEBUG_PUB.debug('Count on config' || x_config_node_tbl.COUNT);
1848 END IF;
1849
1850 END Build_Config_Tree;
1851
1852 -----------------------------------------------------------------------
1853 -- This function calculates the last day of the rolling window based on
1854 -- profile values.
1855
1856 FUNCTION Get_Rolling_Window_Date RETURN DATE IS
1857
1858 l_date_uom VARCHAR2(30);
1859 l_value NUMBER;
1860 l_last_day_of_window DATE;
1861
1862 BEGIN
1863
1864 BEGIN
1865 l_date_uom := FND_PROFILE.VALUE('AHL_UMP_MAX_PLANNING_UOM');
1866 l_value := to_number(FND_PROFILE.VALUE('AHL_UMP_MAX_PLANNING_VALUE'));
1867
1868 IF (l_date_uom IS NULL) THEN
1869 l_last_day_of_window := SYSDATE;
1870 ELSIF (l_value <= 0 OR l_value IS NULL) THEN
1871 l_last_day_of_window := SYSDATE;
1872 ELSIF (l_date_uom = 'YR') THEN
1873 l_last_day_of_window := ADD_MONTHS(SYSDATE, 12 * l_value);
1874 ELSIF (l_date_uom = 'MTH') THEN
1875 l_last_day_of_window := ADD_MONTHS(SYSDATE, l_value);
1876 ELSIF (l_date_uom = 'WK') THEN
1877 l_last_day_of_window := SYSDATE + (7 * l_value);
1878 ELSIF (l_date_uom = 'DAY') THEN
1879 l_last_day_of_window := SYSDATE + l_value;
1880 END IF;
1881
1882 -- Add debug mesg.
1883 IF G_DEBUG = 'Y' THEN
1884 AHL_DEBUG_PUB.debug('last day of window' || l_last_day_of_window);
1885 AHL_DEBUG_PUB.debug('profile uom:' || l_date_uom);
1886 AHL_DEBUG_PUB.debug('profile value:' || l_value);
1887 END IF;
1888
1889 EXCEPTION
1890 WHEN VALUE_ERROR THEN
1891 l_last_day_of_window := SYSDATE;
1892
1893 WHEN INVALID_NUMBER THEN
1894 l_last_day_of_window := SYSDATE;
1895
1896 END;
1897
1898 -- return date.
1899 RETURN l_last_day_of_window;
1900
1901 END Get_Rolling_Window_Date;
1902
1903 --------------------------------------------------------------------
1904 -- Get the utilization forecast applicable to the input item instance/unit.
1905 -- For preventive maintenance, forecast definition is at either instance level
1906 -- or item level.
1907 PROCEDURE Get_Utilization_Forecast (p_csi_item_instance_id IN NUMBER,
1908 p_uc_header_id IN NUMBER,
1909 p_inventory_item_id IN NUMBER,
1910 p_inventory_org_id IN NUMBER,
1911 x_forecast_details_tbl OUT NOCOPY forecast_details_tbl_type)
1912 IS
1913
1914 CURSOR ahl_uf_headers_csr(p_uc_header_id IN NUMBER) IS
1915 SELECT uf_header_id, use_unit_flag
1916 FROM ahl_uf_headers
1917 WHERE unit_config_header_id = p_uc_header_id;
1918
1919 CURSOR ahl_uf_details_csr(p_uf_header_id IN NUMBER) IS
1920 SELECT uom_code, start_date, end_date, usage_per_day
1921 FROM ahl_uf_details
1922 WHERE uf_header_id = p_uf_header_id
1923 AND trunc(nvl(end_date, sysdate)) >= trunc(sysdate)
1924 order by uom_code, start_date;
1925
1926 CURSOR ahl_pm_uf_headers_csr(p_csi_item_instance_id IN NUMBER) IS
1927 SELECT uf_header_id, use_unit_flag
1928 FROM ahl_uf_headers
1929 WHERE csi_item_instance_id = p_csi_item_instance_id;
1930
1931 CURSOR ahl_pm_item_uf_csr (p_csi_item_instance_id IN NUMBER) IS
1932 SELECT uom_code, start_date, end_date, usage_per_day
1933 FROM ahl_uf_headers uh, ahl_uf_details ud, csi_item_instances csi
1934 WHERE uh.uf_header_id = ud.uf_header_id
1935 AND csi.instance_id = p_csi_item_instance_id
1936 AND csi.inventory_item_id = uh.inventory_item_id
1937 AND trunc(nvl(end_date, sysdate)) >= trunc(sysdate)
1938 order by uom_code, start_date;
1939
1940 -- JKJain, NR Analysis and Forecasting
1941
1942 CURSOR ahl_fleet_uf_header_csr(c_uc_header_id IN NUMBER) IS
1943 SELECT simulation_plan_id
1944 FROM ahl_fleet_unit_assocs
1945 WHERE unit_config_header_id = c_uc_header_id
1946 AND simulation_plan_id = nvl(G_SIMULATION_PLAN_ID, get_primary_plan_id)
1947 AND trunc(nvl(association_end, sysdate)) >= trunc(sysdate);
1948
1949 CURSOR ahl_fleet_uf_details_csr(c_uc_header_id IN NUMBER, c_simulation_plan_id In NUMBER) IS
1950 SELECT FUF.uom_code, FUF.period_start_date, FUF.period_end_date,FUA.association_start ,FUA.association_end, FUF.forecasted_daily_usage usage_per_day
1951 FROM ahl_fleet_utlzn_forecast FUF ,ahl_fleet_unit_assocs FUA, ahl_fleet_headers_b FLT
1952 WHERE FUF.fleet_header_id = FUA.fleet_header_id
1953 AND trunc(nvl(period_end_date, sysdate)) >= trunc(sysdate)
1954 AND trunc(nvl(association_end, sysdate)) >= trunc(sysdate)
1955 AND trunc(nvl(period_end_date, association_start)) >= trunc(association_start)
1956 AND trunc(period_start_date) <= trunc(nvl(association_end,period_start_date)) -- Bug 13012968
1957 AND FUA.unit_config_header_id = c_uc_header_id
1958 AND FUA.simulation_plan_id = c_simulation_plan_id
1959 AND FLT.fleet_header_id = FUA.fleet_header_id
1960 AND FLT.status_code = 'COMPLETE'
1961 order by uom_code, association_start, period_start_date;
1962
1963 -- JKJain, NR Analysis and Forecasting
1964 l_forecast_details_flt_tbl forecast_details_tbl_type;
1965 l_forecast_details_pc_tbl forecast_details_tbl_type;
1966 l_simulation_plan_id NUMBER;
1967 l_flt_start_date DATE;
1968 l_flt_end_date DATE;
1969 l_pc_start_date DATE;
1970 l_pc_end_date DATE;
1971 l_previous_end_date DATE := sysdate;
1972 l_pc_index NUMBER;
1973 l_flt_index NUMBER;
1974 l_flt_uom_code VARCHAR2(3);
1975 l_pc_uom_code VARCHAR2(3);
1976
1977 l_uf_header_id NUMBER;
1978 l_use_unit_flag AHL_UF_HEADERS.USE_UNIT_FLAG%TYPE;
1979 l_uf_details_tbl AHL_UMP_UF_PVT.uf_details_tbl_type;
1980
1981 l_index NUMBER := 1;
1982 l_forecast_details_tbl forecast_details_tbl_type;
1983 l_return_status VARCHAR2(1);
1984
1985 -- Added to fix bug# 6326056.
1986 l_duplicate_flag VARCHAR2(1);
1987
1988 -- Added to fix bug# 13025105
1989 l_uom_code VARCHAR2(3);
1990
1991 BEGIN
1992
1993 IF G_DEBUG = 'Y' THEN
1994 AHL_DEBUG_PUB.debug('Start Get_Utilization_Forecast');
1995 AHL_DEBUG_PUB.debug ('Input csi'|| p_csi_item_instance_id);
1996 AHL_DEBUG_PUB.debug ('Input uc'|| p_uc_header_id);
1997 AHL_DEBUG_PUB.debug ('Input invID' || p_inventory_item_id);
1998 AHL_DEBUG_PUB.debug ('Input invORGID' || p_inventory_org_id);
1999 END IF;
2000
2001 -- Check installation to get appropriate forecast.
2002 IF (G_IS_PM_INSTALLED = 'Y') THEN
2003 -- pm is installed.
2004
2005 IF G_DEBUG = 'Y' THEN
2006 AHL_DEBUG_PUB.debug('PM forecast');
2007 END IF;
2008
2009 -- Check if forecast available at instance level.
2010 OPEN ahl_pm_uf_headers_csr(p_csi_item_instance_id);
2011 FETCH ahl_pm_uf_headers_csr INTO l_uf_header_id, l_use_unit_flag;
2012 IF (ahl_pm_uf_headers_csr%FOUND) AND (l_use_unit_flag = 'Y') THEN
2013 --dbms_output.put_line('Found uf header and use_unit_flag' || l_uf_header_id);
2014
2015 -- initialize.
2016 l_index := 1;
2017 FOR l_forecast_detail_rec IN ahl_uf_details_csr(l_uf_header_id) LOOP
2018 l_forecast_details_tbl(l_index).uom_code := l_forecast_detail_rec.uom_code;
2019 l_forecast_details_tbl(l_index).start_date := trunc(l_forecast_detail_rec.start_date);
2020 l_forecast_details_tbl(l_index).end_date := trunc(l_forecast_detail_rec.end_date);
2021 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_detail_rec.usage_per_day;
2022 -- JKJain, NR Analysis and Forecasting
2023 l_forecast_details_tbl(l_index).utilization_type := 'PM-UNIT';
2024 l_index := l_index + 1;
2025
2026 END LOOP;
2027 ELSE -- use item forecast.
2028 --dbms_output.put_line ('item forecast');
2029
2030 -- initialize.
2031 l_index := 1;
2032 FOR l_forecast_detail_rec IN ahl_pm_item_uf_csr(p_csi_item_instance_id) LOOP
2033 l_forecast_details_tbl(l_index).uom_code := l_forecast_detail_rec.uom_code;
2034 l_forecast_details_tbl(l_index).start_date := trunc(l_forecast_detail_rec.start_date);
2035 l_forecast_details_tbl(l_index).end_date := trunc(l_forecast_detail_rec.end_date);
2036 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_detail_rec.usage_per_day;
2037 -- JKJain, NR Analysis and Forecasting
2038 l_forecast_details_tbl(l_index).utilization_type := 'PM-ITEM';
2039 l_index := l_index + 1;
2040
2041 END LOOP;
2042 END IF;
2043 CLOSE ahl_pm_uf_headers_csr;
2044 ELSE -- is_pm_installed.
2045 -- forecast for AHL installation.
2046 IF G_DEBUG = 'Y' THEN
2047 AHL_DEBUG_PUB.debug('AHL Installation forecast');
2048 END IF;
2049
2050 -- If Utlization forecast defined at unit level
2051 IF (p_uc_header_id IS NOT NULL) THEN
2052 --dbms_output.put_line ('uc header not null');
2053 -- check if forecast defined.
2054
2055 -- JKJain, NR Analysis and Forecasting
2056 --If utilization defined at Fleet Level
2057 OPEN ahl_fleet_uf_header_csr(p_uc_header_id);
2058 FETCH ahl_fleet_uf_header_csr INTO l_simulation_plan_id;
2059 IF (ahl_fleet_uf_header_csr%FOUND) THEN --Fleet
2060 l_index := 1;
2061 FOR l_forecast_detail_rec IN ahl_fleet_uf_details_csr(p_uc_header_id,l_simulation_plan_id) LOOP
2062
2063 IF(l_forecast_detail_rec.association_start > l_forecast_detail_rec.period_start_date) THEN
2064 l_flt_start_date := trunc(l_forecast_detail_rec.association_start);
2065 ELSE
2066 l_flt_start_date := trunc(l_forecast_detail_rec.period_start_date);
2067 END IF;
2068
2069
2070 IF(l_forecast_detail_rec.association_end IS NOT NULL) THEN
2071 IF(l_forecast_detail_rec.period_end_date IS NULL OR l_forecast_detail_rec.period_end_date > l_forecast_detail_rec.association_end) THEN
2072 l_flt_end_date := trunc(l_forecast_detail_rec.association_end);
2073 ELSE
2074 l_flt_end_date := trunc(l_forecast_detail_rec.period_end_date);
2075 END IF;
2076 ELSE
2077 l_flt_end_date := trunc(l_forecast_detail_rec.period_end_date);
2078 END IF;
2079
2080 l_forecast_details_flt_tbl(l_index).uom_code := l_forecast_detail_rec.uom_code;
2081 l_forecast_details_flt_tbl(l_index).start_date := l_flt_start_date;
2082 l_forecast_details_flt_tbl(l_index).end_date := l_flt_end_date;
2083 l_forecast_details_flt_tbl(l_index).usage_per_day := l_forecast_detail_rec.usage_per_day;
2084 l_forecast_details_flt_tbl(l_index).utilization_type := 'FLEET';
2085 l_index := l_index + 1;
2086
2087
2088 END LOOP;
2089
2090 END IF; -- Fleet
2091 CLOSE ahl_fleet_uf_header_csr;
2092
2093 -- JKJain, NR Analysis and Forecasting
2094 l_index :=1;
2095 OPEN ahl_uf_headers_csr (p_uc_header_id);
2096 FETCH ahl_uf_headers_csr INTO l_uf_header_id, l_use_unit_flag;
2097 IF (ahl_uf_headers_csr%FOUND) AND (l_use_unit_flag = 'Y') THEN
2098 FOR l_forecast_detail_rec IN ahl_uf_details_csr(l_uf_header_id) LOOP
2099 l_forecast_details_pc_tbl(l_index).uom_code := l_forecast_detail_rec.uom_code;
2100 l_forecast_details_pc_tbl(l_index).start_date := trunc(l_forecast_detail_rec.start_date);
2101 l_forecast_details_pc_tbl(l_index).end_date := trunc(l_forecast_detail_rec.end_date);
2102 l_forecast_details_pc_tbl(l_index).usage_per_day := l_forecast_detail_rec.usage_per_day;
2103 -- JKJain, NR Analysis and Forecasting
2104 l_forecast_details_pc_tbl(l_index).utilization_type := 'UNIT';
2105 l_index := l_index + 1;
2106
2107 END LOOP;
2108 ELSE /* forecast not defined at UC */
2109 --dbms_output.put_line ('use_unit_flag not Y');
2110 IF G_DEBUG = 'Y' THEN
2111 AHL_DEBUG_PUB.debug('AHL PC forecast for UNIT');
2112 END IF;
2113
2114 -- added parameter p_add_unit_item_forecast to fix bug# 6749351.
2115 AHL_UMP_UF_PVT.Get_UF_FROM_PC (p_unit_config_header_id => p_uc_header_id,
2116 p_add_unit_item_forecast => 'Y',
2117 p_onward_end_date => trunc(sysdate),
2118 x_uf_details_tbl => l_uf_details_tbl,
2119 x_return_status => l_return_status);
2120 /* This will give forecast defined item/pc_node level. */
2121
2122 IF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2123 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2124 ELSIF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
2125 RAISE FND_API.G_EXC_ERROR;
2126 END IF;
2127
2128 -- populate l_forecast_details_tbl based on l_uf_details_tbl.
2129 IF (l_uf_details_tbl.COUNT) > 0 THEN
2130 l_index := 1;
2131
2132 FOR i IN l_uf_details_tbl.FIRST..l_uf_details_tbl.LAST LOOP
2133 l_forecast_details_pc_tbl(l_index).uom_code := l_uf_details_tbl(i).uom_code;
2134 l_forecast_details_pc_tbl(l_index).start_date := trunc(l_uf_details_tbl(i).start_date);
2135 l_forecast_details_pc_tbl(l_index).end_date := trunc(l_uf_details_tbl(i).end_date);
2136 l_forecast_details_pc_tbl(l_index).usage_per_day := l_uf_details_tbl(i).usage_per_day;
2137 -- JKJain, NR Analysis and Forecasting
2138 l_forecast_details_pc_tbl(l_index).utilization_type := 'PC';
2139 l_index := l_index + 1;
2140
2141 END LOOP;
2142
2143 END IF; /* count > 0 */
2144
2145 END IF; -- %found.
2146 CLOSE ahl_uf_headers_csr;
2147 ELSE
2148 IF G_DEBUG = 'Y' THEN
2149 AHL_DEBUG_PUB.debug('AHL PC forecast for ITEM');
2150 END IF;
2151 --dbms_output.put_line ('inv case');
2152
2153 /* following taken care by get_uf_from_pc as part fix for bug# 6749351.
2154 -- first get forecast at item level (fix for bug# 6002569).
2155 -- initialize.
2156 l_index := 1;
2157 FOR l_forecast_detail_rec IN ahl_pm_item_uf_csr(p_csi_item_instance_id)
2158 LOOP
2159 l_forecast_details_tbl(l_index).uom_code := l_forecast_detail_rec.uom_code;
2160 l_forecast_details_tbl(l_index).start_date := trunc(l_forecast_detail_rec.start_date);
2161 l_forecast_details_tbl(l_index).end_date := trunc(l_forecast_detail_rec.end_date);
2162 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_detail_rec.usage_per_day;
2163
2164 l_index := l_index + 1;
2165
2166 END LOOP;
2167 */
2168 /* Next, get forecast defined at instance's item/pc node level. */
2169 -- set parameter to get forecast at item level as well.
2170 AHL_UMP_UF_PVT.Get_UF_FROM_PC (p_inventory_item_id => p_inventory_item_id,
2171 p_inventory_org_id => p_inventory_org_id,
2172 p_add_unit_item_forecast => 'Y',
2173 p_onward_end_date => trunc(sysdate),
2174 x_uf_details_tbl => l_uf_details_tbl,
2175 x_return_status => l_return_status);
2176
2177 IF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2178 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2179 ELSIF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
2180 RAISE FND_API.G_EXC_ERROR;
2181 END IF;
2182
2183 -- Bug# 6749351:Removed duplicate check which is now taken care by get_uf_from_pc.
2184 IF (l_uf_details_tbl.count > 0) THEN
2185 l_index := 1;
2186
2187 FOR i IN l_uf_details_tbl.FIRST..l_uf_details_tbl.LAST LOOP
2188
2189 l_forecast_details_pc_tbl(l_index).uom_code := l_uf_details_tbl(i).uom_code;
2190 l_forecast_details_pc_tbl(l_index).start_date := trunc(l_uf_details_tbl(i).start_date);
2191 l_forecast_details_pc_tbl(l_index).end_date := trunc(l_uf_details_tbl(i).end_date);
2192 l_forecast_details_pc_tbl(l_index).usage_per_day := l_uf_details_tbl(i).usage_per_day;
2193 -- JKJain, NR Analysis and Forecasting
2194 l_forecast_details_pc_tbl(l_index).utilization_type := 'ITEM';
2195 l_index := l_index + 1;
2196
2197 END LOOP; -- l_uf_details_tbl
2198 END IF; -- l_uf_details_tbl.count
2199
2200 END IF; -- p_uc_header_id is not null.
2201
2202 -- JKJain, NR Analysis and Forecasting : Merging Fllet and PC forecasts.
2203 IF (G_DEBUG = 'Y') THEN
2204 AHL_DEBUG_PUB.debug('l_forecast_details_flt_tbl.COUNT '|| l_forecast_details_flt_tbl.COUNT);
2205 AHL_DEBUG_PUB.debug('l_forecast_details_pc_tbl.COUNT ' || l_forecast_details_pc_tbl.COUNT);
2206 END IF;
2207
2208 IF (l_forecast_details_flt_tbl.COUNT > 0) THEN
2209 l_index := 1;
2210 l_pc_index :=1;
2211 l_flt_index :=1;
2212
2213 LOOP
2214
2215 IF ( l_forecast_details_flt_tbl.EXISTS(l_flt_index)) THEN
2216 l_flt_uom_code := l_forecast_details_flt_tbl(l_flt_index).uom_code ;
2217 ELSE
2218 l_flt_uom_code := 'zzz';
2219 END IF;
2220
2221
2222 IF (l_forecast_details_pc_tbl.EXISTS(l_pc_index) ) THEN
2223 l_pc_uom_code := l_forecast_details_pc_tbl(l_pc_index).uom_code ;
2224 ELSE
2225 l_pc_uom_code := 'zzz';
2226 END IF;
2227
2228 IF (G_DEBUG = 'Y') THEN
2229 AHL_DEBUG_PUB.debug('l_flt_uom_code = '|| l_flt_uom_code || ' and l_pc_uom_code = ' || l_pc_uom_code);
2230 END IF;
2231
2232 EXIT WHEN (l_pc_uom_code = 'zzz' AND l_flt_uom_code = 'zzz');
2233 -- Add pc_uom if it is less than flt_uom
2234 IF(l_flt_uom_code > l_pc_uom_code)THEN
2235 LOOP -- If same UOM has multiple records with different usage
2236
2237 l_forecast_details_tbl(l_index).uom_code := l_pc_uom_code;
2238 l_forecast_details_tbl(l_index).start_date := trunc(l_forecast_details_pc_tbl(l_pc_index).start_date);
2239 l_forecast_details_tbl(l_index).end_date := trunc(l_forecast_details_pc_tbl(l_pc_index).end_date);
2240 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_pc_tbl(l_pc_index).usage_per_day;
2241 l_forecast_details_tbl(l_index).utilization_type := l_forecast_details_pc_tbl(l_pc_index).utilization_type;
2242 l_index := l_index + 1;
2243 l_pc_index := l_pc_index + 1;
2244
2245 IF ( l_forecast_details_pc_tbl.EXISTS(l_pc_index)) THEN
2246 EXIT WHEN (l_pc_uom_code <> l_forecast_details_pc_tbl(l_pc_index).uom_code );
2247 ELSE
2248 EXIT;
2249 END IF;
2250 END LOOP;
2251 -- Add flt_uom if it is less than pc_uom
2252 ELSIF (l_flt_uom_code < l_pc_uom_code) THEN
2253 LOOP -- If same UOM has multiple records with different usage
2254
2255 l_forecast_details_tbl(l_index).uom_code := l_flt_uom_code ;
2256 l_forecast_details_tbl(l_index).start_date := trunc(l_forecast_details_flt_tbl(l_flt_index).start_date);
2257 l_forecast_details_tbl(l_index).end_date := trunc(l_forecast_details_flt_tbl(l_flt_index).end_date);
2258 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_flt_tbl(l_flt_index).usage_per_day;
2259 l_forecast_details_tbl(l_index).utilization_type := l_forecast_details_flt_tbl(l_flt_index).utilization_type;
2260 l_index := l_index + 1;
2261 l_flt_index := l_flt_index+1;
2262
2263 IF ( l_forecast_details_flt_tbl.EXISTS(l_flt_index)) THEN
2264 EXIT WHEN (l_flt_uom_code <> l_forecast_details_flt_tbl(l_flt_index).uom_code );
2265 ELSE
2266 EXIT;
2267 END IF;
2268 END LOOP;
2269
2270 ELSE -- l_flt_uom_code = l_pc_uom_code
2271
2272 --Initialize previous end date as a day before today for start of a UOM.
2273 l_previous_end_date := trunc(sysdate-1);
2274
2275 LOOP -- If same UOM has multiple records with different usage
2276 l_flt_start_date := trunc(l_forecast_details_flt_tbl(l_flt_index).start_date);
2277 l_flt_end_date := trunc(l_forecast_details_flt_tbl(l_flt_index).end_date);
2278 l_pc_start_date := trunc(l_forecast_details_pc_tbl(l_pc_index).start_date);
2279 l_pc_end_date := trunc(l_forecast_details_pc_tbl(l_pc_index).end_date);
2280 --Find GAP. New start date should be old_end_date+1
2281 IF(l_flt_start_date > l_previous_end_date+1 AND l_flt_start_date > l_pc_start_date)THEN
2282 --In case of GAP, consider pc utilization
2283 -- IF pc_uom end date is null or more than l_previous_end_date
2284 IF (nvl(l_pc_end_date,l_previous_end_date+1) > l_previous_end_date ) THEN
2285 l_forecast_details_tbl(l_index).uom_code := l_pc_uom_code;
2286 l_forecast_details_tbl(l_index).start_date := GREATEST(l_previous_end_date+1,l_pc_start_date);
2287 l_forecast_details_tbl(l_index).end_date := LEAST(l_flt_start_date-1,nvl(l_pc_end_date,l_flt_start_date-1));
2288 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_pc_tbl(l_pc_index).usage_per_day;
2289 l_forecast_details_tbl(l_index).utilization_type := l_forecast_details_pc_tbl(l_pc_index).utilization_type;
2290
2291 l_previous_end_date := l_forecast_details_tbl(l_index).end_date;
2292 l_index := l_index + 1;
2293
2294 ELSE -- IF pc_uom end date is not null and less than l_previous_end_date
2295 IF(l_forecast_details_pc_tbl.EXISTS(l_pc_index+1)) THEN
2296 IF(l_pc_uom_code = l_forecast_details_pc_tbl(l_pc_index+1).uom_code )THEN -- same UOM
2297 l_pc_index := l_pc_index+1;
2298 ELSE
2299 l_forecast_details_tbl(l_index).uom_code := l_flt_uom_code;
2300 l_forecast_details_tbl(l_index).start_date := l_flt_start_date;
2301 l_forecast_details_tbl(l_index).end_date := l_flt_end_date;
2302 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_flt_tbl(l_flt_index).usage_per_day;
2303 l_forecast_details_tbl(l_index).utilization_type := l_forecast_details_flt_tbl(l_flt_index).utilization_type;
2304
2305 l_previous_end_date := l_flt_end_date;
2306 l_index := l_index + 1;
2307 l_flt_index := l_flt_index+1;
2308 END IF;
2309 ELSE --pc table last record reached
2310 l_forecast_details_tbl(l_index).uom_code := l_flt_uom_code;
2311 l_forecast_details_tbl(l_index).start_date := l_flt_start_date;
2312 l_forecast_details_tbl(l_index).end_date := l_flt_end_date;
2313 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_flt_tbl(l_flt_index).usage_per_day;
2314 l_forecast_details_tbl(l_index).utilization_type := l_forecast_details_flt_tbl(l_flt_index).utilization_type;
2315
2316 l_previous_end_date := l_flt_end_date;
2317 l_index := l_index + 1;
2318 l_flt_index := l_flt_index+1;
2319 END IF;
2320
2321 END IF;
2322
2323 ELSE --l_flt_start_date <= l_previous_end_date+1
2324
2325 l_forecast_details_tbl(l_index).uom_code := l_flt_uom_code;
2326 l_forecast_details_tbl(l_index).start_date := l_flt_start_date;
2327 l_forecast_details_tbl(l_index).end_date := l_flt_end_date;
2328 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_flt_tbl(l_flt_index).usage_per_day;
2329 l_forecast_details_tbl(l_index).utilization_type := l_forecast_details_flt_tbl(l_flt_index).utilization_type;
2330
2331 l_previous_end_date := l_flt_end_date;
2332 l_index := l_index + 1;
2333 l_flt_index := l_flt_index+1;
2334
2335 END IF; --l_flt_start_date > l_previous_end_date+1
2336
2337 IF ( l_forecast_details_flt_tbl.EXISTS(l_flt_index)) THEN
2338 EXIT WHEN (l_flt_uom_code <> l_forecast_details_flt_tbl(l_flt_index).uom_code );
2339 ELSE
2340 EXIT;
2341 END IF;
2342 END LOOP;
2343
2344 --IF pc forecast exists after fleet forecast for the same UOM
2345 IF(l_previous_end_date IS NOT NULL) THEN
2346 LOOP
2347 IF (x_forecast_details_tbl.COUNT > 0) THEN
2348 AHL_DEBUG_PUB.debug('l_previous_end_date = '|| l_previous_end_date|| ' and l_pc_uom_code = '||l_pc_uom_code);
2349 END IF;
2350 IF ( l_forecast_details_pc_tbl.EXISTS(l_pc_index)) THEN
2351 EXIT WHEN (l_pc_uom_code <> l_forecast_details_pc_tbl(l_pc_index).uom_code );
2352 ELSE
2353 EXIT;
2354 END IF;
2355
2356 l_pc_start_date := trunc(l_forecast_details_pc_tbl(l_pc_index).start_date);
2357 l_pc_end_date := trunc(l_forecast_details_pc_tbl(l_pc_index).end_date);
2358 IF(trunc(nvl(l_pc_end_date,l_previous_end_date)) >= l_previous_end_date) THEN
2359 l_forecast_details_tbl(l_index).uom_code := l_pc_uom_code;
2360 l_forecast_details_tbl(l_index).start_date := GREATEST(l_previous_end_date+1,l_pc_start_date);
2361 l_forecast_details_tbl(l_index).end_date := l_pc_end_date;
2362 l_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_pc_tbl(l_pc_index).usage_per_day;
2363 l_forecast_details_tbl(l_index).utilization_type := l_forecast_details_pc_tbl(l_pc_index).utilization_type;
2364
2365 l_previous_end_date := l_forecast_details_tbl(l_index).end_date;
2366 l_index := l_index + 1;
2367 END IF;
2368 l_pc_index := l_pc_index + 1;
2369
2370 END LOOP;
2371 ELSE -- Iterate through pc forecast table till next UOM.
2372 LOOP
2373 IF ( l_forecast_details_pc_tbl.EXISTS(l_pc_index)) THEN
2374 EXIT WHEN (l_pc_uom_code <> l_forecast_details_pc_tbl(l_pc_index).uom_code );
2375 ELSE
2376 EXIT;
2377 END IF;
2378 l_pc_index := l_pc_index + 1;
2379 END LOOP;
2380 END IF;
2381
2382
2383 END IF; --l_flt_uom_code > l_pc_uom_code
2384
2385 END LOOP; -- Loop
2386
2387 ELSE
2388 l_forecast_details_tbl := l_forecast_details_pc_tbl;
2389 END IF; --l_forecast_details_flt_tbl.COUNT >0
2390
2391
2392
2393 END IF; -- end pm installed check.
2394
2395 -- fix for bug# 13025105: Insert 0 usage row from sysdate to start_date - 1 if forecast is missing for sysdate.
2396 l_uom_code := null;
2397 l_index := 1;
2398 -- iterate through the forecast table and insert rows with 0 usage
2399 IF (l_forecast_details_tbl.count > 0) THEN
2400 FOR i IN l_forecast_details_tbl.FIRST..l_forecast_details_tbl.LAST LOOP
2401 -- when UOM changes, check if start date > sysdate
2402 IF (l_uom_code IS NULL) OR (l_uom_code <> l_forecast_details_tbl(i).uom_code) THEN
2403 IF (l_forecast_details_tbl(i).start_date > trunc(sysdate)) THEN
2404 x_forecast_details_tbl(l_index).uom_code := l_forecast_details_tbl(i).uom_code;
2405 x_forecast_details_tbl(l_index).start_date := trunc(sysdate - 1);
2406 x_forecast_details_tbl(l_index).end_date := trunc(l_forecast_details_tbl(i).start_date - 1);
2407 x_forecast_details_tbl(l_index).usage_per_day := 0;
2408 x_forecast_details_tbl(l_index).utilization_type := 'ZR-USAGE';
2409 l_index := l_index + 1;
2410 l_uom_code := l_forecast_details_tbl(i).uom_code;
2411 END IF;
2412 ELSE -- uom has not changed
2413 -- if there is a gap in the forecast, insert rows for 0 usage for this period.
2414 IF (l_index > 1) AND (x_forecast_details_tbl(l_index-1).end_date + 1 <> l_forecast_details_tbl(i).start_date) THEN
2415 -- insert 0 usage row
2416 x_forecast_details_tbl(l_index).uom_code := l_forecast_details_tbl(i).uom_code;
2417 x_forecast_details_tbl(l_index).start_date := trunc(x_forecast_details_tbl(l_index-1).end_date + 1);
2418 x_forecast_details_tbl(l_index).end_date := trunc(l_forecast_details_tbl(i).start_date - 1);
2419 x_forecast_details_tbl(l_index).usage_per_day := 0;
2420 x_forecast_details_tbl(l_index).utilization_type := 'ZR-USAGE';
2421 l_index := l_index + 1;
2422 END IF;
2423 END IF;
2424 x_forecast_details_tbl(l_index).uom_code := l_forecast_details_tbl(i).uom_code;
2425 x_forecast_details_tbl(l_index).start_date := l_forecast_details_tbl(i).start_date;
2426 x_forecast_details_tbl(l_index).end_date := l_forecast_details_tbl(i).end_date;
2427 x_forecast_details_tbl(l_index).usage_per_day := l_forecast_details_tbl(i).usage_per_day;
2428 x_forecast_details_tbl(l_index).utilization_type := l_forecast_details_tbl(i).utilization_type;
2429 l_index := l_index + 1;
2430 END LOOP;
2431 END IF;
2432
2433 -- Set output variable for forecast.
2434 -- x_forecast_details_tbl := l_forecast_details_tbl;
2435
2436 IF G_DEBUG = 'Y' THEN
2437 AHL_DEBUG_PUB.debug ('Count on forecast_details' || x_forecast_details_tbl.COUNT);
2438 AHL_DEBUG_PUB.debug ('Count on l_forecast_details' || l_forecast_details_tbl.COUNT);
2439
2440 IF (x_forecast_details_tbl.COUNT > 0) THEN
2441 FOR i IN x_forecast_details_tbl.FIRST..x_forecast_details_tbl.LAST LOOP
2442 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') Uom_Code' || x_forecast_details_tbl(i).uom_code);
2443 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') Start Date' || x_forecast_details_tbl(i).start_date);
2444 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') End Date' || x_forecast_details_tbl(i).end_date);
2445 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') Usage' || x_forecast_details_tbl(i).usage_per_day);
2446 -- JKJain, NR Analysis and Forecasting
2447 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') utilization_type ' || x_forecast_details_tbl(i).utilization_type);
2448 END LOOP;
2449 END IF;
2450
2451 AHL_DEBUG_PUB.debug ('End Get_Utilization_Forecast');
2452
2453 END IF;
2454
2455 END Get_Utilization_Forecast;
2456
2457 -----------------------------------------
2458 -- Lock all existing unit effectivity records.
2459 -- Modified for perf. bug# 6893404.
2460 PROCEDURE Lock_UnitEffectivity_Records(x_ret_code OUT NOCOPY VARCHAR2) IS
2461
2462 /*
2463 CURSOR ahl_unit_effectivities_csr (p_csi_item_instance_id IN NUMBER) IS
2464 SELECT UNIT_EFFECTIVITY_ID
2465 FROM AHL_UNIT_EFFECTIVITIES_APP_V
2466 WHERE csi_item_instance_id = p_csi_item_instance_id
2467 AND (status_code IS NULL OR status_code = 'INIT-DUE')
2468 FOR UPDATE OF object_version_number NOWAIT;
2469 */
2470
2471 /* 13 Jul 08: Modified query for performance. Instead of looping for every
2472 * instance, we loop for the configuration.
2473 -- 13 Jul 08: Modified query to use status_code instead of object_version_number
2474 CURSOR ahl_unit_effectivities_csr (p_csi_item_instance_id IN NUMBER) IS
2475 --SELECT UNIT_EFFECTIVITY_ID
2476 SELECT 1
2477 FROM AHL_UNIT_EFFECTIVITIES_APP_V
2478 WHERE csi_item_instance_id = p_csi_item_instance_id
2479 AND (status_code IS NULL OR status_code IN ('INIT-DUE','EXCEPTION'))
2480 FOR UPDATE OF status_code NOWAIT;
2481 */
2482
2483 CURSOR ahl_unit_effectivities_csr (p_csi_item_instance_id IN NUMBER, p_appln_usg_code IN VARCHAR2) IS
2484 WITH II AS (SELECT p_csi_item_instance_id instance_id
2485 FROM DUAL
2486 UNION ALL
2487 SELECT A.SUBJECT_ID INSTANCE_ID
2488 FROM CSI_II_RELATIONSHIPS A
2489 START WITH OBJECT_ID = p_csi_item_instance_id
2490 AND RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
2491 AND SYSDATE BETWEEN TRUNC(NVL(ACTIVE_START_DATE,SYSDATE))
2492 AND TRUNC(NVL(ACTIVE_END_DATE, SYSDATE+1))
2493 CONNECT BY OBJECT_ID = PRIOR SUBJECT_ID
2494 AND RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
2495 AND SYSDATE BETWEEN TRUNC(NVL(ACTIVE_START_DATE,SYSDATE))
2496 AND TRUNC(NVL(ACTIVE_END_DATE, SYSDATE+1))
2497 )
2498 SELECT 1
2499 --FROM AHL_UNIT_EFFECTIVITIES_APP_V UE, II
2500 FROM AHL_UNIT_EFFECTIVITIES_B UE, II
2501 WHERE UE.csi_item_instance_id = II.INSTANCE_ID
2502 AND UE.application_usg_code = p_appln_usg_code
2503 AND (status_code IS NULL OR status_code IN ('INIT-DUE','EXCEPTION'))
2504 FOR UPDATE OF status_code NOWAIT;
2505
2506 -- JKJain, NR Analysis and Forecasting
2507 CURSOR ahl_sim_ues_csr (p_csi_item_instance_id IN NUMBER) IS
2508 WITH II AS (SELECT p_csi_item_instance_id instance_id
2509 FROM DUAL
2510 UNION ALL
2511 SELECT A.SUBJECT_ID INSTANCE_ID
2512 FROM CSI_II_RELATIONSHIPS A
2513 START WITH OBJECT_ID = p_csi_item_instance_id
2514 AND RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
2515 AND SYSDATE BETWEEN TRUNC(NVL(ACTIVE_START_DATE,SYSDATE))
2516 AND TRUNC(NVL(ACTIVE_END_DATE, SYSDATE+1))
2517 CONNECT BY OBJECT_ID = PRIOR SUBJECT_ID
2518 AND RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
2519 AND SYSDATE BETWEEN TRUNC(NVL(ACTIVE_START_DATE,SYSDATE))
2520 AND TRUNC(NVL(ACTIVE_END_DATE, SYSDATE+1))
2521 )
2522 SELECT 1
2523 FROM AHL_UE_SIMULATIONS UE, II
2524 WHERE UE.csi_item_instance_id = II.INSTANCE_ID
2525 AND (status_code IS NULL OR status_code IN ('INIT-DUE','EXCEPTION'))
2526 AND UE.SIMULATION_PLAN_ID = G_SIMULATION_PLAN_ID
2527 FOR UPDATE OF status_code NOWAIT;
2528
2529 --l_next_rec_flag BOOLEAN;
2530 --l_unit_effectivity_id NUMBER;
2531
2532 l_ue_id_tbl nbr_tbl_type;
2533
2534 BEGIN
2535
2536 IF G_DEBUG = 'Y' THEN
2537 AHL_DEBUG_PUB.debug ('Start Lock Effectivity records');
2538 END IF;
2539
2540 x_ret_code := '0';
2541
2542 /*
2543 -- Lock all records for all item instances in G_config_node_tbl.
2544 IF G_config_node_tbl.COUNT > 0 THEN
2545 FOR i IN G_config_node_tbl.FIRST..G_config_node_tbl.LAST LOOP
2546 OPEN ahl_unit_effectivities_csr(G_config_node_tbl(i).csi_item_instance_id);
2547 IF ahl_unit_effectivities_csr%NOTFOUND THEN
2548 --dbms_output.put_line (' in lock effecti - no record found');
2549 CLOSE ahl_unit_effectivities_csr;
2550 EXIT;
2551 END IF;
2552 l_next_rec_flag := TRUE; -- there is at least one record
2553 WHILE (l_next_rec_flag) LOOP
2554 FETCH ahl_unit_effectivities_csr INTO l_unit_effectivity_id;
2555 IF ahl_unit_effectivities_csr%NOTFOUND THEN
2556 l_next_rec_flag := FALSE;
2557 END IF;
2558 END LOOP;
2559 CLOSE ahl_unit_effectivities_csr;
2560 END LOOP;
2561 END IF;
2562 */
2563
2564 /* 13 Jul 08: Modified query for performance. Instead of looping for every
2565 * instance, we loop for the configuration.
2566 -- Lock all records for all item instances in G_config_node_tbl.
2567 IF G_config_node_tbl.COUNT > 0 THEN
2568 FOR i IN G_config_node_tbl.FIRST..G_config_node_tbl.LAST LOOP
2569 OPEN ahl_unit_effectivities_csr(G_config_node_tbl(i).csi_item_instance_id);
2570 LOOP
2571 FETCH ahl_unit_effectivities_csr BULK COLLECT INTO l_ue_id_tbl LIMIT 5000;
2572 IF G_DEBUG = 'Y' THEN
2573 AHL_DEBUG_PUB.debug ('Rows processed for instance: ' || G_config_node_tbl(i).csi_item_instance_id
2574 || 'is: ' || ahl_unit_effectivities_csr%ROWCOUNT);
2575 END IF;
2576 --EXIT WHEN ahl_unit_effectivities_csr%NOTFOUND;
2577 EXIT WHEN (l_ue_id_tbl.count = 0);
2578
2579 -- delete tbl
2580 l_ue_id_tbl.delete;
2581
2582 END LOOP;
2583 CLOSE ahl_unit_effectivities_csr;
2584 END LOOP;
2585 END IF;
2586 */
2587
2588 IF (G_config_node_tbl.COUNT <= 0) THEN
2589 -- this should never happen.
2590 RETURN;
2591 END IF;
2592
2593 -- JKJain, NR Analysis and Forecasting
2594 IF (G_PRIMARY_PLAN = 'Y') THEN
2595 -- G_config_node_tbl(1).csi_item_instance_id contains root node.
2596 -- Lock all records for all item instances in G_config_node_tbl.
2597 OPEN ahl_unit_effectivities_csr(G_config_node_tbl(1).csi_item_instance_id, G_application_usg_code);
2598 LOOP
2599 FETCH ahl_unit_effectivities_csr BULK COLLECT INTO l_ue_id_tbl LIMIT 5000;
2600 IF G_DEBUG = 'Y' THEN
2601 AHL_DEBUG_PUB.debug ('Rows processed are: ' || ahl_unit_effectivities_csr%ROWCOUNT);
2602 END IF;
2603 --EXIT WHEN ahl_unit_effectivities_csr%NOTFOUND;
2604 EXIT WHEN (l_ue_id_tbl.count = 0);
2605
2606 -- delete tbl
2607 l_ue_id_tbl.delete;
2608 END LOOP;
2609
2610 CLOSE ahl_unit_effectivities_csr;
2611 ELSE
2612 OPEN ahl_sim_ues_csr(G_config_node_tbl(1).csi_item_instance_id);
2613 LOOP
2614 FETCH ahl_sim_ues_csr BULK COLLECT INTO l_ue_id_tbl LIMIT 5000;
2615 IF G_DEBUG = 'Y' THEN
2616 AHL_DEBUG_PUB.debug ('Rows processed are: ' || ahl_sim_ues_csr%ROWCOUNT);
2617 END IF;
2618 EXIT WHEN (l_ue_id_tbl.count = 0);
2619
2620 -- delete tbl
2621 l_ue_id_tbl.delete;
2622 END LOOP;
2623 CLOSE ahl_sim_ues_csr;
2624 END IF;
2625
2626
2627
2628 IF G_DEBUG = 'Y' THEN
2629 AHL_DEBUG_PUB.debug ('End Lock Effectivity records');
2630 END IF;
2631
2632 EXCEPTION
2633
2634 WHEN OTHERS THEN
2635 IF (SQLCODE = -54) THEN
2636 --FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_ALREADY_RUNNING');
2637 --FND_MSG_PUB.ADD;
2638 --RAISE FND_API.G_EXC_ERROR;
2639 x_ret_code := '-54';
2640 ELSE
2641 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
2642 fnd_msg_pub.add_exc_msg(p_pkg_name => G_PKG_NAME,
2643 p_procedure_name => 'Lock_UnitEffectivity_Records',
2644 p_error_text => SUBSTR(SQLERRM,1,240));
2645 END IF;
2646 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2647 END IF;
2648
2649 END Lock_UnitEffectivity_Records;
2650
2651 --------------------------------------------------------------------------------
2652 -- Process Unit for ASO installation.
2653 PROCEDURE Process_ASO_Unit IS
2654
2655 CURSOR ahl_applicable_MRs (p_csi_item_instance_id IN NUMBER) IS
2656 SELECT DISTINCT appl.csi_item_instance_id,
2657 appl.MR_header_id,
2658 mr.Title,
2659 mr.version_number,
2660 appl.Implement_status_code,
2661 appl.copy_accomplishment_code,
2662 appl.repetitive_flag,
2663 appl.show_repetitive_code,
2664 appl.preceding_mr_header_id,
2665 appl.descendent_count,
2666 mr.whichever_first_code,
2667 mr.effective_to,
2668 mr.effective_from,
2669 appl.processing_order, -- needed for 'order by' to work. This will be the same for all Eff.
2670 appl.terminate_trigger_check,
2671 appl.accomplish_trigger_type,
2672 appl.loop_chain_seq_num
2673 FROM ahl_applicable_MRs appl, ahl_mr_headers_b mr
2674 WHERE appl.csi_item_instance_id = p_csi_item_instance_id
2675 AND (appl.implement_status_code <> 'OPTIONAL_DO_NOT_IMPLEMENT')
2676 -- check on preceding_mr_header_id is commented out as part of SB Enh
2677 --AND appl.preceding_mr_header_id IS NULL
2678 AND appl.mr_header_id = mr.mr_header_id
2679 AND trunc(nvl(mr.effective_from,sysdate)) <= trunc(sysdate)
2680 -- commented to support expired MRs for bug# 9263774
2681 --AND trunc(sysdate) <= trunc(nvl(mr.effective_to,sysdate+1))
2682 -- added check for accomplish_trigger_type and start_mr_header_id for SB Enh
2683 AND nvl(appl.accomplish_trigger_type,'X') <> 'INITIATED_BY'
2684 -- SB ENh: only process start MR for loops and chains
2685 AND nvl(appl.start_mr_header_id,appl.MR_header_id) = appl.MR_header_id
2686 ORDER BY processing_order ASC, descendent_count DESC;
2687
2688 l_applicable_mr_rec applicable_mrs_rec_type;
2689
2690 l_current_usage_tbl counter_values_tbl_type;
2691 /* contains current counter usage */
2692
2693 l_counter_rules_tbl counter_rules_tbl_type;
2694 /* contains current counter rules for the position */
2695
2696 BEGIN
2697
2698 -- added to fix bug# 9266774
2699 -- Build MR applicability for expired MRs.
2700 Process_Appl_Expired_MRs;
2701
2702 -- Added for SB Enh: Set applicable MRs order to process terminating MRs.
2703 -- default value of processing_order = 1
2704 -- select MRs that are terminating other MRs but themselves are not 'initiated_by' MRs.
2705 -- group MRs cannot be in a 'TERMINATES' relationship.
2706 UPDATE AHL_APPLICABLE_MRS appl
2707 SET processing_order = 2,
2708 terminate_trigger_check = 'Y'
2709 WHERE EXISTS (SELECT 'x'
2710 FROM AHL_MR_RELATIONSHIPS mrr, ahl_applicable_mrs parent_appl
2711 WHERE mrr.related_mr_header_id = appl.mr_header_id
2712 AND mrr.mr_header_id = parent_appl.mr_header_id -- parent row exists
2713 AND parent_appl.csi_item_instance_id = appl.csi_item_instance_id
2714 AND mrr.relationship_code = 'TERMINATES');
2715
2716 -- Process Unit beginning with top node.
2717 IF G_config_node_tbl.COUNT > 0 THEN
2718 FOR i IN G_config_node_tbl.FIRST..G_config_node_tbl.LAST LOOP
2719 IF G_DEBUG = 'Y' THEN
2720 AHL_DEBUG_PUB.debug('Processing for..:' || G_config_node_tbl(i).csi_item_instance_id );
2721 END IF;
2722
2723 -- Build counter rules ratio if node is not root node.
2724 IF (G_master_config_id IS NOT NULL AND G_config_node_tbl(i).object_id IS NOT NULL) THEN
2725 build_Counter_Ratio(G_config_node_tbl(i).position_reference,
2726 G_config_node_tbl(i).csi_item_instance_id,
2727 G_master_config_id,
2728 l_counter_rules_tbl);
2729 END IF;
2730
2731 -- Get current usage for all the counters defined for the item instance.
2732 get_Current_Usage (G_config_node_tbl(i).csi_item_instance_id,
2733 l_current_usage_tbl);
2734
2735 -- Add zero forecast row to G_forecast_details_tbl if forecast missing for a UOM.
2736 validate_uf_for_ctr(p_current_usage_tbl => l_current_usage_tbl,
2737 p_x_forecast_details_tbl => G_forecast_details_tbl);
2738
2739 -- Calculate due dates for all deferred MRs.
2740 Process_Deferred_UE (p_csi_item_instance_id => G_config_node_tbl(i).csi_item_instance_id,
2741 p_current_usage_tbl => l_current_usage_tbl,
2742 p_counter_rules_tbl => l_counter_rules_tbl);
2743
2744 -- For UE's of type SR, re-validate MR applicability and explode group MR for next due
2745 -- date calculation.
2746 Process_SR_UE (p_csi_item_instance_id => G_config_node_tbl(i).csi_item_instance_id);
2747
2748 -- JKJain, Bypass Process_Unplanned_UE for simulation plan
2749 IF (G_PRIMARY_PLAN = 'Y') THEN
2750 -- For Unplanned MRs (MRs directly planned into a Visit from FMP), validate applicability.
2751 Process_Unplanned_UE(p_csi_item_instance_id => G_config_node_tbl(i).csi_item_instance_id,
2752 p_current_usage_tbl => l_current_usage_tbl,
2753 p_counter_rules_tbl => l_counter_rules_tbl);
2754 END IF;
2755
2756 -- Read ahl_applicable_mrs for all MRs applicable to the item instance.
2757 FOR l_appl_rec IN ahl_applicable_MRs(G_config_node_tbl(i).csi_item_instance_id) LOOP
2758
2759 IF G_DEBUG = 'Y' THEN
2760 AHL_DEBUG_PUB.debug('Found applicable MR-ID[Title]:' || l_appl_rec.mr_header_id || '[' || l_appl_rec.title || ']');
2761 END IF;
2762
2763 /*
2764 IF (G_concurrent_flag = 'Y') THEN
2765 fnd_file.put_line (FND_FILE.LOG, 'Found applicable MR-ID:title:' || l_appl_rec.mr_header_id || ':'
2766 || l_appl_rec.title);
2767 END IF;
2768 */
2769
2770
2771 l_applicable_mr_rec.csi_item_instance_id := l_appl_rec.csi_item_instance_id;
2772 l_applicable_mr_rec.MR_header_id := l_appl_rec.MR_header_id;
2773 l_applicable_mr_rec.title := l_appl_rec.title;
2774 l_applicable_mr_rec.version_number := l_appl_rec.version_number;
2775 l_applicable_mr_rec.Implement_status_code := l_appl_rec.Implement_status_code;
2776 l_applicable_mr_rec.copy_accomplishment_code := l_appl_rec.copy_accomplishment_code;
2777 l_applicable_mr_rec.repetitive_flag := l_appl_rec.repetitive_flag;
2778 l_applicable_mr_rec.show_repetitive_code := l_appl_rec.show_repetitive_code;
2779 l_applicable_mr_rec.preceding_mr_header_id := l_appl_rec.preceding_mr_header_id;
2780 l_applicable_mr_rec.descendent_count := l_appl_rec.descendent_count;
2781 l_applicable_mr_rec.whichever_first_code := l_appl_rec.whichever_first_code;
2782 l_applicable_mr_rec.effective_to := l_appl_rec.effective_to;
2783 l_applicable_mr_rec.effective_from := l_appl_rec.effective_from;
2784
2785 -- added for bug# 9263774
2786 IF (l_applicable_mr_rec.effective_to < sysdate) THEN
2787 l_applicable_mr_rec.expired_mr_flag := 'Y';
2788 ELSE
2789 l_applicable_mr_rec.expired_mr_flag := 'N';
2790 END IF;
2791
2792 -- Added for SB Effectivity Enh
2793 l_applicable_mr_rec.terminate_trigger_check := l_appl_rec.terminate_trigger_check;
2794 l_applicable_mr_rec.accomplish_trigger_type := l_appl_rec.accomplish_trigger_type;
2795 l_applicable_mr_rec.loop_chain_seq_num := l_appl_rec.loop_chain_seq_num;
2796
2797 -- call procedure to build effectivity.
2798 Build_Effectivity ( p_applicable_mrs_rec => l_applicable_mr_rec,
2799 p_current_usage_tbl => l_current_usage_tbl,
2800 p_counter_rules_tbl => l_counter_rules_tbl );
2801
2802 IF G_DEBUG = 'Y' THEN
2803 AHL_DEBUG_PUB.debug('Process Unit:LOOP to next MR-ID');
2804 END IF;
2805
2806 END LOOP; /* loop through next mr */
2807
2808 IF G_DEBUG = 'Y' THEN
2809 AHL_DEBUG_PUB.debug('Process Unit:LOOP to next NODE');
2810 END IF;
2811
2812 END LOOP; /* loop to process next node. */
2813 END IF; /* for count > 0 */
2814
2815 END Process_ASO_Unit;
2816
2817 --------------------------------------------------------------------------------
2818 -- Build the counter ratio that needs to be applied to the item instance based
2819 -- on its master configuration position. Input is the item instance.
2820 -- Modified per 11.5.10 UC enhancements.
2821
2822 PROCEDURE build_Counter_Ratio(p_position_reference IN VARCHAR2,
2823 p_csi_item_instance_id IN NUMBER,
2824 p_master_config_id IN NUMBER,
2825 x_counter_rules_tbl OUT NOCOPY counter_rules_tbl_type)
2826 IS
2827
2828 -- for counter rules given a relationship_id.
2829 CURSOR ahl_ctr_rule_csr ( p_relationship_id IN NUMBER) IS
2830 SELECT uom_code, ratio
2831 FROM ahl_ctr_update_rules
2832 WHERE relationship_id = p_relationship_id
2833 AND rule_code = 'STANDARD';
2834
2835 -- traverse up the master configuration to top node.
2836 /* CURSOR ahl_master_config_csr (p_start_node_id IN NUMBER) IS
2837 SELECT relationship_id
2838 FROM ahl_relationships_b
2839 START WITH relationship_id = p_start_node_id
2840 CONNECT BY PRIOR parent_relationship_id = relationship_id
2841 AND trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate)
2842 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate + 1));
2843 */
2844
2845 -- Per UC 11.5.10 enhancements, instead of traversing MC; we traverse UC and get the position
2846 -- reference.
2847 CURSOR ahl_unit_config_csr (p_csi_item_instance_id IN NUMBER) IS
2848 SELECT to_number(position_reference) position_reference
2849 FROM csi_ii_relationships
2850 START WITH subject_id = p_csi_item_instance_id
2851 AND relationship_type_code = 'COMPONENT-OF'
2852 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
2853 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1))
2854 CONNECT BY PRIOR subject_id = object_id
2855 AND relationship_type_code = 'COMPONENT-OF'
2856 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
2857 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1));
2858
2859 -- get root master configuration for the item's position reference.
2860 CURSOR ahl_posn_master_config_csr (p_start_node_id IN NUMBER) IS
2861 SELECT relationship_id
2862 FROM ahl_mc_relationships
2863 WHERE parent_relationship_id IS NULL
2864 START WITH relationship_id = p_start_node_id
2865 CONNECT BY PRIOR parent_relationship_id = relationship_id
2866 AND trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate)
2867 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate + 1));
2868
2869
2870 l_position_ref NUMBER;
2871 l_uom_code ahl_ctr_update_rules.uom_code%TYPE;
2872 l_ratio NUMBER;
2873 l_match_found_flag BOOLEAN;
2874 l_table_count NUMBER;
2875 l_posn_master_config_id NUMBER;
2876
2877 l_counter_rules_tbl counter_rules_tbl_type;
2878
2879
2880 BEGIN
2881
2882 IF G_DEBUG = 'Y' THEN
2883 AHL_DEBUG_PUB.debug ('Start Build Counter Ratio');
2884 END IF;
2885
2886 -- If there is no master configuration
2887 IF (p_master_config_id IS NOT NULL) THEN
2888
2889 l_position_ref := to_number(p_position_reference);
2890 x_counter_rules_tbl := l_counter_rules_tbl;
2891
2892 -- Check if position reference belongs to master configuration.
2893 OPEN ahl_posn_master_config_csr(l_position_ref);
2894 FETCH ahl_posn_master_config_csr INTO l_posn_master_config_id;
2895 IF (ahl_posn_master_config_csr%FOUND) THEN
2896 IF (l_posn_master_config_id = p_master_config_id) THEN
2897
2898 l_table_count := 0;
2899 -- Build counter rules table.
2900 FOR l_relationship_id IN ahl_unit_config_csr(p_csi_item_instance_id) LOOP
2901 FOR l_ratio_rec IN ahl_ctr_rule_csr (l_relationship_id.position_reference) LOOP
2902 l_uom_code := l_ratio_rec.uom_code;
2903 l_ratio := l_ratio_rec.ratio;
2904
2905 -- Check if uom_code already exists in x_counter_rules_tbl.
2906 l_match_found_flag := FALSE;
2907
2908 IF (l_table_count > 0) THEN
2909 FOR i IN x_counter_rules_tbl.FIRST..x_counter_rules_tbl.LAST LOOP
2910 IF (x_counter_rules_tbl(i).uom_code = l_uom_code) THEN
2911 x_counter_rules_tbl(i).ratio := x_counter_rules_tbl(i).ratio * l_ratio;
2912 l_match_found_flag := TRUE;
2913 END IF;
2914 END LOOP; /* counter_rules_tbl */
2915 END IF; /* count > 0 */
2916
2917 -- Add new row if match not found.
2918 IF NOT (l_match_found_flag) THEN
2919 l_table_count := l_table_count + 1;
2920 x_counter_rules_tbl(l_table_count).uom_code := l_uom_code;
2921 x_counter_rules_tbl(l_table_count).ratio := l_ratio;
2922 END IF;
2923 END LOOP; /* for ahl_ctr_rule_csr */
2924
2925 END LOOP; /* for ahl_master-config_csr */
2926 END IF; /* master config id matches */
2927 END IF; /* found */
2928 CLOSE ahl_posn_master_config_csr;
2929 END IF; /* master config not null */
2930
2931 IF G_DEBUG = 'Y' THEN
2932 AHL_DEBUG_PUB.debug ('End Build Counter Ratio');
2933 AHL_DEBUG_PUB.debug ('Counter Rules tbl count' || x_counter_rules_tbl.COUNT);
2934 END IF;
2935
2936 EXCEPTION
2937
2938 WHEN INVALID_NUMBER THEN
2939 x_counter_rules_tbl := l_counter_rules_tbl;
2940
2941 END build_Counter_Ratio;
2942
2943 ----------------------------------------------------------------------------------
2944 -- Build the current usage on the item instance's counters based on counters attached
2945 -- to the item instance.
2946
2947 PROCEDURE get_Current_Usage ( p_csi_item_instance_id IN NUMBER,
2948 x_current_usage_tbl OUT NOCOPY counter_values_tbl_type )
2949 IS
2950
2951 CURSOR csi_cp_counters_csr (p_csi_instance_id IN NUMBER) IS
2952 /*
2953 SELECT counter_id, uom_code, net_reading, counter_name
2954 FROM csi_cp_counters_v
2955 WHERE customer_product_id = p_csi_item_instance_id
2956 ORDER BY uom_code;
2957
2958 SELECT cc.counter_id, cc.uom_code,
2959 cc.counter_template_name counter_name
2960 from csi_counter_associations cca, csi_counters_vl cc
2961 where cca.counter_id = cc.counter_id
2962 AND source_object_code = 'CP'
2963 AND source_object_id = p_csi_instance_id;
2964 */
2965
2966 /* reverted to old code - see bug# 7355947
2967 SELECT cc.counter_id, cc.uom_code,
2968 cc.counter_template_name counter_name,
2969 (select ccr.net_reading
2970 from csi_counter_readings ccr
2971 where ccr.counter_id = cc.counter_id
2972 and value_timestamp = (select max(value_timestamp) from csi_counter_readings rd
2973 where counter_id = cc.counter_id
2974 and nvl(disabled_flag,'N') = 'N')) net_reading
2975 FROM csi_counter_associations cca, csi_counters_vl cc
2976 WHERE cca.counter_id = cc.counter_id
2977 AND source_object_code = 'CP'
2978 AND source_object_id = p_csi_item_instance_id;
2979 */
2980
2981 -- 15 Sept 08: Modified based on IB changes - refer bug# 7374316
2982 SELECT cc.counter_id, cc.uom_code,
2983 cc.counter_template_name counter_name,
2984 (select ccr.net_reading
2985 from csi_counter_readings ccr
2986 where ccr.counter_value_id = cc.CTR_VAL_MAX_SEQ_NO
2987 and nvl(ccr.disabled_flag,'N') = 'N')
2988 FROM csi_counter_associations cca, csi_counters_vl cc
2989 WHERE cca.counter_id = cc.counter_id
2990 AND source_object_code = 'CP'
2991 AND source_object_id = p_csi_instance_id;
2992
2993 /*
2994 -- get net reading.
2995 CURSOR csi_cp_counters_val_csr (p_counter_id IN NUMBER) IS
2996 SELECT nvl(cv.net_reading,0) net_reading
2997 FROM csi_counter_values_v cv
2998 WHERE cv.counter_id = p_counter_id
2999 AND rownum < 2;
3000
3001 -- get net reading.
3002 CURSOR csi_cp_counters_val_csr (p_counter_id IN NUMBER) IS
3003 SELECT * FROM
3004 (SELECT net_reading
3005 FROM csi_counter_readings
3006 WHERE counter_id = p_counter_id
3007 AND nvl(disabled_flag,'N') = 'N'
3008 ORDER BY value_timestamp desc)
3009 WHERE rownum < 2;
3010 */
3011
3012 i NUMBER;
3013
3014 l_current_usage_tbl counter_values_tbl_type;
3015
3016 -- added for perf fix.
3017 l_ctr_id_tbl nbr_tbl_type;
3018 l_ctr_uom_tbl vchar_tbl_type;
3019 l_ctr_name_tbl vchar_tbl_type;
3020 l_ctr_net_read_tbl nbr_tbl_type;
3021
3022 BEGIN
3023
3024 IF G_DEBUG = 'Y' THEN
3025 AHL_DEBUG_PUB.debug ('Start Get Current Usage');
3026 END IF;
3027
3028 -- Build current usage counters.
3029 OPEN csi_cp_counters_csr(p_csi_item_instance_id);
3030 FETCH csi_cp_counters_csr BULK COLLECT INTO l_ctr_id_tbl, l_ctr_uom_tbl, l_ctr_name_tbl,
3031 l_ctr_net_read_tbl;
3032 CLOSE csi_cp_counters_csr;
3033
3034 /*
3035 LOOP
3036 FETCH csi_cp_counters_csr INTO l_current_usage_tbl(i).counter_id,
3037 l_current_usage_tbl(i).uom_code,
3038 l_current_usage_tbl(i).counter_name;
3039 EXIT WHEN csi_cp_counters_csr%NOTFOUND;
3040
3041 -- get latest net reading.
3042 OPEN csi_cp_counters_val_csr(l_current_usage_tbl(i).counter_id);
3043 FETCH csi_cp_counters_val_csr INTO l_current_usage_tbl(i).counter_value;
3044 CLOSE csi_cp_counters_val_csr;
3045
3046 IF (l_current_usage_tbl(i).counter_value IS NULL) THEN
3047 l_current_usage_tbl(i).counter_value := 0;
3048 END IF;
3049
3050 i := i + 1;
3051 END LOOP;
3052 */
3053
3054 IF (l_ctr_id_tbl.COUNT > 0) THEN
3055
3056 i := 1;
3057 FOR j IN l_ctr_id_tbl.FIRST..l_ctr_id_tbl.LAST LOOP
3058 l_current_usage_tbl(i).counter_id := l_ctr_id_tbl(j);
3059 l_current_usage_tbl(i).uom_code := l_ctr_uom_tbl(j);
3060 l_current_usage_tbl(i).counter_name := l_ctr_name_tbl(j);
3061
3062 /* 15 Sept 08: commented to incorporate IB changes - see bug# 7374316
3063 -- get latest net reading.
3064 OPEN csi_cp_counters_val_csr(l_current_usage_tbl(i).counter_id);
3065 FETCH csi_cp_counters_val_csr INTO l_current_usage_tbl(i).counter_value;
3066 CLOSE csi_cp_counters_val_csr;
3067
3068 IF (l_current_usage_tbl(i).counter_value IS NULL) THEN
3069 l_current_usage_tbl(i).counter_value := 0;
3070 END IF;
3071 */
3072
3073 IF (l_ctr_net_read_tbl(j) IS NULL) THEN
3074 l_current_usage_tbl(i).counter_value := 0;
3075 ELSE
3076 l_current_usage_tbl(i).counter_value := l_ctr_net_read_tbl(j);
3077 END IF;
3078
3079 i := i + 1;
3080 END LOOP;
3081 END IF; -- l_ctr_id_tbl.COUNT
3082
3083 -- Set return value.
3084 x_current_usage_tbl := l_current_usage_tbl;
3085
3086 IF G_DEBUG = 'Y' THEN
3087 AHL_DEBUG_PUB.debug ('Counter Usage tbl count' || x_current_usage_tbl.COUNT);
3088 AHL_DEBUG_PUB.debug ('End Get Current Usage');
3089 END IF;
3090
3091 END get_Current_Usage;
3092
3093 --------------------------------------------------------------------------------------------
3094 -- Get accomplishment details for an MR.
3095 -- Added parameter x_no_forecast_flag to fix bug# 6711228.
3096 PROCEDURE get_accomplishment_details (p_applicable_mrs_rec IN applicable_mrs_rec_type,
3097 p_current_usage_tbl IN counter_values_tbl_type,
3098 p_counter_rules_tbl IN counter_rules_tbl_type,
3099 x_accomplishment_date OUT NOCOPY DATE,
3100 x_last_acc_counter_val_tbl OUT NOCOPY counter_values_tbl_type,
3101 x_one_time_mr_flag OUT NOCOPY BOOLEAN,
3102 -- x_update_check_flag OUT NOCOPY BOOLEAN,
3103 x_dependent_mr_flag OUT NOCOPY BOOLEAN,
3104 x_get_preceding_next_due OUT NOCOPY BOOLEAN,
3105 x_mr_accomplish_exists OUT NOCOPY BOOLEAN,
3106 x_no_forecast_flag OUT NOCOPY BOOLEAN,
3107 -- added to fix bug# 8994566
3108 x_accomplished_ue_id OUT NOCOPY NUMBER)
3109
3110 IS
3111
3112 -- Get last accomplishment counter values.
3113 CURSOR ahl_unit_accomplish_csr (p_unit_effectivity_id IN NUMBER) IS
3114
3115 /*
3116 SELECT ua.counter_id, ua.counter_value, cs.uom_code, cs.name counter_name
3117 FROM ahl_unit_accomplishmnts ua, cs_counters_v cs
3118 WHERE ua.counter_id = cs.counter_id AND
3119 ua.unit_effectivity_id = p_unit_effectivity_id
3120 ORDER BY cs.uom_code;
3121 */
3122
3123 --Priyan
3124 --Query being changed due to performance related fixes
3125 --Refer Bug # 4918744
3126 --Changed the usage of CS_COUNTERS_V to CSI_COUNTERS_VL
3127
3128 SELECT
3129 UA.COUNTER_ID,
3130 UA.COUNTER_VALUE,
3131 CS.UOM_CODE,
3132 --CS.NAME COUNTER_NAME
3133 CS.COUNTER_TEMPLATE_NAME COUNTER_NAME
3134 FROM
3135 AHL_UNIT_ACCOMPLISHMNTS UA,
3136 CSI_COUNTERS_VL CS
3137 WHERE
3138 UA.COUNTER_ID = CS.COUNTER_ID AND
3139 UA.UNIT_EFFECTIVITY_ID = P_UNIT_EFFECTIVITY_ID
3140 ORDER BY
3141 CS.UOM_CODE ;
3142
3143 -- Get instance counter details.
3144 CURSOR csi_cp_counters_csr (p_csi_instance_id IN NUMBER) IS
3145 /*
3146 SELECT counter_id, uom_code, counter_name
3147 FROM csi_cp_counters_v
3148 WHERE customer_product_id = p_csi_instance_id
3149 ORDER BY uom_code;
3150 */
3151 SELECT cc.counter_id, cc.uom_code,
3152 cc.counter_template_name counter_name
3153 from csi_counter_associations cca, csi_counters_vl cc
3154 where cca.counter_id = cc.counter_id
3155 AND source_object_code = 'CP'
3156 AND source_object_id = p_csi_instance_id;
3157
3158 -- Get deferred MRs.
3159 -- consider deferral_effective_on instead of due date, only if l_affect_calc_due_date is 'N'.
3160 -- include prior MR revisions
3161 CURSOR ahl_def_csr (p_csi_instance_id IN NUMBER,
3162 p_mr_header_id IN NUMBER) IS
3163 SELECT
3164 -- fix for bug# 6875650. Deferral date includes timestamp.
3165 --decode (affect_due_calc_flag, 'N', trunc(nvl(visit_end_date, deferral_effective_on)), trunc(nvl(visit_end_date, due_date)))
3166
3167 decode (def.affect_due_calc_flag, 'N', def.deferral_effective_on, nvl(def.visit_end_date, def.due_date))
3168 FROM ahl_temp_unit_SR_deferrals def, ahl_mr_headers_b mr1,
3169 (select title from ahl_mr_headers_b where mr_header_id = p_mr_header_id) mr2
3170 WHERE def.csi_item_instance_id = p_csi_instance_id
3171 AND def.mr_header_id = mr1.mr_header_id
3172 AND mr1.title = mr2.title
3173 --AND mr_header_id = p_mr_header_id
3174 AND def.object_type = 'MR'
3175 AND def.deferral_effective_on IS NOT NULL
3176 ORDER BY def.deferral_effective_on DESC;
3177 -- get the latest deferral.
3178 -- pick only deferrals and not SR related MRs.
3179
3180 -- check for existence of old MR revision
3181 CURSOR check_old_mr_ver (p_csi_instance_id IN NUMBER,
3182 p_mr_header_id IN NUMBER) IS
3183 SELECT 'x'
3184 FROM ahl_unit_effectivities_b ue, ahl_mr_headers_b mr1, ahl_mr_headers_b mr2
3185 WHERE mr2.mr_header_id = p_mr_header_id
3186 and mr1.title = mr2.title
3187 and mr1.version_number <> mr2.version_number
3188 and mr1.mr_header_id = ue.mr_header_id
3189 and ue.csi_item_instance_id = p_csi_instance_id
3190 and (ue.status_code IS NULL or ue.status_code = 'INIT-DUE');
3191
3192
3193 l_acc_unit_effectivity_id NUMBER;
3194 l_acc_status_code ahl_unit_effectivities_app_v.status_code%TYPE;
3195
3196 l_last_accomplishment_date DATE;
3197 l_last_acc_counter_val_tbl counter_values_tbl_type;
3198 l_due_counter_val_tbl counter_values_tbl_type;
3199 l_due_date DATE;
3200
3201 l_return_val BOOLEAN;
3202 i NUMBER;
3203 l_acc_deferral_flag BOOLEAN;
3204
3205 l_dependent_mr_flag BOOLEAN;
3206 /* set based on preceding mr and accomplishment */
3207
3208 --l_update_check_flag BOOLEAN := FALSE;
3209 l_get_preceding_next_due BOOLEAN := FALSE;
3210
3211 l_one_time_mr_flag BOOLEAN := FALSE;
3212 /* set to true if the MR is a one time MR and already has an accomplishment */
3213 /* or there exists a deferral with it's due date = null. */
3214
3215 l_net_reading NUMBER;
3216
3217 l_no_forecast_flag BOOLEAN := FALSE;
3218 -- set this flag to true if no forecast available when calculating deferral due date.
3219
3220 l_mr_accomplish_exists BOOLEAN := FALSE;
3221 -- set this flag if a mr accomplishment exists.
3222
3223 l_junk VARCHAR2(1);
3224
3225 BEGIN
3226
3227 IF G_DEBUG = 'Y' THEN
3228 AHL_DEBUG_PUB.debug ('Start Get Accomplishment Details');
3229 END IF;
3230
3231 -- Check if any deferrals exist.
3232 OPEN ahl_def_csr (p_applicable_mrs_rec.csi_item_instance_id,
3233 p_applicable_mrs_rec.mr_header_id);
3234 FETCH ahl_def_csr INTO l_last_accomplishment_date;
3235 IF (ahl_def_csr%FOUND) THEN
3236 l_acc_deferral_flag := TRUE;
3237 l_mr_accomplish_exists := TRUE; -- deferral record.
3238 ELSE
3239 -- Lookup if any accomplishments exist.
3240
3241 -- Get last accomplishment for the MR..
3242 AHL_UMP_UTIL_PKG.get_last_accomplishment(p_applicable_mrs_rec.csi_item_instance_id,
3243 p_applicable_mrs_rec.mr_header_id,
3244 l_last_accomplishment_date,
3245 l_acc_unit_effectivity_id,
3246 l_acc_deferral_flag,
3247 l_acc_status_code,
3248 l_return_val);
3249 IF (l_acc_unit_effectivity_id IS NOT NULL) THEN
3250 l_mr_accomplish_exists := TRUE;
3251 -- added for bug# 8994566
3252 x_accomplished_ue_id := l_acc_unit_effectivity_id;
3253 END IF;
3254
3255 END IF;
3256
3257 -- Check for one time MR.
3258 IF (l_acc_unit_effectivity_id IS NOT NULL AND p_applicable_mrs_rec.repetitive_flag = 'N') OR
3259 (l_acc_deferral_flag = TRUE AND p_applicable_mrs_rec.repetitive_flag = 'N') THEN
3260 --dbms_output.put_line('one time true');
3261 l_one_time_mr_flag := TRUE;
3262 END IF;
3263
3264 -- check for old revisions.
3265 IF (p_applicable_mrs_rec.repetitive_flag = 'N' AND NOT(l_one_time_mr_flag)) THEN
3266 OPEN check_old_mr_ver(p_applicable_mrs_rec.csi_item_instance_id,
3267 p_applicable_mrs_rec.mr_header_id);
3268 FETCH check_old_mr_ver INTO l_junk;
3269 IF (check_old_mr_ver%FOUND) THEN
3270 l_one_time_mr_flag := TRUE;
3271 END IF;
3272 CLOSE check_old_mr_ver;
3273 END IF;
3274
3275 l_dependent_mr_flag := FALSE;
3276 -- Set this flag only if there are no accomplishments for the MR and this MR has
3277 -- a preceding MR.
3278
3279 IF (p_applicable_mrs_rec.preceding_mr_header_id IS NOT NULL AND
3280 l_acc_unit_effectivity_id IS NULL)
3281 THEN
3282 l_dependent_mr_flag := TRUE;
3283 --dbms_output.put_line ('dependent flag true');
3284 -- Modified to get first accomplishment to fix bug#6711228
3285 AHL_UMP_UTIL_PKG.get_first_accomplishment(p_applicable_mrs_rec.csi_item_instance_id,
3286 p_applicable_mrs_rec.preceding_mr_header_id,
3287 l_last_accomplishment_date,
3288 l_acc_unit_effectivity_id,
3289 l_acc_deferral_flag,
3290 l_acc_status_code,
3291 l_return_val);
3292 END IF;
3293
3294 IF (l_acc_deferral_flag) THEN
3295 IF (l_last_accomplishment_date IS NULL) THEN
3296 --l_one_time_mr_flag := TRUE; -- no forecast and cannot calculate deferral due date.
3297 l_no_forecast_flag := TRUE; -- no forecast and cannot calculate deferral due date.
3298 -- fix for bug# 6875650.
3299 -- ELSIF (trunc(l_last_accomplishment_date) <= trunc(sysdate)) THEN
3300 ELSIF (l_last_accomplishment_date <= sysdate) THEN
3301 -- get counter values from counter values tables.
3302 i := 1;
3303 FOR instance_counter_rec IN csi_cp_counters_csr(p_applicable_mrs_rec.csi_item_instance_id) LOOP
3304 l_net_reading := 0;
3305 get_ctr_reading_for_datetime (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
3306 p_counter_id => instance_counter_rec.counter_id,
3307 p_reading_date => l_last_accomplishment_date,
3308 x_net_reading => l_net_reading);
3309
3310 l_last_acc_counter_val_tbl(i).uom_code := instance_counter_rec.uom_code;
3311 l_last_acc_counter_val_tbl(i).counter_id := instance_counter_rec.counter_id;
3312 l_last_acc_counter_val_tbl(i).counter_name := instance_counter_rec.counter_name;
3313 l_last_acc_counter_val_tbl(i).counter_value := l_net_reading;
3314 i := i + 1;
3315
3316 END LOOP;
3317 ELSE -- deferral due date is a future date.
3318 -- get all counter values as on l_preceding_next_due_date.
3319 Get_Due_at_Counter_Values (p_last_due_date => sysdate,
3320 p_last_due_counter_val_tbl => p_current_usage_tbl,
3321 p_due_date => l_last_accomplishment_date,
3322 p_counter_rules_tbl => p_counter_rules_tbl,
3323 x_due_at_counter_val_tbl => l_last_acc_counter_val_tbl,
3324 x_return_value => l_return_val);
3325
3326 IF G_DEBUG = 'Y' THEN
3327 AHL_DEBUG_PUB.Debug('l_deferral_due_date: ' || l_last_accomplishment_date);
3328 IF (l_last_acc_counter_val_tbl.COUNT) > 0 THEN
3329 for i in l_last_acc_counter_val_tbl.FIRST..l_last_acc_counter_val_tbl.LAST LOOP
3330 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_last_acc_counter_val_tbl(i).counter_value || 'ID: ' || l_last_acc_counter_val_tbl(i).counter_id);
3331 end loop;
3332 END IF;
3333 END IF;
3334
3335 -- check return value.
3336 IF NOT(l_return_val) THEN -- no forecast case.
3337 --l_one_time_mr_flag := TRUE;
3338 l_no_forecast_flag := TRUE;
3339 END IF;
3340
3341 END IF; -- Last accomplishment date.
3342 ELSE -- not based on deferral_effective_date.
3343 IF (l_acc_unit_effectivity_id IS NOT NULL) THEN
3344 i := 1;
3345 -- Build last accomplishment counter values.
3346 FOR l_acc_counter_rec IN ahl_unit_accomplish_csr(l_acc_unit_effectivity_id) LOOP
3347 l_last_acc_counter_val_tbl(i).uom_code := l_acc_counter_rec.uom_code;
3348 l_last_acc_counter_val_tbl(i).counter_id := l_acc_counter_rec.counter_id;
3349 l_last_acc_counter_val_tbl(i).counter_name := l_acc_counter_rec.counter_name;
3350 l_last_acc_counter_val_tbl(i).counter_value := l_acc_counter_rec.counter_value;
3351 i := i + 1;
3352 END LOOP;
3353
3354 ELSIF (l_dependent_mr_flag) THEN
3355 -- no accomplishment for preceding MR available.
3356 -- get the next due date from temporary table for calculation.
3357 l_get_preceding_next_due := TRUE;
3358 END IF;
3359 END IF; -- l_acc_deferral_flag.
3360
3361 -- set return parameters.
3362 x_accomplishment_date := l_last_accomplishment_date;
3363 x_last_acc_counter_val_tbl := l_last_acc_counter_val_tbl;
3364 x_one_time_mr_flag := l_one_time_mr_flag;
3365 x_dependent_mr_flag := l_dependent_mr_flag;
3366 x_get_preceding_next_due := l_get_preceding_next_due;
3367 x_no_forecast_flag := l_no_forecast_flag;
3368 x_mr_accomplish_exists := l_mr_accomplish_exists;
3369
3370 IF G_DEBUG = 'Y' THEN
3371 AHL_DEBUG_PUB.debug ('Last Accomplished Date:' || x_accomplishment_date);
3372 AHL_DEBUG_PUB.debug ('Last Accomplished UE ID:' || x_accomplished_ue_id);
3373 AHL_DEBUG_PUB.debug ('Count of ctr values:' || x_last_acc_counter_val_tbl.COUNT);
3374 AHL_DEBUG_PUB.debug ('End Get Accomplishment Details');
3375 END IF;
3376
3377 END get_accomplishment_details;
3378
3379 ------------------------------------------------------------------------------
3380 -- Build unit effectivity for a given item instance and a maintenance requirement.
3381 -- The unit effectivities created here will be written into a temporary table.
3382
3383 PROCEDURE Build_Effectivity ( p_applicable_mrs_rec IN applicable_mrs_rec_type,
3384 p_current_usage_tbl IN counter_values_tbl_type,
3385 p_counter_rules_tbl IN counter_rules_tbl_type)
3386
3387 IS
3388
3389 /* modified for bug# 9263774 - calc due date for prior revisions.
3390 -- retrieve current unit effectivity records.
3391 CURSOR ahl_unit_effectivity_csr (p_mr_header_id IN NUMBER,
3392 p_csi_item_instance_id IN NUMBER) IS
3393 SELECT ue.unit_effectivity_id, ue.status_code, reln.related_ue_id, reln.originator_ue_id
3394 FROM ahl_unit_effectivities_app_v UE, ahl_UE_relationships reln
3395 WHERE UE.unit_effectivity_id = RELN.RELATED_UE_ID(+)
3396 AND mr_header_id = p_mr_header_id
3397 AND csi_item_instance_id = p_csi_item_instance_id
3398 AND (UE.Status_code IS NULL OR status_code = 'INIT-DUE')
3399 AND UE.defer_from_ue_id IS NULL -- do not pick deferred unit effectivities.
3400 AND nvl(UE.manually_planned_flag,'N') = 'N' -- do not pick manually planned UEs.
3401 -- do not pick up child UEs if parent init-accomplished.
3402 AND NOT EXISTS (SELECT 'x' FROM AHL_UNIT_EFFECTIVITIES_B PARENT_UE
3403 WHERE PARENT_UE.UNIT_EFFECTIVITY_ID = RELN.ORIGINATOR_UE_ID
3404 AND PARENT_UE.STATUS_CODE = 'INIT-ACCOMPLISHED')
3405 ORDER BY forecast_sequence ASC;
3406 */
3407
3408 -- retrieve current unit effectivity records(including prior revisions).
3409 CURSOR ahl_unit_effectivity_csr (p_title IN VARCHAR2,
3410 p_csi_item_instance_id IN NUMBER,
3411 p_appln_usg_code IN VARCHAR2) IS
3412 SELECT ue.unit_effectivity_id, ue.status_code, reln.related_ue_id, reln.originator_ue_id, ue.mr_header_id
3413 --FROM ahl_unit_effectivities_app_v UE, ahl_UE_relationships reln,
3414 FROM ahl_unit_effectivities_b UE, ahl_UE_relationships reln,
3415 ahl_mr_headers_b mr
3416 WHERE UE.unit_effectivity_id = RELN.RELATED_UE_ID(+)
3417 AND UE.mr_header_id = mr.mr_header_id
3418 AND mr.mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1 where mr1.title = p_title)
3419 AND UE.csi_item_instance_id = p_csi_item_instance_id
3420 AND UE.application_usg_code = p_appln_usg_code
3421 AND (UE.Status_code IS NULL OR UE.status_code = 'INIT-DUE')
3422 AND UE.defer_from_ue_id IS NULL -- do not pick deferred unit effectivities.
3423 AND nvl(UE.manually_planned_flag,'N') = 'N' -- do not pick manually planned UEs.
3424 -- do not pick up child UEs if parent init-accomplished.
3425 AND NOT EXISTS (SELECT 'x' FROM AHL_UNIT_EFFECTIVITIES_B PARENT_UE
3426 WHERE PARENT_UE.UNIT_EFFECTIVITY_ID = RELN.ORIGINATOR_UE_ID
3427 AND PARENT_UE.STATUS_CODE = 'INIT-ACCOMPLISHED')
3428 ORDER BY mr.version_number ASC, forecast_sequence ASC ;
3429
3430 -- Get group MRs if any, from ahl_temp_unit_effectivities for the item instance.
3431 -- select only the first row.
3432 -- modified to support multiple MR revisions for bug# 9263774
3433 CURSOR ahl_temp_ue_csr (p_item_instance_id IN NUMBER,
3434 --p_mr_header_id IN NUMBER,
3435 p_title IN VARCHAR2,
3436 p_last_due_date IN DATE,
3437 p_due_date IN DATE ) IS
3438 SELECT *
3439 FROM (
3440 SELECT due_date,
3441 orig_csi_item_instance_id,
3442 orig_mr_header_id,
3443 --orig_forecast_sequence,
3444 visit_end_date
3445 FROM ahl_temp_unit_effectivities
3446 WHERE csi_item_instance_id = p_item_instance_id AND
3447 --mr_header_id = p_mr_header_id AND
3448 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1 where mr1.title = p_title) AND
3449 orig_csi_item_instance_id IS NOT NULL AND
3450 orig_mr_header_id IS NOT NULL AND
3451 trunc(nvl(visit_end_date, nvl(due_date, p_last_due_date))) > trunc(p_last_due_date) AND
3452 trunc(nvl(visit_end_date, nvl(due_date, p_due_date+1))) <= trunc(p_due_date) AND
3453 preceding_check_flag = 'N'
3454 /* ignore records with null due dates */
3455 /* order selected rows so that the record with max due date is first */
3456 /* consider visit end date instead of due date, if it is available. */
3457
3458 UNION
3459
3460 -- Get SR's.
3461 SELECT due_date,
3462 csi_item_instance_id orig_csi_item_instance_id,
3463 mr_header_id orig_mr_header_id,
3464 visit_end_date
3465 FROM ahl_temp_unit_SR_deferrals
3466 WHERE csi_item_instance_id = p_item_instance_id
3467 --AND mr_header_id = p_mr_header_id
3468 AND mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1 where mr1.title = p_title)
3469 AND trunc(nvl(visit_end_date, nvl(due_date, p_last_due_date))) > trunc(p_last_due_date)
3470 AND trunc(nvl(visit_end_date, nvl(due_date, p_due_date+1))) <= trunc(p_due_date)
3471 AND deferral_effective_on IS NULL -- pick only SR related MRs.
3472 -- ignore records with null due dates.
3473 -- ignore deferral records.
3474
3475 ORDER BY due_date DESC
3476 )
3477 WHERE ROWNUM < 2;
3478
3479 -- in case of 'next-due', we need to check p_last_due_date equality condition too.
3480 -- Get group MRs if any, from ahl_temp_unit_effectivities for the item instance.
3481 -- select only the first row.
3482 -- modified to support multiple MR revisions for bug# 9263774
3483 CURSOR ahl_temp_ue_csr1 (p_item_instance_id IN NUMBER,
3484 --p_mr_header_id IN NUMBER,
3485 p_title IN VARCHAR2,
3486 p_last_due_date IN DATE,
3487 p_due_date IN DATE ) IS
3488 SELECT *
3489 FROM (
3490 SELECT due_date,
3491 orig_csi_item_instance_id,
3492 orig_mr_header_id,
3493 --orig_forecast_sequence,
3494 visit_end_date
3495 FROM ahl_temp_unit_effectivities
3496 WHERE csi_item_instance_id = p_item_instance_id AND
3497 --mr_header_id = p_mr_header_id AND
3498 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1 where mr1.title = p_title) AND
3499 orig_csi_item_instance_id IS NOT NULL AND
3500 orig_mr_header_id IS NOT NULL AND
3501 trunc(nvl(visit_end_date, nvl(due_date, p_last_due_date))) >= trunc(p_last_due_date) AND
3502 trunc(nvl(visit_end_date, nvl(due_date, p_due_date+1))) <= trunc(p_due_date) AND
3503 preceding_check_flag = 'N'
3504 /* ignore records with null due dates */
3505 /* order selected rows so that the record with max due date is first */
3506 /* consider visit end date instead of due date, if it is available. */
3507
3508 UNION
3509
3510 -- Get SR's.
3511 SELECT due_date,
3512 csi_item_instance_id orig_csi_item_instance_id,
3513 mr_header_id orig_mr_header_id,
3514 visit_end_date
3515 FROM ahl_temp_unit_SR_deferrals
3516 WHERE csi_item_instance_id = p_item_instance_id
3517 --AND mr_header_id = p_mr_header_id
3518 AND mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1 where mr1.title = p_title)
3519 AND trunc(nvl(visit_end_date, nvl(due_date, p_last_due_date))) >= trunc(p_last_due_date)
3520 AND trunc(nvl(visit_end_date, nvl(due_date, p_due_date+1))) <= trunc(p_due_date)
3521 AND deferral_effective_on IS NULL -- pick only SR related MRs.
3522 -- ignore records with null due dates.
3523 -- ignore deferral records.
3524 ORDER BY due_date DESC
3525 )
3526 WHERE ROWNUM < 2;
3527
3528 -- Check if MR is a group MR.
3529 CURSOR group_check_csr (p_item_instance_id IN NUMBER,
3530 p_mr_header_id IN NUMBER) IS
3531 SELECT 'x'
3532 FROM ahl_applicable_mr_relns
3533 WHERE orig_csi_item_instance_id = p_item_instance_id AND
3534 orig_mr_header_id = p_mr_header_id;
3535
3536 -- Get next due date of preceding MR from temporary table.
3537 -- modified to support multiple MR revisions for bug# 9263774
3538 -- fix for bug# 9673770. next due from deferral temp table.
3539 CURSOR preceding_due_date_csr (p_preceding_instance_id IN NUMBER,
3540 p_preceding_mr_header_id IN NUMBER) IS
3541 SELECT * FROM (
3542 SELECT due_date
3543 FROM ahl_temp_unit_effectivities
3544 WHERE csi_item_instance_id = p_preceding_instance_id AND
3545 --mr_header_id = p_preceding_mr_header_id AND
3546 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1
3547 where mr1.title = (select mr2.title from ahl_mr_headers_b mr2 where mr2.mr_header_id = p_preceding_mr_header_id)
3548 ) AND
3549 preceding_check_flag = 'N'
3550
3551 UNION
3552 SELECT due_date
3553 FROM ahl_temp_unit_SR_deferrals
3554 WHERE csi_item_instance_id = p_preceding_instance_id AND
3555 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1
3556 where mr1.title = (select mr2.title from ahl_mr_headers_b mr2 where mr2.mr_header_id = p_preceding_mr_header_id)
3557 )
3558 ORDER by due_date
3559 )
3560 WHERE ROWNUM < 2;
3561
3562 -- Added for 11.5.10+ enhancements for Unplanned MRs.
3563 -- Read open Unplanned MRs.
3564 -- modified to consider prior MR revsions to fix bug# 9263774.
3565 CURSOR ahl_unplanned_MRs_csr(p_item_instance_id IN NUMBER,
3566 p_title IN VARCHAR2,
3567 p_appln_usg_code IN VARCHAR2) IS
3568 SELECT ue.unit_effectivity_id
3569 --FROM ahl_unit_effectivities_app_v ue
3570 FROM ahl_unit_effectivities_b ue
3571 WHERE ue.csi_item_instance_id = p_item_instance_id
3572 AND ue.application_usg_code = p_appln_usg_code
3573 AND ue.mr_header_id IN (select amh.mr_header_id from ahl_mr_headers_b amh where amh.title = p_title)
3574 AND ue.status_code IS NULL
3575 AND ue.manually_planned_flag = 'Y'
3576 AND NOT EXISTS (SELECT 'x'
3577 FROM ahl_ue_relationships uer, ahl_unit_effectivities_b ue1
3578 WHERE uer.related_ue_id = ue.unit_effectivity_id
3579 AND uer.originator_ue_id = ue1.unit_effectivity_id
3580 AND ue1.object_type = 'SR');
3581 -- Do not pick MRs associated to a SR.
3582 --
3583 l_unit_effectivity_tbl unit_effectivity_tbl_type;
3584 /* this table will contain the current unit effectivity definitions for the mr and item instance */
3585
3586 i NUMBER := 0;
3587 /* running index for unit effectivity tbl */
3588
3589 l_visit_start_date DATE;
3590 l_visit_end_date DATE;
3591 l_visit_assign_code VARCHAR2(30);
3592
3593 l_forecast_sequence NUMBER;
3594 l_old_UE_forecast_sequence NUMBER;
3595 l_next_due_date_rec next_due_date_rec_type;
3596
3597 l_new_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
3598 l_new_unit_effectivity_initrec ahl_temp_unit_effectivities%ROWTYPE;
3599
3600 l_temp_grp_mr_rec ahl_temp_ue_csr%ROWTYPE;
3601
3602 l_last_accomplishment_date DATE;
3603 l_last_acc_counter_val_tbl counter_values_tbl_type;
3604 l_dependent_mr_flag BOOLEAN;
3605 l_get_preceding_next_due BOOLEAN; -- to indicate that the dependent MR calculation is based on preceding MR's next due.
3606 l_preceding_next_due_date DATE;
3607
3608 l_one_time_mr_flag BOOLEAN;
3609
3610 l_calc_due_date_flag BOOLEAN := TRUE;
3611 -- set to true if preceding MR due date is null. So the dependent's due date
3612 -- will also be null. Calc due date must not be done.
3613
3614 --l_bef_tolr_due_date DATE;
3615 --l_aft_tolr_due_date DATE;
3616
3617 l_last_due_date DATE;
3618 l_last_due_counter_val_tbl counter_values_tbl_type;
3619 l_due_at_counter_val_tbl counter_values_tbl_type;
3620 l_due_date DATE;
3621
3622 l_next_due_flag BOOLEAN;
3623 l_grp_duedate_found BOOLEAN;
3624 l_old_UE_forecast_found BOOLEAN := TRUE;
3625
3626 l_return_value BOOLEAN;
3627 l_junk VARCHAR2(1);
3628 group_check_flag BOOLEAN := FALSE; -- flag to check if it is a group MR.
3629
3630 -- Added for 11.5.10+ enhancements for Unplanned MRs.
3631 -- Define rec and table type to hold Unplanned MRs.
3632 TYPE Unplanned_UE_rec_type IS RECORD(
3633 UNIT_EFFECTIVITY_ID NUMBER,
3634 VISIT_END_DATE DATE);
3635
3636 TYPE Unplanned_UE_Tbl_type IS TABLE OF Unplanned_UE_rec_type INDEX BY BINARY_INTEGER;
3637
3638 l_unplanned_MRs_tbl Unplanned_UE_Tbl_type;
3639 l_min_visit_date DATE;
3640
3641 -- R12 to fix bug# 4224867.
3642 l_duplicate_MRs NUMBER;
3643 l_usage_per_day NUMBER;
3644
3645 -- Added to fix bug# 6711228.
3646 l_no_forecast_flag BOOLEAN;
3647 l_mr_accomplish_exists BOOLEAN;
3648
3649 -- Added to fix bug# 6858788
3650 l_last_due_mr_interval_id NUMBER;
3651
3652 -- Added for performance.
3653 l_ue_id_tbl nbr_tbl_type;
3654 l_ue_status_tbl vchar_tbl_type;
3655 l_related_ue_tbl nbr_tbl_type;
3656 l_orig_ue_tbl nbr_tbl_type;
3657 l_prior_mr_header_tbl nbr_tbl_type;
3658
3659 l_buffer_limit NUMBER := 1000;
3660
3661 -- Added to fix bug# 8994566
3662 l_accomplished_ue_id NUMBER;
3663
3664 -- Added for SB Enhancements
3665 l_mr_termination_date DATE;
3666 l_lc_mr_tbl loop_chain_MR_tbl_type;
3667
3668 l_loop_due_date DATE;
3669 l_loop_last_due_date DATE;
3670 l_loop_last_counter_val_tbl counter_values_tbl_type;
3671 l_skip_next_due_flag VARCHAR2(1);
3672 l_single_mr_seq NUMBER;
3673
3674 l_visit_status VARCHAR2(30);
3675 l_process_status_flag VARCHAR2(1);
3676
3677 -- JKJain, NR Analysis and Forecasting
3678 l_next_fleet_asso_date DATE;
3679 l_fleet_asso_rej_date DATE;
3680
3681
3682 CURSOR get_next_fleet_asso_date(l_date DATE)
3683 IS
3684 SELECT * FROM(
3685 SELECT FUA.association_start
3686 FROM ahl_fleet_unit_assocs FUA, ahl_fleet_headers_b FLT
3687 WHERE FUA.unit_config_header_id = G_UC_HEADER_ID
3688 AND FUA.simulation_plan_id = nvl(G_SIMULATION_PLAN_ID, get_primary_plan_id)
3689 AND FLT.fleet_header_id = FUA.fleet_header_id
3690 AND FLT.status_code = 'COMPLETE'
3691 AND trunc(FUA.association_start) >= trunc(l_date)
3692 ORDER BY FUA.association_start ASC)
3693 WHERE rownum < 2;
3694
3695 BEGIN
3696
3697
3698 IF G_DEBUG = 'Y' THEN
3699 AHL_DEBUG_PUB.debug ('Start Build Effectivity for mr:csi' || p_applicable_mrs_rec.mr_header_id || ':' || p_applicable_mrs_rec.csi_item_instance_id );
3700 END IF;
3701
3702 -- verify processing flag as it may have been updated during processing.
3703 BEGIN
3704 SELECT process_status_flag
3705 INTO l_process_status_flag
3706 FROM ahl_applicable_MRs
3707 WHERE mr_header_id = p_applicable_mrs_rec.mr_header_id
3708 AND csi_item_instance_id = p_applicable_mrs_rec.csi_item_instance_id
3709 AND rownum < 2;
3710
3711 IF l_process_status_flag = 'Y' THEN
3712 IF G_DEBUG = 'Y' THEN
3713 AHL_DEBUG_PUB.debug ('Already Processed ...Skipping Build Effectivity for mr:csi' || p_applicable_mrs_rec.mr_header_id || ':' || p_applicable_mrs_rec.csi_item_instance_id );
3714 END IF;
3715 RETURN;
3716 END IF;
3717
3718 EXCEPTION
3719 WHEN OTHERS THEN
3720 NULL;
3721 END;
3722
3723 -- If MR has a accomplishment trigger of 'terminated_by' then check if parent MRs are processed and if not, process them.
3724 -- added for SB Enh.
3725 IF (p_applicable_mrs_rec.terminate_trigger_check = 'Y') THEN
3726 Process_terminating_parent_MRs(p_applicable_mrs_rec => p_applicable_mrs_rec,
3727 p_current_usage_tbl => p_current_usage_tbl,
3728 p_counter_rules_tbl => p_counter_rules_tbl,
3729 x_mr_termination_date => l_mr_termination_date);
3730
3731 -- delete any processed deferrals from temp table.
3732 -- *******handle group MRs?
3733 IF (l_mr_termination_date IS NOT NULL) THEN
3734 BEGIN
3735 --dbms_output.put_line ('Start Build Effectivity for mr:csi' || p_applicable_mrs_rec.mr_header_id || ':' || p_applicable_mrs_rec.csi_item_instance_id );
3736 --dbms_output.put_line ('l_mr_termination_date:' || l_mr_termination_date || ':' || p_applicable_mrs_rec.title);
3737 DELETE FROM ahl_temp_unit_SR_deferrals tdef
3738 WHERE tdef.CSI_ITEM_INSTANCE_ID = p_applicable_mrs_rec.csi_item_instance_id
3739 AND tdef.MR_HEADER_ID IN (select MR_HEADER_ID from ahl_mr_headers_b where title = p_applicable_mrs_rec.title)
3740 AND trunc(tdef.DUE_DATE) >= trunc(l_mr_termination_date)
3741 AND NOT EXISTS (select 'x' from ahl_temp_unit_SR_deferrals where orig_unit_effectivity_id = tdef.unit_effectivity_id);
3742 EXCEPTION
3743 WHEN OTHERS THEN
3744 null;
3745 END;
3746 END IF;
3747 END IF;
3748
3749
3750
3751 -- Added for SB Enhancements
3752 -- If p_applicable_mrs_rec.mr_header_id is a starting mr for a loop or chain
3753 -- then initialize
3754 IF (p_applicable_mrs_rec.accomplish_trigger_type = 'CHAIN') THEN
3755
3756 Process_Chain_Init(p_applicable_mrs_rec => p_applicable_mrs_rec,
3757 p_current_usage_tbl => p_current_usage_tbl,
3758 p_counter_rules_tbl => p_counter_rules_tbl,
3759 x_loop_chain_MR_tbl => l_lc_mr_tbl);
3760
3761 l_skip_next_due_flag := 'N';
3762 IF G_DEBUG = 'Y' THEN
3763 AHL_DEBUG_PUB.debug ('count x_loop_chain_MR_tbl:next_due_flag:' || l_lc_mr_tbl.count || ':' || l_skip_next_due_flag);
3764 END IF;
3765 END IF;
3766
3767
3768 IF (p_applicable_mrs_rec.accomplish_trigger_type = 'LOOP') THEN
3769 Process_Loop_Init(p_applicable_mrs_rec => p_applicable_mrs_rec,
3770 p_current_usage_tbl => p_current_usage_tbl,
3771 p_counter_rules_tbl => p_counter_rules_tbl,
3772 x_loop_chain_MR_tbl => l_lc_mr_tbl,
3773 x_loop_last_due_date => l_loop_last_due_date,
3774 x_loop_last_counter_val_tbl => l_loop_last_counter_val_tbl,
3775 x_next_due_skip_flag => l_skip_next_due_flag);
3776
3777 IF G_DEBUG = 'Y' THEN
3778 AHL_DEBUG_PUB.debug ('count x_loop_chain_MR_tbl:next_due_flag:' || l_lc_mr_tbl.count || ':' || l_skip_next_due_flag);
3779 END IF;
3780
3781 -- for loop case, l_skip_next_due_flag returned from Process_Loop_Init indicates if
3782 -- next due calculation needs to be skipped, in which case, we start calculating based on repetivity flag = Y
3783 -- as there is at least one child MR in the loop that is not accomplished yet.
3784 IF (l_skip_next_due_flag IS NULL) THEN
3785 l_skip_next_due_flag := 'N';
3786 ELSIF (l_skip_next_due_flag = 'Y') THEN
3787
3788 -- initialize calculation variables.
3789 l_next_due_flag := FALSE;
3790 l_forecast_sequence := 1; -- start from 1 instead of 0
3791
3792 -- start calculation from last loop num ctr values.
3793 l_last_due_date := l_loop_last_due_date;
3794 l_last_due_counter_val_tbl := l_loop_last_counter_val_tbl;
3795
3796 GOTO process_next_mr_and_repetivity;
3797
3798 END IF;
3799
3800 END IF;
3801 -- End SB Enh loop/chain init ---
3802
3803 -- Set last accomplishment details.
3804 Get_accomplishment_details(p_applicable_mrs_rec => p_applicable_mrs_rec,
3805 p_current_usage_tbl => p_current_usage_tbl,
3806 p_counter_rules_tbl => p_counter_rules_tbl,
3807 x_accomplishment_date => l_last_accomplishment_date,
3808 x_last_acc_counter_val_tbl => l_last_acc_counter_val_tbl,
3809 x_one_time_mr_flag => l_one_time_mr_flag,
3810 x_dependent_mr_flag => l_dependent_mr_flag,
3811 x_get_preceding_next_due => l_get_preceding_next_due,
3812 x_mr_accomplish_exists => l_mr_accomplish_exists,
3813 x_no_forecast_flag => l_no_forecast_flag,
3814 x_accomplished_ue_id => l_accomplished_ue_id);
3815
3816 -- Check for one time MR case.
3817 IF (l_one_time_mr_flag) THEN
3818 --dbms_output.put_line('one time true in build');
3819 GOTO process_preceding_mr;
3820 ELSIF (l_no_forecast_flag) THEN
3821 RETURN; -- no more MRs needed.
3822 END IF;
3823
3824 -- get next accomplishment details for the preceding MR if needed.
3825 IF (l_get_preceding_next_due) THEN
3826 OPEN preceding_due_date_csr (p_applicable_mrs_rec.csi_item_instance_id,
3827 p_applicable_mrs_rec.preceding_mr_header_id);
3828
3829 FETCH preceding_due_date_csr INTO l_preceding_next_due_date;
3830 IF (preceding_due_date_csr%NOTFOUND) OR (l_preceding_next_due_date IS NULL) THEN
3831 --dbms_output.put_line ('not found preceding');
3832 l_calc_due_date_flag := FALSE;
3833 ELSE
3834 IF G_DEBUG = 'Y' THEN
3835 AHL_DEBUG_PUB.Debug('Found due_date for preceding MR: '|| l_preceding_next_due_date);
3836 END IF;
3837 l_last_accomplishment_date := l_preceding_next_due_date;
3838 --dbms_output.put_line ('found preceding due_date' ||l_preceding_next_due_date );
3839 -- get all counter values as on l_preceding_next_due_date.
3840 Get_Due_at_Counter_Values (p_last_due_date => sysdate,
3841 p_last_due_counter_val_tbl => p_current_usage_tbl,
3842 p_due_date => l_preceding_next_due_date,
3843 p_counter_rules_tbl => p_counter_rules_tbl,
3844 x_due_at_counter_val_tbl => l_last_acc_counter_val_tbl,
3845 x_return_value => l_return_value);
3846
3847 IF G_DEBUG = 'Y' THEN
3848 AHL_DEBUG_PUB.Debug('l_preceding_due_date: '|| l_preceding_next_due_date);
3849 IF (l_last_acc_counter_val_tbl.COUNT) > 0 THEN
3850 for i in l_last_acc_counter_val_tbl.FIRST..l_last_acc_counter_val_tbl.LAST LOOP
3851 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_last_acc_counter_val_tbl(i).counter_value || 'ID: ' || l_last_acc_counter_val_tbl(i).counter_id);
3852 --dbms_output.put_line('i:'|| i|| ' value:' || l_last_acc_counter_val_tbl(i).counter_value || 'ID: ' || l_last_acc_counter_val_tbl(i).counter_id);
3853 end loop;
3854 END IF;
3855 END IF;
3856
3857 -- check return value.
3858 IF NOT(l_return_value) THEN -- no forecast case.
3859 --l_preceding_next_due_date := NULL;
3860 l_calc_due_date_flag := FALSE;
3861 END IF;
3862 END IF;
3863 CLOSE preceding_due_date_csr;
3864 END IF;
3865
3866
3867 -- Calculate Due date.
3868 IF (l_calc_due_date_flag) THEN -- no calculation needed if preceding mr's next due has no due date.
3869
3870 --dbms_output.put_line ('bef calculate_due_date');
3871 --dbms_output.put_line ('accomplish:date:' || l_last_accomplishment_date);
3872
3873 -- Calculate next due date.
3874 -- Added parameter p_dependent_mr_flag to fix bug# 6711228.
3875 Calculate_Due_Date (p_repetivity_flag => 'N',
3876 p_applicable_mrs_rec => p_applicable_mrs_rec,
3877 p_current_usage_tbl => p_current_usage_tbl,
3878 p_counter_rules_tbl => p_counter_rules_tbl,
3879 p_last_due_date => l_last_accomplishment_date,
3880 p_last_due_counter_val_tbl => l_last_acc_counter_val_tbl,
3881 p_dependent_mr_flag => l_dependent_mr_flag,
3882 p_mr_accomplish_exists => l_mr_accomplish_exists,
3883 x_next_due_date_rec => l_next_due_date_rec);
3884 END IF;
3885
3886 IF G_DEBUG = 'Y' THEN
3887 AHL_DEBUG_PUB.Debug('Aft calculate_due_date nextdue');
3888 AHL_DEBUG_PUB.Debug('due date is ' || l_next_due_date_rec.DUE_DATE);
3889 AHL_DEBUG_PUB.Debug('earliest due date is ' || l_next_due_date_rec.EARLIEST_DUE_DATE);
3890 AHL_DEBUG_PUB.Debug('latest due date is ' || l_next_due_date_rec.latest_due_date);
3891 AHL_DEBUG_PUB.Debug('p_repetivity_flag => N, FLEET_ASSO_REJECTED ' || l_next_due_date_rec.FLEET_ASSO_REJECTED);
3892 END IF;
3893
3894 -- JKJain, NR Analysis and Forecasting
3895 IF(l_next_due_date_rec.FLEET_ASSO_REJECTED = 'Y' AND l_next_due_date_rec.DUE_DATE IS NOT NULL) THEN
3896 l_fleet_asso_rej_date := l_next_due_date_rec.DUE_DATE;
3897 l_next_due_date_rec.DUE_DATE := null;
3898 END IF;
3899
3900 -- added for SB Enhancements - termination trigger.
3901 -- if due date > l_mr_termination_date then MR is terminated and no calc is required.
3902 IF (l_mr_termination_date IS NOT NULL) THEN
3903 IF (l_next_due_date_rec.due_date is NOT NULL AND l_next_due_date_rec.due_date >= l_mr_termination_date) THEN
3904 IF G_DEBUG = 'Y' THEN
3905 AHL_DEBUG_PUB.Debug(p_applicable_mrs_rec.title || 'is terminated');
3906 END IF;
3907 RETURN;
3908 ELSIF l_mr_termination_date <= trunc(sysdate) THEN
3909 IF G_DEBUG = 'Y' THEN
3910 AHL_DEBUG_PUB.Debug(p_applicable_mrs_rec.title || 'is terminated');
3911 END IF;
3912 RETURN;
3913 END IF;
3914 END IF;
3915
3916 -- If the MR is a dependent MR: (1) If calculated due date is earlier than preceding MR due date,
3917 -- then change due date to be equal to preceding MR due date.
3918 -- (2) Update the preceding_check_flag, based on due date.
3919 IF (p_applicable_mrs_rec.preceding_mr_header_id IS NOT NULL) THEN
3920 IF (trunc(l_next_due_date_rec.DUE_DATE) < trunc(l_last_accomplishment_date)) THEN
3921 l_next_due_date_rec.DUE_DATE := l_last_accomplishment_date;
3922 END IF;
3923
3924 Update_check_flag (p_applicable_mrs_rec => p_applicable_mrs_rec,
3925 p_dependent_mr_flag => l_dependent_mr_flag,
3926 p_next_due_date_rec => l_next_due_date_rec);
3927 END IF;
3928
3929 --- Initialize before processing starts.
3930 l_next_due_flag := TRUE;
3931 /* next due mr calculation. */
3932 l_forecast_sequence := 0;
3933
3934 -- set last_due values to current values.
3935 l_last_due_date := sysdate;
3936 l_last_due_counter_val_tbl := p_current_usage_tbl;
3937 -----
3938
3939 <<process_next_mr_and_repetivity>>
3940
3941 -- Initialize forecast sequence numbers.
3942 l_old_UE_forecast_sequence := 0;
3943 l_old_UE_forecast_found := TRUE;
3944
3945 -- Read existing unit effectivity records for the mr and item instance.
3946 OPEN ahl_unit_effectivity_csr(p_applicable_mrs_rec.title,
3947 p_applicable_mrs_rec.csi_item_instance_id,
3948 G_application_usg_code);
3949 i := 0;
3950 l_single_mr_seq := 0;
3951 LOOP
3952 FETCH ahl_unit_effectivity_csr BULK COLLECT INTO l_ue_id_tbl, l_ue_status_tbl, l_related_ue_tbl,
3953 l_orig_ue_tbl, l_prior_mr_header_tbl LIMIT l_buffer_limit;
3954 EXIT WHEN (l_ue_id_tbl.count = 0);
3955
3956 IF G_DEBUG = 'Y' THEN
3957 AHL_DEBUG_PUB.debug ('Rows fetched for instance-mr is: ' || ahl_unit_effectivity_csr%ROWCOUNT);
3958 END IF;
3959
3960 --dbms_output.put_line ('unit eff load i:' || l_unit_effectivity_tbl(i).unit_effectivity_id);
3961
3962 FOR j IN l_ue_id_tbl.FIRST..l_ue_id_tbl.LAST LOOP
3963
3964 l_visit_status := AHL_UMP_UTIL_PKG.get_Visit_Status(l_ue_id_tbl(j));
3965
3966 -- modified for bug# 9263774: calc due date for prior MR versions.
3967 -- for expired MRs, we need to select only those UEs that have WOs associated.
3968 IF (p_applicable_mrs_rec.expired_mr_flag = 'N' AND l_prior_mr_header_tbl(j) = p_applicable_mrs_rec.mr_header_id ) OR
3969 (p_applicable_mrs_rec.expired_mr_flag = 'N' AND l_visit_status IN ('RELEASED','CLOSED')) OR
3970 -- assigned to a visit
3971 (p_applicable_mrs_rec.expired_mr_flag = 'Y' AND l_visit_status IN ('RELEASED','CLOSED'))
3972 THEN
3973 i := i + 1;
3974 -- initialize
3975 l_unit_effectivity_tbl(i).unit_effectivity_id := l_ue_id_tbl(j);
3976 l_unit_effectivity_tbl(i).status_code := l_ue_status_tbl(j);
3977 l_unit_effectivity_tbl(i).related_ue_id := l_related_ue_tbl(j);
3978 l_unit_effectivity_tbl(i).originator_ue_id := l_orig_ue_tbl(j);
3979
3980 -- added for bug# 9263774
3981 IF (l_prior_mr_header_tbl(j) <> p_applicable_mrs_rec.mr_header_id) THEN
3982 l_unit_effectivity_tbl(i).prior_mr_header_id := l_prior_mr_header_tbl(j);
3983 END IF;
3984
3985 -- Call visit work package to get visit end date if unit effectivity has been assigned to a visit.
3986 AHL_UMP_UTIL_PKG.get_visit_details (l_unit_effectivity_tbl(i).unit_effectivity_id,
3987 l_visit_start_date,
3988 l_visit_end_date,
3989 l_visit_assign_code);
3990
3991 IF (l_visit_end_date IS NOT NULL AND trunc(l_visit_end_date) >= trunc(sysdate)) THEN
3992 IF G_DEBUG = 'Y' THEN
3993 AHL_DEBUG_PUB.Debug('Visit assigned:End Date:' || l_visit_end_date);
3994 END IF;
3995
3996 l_unit_effectivity_tbl(i).visit_assign_flag := 'Y';
3997 l_unit_effectivity_tbl(i).visit_end_date := l_visit_end_date;
3998 ELSE
3999 l_unit_effectivity_tbl(i).visit_assign_flag := 'N';
4000 l_unit_effectivity_tbl(i).visit_end_date := null;
4001 END IF;
4002
4003 -- Assign forecast sequence for single (non-group) MRs.
4004 IF (l_unit_effectivity_tbl(i).originator_ue_id IS NULL) THEN
4005 l_single_mr_seq := l_single_mr_seq + 1;
4006 l_unit_effectivity_tbl(i).forecast_sequence := l_single_mr_seq;
4007 END IF;
4008 END IF; -- expired flag
4009 END LOOP; -- l_ue_id_tbl
4010
4011 -- clean up.
4012 l_ue_id_tbl.DELETE;
4013 l_ue_status_tbl.DELETE;
4014 l_related_ue_tbl.DELETE;
4015 l_orig_ue_tbl.DELETE;
4016
4017 END LOOP;
4018 CLOSE ahl_unit_effectivity_csr;
4019
4020 -- Added for 11.5.10+ enhancements for Unplanned MRs.
4021 -- Build table of visit end dates for Unplanned MRs.
4022 i := 0;
4023 FOR ahl_unplanned_MRs_rec IN ahl_unplanned_MRs_csr(p_applicable_mrs_rec.csi_item_instance_id,
4024 p_applicable_mrs_rec.title,
4025 G_application_usg_code)
4026 LOOP
4027 -- Get visit end date; unplanned MRs is always assigned to a visit.
4028 AHL_UMP_UTIL_PKG.get_visit_details (ahl_unplanned_MRs_rec.unit_effectivity_id,
4029 l_visit_start_date,
4030 l_visit_end_date,
4031 l_visit_assign_code);
4032 IF (l_visit_end_date IS NOT NULL) THEN
4033 i := i + 1;
4034 l_unplanned_MRs_tbl(i).unit_effectivity_id := ahl_unplanned_MRs_rec.unit_effectivity_id;
4035 l_unplanned_MRs_tbl(i).visit_end_date := trunc(l_visit_end_date);
4036 END IF;
4037
4038 END LOOP; -- unplanned MRs.
4039
4040 -- Check for group MR.
4041 OPEN group_check_csr(p_applicable_mrs_rec.csi_item_instance_id,
4042 p_applicable_mrs_rec.mr_header_id);
4043 FETCH group_check_csr INTO l_junk;
4044 IF (group_check_csr%NOTFOUND) THEN
4045 --dbms_output.put_line ('group check false');
4046 group_check_flag := FALSE;
4047 ELSE
4048 group_check_flag := TRUE;
4049 END IF;
4050 CLOSE group_check_csr;
4051
4052 -- process next due and repetivity.
4053 LOOP
4054
4055 -- Added for SB Enh: If skip next due flag is set, then
4056 -- jump to repetivity calculation.
4057 IF (l_skip_next_due_flag = 'Y') THEN
4058 l_skip_next_due_flag := 'N';
4059 GOTO Calculate_Repetivity_DueDate;
4060 END IF;
4061
4062 -- At this time assume, that there are no MRs with due dates less than the calc due date.
4063 l_grp_duedate_found := FALSE;
4064
4065 -- Check output from calculate_due_date.
4066 IF (l_next_due_date_rec.due_date IS NOT NULL AND l_next_due_date_rec.FLEET_ASSO_REJECTED = 'N') THEN
4067
4068 IF (l_next_due_flag) THEN
4069 -- read ahl_temp_unit_effectivity
4070 IF (l_last_due_date < l_next_due_date_rec.due_date) THEN
4071 OPEN ahl_temp_ue_csr1(p_applicable_mrs_rec.csi_item_instance_id,
4072 --p_applicable_mrs_rec.mr_header_id,
4073 p_applicable_mrs_rec.title,
4074 l_last_due_date,
4075 l_next_due_date_rec.due_date);
4076 ELSE
4077 OPEN ahl_temp_ue_csr1(p_applicable_mrs_rec.csi_item_instance_id,
4078 --p_applicable_mrs_rec.mr_header_id,
4079 p_applicable_mrs_rec.title,
4080 l_next_due_date_rec.due_date,
4081 l_last_due_date);
4082 END IF;
4083
4084 FETCH ahl_temp_ue_csr1 INTO l_temp_grp_mr_rec;
4085 IF (ahl_temp_ue_csr1%FOUND) THEN
4086 --dbms_output.put_line ('exists grp rec' || l_temp_grp_mr_rec.due_date);
4087 /* there exists a group record with due date less than the calculated * one */
4088 l_grp_duedate_found := TRUE;
4089
4090 -- added to fix bug# 6530920.
4091 -- this is to avoid creation of one child UMP row at the end of the
4092 -- planning window when the child MR and parent MR have the same interval
4093 -- threshold. Next due MR can be individual MR or part of a group MR.
4094 l_next_due_flag := FALSE;
4095
4096 END IF;
4097 CLOSE ahl_temp_ue_csr1;
4098 ELSE
4099 -- read ahl_temp_unit_effectivity
4100 OPEN ahl_temp_ue_csr(p_applicable_mrs_rec.csi_item_instance_id,
4101 --p_applicable_mrs_rec.mr_header_id,
4102 p_applicable_mrs_rec.title,
4103 l_last_due_date,
4104 l_next_due_date_rec.due_date);
4105 FETCH ahl_temp_ue_csr INTO l_temp_grp_mr_rec;
4106 IF (ahl_temp_ue_csr%FOUND) THEN
4107 --dbms_output.put_line ('exists grp rec' || l_temp_grp_mr_rec.due_date);
4108 /* there exists a group record with due date less than the calculated one */
4109 l_grp_duedate_found := TRUE;
4110 END IF;
4111 CLOSE ahl_temp_ue_csr;
4112 END IF;
4113 -- Added for 11.5.10+ Unplanned MRs enhancement.
4114 l_min_visit_date := NULL;
4115 IF (l_unplanned_MRs_tbl.COUNT > 0) THEN
4116 FOR i IN l_unplanned_MRs_tbl.FIRST..l_unplanned_MRs_tbl.LAST LOOP
4117 IF (l_unplanned_MRs_tbl(i).visit_end_date > l_last_due_date AND
4118 l_unplanned_MRs_tbl(i).visit_end_date <= l_next_due_date_rec.due_date) THEN
4119 IF (l_min_visit_date IS NULL) THEN
4120 l_min_visit_date := l_unplanned_MRs_tbl(i).visit_end_date;
4121 ELSIF (l_min_visit_date > l_unplanned_MRs_tbl(i).visit_end_date) THEN
4122 l_min_visit_date := l_unplanned_MRs_tbl(i).visit_end_date;
4123 END IF;
4124 END IF;
4125 END LOOP; -- l_unplanned_MRs_tbl.
4126 END IF; -- Count.
4127
4128 -- Compare dates from ahl_temp_ue_csr and l_min_visit_date.
4129 IF (l_grp_duedate_found) THEN
4130 IF (l_min_visit_date IS NOT NULL) THEN
4131 IF (l_temp_grp_mr_rec.visit_end_date IS NOT NULL) THEN
4132 IF (l_min_visit_date < l_temp_grp_mr_rec.visit_end_date) THEN
4133 l_temp_grp_mr_rec.visit_end_date := l_min_visit_date;
4134 l_temp_grp_mr_rec.due_date := NULL;
4135 END IF;
4136 ELSIF (l_temp_grp_mr_rec.due_date IS NOT NULL) THEN
4137 IF (l_min_visit_date < l_temp_grp_mr_rec.due_date) THEN
4138 l_temp_grp_mr_rec.visit_end_date := l_min_visit_date;
4139 l_temp_grp_mr_rec.due_date := NULL;
4140 END IF;
4141 ELSE -- both due date and visit end dates are null.
4142 l_temp_grp_mr_rec.visit_end_date := l_min_visit_date;
4143 l_temp_grp_mr_rec.due_date := NULL;
4144 END IF;
4145 END IF; -- l_min_visit_date chk.
4146 ELSE
4147 IF (l_min_visit_date IS NOT NULL) THEN
4148 l_temp_grp_mr_rec.visit_end_date := l_min_visit_date;
4149 l_temp_grp_mr_rec.due_date := NULL;
4150 l_grp_duedate_found := TRUE;
4151 /*
4152 -- added to fix bug# 6530920.
4153 -- this is to avoid creation of one child UMP row at the end of the
4154 -- planning window when the child MR and parent MR have the same interval
4155 -- threshold. Next due MR can be individual MR or part of a group MR.
4156 l_next_due_flag := FALSE;
4157 */
4158 END IF;
4159 END IF; -- l_grp_duedate_found.
4160
4161 END IF; -- l_next_due_date_rec.due_date chk.
4162
4163 IF (l_next_due_date_rec.due_date IS NULL AND l_next_due_flag = TRUE and l_next_due_date_rec.FLEET_ASSO_REJECTED = 'N') OR /* no repetivity as due_date is null */
4164 (NOT(l_grp_duedate_found) AND l_next_due_flag = TRUE and l_next_due_date_rec.FLEET_ASSO_REJECTED = 'N') OR
4165 (NOT(l_grp_duedate_found) AND l_next_due_date_rec.due_date IS NOT NULL AND l_next_due_flag = FALSE
4166 AND trunc(l_next_due_date_rec.due_date) <= trunc(nvl(l_mr_termination_date-1,G_last_day_of_window)))
4167 THEN
4168
4169 -- R12:Added following logic to fix bug# 4224867.
4170 l_duplicate_MRs := 1; -- default to create only one occurrence of UMP for a day.
4171
4172 -- find out if multiple UMPs need to be created for a given day.
4173 IF (l_next_due_date_rec.due_date IS NOT NULL AND l_last_due_date = l_next_due_date_rec.due_date
4174 AND l_next_due_date_rec.counter_remain IS NOT NULL AND l_next_due_date_rec.counter_remain > 0)
4175 THEN
4176 IF G_DEBUG = 'Y' THEN
4177 AHL_DEBUG_PUB.Debug('Check Multiple UMPs for due date:' || l_next_due_date_rec.due_date);
4178 AHL_DEBUG_PUB.Debug('Counter Remain:' || l_next_due_date_rec.counter_remain );
4179 END IF;
4180
4181 -- get usage for due date.
4182 get_usage_for_date(l_next_due_date_rec.due_date,
4183 l_next_due_date_rec.ctr_uom_code,
4184 p_counter_rules_tbl,
4185 l_usage_per_day);
4186
4187 l_duplicate_MRs := trunc(l_usage_per_day/l_next_due_date_rec.counter_remain);
4188 IF (l_duplicate_MRs = 0) THEN
4189 l_duplicate_MRs := 1;
4190 END IF;
4191
4192 IF G_DEBUG = 'Y' THEN
4193 AHL_DEBUG_PUB.Debug('get_usage_for_date:' || l_usage_per_day);
4194 AHL_DEBUG_PUB.Debug('l_duplicate_MRs:' || l_duplicate_MRs);
4195 END IF;
4196
4197 END IF; -- l_next_due_date_rec.due_date IS NOT NULL
4198
4199 -- Now loop to create temp unit effectivities l_duplicate_MRs times.
4200 FOR m IN 1..l_duplicate_MRs LOOP
4201 -- R12:End code added to fix bug# 4224867.
4202
4203 -- construct ahl_unit_effectivity record and write into temporary table.
4204 l_new_unit_effectivity_rec := l_new_unit_effectivity_initrec; -- initialise.
4205
4206 -- find the corressponding match in l_unit_effectivity_tbl if exists.
4207 IF (l_old_UE_forecast_found = TRUE) AND (l_unit_effectivity_tbl.EXISTS(l_old_UE_forecast_sequence+1))
4208 THEN
4209
4210 -- loop to find the next individual MR.
4211 LOOP
4212 l_old_UE_forecast_sequence := l_old_UE_forecast_sequence + 1;
4213 IF (l_unit_effectivity_tbl(l_old_UE_forecast_sequence).forecast_sequence is not null) THEN
4214 l_new_unit_effectivity_rec.unit_effectivity_id :=
4215 l_unit_effectivity_tbl(l_old_UE_forecast_sequence).unit_effectivity_id;
4216 -- added for SB Enh. We need to store visit end date for calculating 'terminated_by' and 'initiated_by' dates.
4217 -- we only do for non-group UEs. Group case is handled in process_groupMR procedure
4218 IF NOT(group_check_flag) THEN
4219 l_new_unit_effectivity_rec.visit_end_date := trunc(l_unit_effectivity_tbl(l_old_UE_forecast_sequence).visit_end_date);
4220 END IF;
4221 EXIT; -- matched record found.
4222 ELSIF NOT(l_unit_effectivity_tbl.EXISTS(l_old_UE_forecast_sequence+1)) THEN
4223 l_new_unit_effectivity_rec.unit_effectivity_id := null;
4224 l_old_UE_forecast_sequence := -1;
4225 l_old_UE_forecast_found := FALSE;
4226 EXIT;
4227 END IF;
4228 END LOOP;
4229
4230 ELSE
4231 l_new_unit_effectivity_rec.unit_effectivity_id := null;
4232 l_old_UE_forecast_sequence := -1;
4233 l_old_UE_forecast_found := FALSE;
4234 END IF;
4235
4236
4237 -- Check for tolerance if visit has been assigned.
4238 IF (l_old_UE_forecast_found = TRUE) AND (l_next_due_date_rec.due_date IS NOT NULL) THEN
4239 IF (l_unit_effectivity_tbl(l_old_UE_forecast_sequence).visit_assign_flag = 'Y') THEN
4240 IF l_next_due_date_rec.tolerance_before IS NOT NULL THEN
4241 IF ((trunc(l_unit_effectivity_tbl(l_old_UE_forecast_sequence).visit_end_date))
4242 < trunc(l_next_due_date_rec.earliest_due_date)) THEN
4243 -- tolerance before.
4244 l_next_due_date_rec.tolerance_flag := 'Y';
4245 l_next_due_date_rec.message_code := 'TOLERANCE-BEFORE';
4246
4247 END IF;
4248 END IF;
4249
4250 IF l_next_due_date_rec.tolerance_after IS NOT NULL THEN
4251 IF ((trunc(l_unit_effectivity_tbl(l_old_UE_forecast_sequence).visit_end_date))
4252 > trunc(l_next_due_date_rec.latest_due_date)) THEN
4253 -- tolerance after.
4254 l_next_due_date_rec.tolerance_flag := 'Y';
4255 l_next_due_date_rec.message_code := 'TOLERANCE-EXCEEDED';
4256
4257 END IF;
4258 END IF;
4259 END IF;
4260 END IF;
4261
4262
4263 l_new_unit_effectivity_rec.due_date := l_next_due_date_rec.due_date;
4264 l_new_unit_effectivity_rec.mr_interval_id := l_next_due_date_rec.mr_interval_id;
4265 l_new_unit_effectivity_rec.mr_effectivity_id := l_next_due_date_rec.mr_effectivity_id;
4266 l_new_unit_effectivity_rec.due_counter_value := l_next_due_date_rec.due_at_counter_value;
4267 l_new_unit_effectivity_rec.tolerance_flag := l_next_due_date_rec.tolerance_flag;
4268 l_new_unit_effectivity_rec.tolerance_before := l_next_due_date_rec.tolerance_before;
4269 l_new_unit_effectivity_rec.tolerance_after := l_next_due_date_rec.tolerance_after;
4270 l_new_unit_effectivity_rec.message_code := l_next_due_date_rec.message_code;
4271 l_new_unit_effectivity_rec.csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
4272 l_new_unit_effectivity_rec.mr_header_id := p_applicable_mrs_rec.mr_header_id;
4273 l_new_unit_effectivity_rec.preceding_check_flag:= 'N';
4274 -- Added for ER# 2636001.
4275 l_new_unit_effectivity_rec.earliest_due_date := l_next_due_date_rec.earliest_due_date;
4276 l_new_unit_effectivity_rec.latest_due_date := l_next_due_date_rec.latest_due_date;
4277 -- Added to fix bug#2780716.
4278 l_new_unit_effectivity_rec.counter_id := l_next_due_date_rec.counter_id;
4279 -- JKJain, NR Analysis and Forecasting --Add fleet_id
4280 l_new_unit_effectivity_rec.fleet_header_id := l_next_due_date_rec.fleet_header_id ;
4281
4282
4283 -- increment forecast sequence.
4284 l_forecast_sequence := l_forecast_sequence + 1;
4285 l_new_unit_effectivity_rec.forecast_sequence := l_forecast_sequence;
4286
4287 IF G_DEBUG = 'Y' THEN
4288 AHL_DEBUG_PUB.Debug('New Unit eff:' || l_new_unit_effectivity_rec.unit_effectivity_id);
4289 AHL_DEBUG_PUB.Debug('Old forecast seq:'|| l_old_UE_forecast_sequence);
4290 END IF;
4291
4292 -- set repetivity based on next_due_flag.
4293 IF (l_next_due_flag) THEN
4294 l_new_unit_effectivity_rec.repetitive_mr_flag := 'N';
4295 ELSE
4296 l_new_unit_effectivity_rec.repetitive_mr_flag := 'Y';
4297 END IF;
4298
4299 -- Update preceding MR details.
4300 IF (l_dependent_mr_flag AND l_forecast_sequence = 1) THEN
4301 l_new_unit_effectivity_rec.preceding_mr_header_id := p_applicable_mrs_rec.preceding_mr_header_id;
4302 l_new_unit_effectivity_rec.preceding_csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
4303 l_new_unit_effectivity_rec.preceding_forecast_seq := l_forecast_sequence;
4304 l_dependent_mr_flag := FALSE; -- this is required only for next due.
4305 END IF;
4306
4307 -- added for SB Enh
4308 IF (p_applicable_mrs_rec.accomplish_trigger_type IN ('LOOP','CHAIN')) THEN
4309 l_new_unit_effectivity_rec.loop_chain_seq_num := p_applicable_mrs_rec.loop_chain_seq_num;
4310 l_new_unit_effectivity_rec.accomplish_trigger_type := p_applicable_mrs_rec.accomplish_trigger_type;
4311 l_new_unit_effectivity_rec.start_mr_header_id := p_applicable_mrs_rec.mr_header_id;
4312 l_new_unit_effectivity_rec.start_lc_ue_id := l_new_unit_effectivity_rec.unit_effectivity_id;
4313 IF G_DEBUG = 'Y' THEN
4314 AHL_DEBUG_PUB.Debug('SB Changes:Forecast Seq:Seq Num:Trigger:startMR:' || l_forecast_sequence || ':' || l_new_unit_effectivity_rec.loop_chain_seq_num ||
4315 ':' || l_new_unit_effectivity_rec.accomplish_trigger_type || ':' || l_new_unit_effectivity_rec.start_mr_header_id);
4316 END IF;
4317 END IF;
4318
4319 -- if UE ID belongs to prior mr version, call process_prior_mr
4320 IF (l_old_UE_forecast_found = TRUE AND l_unit_effectivity_tbl(l_old_UE_forecast_sequence).prior_mr_header_id IS NOT NULL) OR
4321 (l_old_UE_forecast_found = TRUE AND p_applicable_mrs_rec.expired_mr_flag = 'Y')
4322 THEN
4323
4324 IF G_DEBUG = 'Y' THEN
4325 AHL_DEBUG_PUB.Debug('Prior MR Header_id:' || l_unit_effectivity_tbl(l_old_UE_forecast_sequence).prior_mr_header_id);
4326 END IF;
4327
4328 -- Process prior grpup MR or independent.
4329 Process_Prior_MR_Version (p_applicable_mrs_rec,
4330 l_new_unit_effectivity_rec,
4331 l_unit_effectivity_tbl,
4332 l_old_UE_forecast_sequence);
4333
4334 -- write into temporary table.
4335 ELSIF NOT(group_check_flag) THEN
4336 -- create record in temporary table.
4337 Create_Temp_Unit_Effectivity (l_new_unit_effectivity_rec);
4338
4339 IF G_DEBUG = 'Y' THEN
4340 AHL_DEBUG_PUB.Debug('After create_temp_unit_effectivity');
4341 END IF;
4342
4343 ELSE
4344 -- Process group MR.
4345 Process_groupMR (p_applicable_mrs_rec,
4346 l_new_unit_effectivity_rec,
4347 l_unit_effectivity_tbl,
4348 l_old_UE_forecast_sequence);
4349 END IF;
4350
4351 -- Added for SB Effectivity Enhancements
4352 -- Process loop or chain child MRs for the start MR's due date.
4353 IF (NOT(group_check_flag) AND (p_applicable_mrs_rec.accomplish_trigger_type IN ('LOOP','CHAIN'))) THEN
4354
4355 IF G_DEBUG = 'Y' THEN
4356 AHL_DEBUG_PUB.Debug('Before call to Process_Loop_Chain_MRs for last due date:' || l_last_due_date);
4357 END IF;
4358 Process_Loop_Chain_MRs (p_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
4359 p_repetivity_flag => 'Y',
4360 p_new_unit_effectivity_rec => l_new_unit_effectivity_rec,
4361 p_current_usage_tbl => p_current_usage_tbl,
4362 p_counter_rules_tbl => p_counter_rules_tbl,
4363 p_last_due_date => l_last_due_date,
4364 p_last_due_counter_val_tbl => l_last_due_counter_val_tbl,
4365 p_loop_chain_MR_tbl => l_lc_mr_tbl,
4366 x_loop_due_date => l_loop_due_date,
4367 x_loop_last_due_date => l_loop_last_due_date,
4368 x_loop_last_counter_val_tbl => l_loop_last_counter_val_tbl
4369 --x_return_status => l_return_status
4370 );
4371
4372 IF G_DEBUG = 'Y' THEN
4373 AHL_DEBUG_PUB.Debug('After call to Process_Loop_Chain_MRs:loop_due_date:' || l_loop_due_date); -- || l_return_status);
4374 END IF;
4375 END IF;
4376
4377 -- Set next due flag to FALSE after writing record into temporary unit_effectivity.
4378 IF (l_next_due_flag) THEN
4379 l_next_due_flag := FALSE;
4380 END IF;
4381
4382 -- Fix for bug# 6858788
4383 l_last_due_mr_interval_id := l_next_due_date_rec.mr_interval_id;
4384
4385 END LOOP; -- m (Duplicate_MRs)
4386 END IF; -- l_next_due_date_rec.due_date IS NULL
4387
4388 /* exit if one next due mr has been calculated and its due date is null
4389 or if next due date is beyond the rolling window date */
4390 -- JKJain, NR Analysis and Forecasting
4391 EXIT WHEN ((l_next_due_flag = FALSE AND l_next_due_date_rec.due_date IS NULL AND l_next_due_date_rec.FLEET_ASSO_REJECTED = 'N') OR
4392 (l_next_due_flag = FALSE AND p_applicable_mrs_rec.show_repetitive_code = 'NEXT') OR
4393 (l_next_due_date_rec.due_date IS NOT NULL AND p_applicable_mrs_rec.expired_mr_flag = 'N'
4394 AND p_applicable_mrs_rec.effective_to IS NOT NULL AND trunc(l_next_due_date_rec.due_date) > trunc(p_applicable_mrs_rec.effective_to)) OR
4395 -- added for bug# 9263774
4396 (l_next_due_date_rec.due_date IS NOT NULL AND p_applicable_mrs_rec.expired_mr_flag = 'Y'
4397 AND NOT(l_unit_effectivity_tbl.EXISTS(l_old_UE_forecast_sequence+1))) OR
4398 (l_next_due_flag = FALSE AND trunc(l_next_due_date_rec.due_date) > trunc(G_last_day_of_window) AND p_applicable_mrs_rec.expired_mr_flag = 'N') OR
4399 (l_mr_termination_date IS NOT NULL AND l_next_due_date_rec.due_date IS NOT NULL
4400 AND trunc(l_next_due_date_rec.due_date) >= trunc(l_mr_termination_date))
4401 -- added for SB Effectivity
4402 OR (p_applicable_mrs_rec.accomplish_trigger_type = 'LOOP' AND l_loop_due_date IS NULL)
4403 );
4404
4405 -- added for accomplish trigger type LOOP for SB rules
4406 IF (p_applicable_mrs_rec.accomplish_trigger_type = 'LOOP') THEN
4407 -- Reset l_last_due_mr_interval_id if duedate based on loop
4408 l_last_due_mr_interval_id := NULL;
4409
4410 l_due_date := l_loop_due_date;
4411 l_last_due_date := l_loop_last_due_date;
4412 l_last_due_counter_val_tbl := l_loop_last_counter_val_tbl;
4413
4414 IF G_DEBUG = 'Y' THEN
4415 AHL_DEBUG_PUB.Debug('Calc Loop dates:l_due_date:l_last_due_date:' || l_due_date || ':' || l_last_due_date);
4416 END IF;
4417
4418 -- JKJain, NR Analysis and Forecasting
4419 ELSIF(l_next_due_date_rec.FLEET_ASSO_REJECTED = 'Y') THEN
4420 l_next_fleet_asso_date := null;
4421 OPEN get_next_fleet_asso_date(l_fleet_asso_rej_date);
4422 FETCH get_next_fleet_asso_date into l_next_fleet_asso_date;
4423 CLOSE get_next_fleet_asso_date;
4424
4425 IF G_DEBUG = 'Y' THEN
4426 AHL_DEBUG_PUB.Debug('l_fleet_asso_rej_date = ' || l_fleet_asso_rej_date);
4427 AHL_DEBUG_PUB.Debug('l_next_fleet_asso_date = ' || l_next_fleet_asso_date);
4428 END IF;
4429
4430 IF(l_next_fleet_asso_date IS NULL) THEN
4431 l_next_due_date_rec.FLEET_ASSO_REJECTED := 'N';
4432 EXIT;
4433 END IF;
4434 -- if on date :l_next_fleet_asso_date, no utilization exists, existing logic may not calculate further UEs.
4435 l_due_date := l_next_fleet_asso_date; -- removed -1, as it was resulting in infinite loop if usage > interval
4436 ELSE
4437 -- Set from l_next_due_date_rec.
4438 l_due_date := l_next_due_date_rec.due_date;
4439
4440 -- If grp MR exists with due date less than calculated date, then re-calculate due date.
4441 IF (l_grp_duedate_found) THEN
4442
4443 -- Set due date to be either visit_end_date or due_date.
4444 IF (l_temp_grp_mr_rec.visit_end_date IS NOT NULL) THEN
4445 l_due_date := l_temp_grp_mr_rec.visit_end_date;
4446 ELSE
4447 l_due_date := l_temp_grp_mr_rec.due_date;
4448 END IF;
4449
4450 -- Fix for bug# 6858788. Reset l_last_due_mr_interval_id if duedate based on group MR.
4451 l_last_due_mr_interval_id := NULL;
4452
4453 IF (G_DEBUG = 'Y') THEN
4454 AHL_DEBUG_PUB.Debug('group due date found');
4455 AHL_DEBUG_PUB.Debug('due date is ' || l_DUE_DATE);
4456 END IF;
4457 ELSE
4458
4459 -- Set values for next repetivity calculation.
4460 IF (l_unit_effectivity_tbl.EXISTS(l_old_UE_forecast_sequence)) THEN
4461 IF (l_unit_effectivity_tbl(l_old_UE_forecast_sequence).visit_assign_flag = 'Y') THEN
4462 l_due_date := l_unit_effectivity_tbl(l_old_UE_forecast_sequence).visit_end_date;
4463 END IF;
4464 END IF; -- l_unit_effectivity_tbl.EXISTS
4465 END IF; -- l_grp_duedate_found
4466 END IF; -- accomplish trigger type
4467
4468 -- If due date is a past date, then set it to sysdate.
4469 -- This will happen only when calculating next-due date.
4470 IF (trunc(l_due_date) < trunc(sysdate)) THEN
4471 l_due_date := sysdate;
4472 END IF;
4473
4474 IF G_DEBUG = 'Y' THEN
4475 AHL_DEBUG_PUB.Debug('Processing for repetivity');
4476 AHL_DEBUG_PUB.Debug('Before get_due_at_counter_values');
4477 AHL_DEBUG_PUB.Debug('l_last_due_date: '|| l_last_due_date);
4478 AHL_DEBUG_PUB.Debug('l_due_date: '|| l_due_date);
4479 IF (l_last_due_counter_val_tbl.COUNT > 0) THEN
4480 FOR i in l_last_due_counter_val_tbl.FIRST..l_last_due_counter_val_tbl.LAST LOOP
4481 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_last_due_counter_val_tbl(i).counter_value || 'ID: ' || l_last_due_counter_val_tbl(i).counter_id);
4482 END LOOP;
4483 END IF;
4484 END IF;
4485
4486 -- get all counter values as on l_due_date.
4487 Get_Due_at_Counter_Values (p_last_due_date => l_last_due_date,
4488 p_last_due_counter_val_tbl => l_last_due_counter_val_tbl,
4489 p_due_date => l_due_date,
4490 p_counter_rules_tbl => p_counter_rules_tbl,
4491 x_due_at_counter_val_tbl => l_due_at_counter_val_tbl,
4492 x_return_value => l_return_value);
4493 l_last_due_date := l_due_date;
4494 l_last_due_counter_val_tbl := l_due_at_counter_val_tbl;
4495
4496 IF G_DEBUG = 'Y' THEN
4497 AHL_DEBUG_PUB.Debug('AFter get_due_at_counter_values');
4498 AHL_DEBUG_PUB.Debug('l_last_due_date: '|| l_last_due_date);
4499 AHL_DEBUG_PUB.Debug('l_due_date: '|| l_due_date);
4500 IF (l_due_at_counter_val_tbl.COUNT) > 0 THEN
4501 for i in l_due_at_counter_val_tbl.FIRST..l_due_at_counter_val_tbl.LAST LOOP
4502 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_due_at_counter_val_tbl(i).counter_value || 'ID: ' || l_due_at_counter_val_tbl(i).counter_id);
4503 end loop;
4504 END IF;
4505 END IF;
4506
4507 IF NOT(l_return_value) THEN
4508 EXIT; /* no forecast available so exit */
4509 END IF;
4510
4511 -- goto used by loop and chain processing.
4512 <<Calculate_Repetivity_DueDate>>
4513
4514 -- Calculate next due date.
4515 Calculate_Due_Date (p_repetivity_flag => 'Y',
4516 p_applicable_mrs_rec => p_applicable_mrs_rec,
4517 p_current_usage_tbl => p_current_usage_tbl,
4518 p_counter_rules_tbl => p_counter_rules_tbl,
4519 p_last_due_date => l_last_due_date,
4520 p_last_due_counter_val_tbl => l_last_due_counter_val_tbl,
4521 p_mr_accomplish_exists => l_mr_accomplish_exists,
4522 p_last_due_mr_interval_id => l_last_due_mr_interval_id,
4523 x_next_due_date_rec => l_next_due_date_rec);
4524
4525 IF G_DEBUG = 'Y' THEN
4526 AHL_DEBUG_PUB.Debug('aft calculate_due_date - repetivity');
4527 AHL_DEBUG_PUB.Debug('due date is ' || l_next_due_date_rec.DUE_DATE);
4528 AHL_DEBUG_PUB.Debug('earliest due date is ' || l_next_due_date_rec.EARLIEST_DUE_DATE);
4529 AHL_DEBUG_PUB.Debug('latest due date is ' || l_next_due_date_rec.latest_due_date);
4530 AHL_DEBUG_PUB.Debug('FLEET_ASSO_REJECTED = ' || l_next_due_date_rec.FLEET_ASSO_REJECTED);
4531 END IF;
4532
4533 -- JKJain, NR Analysis and Forecasting
4534 IF(l_next_due_date_rec.FLEET_ASSO_REJECTED = 'Y' AND l_next_due_date_rec.DUE_DATE IS NOT NULL) THEN
4535 l_fleet_asso_rej_date := l_next_due_date_rec.DUE_DATE;
4536 l_next_due_date_rec.DUE_DATE := null;
4537 END IF;
4538
4539 -- Check if calculated date is same as last due date. If they are the same then, add one day.
4540 IF (l_next_due_date_rec.due_date IS NOT NULL) THEN
4541 IF (trunc(l_last_due_date) = trunc(l_next_due_date_rec.due_date)) THEN
4542 l_next_due_date_rec.due_date := l_next_due_date_rec.due_date + 1;
4543 l_next_due_date_rec.EARLIEST_DUE_DATE := NULL;
4544 l_next_due_date_rec.latest_due_date := NULL;
4545
4546 IF G_DEBUG = 'Y' THEN
4547 AHL_DEBUG_PUB.Debug('Adding one day to l_next_due_date_rec.due_date:' || l_next_due_date_rec.due_date);
4548 END IF;
4549
4550 --IF G_DEBUG = 'Y' THEN
4551 -- AHL_DEBUG_PUB.Debug('Exiting build effectivity as last due = due date');
4552 --END IF;
4553 --EXIT;
4554 END IF;
4555 END IF;
4556
4557 END LOOP;
4558
4559 -- update ahl_applicable MRs table after processing complete.
4560 UPDATE AHL_APPLICABLE_MRS
4561 SET process_status_flag = 'Y',
4562 accomplished_ue_id = l_accomplished_ue_id
4563 WHERE mr_header_id = p_applicable_mrs_rec.mr_header_id
4564 AND csi_item_instance_id = p_applicable_mrs_rec.csi_item_instance_id;
4565
4566
4567 -- Fix for bug# 6711228.
4568 <<process_preceding_mr>>
4569 -- Process preceding MRs.
4570 IF ((p_applicable_mrs_rec.implement_status_code = 'MANDATORY') OR
4571 --(l_mr_accomplish_exists)) THEN
4572 -- changing check from l_mr_accomplish_exists to l_accomplished_ue_id as l_mr_accomplish_exists is true when open deferral exists.
4573 (l_accomplished_ue_id IS NOT NULL)) THEN
4574 Process_PrecedingMR (p_applicable_mrs_rec => p_applicable_mrs_rec,
4575 p_counter_rules_tbl => p_counter_rules_tbl,
4576 p_current_usage_tbl => p_current_usage_tbl);
4577
4578 END IF;
4579
4580 END Build_Effectivity;
4581
4582 --------------------------------------------------------------------------------------
4583 -- Calculate due date for the item instance and mr using current usage, counter rules,
4584 -- last accomplishment counters and forecast (defined in global variable).
4585 -- Added parameter p_dependent_mr_flag to fix bug# 6711228 used when
4586 -- calculating nextdue date.
4587 -- Added parameters p_mr_accomplish_exists and p_last_due_mr_interval_id to fix bug# 6858788.
4588 PROCEDURE Calculate_Due_Date ( p_repetivity_flag IN VARCHAR2 := 'Y',
4589 p_applicable_mrs_rec IN applicable_mrs_rec_type,
4590 p_current_usage_tbl IN counter_values_tbl_type,
4591 p_counter_rules_tbl IN counter_rules_tbl_type,
4592 p_last_due_date IN DATE,
4593 p_last_due_counter_val_tbl IN counter_values_tbl_type,
4594 p_dependent_mr_flag IN BOOLEAN := FALSE,
4595 p_mr_accomplish_exists IN BOOLEAN,
4596 p_last_due_mr_interval_id IN NUMBER := NULL,
4597 x_next_due_date_rec OUT NOCOPY next_due_date_rec_type)
4598
4599 IS
4600
4601 -- Read all effectivities for the mr and item instance.
4602 -- JKJain, NR Analysis and Forecasting
4603 CURSOR ahl_applicable_csr (p_instance_id IN NUMBER,
4604 p_mr_header_id IN NUMBER) IS
4605 SELECT DISTINCT mr.mr_effectivity_id, threshold_date,eff.fleet_header_id
4606 FROM ahl_applicable_mrs mr, ahl_mr_effectivities eff
4607 WHERE mr.mr_effectivity_id = eff.mr_effectivity_id AND
4608 csi_item_instance_id = p_instance_id AND
4609 mr.mr_header_id = p_mr_header_id;
4610
4611 -- read all intervals for the effectivity id.
4612 CURSOR ahl_mr_interval_csr (p_mr_effectivity_id IN NUMBER,
4613 --p_counter_id IN NUMBER,
4614 p_counter_name IN VARCHAR2,
4615 p_counter_value IN NUMBER,
4616 p_start_date IN DATE) IS
4617 SELECT INT.mr_interval_id, INT.start_date, INT.stop_date,
4618 INT.start_value, INT.stop_value, INT.counter_id,
4619 INT.interval_value, INT.tolerance_after, INT.tolerance_before,
4620 INT.earliest_due_value, -- added for bug# 6358940.
4621 INT.calc_duedate_rule_code -- added for ER 7415856
4622 --Replaced cs_counters_v with cs_counters to fix perf bug# 3786647.
4623 --FROM ahl_mr_intervals INT, cs_counters_v CTR, cs_counters_v CN
4624 --replaced cs_counters CTR with csi_counter_template_vl
4625 --and cs_counters CN with csi_counters_vl CN to fix bug# 5918525.
4626 FROM ahl_mr_intervals INT, csi_counter_template_vl CTR --, csi_counters_vl CN
4627 WHERE INT.counter_id = CTR.counter_id AND
4628 --CTR.name = CN.name AND -- bug# 5918525.
4629 --CTR.name = CN.counter_template_name AND -- removed for perf fix.
4630 CTR.name = p_counter_name AND
4631 INT.mr_effectivity_id = p_mr_effectivity_id AND
4632 --CN.counter_id = p_counter_id AND -- removed for perf fix.
4633 (
4634 ( (nvl(start_value, p_counter_value+1) <= p_counter_value AND
4635 --p_counter_value < nvl(stop_value, p_counter_value+1)) OR
4636 -- Fix for bug# 3482307.
4637 p_counter_value <= nvl(stop_value, p_counter_value+1)) OR
4638 (trunc(nvl(start_date, p_start_date+1)) <= trunc(p_start_date) AND
4639 --trunc(p_start_date) < trunc(nvl(stop_date, p_start_date+1)) )
4640 -- Fix for bug# 3482307.
4641 trunc(p_start_date) <= trunc(nvl(stop_date, p_start_date+1)) )
4642 )
4643 OR
4644 /* pick records with no start/stop values/dates. */
4645 (start_value IS NULL AND stop_value IS NULL AND start_date IS NULL AND stop_date IS NULL
4646 AND interval_value IS NOT NULL)
4647 );
4648
4649 -- get the unit effectivity record for init-due for this mr and item.
4650 -- modified query to fix bug# 9264774. Replaced input p_mr_header_id with p_title.
4651 CURSOR ahl_init_due_csr (p_csi_item_instance_id IN NUMBER,
4652 p_title IN VARCHAR2) IS
4653 SELECT ud.set_due_date, ue.unit_effectivity_id, ud.unit_deferral_id
4654 --FROM ahl_unit_effectivities_app_v ue, ahl_unit_deferrals_vl ud
4655 FROM ahl_unit_effectivities_b ue, ahl_unit_deferrals_b ud
4656 WHERE ue.unit_effectivity_id = ud.unit_effectivity_id AND
4657 ud.unit_deferral_type = 'INIT-DUE' AND
4658 ue.csi_item_instance_id = p_csi_item_instance_id AND
4659 ue.mr_header_id IN (select mr_header_id from ahl_mr_headers_b mr where mr.title = p_title) AND
4660 ue.status_code = 'INIT-DUE';
4661
4662 -- get all init-due counter records setup for this unit effectivity.
4663 CURSOR ahl_unit_thresholds_csr (p_unit_deferral_id IN NUMBER) IS
4664 SELECT counter_id, counter_value
4665 FROM ahl_unit_thresholds
4666 WHERE unit_deferral_id = p_unit_deferral_id;
4667
4668 -- added for performance fix bug# 6893404.
4669 CURSOR get_interval_ctr_name(p_mr_effectivity_id IN NUMBER) IS
4670 SELECT DISTINCT name counter_name
4671 FROM ahl_mr_intervals int, csi_counter_template_vl ctr
4672 WHERE int.mr_effectivity_id = p_mr_effectivity_id
4673 AND int.counter_id = ctr.counter_id;
4674
4675 --
4676 DUE_DATE_NULL EXCEPTION ;
4677 NO_VALID_INTERVAL EXCEPTION;
4678
4679 l_next_due_date_rec Next_Due_Date_Rec_Type;
4680
4681 l_due_date DATE; /* due date returned back after forecast calculation */
4682 l_calc_due_date DATE; /* next due date that will be returned by this procedure */
4683 l_adjusted_due_date DATE; /* adjusted due date returned in case of overflow into next interval */
4684 l_adjusted_int_value NUMBER; /* adjusted interval value returned in case of overflow into next interval */
4685 l_nxt_interval_found BOOLEAN;
4686
4687 l_mr_interval_id NUMBER; /* the interval id that triggered this mr due date */
4688 l_due_at_counter_value NUMBER; /* next due counter value */
4689 l_counter_remain NUMBER;
4690 l_mr_interval_found BOOLEAN; /*indicates if at one mr_interval exists for the effectivity */
4691
4692 -- modified to fix bug# 6725769.
4693 --l_old_mr_interval_found BOOLEAN;
4694 l_old_ctr_interval_found BOOLEAN;
4695 -- added to fix bug# 6725769.
4696 l_ctr_interval_found BOOLEAN; -- indicates if a mr interval was found for a counter.
4697
4698 l_temp_counter_tbl counter_values_tbl_type;
4699 l_counter_value NUMBER;
4700 l_current_ctr_value NUMBER;
4701 l_set_due_date DATE;
4702 l_threshold_date DATE;
4703 l_start_date DATE;
4704 l_start_int_match_at_ctr NUMBER; /* interval match start counter value. */
4705
4706 l_mr_interval_rec ahl_mr_interval_csr%ROWTYPE;
4707
4708 l_unit_effectivity_id NUMBER;
4709 k NUMBER; /* for l_temp_counter_tbl */
4710
4711 l_return_val BOOLEAN; -- return status indicator.
4712 l_counter_read_date DATE;
4713 l_unit_deferral_id NUMBER;
4714
4715 l_reset_start_value_flag BOOLEAN;
4716 l_due_counter_tbl counter_values_tbl_type;
4717 l_last_due_counter_tbl counter_values_tbl_type;
4718
4719 l_adjusted_due_ctr NUMBER;
4720
4721 -- added to fix calculation of before and after tolerance dates when
4722 -- uom_remain < 0.
4723 l_calc_due_date_ctr_id NUMBER;
4724
4725 -- added to fix bug# 6358940.
4726 l_reset_start_date_flag BOOLEAN;
4727
4728 -- added to fix perf bug# 6893404.
4729 i NUMBER; -- setting l_temp_counter_tbl index.
4730
4731 -- JKJain, NR Analysis and Forecasting
4732 l_fleet_header_id NUMBER ;
4733 l_earliest_due_date DATE;
4734 l_fleet_reject_due_date DATE;
4735
4736 BEGIN
4737
4738 IF G_DEBUG = 'Y' THEN
4739 AHL_DEBUG_PUB.Debug('In calculate due date');
4740 END IF;
4741
4742 -- Initialize due date.
4743 l_calc_due_date := null;
4744 l_calc_due_date_ctr_id := null;
4745
4746 -- Initialize OUT record.
4747 x_next_due_date_rec := l_next_due_date_rec;
4748 -- JKJain, NR Analysis and Forecasting
4749 x_next_due_date_rec.FLEET_ASSO_REJECTED := 'N';
4750
4751 IF (p_repetivity_flag = 'N') THEN
4752 l_temp_counter_tbl := p_current_usage_tbl;
4753 ELSE
4754 l_temp_counter_tbl := p_last_due_counter_val_tbl;
4755 END IF;
4756
4757 -- Fix for bug# 6358940. Due Date should be based only on init-due if it
4758 -- exists. MR thresholds should not be used.
4759 -- Calculate due date based on init-due defination; if exists.
4760 -- skip init-due check for child loop or chain MRs
4761 IF (p_repetivity_flag = 'N') THEN
4762 --dbms_output.put_line ('in INIT-due part');
4763
4764 -- Check if there is any init-due record for this item instance and mr exists.
4765 OPEN ahl_init_due_csr(p_applicable_mrs_rec.csi_item_instance_id,
4766 --p_applicable_mrs_rec.mr_header_id);
4767 p_applicable_mrs_rec.title);
4768 FETCH ahl_init_due_csr INTO l_set_due_date, l_unit_effectivity_id, l_unit_deferral_id;
4769 IF (ahl_init_due_csr%FOUND) THEN
4770
4771 IF G_DEBUG = 'Y' THEN
4772 AHL_DEBUG_PUB.Debug('INIT-Due processing: Set due_date:UE_ID:' || l_set_due_date || ':' || l_unit_effectivity_id);
4773 END IF;
4774 --dbms_output.put_line ('in INIT-due part: due_date' || l_set_due_date);
4775
4776 FOR threshold_rec IN ahl_unit_thresholds_csr (l_unit_deferral_id)
4777 LOOP
4778 -- for init due, ctr_value_type_code is always 'defer_to'.
4779 l_due_at_counter_value := threshold_rec.counter_value;
4780 l_counter_remain := 0;
4781 l_current_ctr_value := 0;
4782 k := 0;
4783 -- search for the current counter value in l_current_usage_tbl.
4784 IF (l_temp_counter_tbl.COUNT > 0) THEN
4785 FOR i IN l_temp_counter_tbl.FIRST..l_temp_counter_tbl.LAST LOOP
4786 IF (l_temp_counter_tbl(i).counter_id = threshold_rec.counter_id) THEN
4787 l_current_ctr_value := l_temp_counter_tbl(i).counter_value;
4788 k := i;
4789 EXIT;
4790 END IF;
4791 END LOOP;
4792 l_counter_remain := l_due_at_counter_value - l_current_ctr_value;
4793 END IF;
4794
4795 -- calculate due date from forecast.
4796 IF (l_counter_remain > 0) THEN
4797 -- get date from forecast.
4798 get_date_from_uf(l_counter_remain,
4799 l_temp_counter_tbl(k).uom_code,
4800 p_counter_rules_tbl,
4801 null, -- start date = sysdate
4802 l_due_date);
4803 ELSIF (l_counter_remain < 0) THEN
4804 -- Due date = counter reading date.
4805 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
4806 p_counter_id => l_temp_counter_tbl(k).counter_id,
4807 p_counter_value => l_due_at_counter_value,
4808 x_ctr_record_date => l_counter_read_date,
4809 x_return_val => l_return_val);
4810
4811 IF NOT(l_return_val) THEN
4812 l_due_date := sysdate;
4813 ELSE
4814 l_due_date := l_counter_read_date;
4815 END IF;
4816
4817 ELSIF (l_counter_remain = 0) THEN -- due_date = sysdate
4818 --dbms_output.put_line ('counter remain less than zero');
4819 l_due_date := sysdate;
4820 END IF;
4821
4822 -- Compare with whichever first code and set l_calc_due_date.
4823 IF (l_due_date IS NULL) THEN
4824 -- Added to fix bug# 6907562.
4825 IF (validate_for_duedate_reset(l_due_date,
4826 l_counter_remain,
4827 l_calc_due_date,
4828 l_calc_due_date_ctr_id,
4829 x_next_due_date_rec.counter_remain)) = 'Y' THEN
4830
4831 --dbms_output.put_line ('due date null');
4832 l_calc_due_date := l_due_date;
4833 x_next_due_date_rec.due_date := null;
4834 x_next_due_date_rec.tolerance_after := null;
4835 x_next_due_date_rec.tolerance_before := null;
4836 x_next_due_date_rec.mr_interval_id := null;
4837 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
4838 x_next_due_date_rec.mr_effectivity_id := null;
4839 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
4840 x_next_due_date_rec.last_ctr_value := null;
4841 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
4842 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
4843 x_next_due_date_rec.counter_remain := l_counter_remain;
4844 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
4845 -- fix for bug# 6907562. Loop to next threshold when due date is null.
4846 --EXIT;
4847 END IF;
4848 ELSE
4849 IF (l_calc_due_date IS NULL) THEN
4850 -- Added to fix bug# 6907562.
4851 IF (validate_for_duedate_reset(l_due_date,
4852 l_counter_remain,
4853 l_calc_due_date,
4854 l_calc_due_date_ctr_id,
4855 x_next_due_date_rec.counter_remain)) = 'Y' THEN
4856 --dbms_output.put_line ('calc due date null');
4857 l_calc_due_date := l_due_date;
4858 x_next_due_date_rec.due_date := l_due_date;
4859 x_next_due_date_rec.tolerance_after := null;
4860 x_next_due_date_rec.tolerance_before := null;
4861 x_next_due_date_rec.mr_interval_id := null;
4862 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
4863 x_next_due_date_rec.mr_effectivity_id := null;
4864 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
4865 x_next_due_date_rec.last_ctr_value := null;
4866 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
4867 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
4868 x_next_due_date_rec.counter_remain := l_counter_remain;
4869 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
4870 END IF;
4871 ELSE
4872 IF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
4873 -- Check due date based on whichever_first_code.
4874 -- if dates are equal, switch based on lower uom remain value. (bug# 6907562).
4875 IF (l_calc_due_date > l_due_date) OR
4876 (trunc(l_calc_due_date) = trunc(l_due_date) AND l_counter_remain IS NOT NULL
4877 AND x_next_due_date_rec.counter_remain IS NOT NULL
4878 AND l_counter_remain < x_next_due_date_rec.counter_remain) THEN
4879 l_calc_due_date := l_due_date;
4880 x_next_due_date_rec.due_date := l_due_date;
4881 x_next_due_date_rec.tolerance_after := null;
4882 x_next_due_date_rec.tolerance_before := null;
4883 x_next_due_date_rec.mr_interval_id := null;
4884 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
4885 x_next_due_date_rec.mr_effectivity_id := null;
4886 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
4887 x_next_due_date_rec.last_ctr_value := null;
4888 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
4889 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
4890 x_next_due_date_rec.counter_remain := l_counter_remain;
4891 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
4892
4893 END IF;
4894 ELSE -- whichever_first_code = 'LAST'
4895 -- if dates are equal, switch based on higher uom remain value. (bug# 6907562).
4896 IF (l_calc_due_date < l_due_date) OR
4897 (trunc(l_calc_due_date) = trunc(l_due_date) AND l_counter_remain IS NOT NULL
4898 AND x_next_due_date_rec.counter_remain IS NOT NULL
4899 AND l_counter_remain > x_next_due_date_rec.counter_remain) THEN
4900 --dbms_output.put_line ('set due date');
4901 l_calc_due_date := l_due_date;
4902 x_next_due_date_rec.due_date := l_due_date;
4903 x_next_due_date_rec.tolerance_after := null;
4904 x_next_due_date_rec.tolerance_before := null;
4905 x_next_due_date_rec.mr_interval_id := null;
4906 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
4907 x_next_due_date_rec.mr_effectivity_id := null;
4908 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
4909 x_next_due_date_rec.last_ctr_value := null;
4910 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
4911 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
4912 x_next_due_date_rec.counter_remain := l_counter_remain;
4913 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
4914
4915 END IF;
4916 END IF; -- applicable_mrs_rec
4917 END IF; -- calc_due_date null
4918 END IF; -- l_due_date IS NULL
4919 END LOOP; -- set_threshold_rec
4920
4921 -- Check for set due date.
4922 IF (l_set_due_date IS NOT NULL) THEN
4923 IF (l_calc_due_date IS NULL) THEN
4924 -- added to fix bug# 6907562.
4925 -- reset only when l_calc_due_date_ctr_id is also null.
4926 IF (l_calc_due_date_ctr_id IS NULL) THEN
4927 l_calc_due_date := l_set_due_date;
4928 x_next_due_date_rec.due_date := l_set_due_date;
4929 x_next_due_date_rec.tolerance_after := null;
4930 x_next_due_date_rec.tolerance_before := null;
4931 x_next_due_date_rec.mr_effectivity_id := null;
4932 x_next_due_date_rec.due_at_counter_value := null;
4933 x_next_due_date_rec.current_ctr_value := null;
4934 x_next_due_date_rec.last_ctr_value := null;
4935 x_next_due_date_rec.mr_interval_id := null;
4936 x_next_due_date_rec.ctr_uom_code := null;
4937 x_next_due_date_rec.counter_id := null;
4938 x_next_due_date_rec.counter_remain := null;
4939 l_calc_due_date_ctr_id := null;
4940 END IF;
4941 ELSE
4942 IF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
4943 IF (l_calc_due_date > l_set_due_date) THEN
4944 --dbms_output.put_line ('set due da te');
4945 l_calc_due_date := l_set_due_date;
4946 x_next_due_date_rec.due_date := l_set_due_date;
4947 x_next_due_date_rec.tolerance_after := null;
4948 x_next_due_date_rec.tolerance_before := null;
4949 x_next_due_date_rec.mr_interval_id := null;
4950 x_next_due_date_rec.due_at_counter_value := null;
4951 x_next_due_date_rec.mr_effectivity_id := null;
4952 x_next_due_date_rec.current_ctr_value := null;
4953 x_next_due_date_rec.last_ctr_value := null;
4954 x_next_due_date_rec.ctr_uom_code := null;
4955 x_next_due_date_rec.counter_id := null;
4956 x_next_due_date_rec.counter_remain := null;
4957 l_calc_due_date_ctr_id := null;
4958
4959 END IF;
4960 ELSE
4961 -- Check for set due date.
4962 IF (l_calc_due_date < l_set_due_date) THEN
4963 l_calc_due_date := l_set_due_date;
4964 x_next_due_date_rec.due_date := l_set_due_date;
4965 x_next_due_date_rec.tolerance_after := null;
4966 x_next_due_date_rec.tolerance_before := null;
4967 x_next_due_date_rec.mr_interval_id := null;
4968 x_next_due_date_rec.due_at_counter_value := null;
4969 x_next_due_date_rec.mr_effectivity_id := null;
4970 x_next_due_date_rec.current_ctr_value := null;
4971 x_next_due_date_rec.last_ctr_value := null;
4972 x_next_due_date_rec.ctr_uom_code := null;
4973 x_next_due_date_rec.counter_id := null;
4974 x_next_due_date_rec.counter_remain := null;
4975 l_calc_due_date_ctr_id := null;
4976
4977 END IF;
4978 END IF; -- applicable
4979 END IF;
4980 END IF; -- set due date
4981 -- If due date is less than sysdate, then flag tolerance.
4982 IF (x_next_due_date_rec.due_date IS NOT NULL) AND
4983 (trunc(x_next_due_date_rec.due_date) < trunc(sysdate)) THEN
4984 x_next_due_date_rec.tolerance_flag := 'Y';
4985 x_next_due_date_rec.message_code := 'TOLERANCE-EXCEEDED';
4986 END IF;
4987 CLOSE ahl_init_due_csr;
4988 RETURN; -- exit calculation.
4989 END IF; -- init_due_csr
4990 CLOSE ahl_init_due_csr;
4991 END IF; -- repetitive_flag
4992
4993 -- Loop through each effectivity record.
4994 <<mr_effectivity_loop>>
4995 FOR effectivity_rec IN ahl_applicable_csr(p_applicable_mrs_rec.csi_item_instance_id,
4996 p_applicable_mrs_rec.mr_header_id)
4997 LOOP
4998
4999 IF G_DEBUG = 'Y' THEN
5000 AHL_DEBUG_PUB.Debug('eff ID' || effectivity_rec.mr_effectivity_id );
5001 END IF;
5002
5003 l_threshold_date := effectivity_rec.threshold_date;
5004 l_mr_interval_found := FALSE;
5005 -- JKJain, NR Analysis and Forecasting
5006 l_fleet_header_id := effectivity_rec.fleet_header_id;
5007
5008 --l_old_mr_interval_found := FALSE;
5009
5010 -- Loop through all counters in l_temp_counter_tbl.
5011 IF (l_temp_counter_tbl.COUNT > 0) THEN
5012
5013 -- instead of looping through all counters, loop through interval counters
5014 -- and match counter name in l_temp_counter_tbl and set index i.
5015 --FOR i IN l_temp_counter_tbl.FIRST..l_temp_counter_tbl.LAST LOOP
5016
5017 FOR ctr_name_rec IN get_interval_ctr_name(effectivity_rec.mr_effectivity_id) LOOP
5018 -- set l_temp_counter_tbl row for matching counter.
5019 i := -1;
5020
5021 FOR k IN l_temp_counter_tbl.FIRST..l_temp_counter_tbl.LAST LOOP
5022 IF (l_temp_counter_tbl(k).counter_name = ctr_name_rec.counter_name) THEN
5023 i := k;
5024 EXIT;
5025 END IF;
5026 END LOOP;
5027
5028 -- if no match for interval counter then
5029 -- proceed to next counter.
5030 IF (i = -1) THEN
5031 GOTO next_counter_loop;
5032 END IF;
5033
5034 -- Added for fix 6725769.
5035 l_ctr_interval_found := FALSE;
5036 l_old_ctr_interval_found := FALSE;
5037
5038 -- find the counter value from p_last_due_counter_val_tbl
5039 -- for this counter id.
5040 IF (p_repetivity_flag = 'N') THEN
5041 -- set current ctr value from l_current_usage_tbl.
5042 l_start_date := sysdate; /* interval start/stop dates validation on sysdate */
5043 l_current_ctr_value := l_temp_counter_tbl(i).counter_value;
5044 l_counter_value := 0; /* initialize last due counter value */
5045
5046 IF (p_last_due_counter_val_tbl.COUNT > 0) THEN
5047 --dbms_output.put_line ('in last due counter loop-count'||p_last_due_counter_val_tbl.COUNT );
5048 FOR j IN p_last_due_counter_val_tbl.FIRST..p_last_due_counter_val_tbl.LAST
5049 LOOP
5050 --dbms_output.put_line ('in last due counter loop');
5051 IF (p_last_due_counter_val_tbl(j).counter_id = l_temp_counter_tbl(i).counter_id) THEN
5052 -- counter value will be just from last due.
5053 l_counter_value := p_last_due_counter_val_tbl(j).counter_value;
5054
5055 -- start interval matching at last accomplishment data as it is available.
5056 l_start_int_match_at_ctr := l_counter_value;
5057 END IF;
5058 END LOOP;
5059 ELSE
5060 -- start interval matching at current counter value as last accomplishment data
5061 -- is not available.
5062 l_start_int_match_at_ctr := l_current_ctr_value;
5063 END IF; /* count > 0 */
5064 --dbms_output.put_line ('SKR_counter_value' || l_counter_value);
5065 ELSE
5066 -- For repetity, set current_ctr_value to zero.
5067 -- Set l_counter_value from l_temp_counter_tbl.
5068 l_counter_value := l_temp_counter_tbl(i).counter_value;
5069 l_current_ctr_value := 0; /* initialize current usage on counter */
5070 l_start_date := p_last_due_date; /* interval start/stop dates validation on last due date */
5071
5072 -- For repetity, l_start_int_match_at_ctr is last counter value.
5073 l_start_int_match_at_ctr := l_counter_value;
5074
5075 END IF; /* repetivity */
5076
5077 --dbms_output.put_line ('CounterID' || l_temp_counter_tbl(i).counter_id);
5078 --dbms_output.put_line ('counter_value' || l_counter_value);
5079
5080 -- For each effectivity, loop through mr intervals.
5081 FOR mr_interval_rec IN ahl_mr_interval_csr(effectivity_rec.mr_effectivity_id,
5082 --l_temp_counter_tbl(i).counter_id,
5083 l_temp_counter_tbl(i).counter_name,
5084 l_start_int_match_at_ctr,
5085 l_start_date)
5086 LOOP
5087
5088 -- reset loop variables.
5089 l_old_ctr_interval_found := l_ctr_interval_found;
5090 l_reset_start_value_flag := FALSE;
5091 l_reset_start_date_flag := FALSE;
5092
5093 -- added to fix bug# 6725769
5094 IF NOT(l_ctr_interval_found) THEN
5095 l_ctr_interval_found := TRUE; /* found a interval. */
5096 END IF;
5097
5098 --l_mr_interval_found := TRUE; /* found a interval. */
5099 l_mr_interval_rec := mr_interval_rec;
5100
5101 IF G_DEBUG = 'Y' THEN
5102 AHL_DEBUG_PUB.Debug('In interval table loop');
5103 AHL_DEBUG_PUB.Debug('mr interval:' || l_mr_interval_rec.mr_interval_id );
5104 AHL_DEBUG_PUB.Debug('start value:' ||l_mr_interval_rec.start_value);
5105 AHL_DEBUG_PUB.Debug('stop value:' ||l_mr_interval_rec.stop_value);
5106 AHL_DEBUG_PUB.Debug('start date:' ||l_mr_interval_rec.start_date);
5107 AHL_DEBUG_PUB.Debug('stop date:' ||l_mr_interval_rec.stop_date);
5108 AHL_DEBUG_PUB.Debug('Interval Value:' ||l_mr_interval_rec.interval_value);
5109 AHL_DEBUG_PUB.Debug('tolerance bef:' ||l_mr_interval_rec.tolerance_before);
5110 AHL_DEBUG_PUB.Debug('tolerance aft:' ||l_mr_interval_rec.tolerance_after);
5111 AHL_DEBUG_PUB.Debug('earliest_due_value:' ||l_mr_interval_rec.earliest_due_value);
5112 AHL_DEBUG_PUB.Debug('CounterID:' || l_temp_counter_tbl(i).counter_id);
5113 AHL_DEBUG_PUB.Debug('CounterName:' || l_temp_counter_tbl(i).counter_name);
5114 AHL_DEBUG_PUB.Debug('counter_value:' || l_counter_value);
5115 AHL_DEBUG_PUB.Debug('current ctr:' ||l_current_ctr_value);
5116 END IF;
5117
5118 l_counter_remain := 0; /* initialize */
5119
5120 l_due_at_counter_value := l_mr_interval_rec.interval_value + l_counter_value;
5121
5122 -- dbms_output.put_line ('SKR_due_at_counter_value' || l_due_at_counter_value);
5123 -- Added for bug# 6358940(start_value).
5124 -- if at least one MR is accomplished and earliest_due_value is defined.
5125 -- (SB Enh) IF (p_last_due_date IS NOT NULL AND p_repetivity_flag = 'N' AND
5126 IF (p_mr_accomplish_exists AND p_repetivity_flag = 'N' AND
5127 mr_interval_rec.start_value IS NOT NULL AND
5128 p_dependent_mr_flag = FALSE) THEN
5129 IF (l_mr_interval_rec.earliest_due_value IS NOT NULL) THEN
5130 IF (l_counter_value < l_mr_interval_rec.earliest_due_value) THEN
5131 l_due_at_counter_value := l_mr_interval_rec.start_value;
5132 l_reset_start_value_flag := TRUE;
5133 END IF;
5134 END IF;
5135 -- fix for bug#6711228(issue described in problem#2).
5136 -- l_counter_value for this case contains the counter value as of
5137 -- preceding MR's due date so we need to handle this seperately.
5138 ELSIF (p_repetivity_flag = 'N' AND p_dependent_mr_flag = TRUE AND
5139 mr_interval_rec.start_value IS NOT NULL) THEN
5140 -- Added for ER 7415856
5141 -- if rule code is set as INTERVAL
5142 IF (l_mr_interval_rec.calc_duedate_rule_code = 'INTERVAL') THEN
5143 l_due_at_counter_value := l_mr_interval_rec.start_value + l_mr_interval_rec.interval_value;
5144 l_reset_start_value_flag := TRUE;
5145 ELSE
5146 l_due_at_counter_value := l_mr_interval_rec.start_value;
5147 l_reset_start_value_flag := TRUE;
5148 END IF;
5149 ELSE
5150 -- Check if due counter less than start value or start date. If yes, set it
5151 -- to start value.
5152 IF (l_mr_interval_rec.start_value IS NOT NULL) THEN
5153 IF (l_counter_value < l_mr_interval_rec.start_value) THEN
5154 -- Added for ER 7415856
5155 -- if rule code is set as INTERVAL then add interval to due counter value.
5156 IF (l_mr_interval_rec.calc_duedate_rule_code = 'INTERVAL') THEN
5157 l_due_at_counter_value := l_mr_interval_rec.start_value + l_mr_interval_rec.interval_value;
5158 l_reset_start_value_flag := TRUE;
5159 ELSE
5160 l_due_at_counter_value := l_mr_interval_rec.start_value;
5161 l_reset_start_value_flag := TRUE;
5162 END IF;
5163 END IF;
5164 END IF;
5165 END IF;
5166
5167 -- dbms_output.put_line ('SKR1_due_at_counter_value' || l_due_at_counter_value);
5168 -- Added for bug# 6358940(start_date).
5169 IF (p_repetivity_flag = 'N') AND (mr_interval_rec.start_date IS NOT NULL) THEN
5170 -- (SB Enh) IF (p_last_due_date IS NOT NULL AND p_dependent_mr_flag = FALSE) THEN
5171 IF (p_mr_accomplish_exists AND p_dependent_mr_flag = FALSE) THEN
5172 -- MR accomplished
5173 IF (mr_interval_rec.earliest_due_value IS NOT NULL) THEN
5174 IF (l_counter_value < mr_interval_rec.earliest_due_value) THEN
5175 l_due_date := mr_interval_rec.start_date;
5176 l_reset_start_date_flag := TRUE;
5177 END IF;
5178 END IF;
5179 ELSE -- no accomplishment. first time MR must be done on start date.
5180 l_due_date := mr_interval_rec.start_date;
5181 l_reset_start_date_flag := TRUE;
5182 END IF;
5183
5184 -- dbms_output.put_line ('SKR2_due_at_counter_value' || l_due_at_counter_value);
5185 -- calculate due counter value.
5186 IF (l_reset_start_date_flag) THEN
5187 IF (l_due_date < trunc(sysdate)) THEN
5188 get_ctr_reading_for_date (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
5189 p_counter_id => l_temp_counter_tbl(i).counter_id,
5190 p_reading_date => l_due_date,
5191 x_net_reading => l_due_at_counter_value);
5192
5193 ELSIF (l_due_date = trunc(sysdate)) THEN
5194 -- current counter value.
5195 l_due_at_counter_value := l_temp_counter_tbl(i).counter_value;
5196 ELSE
5197 -- calculate due counter value.
5198 l_last_due_counter_tbl(1) := l_temp_counter_tbl(i); -- current ctr
5199
5200 -- before the due counter value.
5201 Get_Due_At_Counter_Values (p_last_due_date => p_last_due_date,
5202 p_last_due_counter_val_tbl => l_last_due_counter_tbl,
5203 p_due_date => l_due_date,
5204 p_counter_rules_tbl => p_counter_rules_tbl,
5205 x_due_at_counter_val_tbl => l_due_counter_tbl,
5206 x_return_value => l_return_val);
5207
5208 -- if forecast not setup, cannot calculate due counter value for
5209 -- start date.
5210 IF NOT(l_return_val) THEN
5211 l_due_date := NULL;
5212 RAISE DUE_DATE_NULL;
5213 ELSE
5214 l_due_at_counter_value := l_due_counter_tbl(1).counter_value;
5215 END IF;
5216
5217 END IF; -- l_due_date < trunc(sysdate)
5218
5219 -- dbms_output.put_line ('SKR3_due_at_counter_value' || l_due_at_counter_value);
5220 -- Added for ER 7415856
5221 IF (l_mr_interval_rec.calc_duedate_rule_code = 'INTERVAL') THEN
5222 l_due_at_counter_value := l_due_at_counter_value + l_mr_interval_rec.interval_value;
5223 l_reset_start_date_flag := FALSE; -- need to calculate new due date.
5224 END IF;
5225 END IF; -- (l_reset_start_date_flag)
5226
5227 END IF; -- p_repetivity_flag = 'N') AND ..
5228
5229 --dbms_output.put_line ('due at counter' || l_due_at_counter_value );
5230
5231 -- Check for interval value overflow.
5232 IF (mr_interval_rec.stop_value IS NOT NULL) THEN
5233 --IF (l_due_at_counter_value >= mr_interval_rec.stop_value) THEN
5234 -- Fix for bug# 3482307.
5235 IF (l_due_at_counter_value > mr_interval_rec.stop_value) THEN
5236
5237 Adjust_Interval_Value (p_mr_effectivity_id => effectivity_rec.mr_effectivity_id,
5238 p_counter_id => l_temp_counter_tbl(i).counter_id,
5239 p_counter_value => l_counter_value,
5240 p_interval_value => mr_interval_rec.interval_value,
5241 p_stop_value => mr_interval_rec.stop_value,
5242 x_adjusted_int_value => l_adjusted_int_value,
5243 x_nxt_interval_found => l_nxt_interval_found);
5244 -- Fix for bug# 3461118.
5245 IF NOT(l_nxt_interval_found) THEN
5246 IF (l_ctr_interval_found = TRUE AND l_old_ctr_interval_found = FALSE) THEN
5247 l_ctr_interval_found := FALSE;
5248 END IF;
5249 GOTO next_mr_interval_loop;
5250 ELSE
5251 l_due_at_counter_value := l_adjusted_int_value + l_counter_value;
5252 END IF;
5253 END IF;
5254 END IF;
5255
5256
5257 IF (p_repetivity_flag = 'N') THEN
5258 l_counter_remain := l_due_at_counter_value - l_current_ctr_value;
5259 ELSE
5260 l_counter_remain := l_due_at_counter_value - l_counter_value;
5261 END IF;
5262
5263 --dbms_output.put_line ('counter remain' || l_counter_remain );
5264
5265 IF G_DEBUG = 'Y' THEN
5266 AHL_DEBUG_PUB.Debug('due at counter_value:' || l_due_at_counter_value);
5267 AHL_DEBUG_PUB.Debug('counter remain:' || l_counter_remain);
5268 END IF;
5269
5270 -- if due date already set based on start date then skip date calculation.
5271 IF NOT(l_reset_start_date_flag) THEN
5272 -- calculate due date based on forecast.
5273 IF (l_counter_remain > 0) THEN
5274 -- get date from forecast.
5275 get_date_from_uf(l_counter_remain,
5276 l_temp_counter_tbl(i).uom_code,
5277 p_counter_rules_tbl,
5278 l_start_date,
5279 --null, /* start date = sysdate */
5280 l_due_date);
5281
5282 --dbms_output.put_line ('due date by forecast' || l_due_date );
5283
5284 ELSIF (l_counter_remain < 0) THEN
5285 -- Due date = counter reading date.
5286 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
5287 p_counter_id => l_temp_counter_tbl(i).counter_id,
5288 p_counter_value => l_due_at_counter_value,
5289 x_ctr_record_date => l_counter_read_date,
5290 x_return_val => l_return_val);
5291
5292 IF NOT(l_return_val) THEN
5293 l_due_date := sysdate;
5294 ELSE
5295 l_due_date := l_counter_read_date;
5296 END IF;
5297
5298 ELSIF (l_counter_remain = 0) THEN /* due_date = sysdate */
5299 --dbms_output.put_line ('counter remain less than zero');
5300 l_due_date := sysdate;
5301 END IF;
5302 END IF; -- l_reset_start_date_flag
5303
5304 /* commented out to fix bug# 6907562
5305 -- Check the due date value.
5306 IF (l_due_date IS NULL) THEN
5307 RAISE DUE_DATE_NULL;
5308 END IF;
5309 */
5310
5311 -- Check Due date overflow to next interval.
5312 IF (mr_interval_rec.stop_date IS NOT NULL) THEN
5313 IF (l_due_date > mr_interval_rec.stop_date) THEN
5314
5315 -- Call procedure to adjust due date.
5316 Adjust_Due_Date ( p_mr_effectivity_id => effectivity_rec.mr_effectivity_id,
5317 p_start_counter_rec => l_temp_counter_tbl(i),
5318 p_start_due_date => p_last_due_date,
5319 p_counter_rules_tbl => p_counter_rules_tbl,
5320 p_interval_value => mr_interval_rec.interval_value,
5321 p_stop_date => mr_interval_rec.stop_date,
5322 p_due_date => l_due_date,
5323 x_adjusted_due_date => l_adjusted_due_date,
5324 x_adjusted_due_ctr => l_adjusted_due_ctr,
5325 x_nxt_interval_found => l_nxt_interval_found);
5326
5327 -- Fix for bug# 3461118.
5328 IF NOT(l_nxt_interval_found) THEN
5329 IF (l_ctr_interval_found = TRUE AND l_old_ctr_interval_found = FALSE) THEN
5330 l_ctr_interval_found := FALSE;
5331 END IF;
5332 GOTO next_mr_interval_loop;
5333 ELSE
5334 IF (l_due_date <> l_adjusted_due_date) THEN
5335 l_due_at_counter_value := l_adjusted_due_ctr + l_counter_value;
5336 END IF;
5337 l_due_date := l_adjusted_due_date;
5338 END IF;
5339 --dbms_output.put_line ('adjusted_due_date' || l_due_date );
5340
5341 END IF;
5342 END IF;
5343
5344 -- JKJain, NR Analysis and Forecasting
5345 IF G_DEBUG = 'Y' THEN
5346 AHL_DEBUG_PUB.Debug('JKJ- G_UC_HEADER_ID :' || G_UC_HEADER_ID || ' and l_due_date = '|| l_due_date);
5347 AHL_DEBUG_PUB.Debug('JKJ- effectivity_rec.fleet_header_id = ' || l_fleet_header_id);
5348 END IF;
5349
5350 --Verify if due date is in fleet-unit asscociation
5351 IF(l_fleet_header_id is NOT NULL) THEN
5352 IF (G_UC_HEADER_ID is NOT NULL AND l_due_date IS NOT NULL) THEN
5353 IF (l_fleet_header_id <> nvl(get_fleet_from_unit_asso(G_UC_HEADER_ID,l_due_date,G_SIMULATION_PLAN_ID),-1)) THEN
5354
5355 IF(l_fleet_reject_due_date IS NULL) THEN
5356 l_fleet_reject_due_date := l_due_date;
5357 ELSIF (l_fleet_reject_due_date > l_due_date) THEN
5358 l_fleet_reject_due_date := l_due_date;
5359 END IF;
5360
5361 --calculate earliest due date and verify the same.
5362 IF l_mr_interval_rec.tolerance_before IS NOT NULL THEN
5363 -- Not required: If due date is today's date then earliest due = due date.
5364 IF (l_due_date IS NOT NULL) THEN
5365 IF (p_repetivity_flag = 'N') THEN
5366 l_counter_remain := (l_due_at_counter_value -
5367 l_mr_interval_rec.tolerance_before) - l_current_ctr_value;
5368 ELSE
5369 l_counter_remain := (l_due_at_counter_value -
5370 l_mr_interval_rec.tolerance_before) -
5371 l_counter_value;
5372 END IF;
5373
5374 IF (l_counter_remain < 0) THEN
5375 -- Due date = counter reading date.
5376 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
5377 p_counter_id => l_calc_due_date_ctr_id,
5378 p_counter_value => l_due_at_counter_value -
5379 l_mr_interval_rec.tolerance_before,
5380 x_ctr_record_date => l_counter_read_date,
5381 x_return_val => l_return_val);
5382 IF NOT(l_return_val) THEN
5383 l_earliest_due_date := null;
5384 ELSE
5385 l_earliest_due_date := l_counter_read_date;
5386 END IF;
5387 -- if earliest_due_date > due date (when no counters readings exist before counter remain).
5388 IF (l_earliest_due_date > l_due_date) THEN
5389 l_earliest_due_date := l_due_date;
5390 END IF;
5391
5392 ELSE /* counter_remain > 0 */
5393 -- get date from forecast.
5394 get_date_from_uf(l_counter_remain,
5395 l_temp_counter_tbl(i).uom_code,
5396 p_counter_rules_tbl,
5397 l_start_date,
5398 l_earliest_due_date);
5399 END IF; -- counter_remain.
5400
5401 END IF; -- due date is not null.
5402 END IF; -- tolerance before.
5403
5404
5405 IF(l_earliest_due_date IS NOT NULL and l_earliest_due_date < l_due_date) THEN
5406 IF (l_fleet_header_id <> nvl(get_fleet_from_unit_asso(G_UC_HEADER_ID,l_earliest_due_date,G_SIMULATION_PLAN_ID),-1)) THEN
5407 IF (l_ctr_interval_found = TRUE AND l_old_ctr_interval_found = FALSE) THEN
5408 l_ctr_interval_found := FALSE;
5409 x_next_due_date_rec.FLEET_ASSO_REJECTED := 'Y';
5410 END IF;
5411 GOTO next_mr_interval_loop;
5412 END IF;
5413 ELSE
5414 x_next_due_date_rec.FLEET_ASSO_REJECTED := 'Y';
5415 l_ctr_interval_found := l_old_ctr_interval_found;
5416 GOTO next_mr_interval_loop;
5417 END IF;
5418 END IF;
5419 ELSE
5420 GOTO next_mr_interval_loop;
5421 END IF;
5422 END IF; --l_fleet_header_id is NOT NULL
5423
5424
5425 /* fix for bug# 6858788: this causes next repetity to be over
5426 * interval value
5427 -- Call Get_Due_At_Counter_Values only if due date is a future date.
5428 IF (l_reset_start_value_flag) AND (trunc(l_due_date) > trunc(sysdate)) THEN
5429 -- Check if the counter value on the due date is less than the due counter value.
5430 -- If less, add a day to the due date. This would ensure that the MR is performed not
5431 -- before due date.
5432 l_last_due_counter_tbl(1) := l_temp_counter_tbl(i);
5433
5434 -- before the due counter value.
5435 Get_Due_At_Counter_Values (p_last_due_date => p_last_due_date,
5436 p_last_due_counter_val_tbl => l_last_due_counter_tbl,
5437 p_due_date => l_due_date,
5438 p_counter_rules_tbl => p_counter_rules_tbl,
5439 x_due_at_counter_val_tbl => l_due_counter_tbl,
5440 x_return_value => l_return_val);
5441
5442 IF (l_return_val) THEN
5443 IF (l_due_counter_tbl(1).counter_value < l_due_at_counter_value) THEN
5444 l_due_date := l_due_date + 1;
5445 END IF;
5446 END IF;
5447
5448 END IF;
5449 */
5450 -- Compare with whichever first code and set l_calc_due_date.
5451 -- logic modified to fix bug# 6907562. Here l_due_date can be null.
5452 IF (l_due_date IS NULL) THEN
5453 -- Added to fix bug# 6907562.
5454 IF (validate_for_duedate_reset(l_due_date,
5455 l_counter_remain,
5456 l_calc_due_date,
5457 l_calc_due_date_ctr_id,
5458 x_next_due_date_rec.counter_remain)) = 'Y' THEN
5459 --dbms_output.put_line ('due date is null');
5460 l_calc_due_date := l_due_date;
5461 x_next_due_date_rec.due_date := l_due_date;
5462 x_next_due_date_rec.tolerance_after := l_mr_interval_rec.tolerance_after;
5463 x_next_due_date_rec.tolerance_before := l_mr_interval_rec.tolerance_before;
5464 x_next_due_date_rec.mr_interval_id := l_mr_interval_rec.mr_interval_id;
5465 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5466 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5467 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5468 x_next_due_date_rec.last_ctr_value := l_counter_value;
5469 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5470 x_next_due_date_rec.counter_id := null;
5471 x_next_due_date_rec.counter_remain := l_counter_remain;
5472 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5473 END IF;
5474 ELSE -- due date is not null
5475 IF (l_calc_due_date IS NULL) THEN
5476 -- Added to fix bug# 6907562.
5477 IF (validate_for_duedate_reset(l_due_date,
5478 l_counter_remain,
5479 l_calc_due_date,
5480 l_calc_due_date_ctr_id,
5481 x_next_due_date_rec.counter_remain)) = 'Y' THEN
5482
5483 --dbms_output.put_line ('calc due date is null');
5484 l_calc_due_date := l_due_date;
5485 x_next_due_date_rec.due_date := l_due_date;
5486 x_next_due_date_rec.tolerance_after := l_mr_interval_rec.tolerance_after;
5487 x_next_due_date_rec.tolerance_before := l_mr_interval_rec.tolerance_before;
5488 x_next_due_date_rec.mr_interval_id := l_mr_interval_rec.mr_interval_id;
5489 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5490 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5491 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5492 x_next_due_date_rec.last_ctr_value := l_counter_value;
5493 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5494 x_next_due_date_rec.counter_id := null;
5495 x_next_due_date_rec.counter_remain := l_counter_remain;
5496 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5497 END IF;
5498 ELSE
5499 IF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
5500 -- dbms_output.put_line ('applicable mr which code = first');
5501 -- Check due date based on whichever_first_code.
5502 -- if dates are equal, switch based on lower uom remain value. (bug# 6907562).
5503 IF (l_calc_due_date > l_due_date) OR
5504 (trunc(l_calc_due_date) = trunc(l_due_date) AND l_counter_remain IS NOT NULL
5505 AND x_next_due_date_rec.counter_remain IS NOT NULL
5506 AND l_counter_remain < x_next_due_date_rec.counter_remain) THEN
5507
5508 --dbms_output.put_line ('calc_due_date > l_due date');
5509 l_calc_due_date := l_due_date;
5510 x_next_due_date_rec.due_date := l_due_date;
5511 x_next_due_date_rec.tolerance_after := l_mr_interval_rec.tolerance_after;
5512 x_next_due_date_rec.tolerance_before := l_mr_interval_rec.tolerance_before;
5513 x_next_due_date_rec.mr_interval_id := l_mr_interval_rec.mr_interval_id;
5514 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5515 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5516 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5517 x_next_due_date_rec.last_ctr_value := l_counter_value;
5518 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5519 x_next_due_date_rec.counter_id := null;
5520 x_next_due_date_rec.counter_remain := l_counter_remain;
5521 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5522 END IF;
5523 ELSE /* whichever_first_code = 'LAST' */
5524 --dbms_output.put_line ('applicable mr which code = last');
5525 -- if dates are equal, switch based on higher uom remain value. (bug# 6907562).
5526 IF (l_calc_due_date < l_due_date) OR
5527 (trunc(l_calc_due_date) = trunc(l_due_date) AND l_counter_remain IS NOT NULL
5528 AND x_next_due_date_rec.counter_remain IS NOT NULL
5529 AND l_counter_remain > x_next_due_date_rec.counter_remain) THEN
5530
5531 --dbms_output.put_line ('calc_due_date < l_due date');
5532 l_calc_due_date := l_due_date;
5533 x_next_due_date_rec.due_date := l_due_date;
5534 x_next_due_date_rec.tolerance_after := l_mr_interval_rec.tolerance_after;
5535 x_next_due_date_rec.tolerance_before := l_mr_interval_rec.tolerance_before;
5536 x_next_due_date_rec.mr_interval_id := l_mr_interval_rec.mr_interval_id;
5537 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5538 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5539 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5540 x_next_due_date_rec.last_ctr_value := l_counter_value;
5541 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5542 x_next_due_date_rec.counter_id := null;
5543 x_next_due_date_rec.counter_remain := l_counter_remain;
5544 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5545 END IF;
5546 END IF;
5547 END IF; /* calc_due_date null */
5548 --dbms_output.put_line ('Next mr interval');
5549 END IF; -- due date is null.
5550
5551 IF G_DEBUG = 'Y' THEN
5552 AHL_DEBUG_PUB.Debug('Before Next interval table loop');
5553 AHL_DEBUG_PUB.Debug('l_due_date:' || l_due_date );
5554 AHL_DEBUG_PUB.Debug('l_calc_due_date:' || l_calc_due_date);
5555 AHL_DEBUG_PUB.Debug('l_calc_due_date_ctr_id:' || l_calc_due_date_ctr_id);
5556 END IF;
5557
5558 -- Fix for bug# 3461118.
5559 <<next_mr_interval_loop>>
5560 NULL;
5561 END LOOP; /* mr_interval_rec */
5562
5563 -- If no interval found, then check if future intervals exist
5564 -- and calculate date based on that interval.
5565 -- Added p_mr_accomplish_exists and p_last_due_mr_interval_id to fix bug# 6858788.
5566 -- Commented p_last_accomplishment_date and will instead use p_mr_accomplish_exists.
5567 IF NOT(l_ctr_interval_found) THEN
5568 Get_DueDate_from_NxtInterval (p_applicable_mrs_rec => p_applicable_mrs_rec,
5569 p_repetivity_flag => p_repetivity_flag,
5570 p_mr_effectivity_id => effectivity_rec.mr_effectivity_id,
5571 p_current_ctr_rec => l_temp_counter_tbl(i),
5572 p_counter_rules_tbl => p_counter_rules_tbl,
5573 p_current_ctr_at_date => l_start_date,
5574 p_start_int_match_at_ctr => l_start_int_match_at_ctr,
5575 p_last_accomplish_ctr_val => l_counter_value,
5576 --p_last_accomplishment_date => p_last_due_date,
5577 p_dependent_mr_flag => p_dependent_mr_flag,
5578 p_mr_accomplish_exists => p_mr_accomplish_exists,
5579 p_last_due_mr_interval_id => p_last_due_mr_interval_id,
5580 x_next_due_date_rec => l_next_due_date_rec,
5581 --x_next_due_date_rec,
5582 x_mr_interval_found => l_ctr_interval_found,
5583 x_return_val => l_return_val);
5584 IF (l_ctr_interval_found) THEN
5585 IF NOT(l_return_val) THEN
5586 RAISE DUE_DATE_NULL; -- forecast not available hence uom remain is not known.
5587 END IF;
5588
5589 -- JKJain, NR Analysis and Forecasting
5590 --Verify if due date is in fleet-unit asscociation
5591 IF (l_fleet_header_id is NOT NULL) THEN
5592 IF (G_UC_HEADER_ID is NOT NULL AND l_next_due_date_rec.due_date IS NOT NULL) THEN
5593 IF (l_fleet_header_id <> nvl(get_fleet_from_unit_asso(G_UC_HEADER_ID,l_next_due_date_rec.due_date,G_SIMULATION_PLAN_ID),-1)) THEN
5594
5595 IF(l_fleet_reject_due_date IS NULL) THEN
5596 l_fleet_reject_due_date := l_next_due_date_rec.due_date;
5597 ELSIF (l_fleet_reject_due_date > l_next_due_date_rec.due_date) THEN
5598 l_fleet_reject_due_date := l_next_due_date_rec.due_date;
5599 END IF;
5600
5601 --calculate earliest due date and verify the same.
5602 IF l_next_due_date_rec.tolerance_before IS NOT NULL THEN
5603 -- Not required: If due date is today's date then earliest due = due date.
5604 IF (l_next_due_date_rec.due_date IS NOT NULL) THEN
5605 IF (p_repetivity_flag = 'N') THEN
5606 l_counter_remain := (l_due_at_counter_value -
5607 l_next_due_date_rec.tolerance_before) -
5608 l_current_ctr_value;
5609 ELSE
5610 l_counter_remain := (l_due_at_counter_value -
5611 l_next_due_date_rec.tolerance_before) -
5612 l_counter_value;
5613 END IF;
5614
5615 IF (l_counter_remain < 0) THEN
5616 -- Due date = counter reading date.
5617 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
5618 p_counter_id => l_calc_due_date_ctr_id,
5619 p_counter_value => l_due_at_counter_value -
5620 l_next_due_date_rec.tolerance_before,
5621 x_ctr_record_date => l_counter_read_date,
5622 x_return_val => l_return_val);
5623 IF NOT(l_return_val) THEN
5624 l_earliest_due_date := null;
5625 ELSE
5626 l_earliest_due_date := l_counter_read_date;
5627 END IF;
5628 -- if earliest_due_date > due date (when no counters readings exist before counter remain).
5629 IF (l_earliest_due_date > l_next_due_date_rec.due_date) THEN
5630 l_earliest_due_date := l_next_due_date_rec.due_date;
5631 END IF;
5632
5633 ELSE /* counter_remain > 0 */
5634 -- get date from forecast.
5635 get_date_from_uf(l_counter_remain,
5636 l_temp_counter_tbl(i).uom_code,
5637 p_counter_rules_tbl,
5638 l_start_date,
5639 l_earliest_due_date);
5640 END IF; -- counter_remain.
5641
5642 END IF; -- due date is not null.
5643 END IF; -- tolerance before.
5644
5645
5646 IF(l_earliest_due_date IS NOT NULL and l_earliest_due_date < l_next_due_date_rec.due_date) THEN
5647 IF (l_fleet_header_id <> nvl(get_fleet_from_unit_asso(G_UC_HEADER_ID,l_earliest_due_date,G_SIMULATION_PLAN_ID),-1)) THEN
5648 IF (l_ctr_interval_found = TRUE AND l_old_ctr_interval_found = FALSE) THEN
5649 l_ctr_interval_found := FALSE;
5650 x_next_due_date_rec.FLEET_ASSO_REJECTED := 'Y';
5651 END IF;
5652 GOTO next_counter_loop;
5653 END IF;
5654 ELSE
5655 l_ctr_interval_found := l_old_ctr_interval_found;
5656 x_next_due_date_rec.FLEET_ASSO_REJECTED := 'Y';
5657 GOTO next_counter_loop;
5658 END IF;
5659 END IF;
5660 ELSE
5661 GOTO next_counter_loop;
5662 END IF;
5663 END IF; -- l_fleet_header_id is NOT NULL
5664
5665 IF (l_next_due_date_rec.due_date IS NOT NULL) THEN
5666 IF (l_calc_due_date IS NULL) THEN
5667 -- Added to fix bug# 6907562.
5668 IF (validate_for_duedate_reset(l_next_due_date_rec.due_date,
5669 l_next_due_date_rec.counter_remain,
5670 l_calc_due_date,
5671 l_calc_due_date_ctr_id,
5672 x_next_due_date_rec.counter_remain)) = 'Y' THEN
5673
5674 x_next_due_date_rec := l_next_due_date_rec;
5675 l_calc_due_date := x_next_due_date_rec.due_date;
5676 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5677 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5678 x_next_due_date_rec.last_ctr_value := l_counter_value;
5679 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5680 x_next_due_date_rec.counter_id := null;
5681 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5682 END IF; -- validate_for_duedate_reset
5683
5684 ELSIF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
5685 -- if dates are equal, switch based on lower uom remain value. (bug# 6907562).
5686 IF (l_calc_due_date > l_next_due_date_rec.due_date) OR
5687 (trunc(l_calc_due_date) = trunc(l_next_due_date_rec.due_date)
5688 AND l_next_due_date_rec.counter_remain IS NOT NULL
5689 AND x_next_due_date_rec.counter_remain IS NOT NULL
5690 AND l_next_due_date_rec.counter_remain < x_next_due_date_rec.counter_remain) THEN
5691
5692 x_next_due_date_rec := l_next_due_date_rec;
5693 l_calc_due_date := x_next_due_date_rec.due_date;
5694 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5695 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5696 x_next_due_date_rec.last_ctr_value := l_counter_value;
5697 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5698 x_next_due_date_rec.counter_id := null;
5699 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5700 END IF;
5701 ELSIF (p_applicable_mrs_rec.whichever_first_code = 'LAST') THEN
5702 -- if dates are equal, switch based on higher uom remain value. (bug# 6907562).
5703 IF (l_calc_due_date < l_next_due_date_rec.due_date) OR
5704 (trunc(l_calc_due_date) = trunc(l_next_due_date_rec.due_date)
5705 AND l_next_due_date_rec.counter_remain IS NOT NULL
5706 AND x_next_due_date_rec.counter_remain IS NOT NULL
5707 AND l_next_due_date_rec.counter_remain > x_next_due_date_rec.counter_remain) THEN
5708 x_next_due_date_rec := l_next_due_date_rec;
5709 l_calc_due_date := x_next_due_date_rec.due_date;
5710 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5711 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5712 x_next_due_date_rec.last_ctr_value := l_counter_value;
5713 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5714 x_next_due_date_rec.counter_id := null;
5715 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5716 END IF;
5717 END IF; -- l_calc_due_date IS NULL
5718 -- else added to fix bug# 6907562.
5719 ELSE -- due date is null.
5720 -- Added to fix bug# 6907562.
5721 IF (validate_for_duedate_reset(l_next_due_date_rec.due_date,
5722 l_next_due_date_rec.counter_remain,
5723 l_calc_due_date,
5724 l_calc_due_date_ctr_id,
5725 x_next_due_date_rec.counter_remain)) = 'Y' THEN
5726 x_next_due_date_rec := l_next_due_date_rec;
5727 l_calc_due_date := x_next_due_date_rec.due_date;
5728 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5729 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5730 x_next_due_date_rec.last_ctr_value := l_counter_value;
5731 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(i).uom_code;
5732 x_next_due_date_rec.counter_id := null;
5733 l_calc_due_date_ctr_id := l_temp_counter_tbl(i).counter_id;
5734
5735 END IF; -- validate_for_duedate_reset
5736 END IF; -- x_next_due_date_rec.due_date IS NOT NULL
5737 END IF; -- l_ctr_interval_found.
5738 END IF; -- NOT(l_ctr_interval_found)
5739
5740 -- added to fix bug# 6725769.
5741 IF NOT(l_mr_interval_found) THEN
5742 IF (l_ctr_interval_found) THEN
5743 l_mr_interval_found := TRUE;
5744 -- JKJain, NR Analysis and Forecasting
5745 x_next_due_date_rec.FLEET_ASSO_REJECTED := 'N';
5746 END IF;
5747 END IF;
5748 --dbms_output.put_line ('next counter');
5749
5750 <<next_counter_loop>>
5751 NULL;
5752 END LOOP; /* temp_counter_tbl */
5753 END IF; /* count > 0 */
5754
5755 -- Check due date with threshold date.
5756 -- If threshold date exists, then the MR is not repetitive.
5757 -- JKJain, NR Analysis and Forecasting
5758 IF ((effectivity_rec.threshold_date IS NOT NULL) AND (p_repetivity_flag = 'N') AND
5759 ( (l_calc_due_date IS NOT NULL AND l_mr_interval_found = TRUE) OR /* case of due date is not null for an interval id */
5760 (l_mr_interval_found = FALSE) ) /* case of no intervals defined for an effectivity */
5761 AND (l_fleet_header_id IS NULL OR G_UC_HEADER_ID IS NULL OR
5762 l_fleet_header_id = get_fleet_from_unit_asso(G_UC_HEADER_ID,effectivity_rec.threshold_date,G_SIMULATION_PLAN_ID)))
5763 THEN
5764 --dbms_output.put_line ('in threshold');
5765 IF (l_calc_due_date IS NULL) THEN
5766 l_calc_due_date := effectivity_rec.threshold_date;
5767 x_next_due_date_rec.due_date := effectivity_rec.threshold_date;
5768 x_next_due_date_rec.tolerance_after := null;
5769 x_next_due_date_rec.tolerance_before := null;
5770 x_next_due_date_rec.mr_interval_id := null;
5771 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5772 x_next_due_date_rec.due_at_counter_value := null;
5773 x_next_due_date_rec.current_ctr_value := null;
5774 x_next_due_date_rec.last_ctr_value := null;
5775 x_next_due_date_rec.ctr_uom_code := null;
5776 x_next_due_date_rec.counter_id := null;
5777 x_next_due_date_rec.counter_remain := null;
5778 l_calc_due_date_ctr_id := null;
5779 ELSIF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
5780 IF (l_calc_due_date > effectivity_rec.threshold_date) THEN
5781 l_calc_due_date := effectivity_rec.threshold_date;
5782 x_next_due_date_rec.due_date := effectivity_rec.threshold_date;
5783 x_next_due_date_rec.tolerance_after := null;
5784 x_next_due_date_rec.tolerance_before := null;
5785 x_next_due_date_rec.mr_interval_id := null;
5786 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5787 x_next_due_date_rec.due_at_counter_value := null;
5788 x_next_due_date_rec.current_ctr_value := null;
5789 x_next_due_date_rec.last_ctr_value := null;
5790 x_next_due_date_rec.ctr_uom_code := null;
5791 x_next_due_date_rec.counter_id := null;
5792 x_next_due_date_rec.counter_remain := null;
5793 l_calc_due_date_ctr_id := null;
5794
5795 END IF;
5796 ELSIF (p_applicable_mrs_rec.whichever_first_code = 'LAST') THEN
5797 /* whichever_first_code = 'LAST' */
5798 IF (l_calc_due_date < effectivity_rec.threshold_date) THEN
5799 l_calc_due_date := effectivity_rec.threshold_date;
5800 x_next_due_date_rec.due_date := effectivity_rec.threshold_date;
5801 x_next_due_date_rec.tolerance_after := null;
5802 x_next_due_date_rec.tolerance_before := null;
5803 x_next_due_date_rec.mr_interval_id := null;
5804 x_next_due_date_rec.due_at_counter_value := null;
5805 x_next_due_date_rec.mr_effectivity_id := effectivity_rec.mr_effectivity_id;
5806 x_next_due_date_rec.current_ctr_value := null;
5807 x_next_due_date_rec.last_ctr_value := null;
5808 x_next_due_date_rec.ctr_uom_code := null;
5809 x_next_due_date_rec.counter_id := null;
5810 x_next_due_date_rec.counter_remain := null;
5811 l_calc_due_date_ctr_id := null;
5812
5813 END IF;
5814 END IF; /* whichever_first_code */
5815 END IF; /* threshold_date not null */
5816
5817 --dbms_output.put_line ('NEXT effectivity');
5818 END LOOP mr_effectivity_loop; /* effectivity_rec */
5819
5820 -- Fix for bug# 6358940. Due Date should be based only on init-due if it
5821 -- exists. MR thresholds should not be used.
5822 -- Moved below logic to the beginning of the this procedure before processing
5823 -- effectivities.
5824 -- Calculate due date based on init-due defination; if exists.
5825 /*
5826 IF (p_repetivity_flag = 'N') THEN
5827 --dbms_output.put_line ('in INIT-due part');
5828
5829 -- Check if there is any init-due record for this item instance and mr exists.
5830 OPEN ahl_init_due_csr(p_applicable_mrs_rec.csi_item_instance_id,
5831 p_applicable_mrs_rec.mr_header_id);
5832 FETCH ahl_init_due_csr INTO l_set_due_date, l_unit_effectivity_id, l_unit_deferral_id;
5833 IF (ahl_init_due_csr%FOUND) THEN
5834
5835 --dbms_output.put_line ('in INIT-due part: due_date' || l_set_due_date);
5836
5837 FOR threshold_rec IN ahl_unit_thresholds_csr (l_unit_deferral_id)
5838 LOOP
5839 -- for init due, ctr_value_type_code is always 'defer_to'.
5840 l_due_at_counter_value := threshold_rec.counter_value;
5841 l_counter_remain := 0;
5842 l_current_ctr_value := 0;
5843 k := 0;
5844 -- search for the current counter value in l_current_usage_tbl.
5845 IF (l_temp_counter_tbl.COUNT > 0) THEN
5846 FOR i IN l_temp_counter_tbl.FIRST..l_temp_counter_tbl.LAST LOOP
5847 IF (l_temp_counter_tbl(i).counter_id = threshold_rec.counter_id) THEN
5848 l_current_ctr_value := l_temp_counter_tbl(i).counter_value;
5849 k := i;
5850 EXIT;
5851 END IF;
5852 END LOOP;
5853 l_counter_remain := l_due_at_counter_value - l_current_ctr_value;
5854 END IF;
5855
5856 -- calculate due date from forecast.
5857 IF (l_counter_remain > 0) THEN
5858 -- get date from forecast.
5859 get_date_from_uf(l_counter_remain,
5860 l_temp_counter_tbl(k).uom_code,
5861 p_counter_rules_tbl,
5862 null, -- start date = sysdate
5863 l_due_date);
5864 ELSIF (l_counter_remain < 0) THEN
5865 -- Due date = counter reading date.
5866 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
5867 p_counter_id => l_temp_counter_tbl(k).counter_id,
5868 p_counter_value => l_due_at_counter_value,
5869 x_ctr_record_date => l_counter_read_date,
5870 x_return_val => l_return_val);
5871
5872 IF NOT(l_return_val) THEN
5873 l_due_date := sysdate;
5874 ELSE
5875 l_due_date := l_counter_read_date;
5876 END IF;
5877
5878 ELSIF (l_counter_remain = 0) THEN -- due_date = sysdate
5879 --dbms_output.put_line ('counter remain less than zero');
5880 l_due_date := sysdate;
5881 END IF;
5882
5883 IF (l_calc_due_date IS NOT NULL AND l_mr_interval_found = TRUE) OR -- case where intervals exist.
5884 (l_mr_interval_found = FALSE) THEN -- case where no intervals.
5885 -- Compare with whichever first code and set l_calc_due_date.
5886 IF (l_due_date IS NULL) THEN
5887 --dbms_output.put_line ('due date null');
5888 l_calc_due_date := l_due_date;
5889 x_next_due_date_rec.due_date := null;
5890 x_next_due_date_rec.tolerance_after := null;
5891 x_next_due_date_rec.tolerance_before := null;
5892 x_next_due_date_rec.mr_interval_id := null;
5893 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5894 x_next_due_date_rec.mr_effectivity_id := null;
5895 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5896 x_next_due_date_rec.last_ctr_value := null;
5897 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
5898 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
5899 x_next_due_date_rec.counter_remain := l_counter_remain;
5900 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
5901 EXIT;
5902 ELSE -- happens when no interval
5903 IF (l_calc_due_date IS NULL) THEN
5904 --dbms_output.put_line ('calc due date null');
5905 l_calc_due_date := l_due_date;
5906 x_next_due_date_rec.due_date := l_due_date;
5907 x_next_due_date_rec.tolerance_after := null;
5908 x_next_due_date_rec.tolerance_before := null;
5909 x_next_due_date_rec.mr_interval_id := null;
5910 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5911 x_next_due_date_rec.mr_effectivity_id := null;
5912 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5913 x_next_due_date_rec.last_ctr_value := null;
5914 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
5915 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
5916 x_next_due_date_rec.counter_remain := l_counter_remain;
5917 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
5918
5919 ELSE
5920 IF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
5921 -- Check due date based on whichever_first_code.
5922 IF (l_calc_due_date > l_due_date) THEN
5923 l_calc_due_date := l_due_date;
5924 x_next_due_date_rec.due_date := l_due_date;
5925 x_next_due_date_rec.tolerance_after := null;
5926 x_next_due_date_rec.tolerance_before := null;
5927 x_next_due_date_rec.mr_interval_id := null;
5928 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5929 x_next_due_date_rec.mr_effectivity_id := null;
5930 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5931 x_next_due_date_rec.last_ctr_value := null;
5932 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
5933 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
5934 x_next_due_date_rec.counter_remain := l_counter_remain;
5935 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
5936
5937 END IF;
5938 ELSE -- whichever_first_code = 'LAST'
5939 IF (l_calc_due_date < l_due_date) THEN
5940 --dbms_output.put_line ('set due date');
5941 l_calc_due_date := l_due_date;
5942 x_next_due_date_rec.due_date := l_due_date;
5943 x_next_due_date_rec.tolerance_after := null;
5944 x_next_due_date_rec.tolerance_before := null;
5945 x_next_due_date_rec.mr_interval_id := null;
5946 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
5947 x_next_due_date_rec.mr_effectivity_id := null;
5948 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
5949 x_next_due_date_rec.last_ctr_value := null;
5950 x_next_due_date_rec.ctr_uom_code := l_temp_counter_tbl(k).uom_code;
5951 x_next_due_date_rec.counter_id := l_temp_counter_tbl(k).counter_id;
5952 x_next_due_date_rec.counter_remain := l_counter_remain;
5953 l_calc_due_date_ctr_id := l_temp_counter_tbl(k).counter_id;
5954
5955 END IF;
5956 END IF; -- applicable_mrs_rec
5957 END IF; -- calc_due_date null
5958 END IF;
5959 END IF; -- calc due date and l_mr_interval_found.
5960 END LOOP; -- set_threshold_rec
5961
5962 -- Check for set due date.
5963 IF (l_set_due_date IS NOT NULL) THEN
5964 IF (l_calc_due_date IS NOT NULL AND l_mr_interval_found = TRUE) OR -- case where intervals exist.
5965 (l_mr_interval_found = FALSE) THEN -- case where no intervals.
5966
5967 IF (l_calc_due_date IS NULL) THEN
5968 l_calc_due_date := l_set_due_date;
5969 x_next_due_date_rec.due_date := l_set_due_date;
5970 x_next_due_date_rec.tolerance_after := null;
5971 x_next_due_date_rec.tolerance_before := null;
5972 x_next_due_date_rec.mr_effectivity_id := null;
5973 x_next_due_date_rec.due_at_counter_value := null;
5974 x_next_due_date_rec.current_ctr_value := null;
5975 x_next_due_date_rec.last_ctr_value := null;
5976 x_next_due_date_rec.mr_interval_id := null;
5977 x_next_due_date_rec.ctr_uom_code := null;
5978 x_next_due_date_rec.counter_id := null;
5979 x_next_due_date_rec.counter_remain := null;
5980 l_calc_due_date_ctr_id := null;
5981
5982 ELSE
5983 IF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
5984 IF (l_calc_due_date > l_set_due_date) THEN
5985 --dbms_output.put_line ('set due da te');
5986 l_calc_due_date := l_set_due_date;
5987 x_next_due_date_rec.due_date := l_set_due_date;
5988 x_next_due_date_rec.tolerance_after := null;
5989 x_next_due_date_rec.tolerance_before := null;
5990 x_next_due_date_rec.mr_interval_id := null;
5991 x_next_due_date_rec.due_at_counter_value := null;
5992 x_next_due_date_rec.mr_effectivity_id := null;
5993 x_next_due_date_rec.current_ctr_value := null;
5994 x_next_due_date_rec.last_ctr_value := null;
5995 x_next_due_date_rec.ctr_uom_code := null;
5996 x_next_due_date_rec.counter_id := null;
5997 x_next_due_date_rec.counter_remain := null;
5998 l_calc_due_date_ctr_id := null;
5999
6000 END IF;
6001 ELSE
6002 -- Check for set due date.
6003 IF (l_calc_due_date < l_set_due_date) THEN
6004 l_calc_due_date := l_set_due_date;
6005 x_next_due_date_rec.due_date := l_set_due_date;
6006 x_next_due_date_rec.tolerance_after := null;
6007 x_next_due_date_rec.tolerance_before := null;
6008 x_next_due_date_rec.mr_interval_id := null;
6009 x_next_due_date_rec.due_at_counter_value := null;
6010 x_next_due_date_rec.mr_effectivity_id := null;
6011 x_next_due_date_rec.current_ctr_value := null;
6012 x_next_due_date_rec.last_ctr_value := null;
6013 x_next_due_date_rec.ctr_uom_code := null;
6014 x_next_due_date_rec.counter_id := null;
6015 x_next_due_date_rec.counter_remain := null;
6016 l_calc_due_date_ctr_id := null;
6017
6018 END IF;
6019 END IF; -- applicable
6020 END IF;
6021 END IF;
6022 END IF; -- set due date
6023 END IF; -- init_due_csr
6024 CLOSE ahl_init_due_csr;
6025 END IF; -- repetitive_flag
6026 */
6027 -- After processing all effectivities, check if any interval got triggered.
6028 -- If not, set all values to null and exit procedure.
6029 IF (x_next_due_date_rec.mr_effectivity_id IS NULL) AND
6030 (x_next_due_date_rec.mr_interval_id IS NULL) AND (l_calc_due_date IS NULL) AND
6031 (x_next_due_date_rec.counter_id IS NULL) THEN
6032 RAISE NO_VALID_INTERVAL;
6033 END IF;
6034
6035 -- Evaluate tolerance condition.
6036 IF (x_next_due_date_rec.mr_interval_id IS NOT NULL) THEN
6037 IF ((x_next_due_date_rec.due_at_counter_value +
6038 x_next_due_date_rec.tolerance_after) < x_next_due_date_rec.current_ctr_value) THEN
6039 x_next_due_date_rec.tolerance_flag := 'Y';
6040 x_next_due_date_rec.message_code := 'TOLERANCE-EXCEEDED';
6041 END IF;
6042
6043 -- Added for ER#2636001.
6044 -- Calculate earliest due date.
6045 IF x_next_due_date_rec.tolerance_before IS NOT NULL THEN
6046 -- Not required: If due date is today's date then earliest due = due date.
6047 IF (x_next_due_date_rec.due_date IS NOT NULL) THEN
6048 --IF (trunc(x_next_due_date_rec.due_date) = trunc(sysdate)) THEN
6049 -- x_next_due_date_rec.earliest_due_date := x_next_due_date_rec.due_date;
6050 --ELSE
6051 -- find the left over counter value
6052 IF (p_repetivity_flag = 'N') THEN
6053 l_counter_remain := (x_next_due_date_rec.due_at_counter_value -
6054 x_next_due_date_rec.tolerance_before) -
6055 x_next_due_date_rec.current_ctr_value;
6056 ELSE
6057 l_counter_remain := (x_next_due_date_rec.due_at_counter_value -
6058 x_next_due_date_rec.tolerance_before) -
6059 x_next_due_date_rec.last_ctr_value;
6060 END IF;
6061
6062 IF (l_counter_remain < 0) THEN
6063 -- Due date = counter reading date.
6064 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
6065 p_counter_id => l_calc_due_date_ctr_id,
6066 p_counter_value => x_next_due_date_rec.due_at_counter_value -
6067 x_next_due_date_rec.tolerance_before,
6068 x_ctr_record_date => l_counter_read_date,
6069 x_return_val => l_return_val);
6070 IF NOT(l_return_val) THEN
6071 x_next_due_date_rec.earliest_due_date := null;
6072 ELSE
6073 x_next_due_date_rec.earliest_due_date := l_counter_read_date;
6074 END IF;
6075 -- if earliest_due_date > due date (when no counters readings exist before counter remain).
6076 IF (x_next_due_date_rec.earliest_due_date > x_next_due_date_rec.due_date) THEN
6077 x_next_due_date_rec.earliest_due_date := x_next_due_date_rec.due_date;
6078 END IF;
6079
6080 ELSE /* counter_remain > 0 */
6081 -- get date from forecast.
6082 get_date_from_uf(l_counter_remain,
6083 x_next_due_date_rec.ctr_uom_code,
6084 p_counter_rules_tbl,
6085 l_start_date,
6086 x_next_due_date_rec.earliest_due_date);
6087 --IF (trunc(x_next_due_date_rec.earliest_due_date) < trunc(sysdate)) THEN
6088 -- x_next_due_date_rec.earliest_due_date := sysdate;
6089 --END IF;
6090 END IF; -- counter_remain.
6091 --END IF; -- due_date = sysdate.
6092 END IF; -- due date is not null.
6093 END IF; -- tolerance before.
6094
6095 IF (x_next_due_date_rec.tolerance_after) IS NOT NULL THEN
6096 -- Calculate counter remain.
6097 IF (p_repetivity_flag = 'N') THEN
6098 l_counter_remain := (x_next_due_date_rec.due_at_counter_value +
6099 x_next_due_date_rec.tolerance_after) -
6100 x_next_due_date_rec.current_ctr_value;
6101 ELSE
6102 l_counter_remain := (x_next_due_date_rec.due_at_counter_value +
6103 x_next_due_date_rec.tolerance_after) -
6104 x_next_due_date_rec.last_ctr_value;
6105 END IF;
6106
6107 IF G_DEBUG = 'Y' THEN
6108 AHL_DEBUG_PUB.Debug('Calculating latest due...uom_remain' || l_counter_remain);
6109 END IF;
6110
6111 IF (l_counter_remain < 0) THEN
6112 -- Due date = counter reading date.
6113 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
6114 p_counter_id => l_calc_due_date_ctr_id,
6115 p_counter_value => x_next_due_date_rec.due_at_counter_value +
6116 x_next_due_date_rec.tolerance_after,
6117 x_ctr_record_date => l_counter_read_date,
6118 x_return_val => l_return_val);
6119
6120 IF NOT(l_return_val) THEN
6121 x_next_due_date_rec.latest_due_date := null;
6122 ELSE
6123 x_next_due_date_rec.latest_due_date := l_counter_read_date;
6124 -- flag tolerance when latest due date < sysdate
6125 x_next_due_date_rec.tolerance_flag := 'Y';
6126 x_next_due_date_rec.message_code := 'TOLERANCE-EXCEEDED';
6127 END IF;
6128
6129 ELSE /* counter_remain > 0 */
6130 IF (x_next_due_date_rec.due_date >= sysdate) THEN
6131 -- Calculate latest tolerance.
6132 get_date_from_uf(x_next_due_date_rec.tolerance_after,
6133 x_next_due_date_rec.ctr_uom_code,
6134 p_counter_rules_tbl,
6135 x_next_due_date_rec.due_date,
6136 x_next_due_date_rec.latest_due_date);
6137 -- added to fix bug# 7646170
6138 ELSE
6139 -- Calculate latest tolerance.
6140 get_date_from_uf(l_counter_remain,
6141 x_next_due_date_rec.ctr_uom_code,
6142 p_counter_rules_tbl,
6143 sysdate,
6144 x_next_due_date_rec.latest_due_date);
6145
6146 END IF;
6147 END IF; -- counter_remain.
6148 ELSE
6149 -- If due date is less than sysdate, then flag tolerance.
6150 IF (x_next_due_date_rec.due_date IS NOT NULL) AND
6151 (trunc(x_next_due_date_rec.due_date) < trunc(sysdate)) THEN
6152 x_next_due_date_rec.tolerance_flag := 'Y';
6153 x_next_due_date_rec.message_code := 'TOLERANCE-EXCEEDED';
6154 END IF;
6155
6156 END IF;
6157 -- End of ER modifications.
6158 END IF;
6159
6160 -- JKJain, NR Analysis and Forecasting
6161 x_next_due_date_rec.FLEET_ASSO_REJECTED := 'N';
6162
6163 IF G_DEBUG = 'Y' THEN
6164 AHL_DEBUG_PUB.Debug('End calculate due date : x_next_due_date_rec.due_date = ' || x_next_due_date_rec.due_date);
6165 END IF;
6166
6167
6168 EXCEPTION
6169 WHEN DUE_DATE_NULL THEN
6170 x_next_due_date_rec.due_date := null;
6171 x_next_due_date_rec.tolerance_after := l_mr_interval_rec.tolerance_after;
6172 x_next_due_date_rec.tolerance_before := l_mr_interval_rec.tolerance_before;
6173 x_next_due_date_rec.mr_interval_id := l_mr_interval_rec.mr_interval_id;
6174 x_next_due_date_rec.due_at_counter_value := l_due_at_counter_value;
6175 x_next_due_date_rec.mr_effectivity_id := null;
6176 x_next_due_date_rec.current_ctr_value := l_current_ctr_value;
6177 x_next_due_date_rec.counter_remain := l_counter_remain;
6178 -- JKJain, NR Analysis and Forecasting
6179 IF (x_next_due_date_rec.due_date IS NULL AND x_next_due_date_rec.FLEET_ASSO_REJECTED = 'Y') THEN
6180 x_next_due_date_rec.due_date := l_fleet_reject_due_date;
6181 IF G_DEBUG = 'Y' THEN
6182 AHL_DEBUG_PUB.Debug('Inside DUE_DATE_NULL l_fleet_reject_due_date = '|| l_fleet_reject_due_date);
6183 END IF;
6184 END IF;
6185
6186 WHEN NO_VALID_INTERVAL THEN
6187 x_next_due_date_rec.due_date := null;
6188 x_next_due_date_rec.tolerance_after := null;
6189 x_next_due_date_rec.tolerance_before := null;
6190 x_next_due_date_rec.mr_interval_id := null;
6191 x_next_due_date_rec.due_at_counter_value := null;
6192 x_next_due_date_rec.mr_effectivity_id := null;
6193 x_next_due_date_rec.current_ctr_value := null;
6194 x_next_due_date_rec.counter_remain := null;
6195 -- JKJain, NR Analysis and Forecasting
6196 IF (x_next_due_date_rec.due_date IS NULL AND x_next_due_date_rec.FLEET_ASSO_REJECTED = 'Y') THEN
6197 x_next_due_date_rec.due_date := l_fleet_reject_due_date;
6198 IF G_DEBUG = 'Y' THEN
6199 AHL_DEBUG_PUB.Debug('Inside NO_VALID_INTERVAL l_fleet_reject_due_date = '|| l_fleet_reject_due_date);
6200 END IF;
6201 END IF;
6202
6203 END Calculate_Due_Date;
6204
6205 -------------------------------------------------------------------------------------------
6206 -- Calculate due at counter values for a given due due from last due date and last due counters using
6207 -- counter rules and forecast (defined in global variable).
6208
6209 PROCEDURE Get_Due_At_Counter_Values ( p_last_due_date IN DATE,
6210 p_last_due_counter_val_tbl IN counter_values_tbl_type,
6211 p_due_date IN DATE,
6212 p_counter_rules_tbl IN counter_rules_tbl_type,
6213 x_due_at_counter_val_tbl OUT NOCOPY counter_values_tbl_type,
6214 x_return_value OUT NOCOPY BOOLEAN)
6215 IS
6216
6217 l_diff_days NUMBER := 0;
6218 l_counter_value NUMBER := 0;
6219 l_forecast_days NUMBER := 0;
6220 l_no_forecast BOOLEAN := FALSE;
6221 l_next_index NUMBER;
6222 l_start_date DATE;
6223 l_total_days_in_period NUMBER;
6224
6225 l_index_found BOOLEAN;
6226
6227 BEGIN
6228
6229
6230 IF G_DEBUG = 'Y' THEN
6231 AHL_DEBUG_PUB.Debug('Start get_due_at_counter_values');
6232 END IF;
6233
6234 -- Initialize return value.
6235 x_return_value := TRUE;
6236
6237 -- find the difference between last due and due dates.
6238 l_diff_days := ABS(trunc(p_due_date) - trunc(p_last_due_date));
6239 --dbms_output.put_line ('l_diff_days'|| l_diff_days);
6240
6241 IF (SIGN(p_due_date - p_last_due_date) = -1) THEN
6242 l_start_date := p_due_date;
6243 ELSE
6244 l_start_date := p_last_due_date;
6245 END IF;
6246
6247 --dbms_output.put_line ('l_start_date' || l_start_date);
6248 --dbms_output.put_line ('count on last due ctr val' || p_last_due_counter_val_tbl.COUNT);
6249
6250 -- Loop through last due counter tbl.
6251 IF (p_last_due_counter_val_tbl.COUNT > 0) THEN
6252 FOR i IN p_last_due_counter_val_tbl.FIRST..p_last_due_counter_val_tbl.LAST LOOP
6253 l_next_index := G_forecast_details_tbl.FIRST;
6254 -- set the starting index matching the start date and uom in forecast table.
6255 IF (l_next_index IS NULL) THEN
6256 l_no_forecast := TRUE;
6257 ELSE
6258 l_no_forecast := TRUE;
6259 FOR k IN G_forecast_details_tbl.FIRST..G_forecast_details_tbl.LAST LOOP
6260 IF (G_forecast_details_tbl(k).uom_code = p_last_due_counter_val_tbl(i).uom_code)
6261 AND (trunc(G_forecast_details_tbl(k).start_date) <= trunc(l_start_date)
6262 AND trunc(l_start_date) <= trunc(nvl(G_forecast_details_tbl(k).end_date,l_start_date)))
6263 THEN
6264 l_next_index := k;
6265 l_no_forecast := FALSE;
6266 EXIT;
6267 END IF;
6268 END LOOP;
6269 END IF;
6270
6271 -- Based on counter uom_code, last_due_date, l_diff_days and G_forecast_details_tbl build counter value.
6272 WHILE (l_diff_days <> 0 AND l_no_forecast <> TRUE) LOOP
6273 IF (G_forecast_details_tbl(l_next_index).uom_code = p_last_due_counter_val_tbl(i).uom_code) THEN
6274 IF (trunc(G_forecast_details_tbl(l_next_index).start_date) <= trunc(l_start_date) AND
6275 trunc(nvl(G_forecast_details_tbl(l_next_index).end_date,l_start_date)) >= trunc(l_start_date)) THEN
6276 IF (G_forecast_details_tbl(l_next_index).end_date) IS NOT NULL THEN
6277 l_total_days_in_period := trunc(G_forecast_details_tbl(l_next_index).end_date - l_start_date) + 1;
6278 --dbms_output.put_line ('total days in period' || l_total_days_in_period);
6279 IF (l_total_days_in_period >= l_diff_days) THEN
6280 l_counter_value := l_counter_value + trunc(l_diff_days * G_forecast_details_tbl(l_next_index).usage_per_day);
6281 l_diff_days := 0;
6282 --dbms_output.put_line ('total >= ldiff; ctr val' || l_counter_value );
6283 ELSE
6284 l_diff_days := l_diff_days - l_total_days_in_period;
6285 l_counter_value := l_counter_value + trunc(l_total_days_in_period * G_forecast_details_tbl(l_next_index).usage_per_day);
6286 --dbms_output.put_line ('total < ldiff; ctr val' || l_counter_value );
6287 -- Get next forecast record.
6288 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6289 IF (l_next_index IS NULL) THEN
6290 l_no_forecast := TRUE;
6291 ELSE
6292 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6293 END IF;
6294 END IF; /* total days */
6295 ELSE
6296 l_counter_value := l_counter_value + trunc(l_diff_days * G_forecast_details_tbl(l_next_index).usage_per_day);
6297 l_diff_days := 0;
6298 END IF; /* end date */
6299 ELSE
6300 -- get next forecast record.
6301 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6302 IF (l_next_index IS NULL) THEN
6303 l_no_forecast := TRUE;
6304 ELSE
6305 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6306 END IF;
6307 END IF; /* start date */
6308 ELSE
6309 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6310 IF (l_next_index IS NULL) THEN
6311 l_no_forecast := TRUE;
6312 ELSE
6313 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6314 END IF;
6315 END IF; /* uom_code */
6316 END LOOP; /* while loop */
6317
6318 IF (l_no_forecast = TRUE AND l_diff_days <> 0 ) THEN
6319 x_return_value := FALSE;
6320 EXIT;
6321 END IF;
6322
6323 l_counter_value := Apply_ReverseCounter_Ratio ( l_counter_value,
6324 p_last_due_counter_val_tbl(i).uom_code,
6325 p_counter_rules_tbl);
6326
6327 -- Add new counter values to return parameter.
6328 x_due_at_counter_val_tbl(i).counter_id := p_last_due_counter_val_tbl(i).counter_id;
6329 x_due_at_counter_val_tbl(i).counter_name := p_last_due_counter_val_tbl(i).counter_name;
6330
6331 IF (SIGN(p_due_date - p_last_due_date) = -1) THEN
6332 l_counter_value := p_last_due_counter_val_tbl(i).counter_value - l_counter_value;
6333 ELSE
6334 l_counter_value := p_last_due_counter_val_tbl(i).counter_value + l_counter_value;
6335 END IF;
6336
6337 x_due_at_counter_val_tbl(i).counter_value := l_counter_value;
6338 x_due_at_counter_val_tbl(i).uom_code := p_last_due_counter_val_tbl(i).uom_code;
6339
6340 -- initialize start date.
6341 IF (SIGN(p_due_date - p_last_due_date) = -1) THEN
6342 l_start_date := p_due_date;
6343 ELSE
6344 l_start_date := p_last_due_date;
6345 END IF;
6346 -- Initialize counter value.
6347 l_counter_value := 0;
6348
6349 l_diff_days := ABS(trunc(p_due_date) - trunc(p_last_due_date));
6350
6351 END LOOP; /* for loop */
6352 END IF; /* count */
6353
6354 IF G_DEBUG = 'Y' THEN
6355 AHL_DEBUG_PUB.Debug('End get_due_at_counter_values');
6356 END IF;
6357
6358 END Get_Due_At_Counter_Values;
6359
6360 ---------------------------------------------------------------------------
6361 -- Calculates the due date for the counter_remain from a given start date using forecast,
6362 -- counter rules and counter uom.
6363
6364 PROCEDURE Get_Date_from_UF ( p_counter_remain IN NUMBER,
6365 p_counter_uom_code IN VARCHAR2,
6366 p_counter_rules_tbl IN counter_rules_tbl_type,
6367 p_start_date IN DATE := NULL,
6368 x_due_date OUT NOCOPY DATE)
6369 IS
6370
6371 l_counter_remain NUMBER := p_counter_remain;
6372 l_forecast_days NUMBER := 0;
6373 l_no_forecast BOOLEAN := FALSE;
6374 l_total_days_in_period NUMBER := 0;
6375 l_index_found BOOLEAN;
6376 l_next_index NUMBER := 0;
6377
6378 l_start_date DATE;
6379
6380 BEGIN
6381
6382 IF G_DEBUG = 'Y' THEN
6383 AHL_DEBUG_PUB.Debug('Start get_date from UF');
6384 AHL_DEBUG_PUB.Debug('counter remain input to forecast' || p_counter_remain );
6385 AHL_DEBUG_PUB.Debug('counter uom' || p_counter_uom_code);
6386 AHL_DEBUG_PUB.Debug('Start date' || p_start_date);
6387 END IF;
6388
6389 l_counter_remain := trunc(apply_counter_ratio (l_counter_remain,
6390 p_counter_uom_code,
6391 p_counter_rules_tbl));
6392 IF G_DEBUG = 'Y' THEN
6393 AHL_DEBUG_PUB.DEBUG('counter remain after ctr_ratio' || l_counter_remain );
6394 END IF;
6395
6396 -- Start date to begin calculation.
6397 IF (p_start_date IS NULL) THEN
6398 l_start_date := trunc(sysdate);
6399 ELSE
6400 l_start_date:= p_start_date;
6401 END IF;
6402
6403 -- Read g_forecast_details_tbl to get forecast values.
6404 l_next_index := G_forecast_details_tbl.FIRST;
6405 IF (l_next_index IS NULL) THEN
6406 --dbms_output.put_line ('l_next_index is null');
6407 x_due_date := null;
6408 RETURN;
6409 ELSE
6410 l_no_forecast := TRUE;
6411 FOR i IN G_forecast_details_tbl.FIRST..G_forecast_details_tbl.LAST LOOP
6412 IF (G_forecast_details_tbl(i).uom_code = p_counter_uom_code) AND
6413 (trunc(G_forecast_details_tbl(i).start_date) <= trunc(l_start_date) AND
6414 trunc(l_start_date) <= trunc(nvl(G_forecast_details_tbl(i).end_date,l_start_date)))
6415 THEN
6416 l_next_index := i;
6417 l_no_forecast := FALSE;
6418 EXIT;
6419 END IF;
6420 END LOOP;
6421 END IF;
6422
6423 --dbms_output.put_line ('counter remain input to forecast' || l_counter_remain );
6424 --dbms_output.put_line ('counter uom' ||p_counter_uom_code);
6425
6426 -- Calculate due date.
6427 WHILE ((l_counter_remain <> 0) AND (l_no_forecast <> TRUE )) LOOP
6428 IF (G_forecast_details_tbl(l_next_index).uom_code = p_counter_uom_code) THEN
6429 IF (trunc(G_forecast_details_tbl(l_next_index).start_date) <= trunc(l_start_date) AND
6430 trunc(nvl(G_forecast_details_tbl(l_next_index).end_date,sysdate)) >= trunc(sysdate)) THEN
6431
6432 IF (G_forecast_details_tbl(l_next_index).end_date) IS NOT NULL THEN
6433 l_total_days_in_period := trunc(G_forecast_details_tbl(l_next_index).end_date - l_start_date) + 1;
6434
6435 IF (G_forecast_details_tbl(l_next_index).usage_per_day <> 0) THEN
6436 IF (trunc(l_total_days_in_period * G_forecast_details_tbl(l_next_index).usage_per_day) >= l_counter_remain) THEN
6437 l_forecast_days := l_forecast_days + trunc(l_counter_remain/G_forecast_details_tbl(l_next_index).usage_per_day);
6438 l_counter_remain := 0;
6439 ELSE
6440 l_counter_remain := l_counter_remain - trunc(l_total_days_in_period * G_forecast_details_tbl(l_next_index).usage_per_day);
6441 l_forecast_days := l_forecast_days + l_total_days_in_period;
6442
6443 -- Get next forecast record.
6444 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6445 IF (l_next_index IS NULL) THEN
6446 l_no_forecast := TRUE;
6447 ELSE
6448 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6449 END IF;
6450
6451 END IF; /* total days */
6452 ELSE -- usage_per_day = 0
6453 -- Get next forecast record.
6454 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6455 IF (l_next_index IS NULL) THEN
6456 l_no_forecast := TRUE;
6457 ELSE
6458 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6459 END IF;
6460 END IF; -- usage_per_day <> 0
6461 ELSE
6462 IF (G_forecast_details_tbl(l_next_index).usage_per_day <> 0) THEN
6463 l_forecast_days := l_forecast_days + trunc(l_counter_remain/G_forecast_details_tbl(l_next_index).usage_per_day);
6464 l_counter_remain := 0;
6465 ELSE -- usage = 0
6466 -- Get next forecast record.
6467 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6468 IF (l_next_index IS NULL) THEN
6469 l_no_forecast := TRUE;
6470 ELSE
6471 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6472 END IF;
6473 END IF; -- usage_per_day <> 0
6474 END IF; /* end date */
6475 ELSE
6476 -- fix for bug# 7646170
6477 -- Get next forecast record.
6478 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6479 IF (l_next_index IS NULL) THEN
6480 l_no_forecast := TRUE;
6481 ELSE
6482 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6483 END IF;
6484
6485 END IF; /* start date */
6486 ELSE
6487 l_next_index := G_forecast_details_tbl.NEXT(l_next_index);
6488 IF (l_next_index IS NULL) THEN
6489 l_no_forecast := TRUE;
6490 ELSE
6491 l_start_date := G_forecast_details_tbl(l_next_index).START_DATE;
6492 END IF;
6493 END IF; /* uom_code */
6494
6495 END LOOP; /* while */
6496
6497 IF (l_no_forecast = TRUE AND l_counter_remain <> 0) THEN
6498 x_due_date := null;
6499 ELSE
6500 IF (p_start_date IS NULL) THEN
6501 -- Added condition to avoid due date > 31-dec-9999 when forecast
6502 -- is very less (like .00001, .000001 etc)
6503 IF (l_forecast_days > (to_date('31/12/9999','DD/MM/YYYY') - trunc(sysdate))) THEN
6504 x_due_date := null;
6505 ELSE
6506 x_due_date := trunc(sysdate + l_forecast_days);
6507 END IF;
6508 ELSE
6509 -- Added condition to avoid due date > 31-dec-9999 when forecast
6510 -- is very less (like .00001, .000001 etc)
6511 IF (l_forecast_days > (to_date('31/12/9999','DD/MM/YYYY') - trunc(p_start_date))) THEN
6512 x_due_date := null;
6513 ELSE
6514 x_due_date := trunc(p_start_date + l_forecast_days);
6515 END IF;
6516 END IF;
6517 END IF;
6518
6519 IF G_DEBUG = 'Y' THEN
6520 AHL_DEBUG_PUB.Debug('Date calculated by forecast:' || x_due_date);
6521 AHL_DEBUG_PUB.Debug('End Get_Date_from_UF');
6522 END IF;
6523
6524
6525 END Get_Date_from_UF;
6526
6527 -------------------------------------------------------------------------------
6528 -- This will return the adjusted interval value if the next due counter value
6529 -- overlaps two intervals. It will be used where the overflow condition occurs
6530 -- based on the interval's start value and stop value.
6531
6532 PROCEDURE Adjust_Interval_Value ( p_mr_effectivity_id IN NUMBER,
6533 p_counter_id IN NUMBER,
6534 p_counter_value IN NUMBER,
6535 p_interval_value IN NUMBER,
6536 p_stop_value IN NUMBER,
6537 x_adjusted_int_value OUT NOCOPY NUMBER,
6538 x_nxt_interval_found OUT NOCOPY BOOLEAN)
6539 IS
6540 -- read intervals for the effectivity id.
6541 CURSOR ahl_mr_intervalvalue_csr (p_mr_effectivity_id IN NUMBER,
6542 p_counter_id IN NUMBER,
6543 p_counter_value IN NUMBER) IS
6544 /*
6545 SELECT INT.start_value, INT.stop_value,
6546 INT.interval_value
6547 FROM ahl_mr_intervals INT, cs_counters_v CTR, cs_counters_v CN
6548 WHERE INT.counter_id = CTR.counter_id AND
6549 CTR.name = CN.name AND
6550 INT.mr_effectivity_id = p_mr_effectivity_id AND
6551 CN.counter_id = p_counter_id AND
6552 ( nvl(start_value, p_counter_value+1) <= p_counter_value AND
6553 --p_counter_value < nvl(stop_value, p_counter_value)
6554 p_counter_value < nvl(stop_value, p_counter_value + 1)--fix for bug number 3713078
6555 );
6556 */
6557
6558 --Priyan
6559 --Query being changed due to performance related fixes
6560 --Refer Bug # 4918744
6561
6562 SELECT
6563 INT.START_VALUE,
6564 INT.STOP_VALUE,
6565 INT.INTERVAL_VALUE
6566 FROM
6567 AHL_MR_INTERVALS INT,
6568 CSI_COUNTER_TEMPLATE_VL CTR,
6569 --CSI_COUNTER_TEMPLATE_VL CN --bug# 5918525
6570 csi_counters_vl CN
6571 WHERE
6572 INT.COUNTER_ID = CTR.COUNTER_ID AND
6573 --CTR.NAME = CN.NAME AND -- bug# 5918525
6574 CTR.NAME = CN.counter_template_name AND
6575 INT.MR_EFFECTIVITY_ID = P_MR_EFFECTIVITY_ID AND
6576 CN.COUNTER_ID = P_COUNTER_ID AND
6577 (
6578 NVL(START_VALUE, P_COUNTER_VALUE +1) <= P_COUNTER_VALUE AND
6579 P_COUNTER_VALUE < NVL(STOP_VALUE, P_COUNTER_VALUE + 1)
6580 ) ;
6581
6582 l_remaining_ctr_fraction NUMBER; /* reminder fraction that needs to be interpolated with
6583 the interval value of the next mr interval record */
6584 l_overflow_value NUMBER; /* the counter value that overflows to the next interval. */
6585 l_next_due_counter_value NUMBER;
6586
6587 -- variables used in cursor fetch.
6588 l_start_value NUMBER;
6589 l_stop_value NUMBER;
6590 l_interval_value NUMBER;
6591
6592 BEGIN
6593
6594 IF G_DEBUG = 'Y' THEN
6595 AHL_DEBUG_PUB.Debug('Start Adjust Interval Value');
6596 END IF;
6597
6598 IF (p_stop_value IS NULL) THEN
6599 x_adjusted_int_value := p_interval_value;
6600 x_nxt_interval_found := TRUE;
6601 ELSE
6602 l_next_due_counter_value := p_counter_value + p_interval_value;
6603 l_overflow_value := l_next_due_counter_value - p_stop_value;
6604
6605 x_adjusted_int_value := p_stop_value - p_counter_value;
6606
6607 l_remaining_ctr_fraction := (l_overflow_value/p_interval_value);
6608
6609 -- Get next record to match this interval.
6610 OPEN ahl_mr_intervalvalue_csr (p_mr_effectivity_id,
6611 p_counter_id,
6612 p_stop_value + 1);
6613 FETCH ahl_mr_intervalvalue_csr INTO l_start_value, l_stop_value, l_interval_value;
6614 IF (ahl_mr_intervalvalue_csr%NOTFOUND) THEN
6615
6616 -- Fix for bug# 3461118.
6617 x_nxt_interval_found := FALSE;
6618 x_adjusted_int_value := p_interval_value;
6619 ELSE
6620 x_nxt_interval_found := TRUE;
6621 x_adjusted_int_value := x_adjusted_int_value + (l_remaining_ctr_fraction * l_interval_value);
6622 END IF; /* end ahl_mr_intervalvalue_csr if */
6623
6624 CLOSE ahl_mr_intervalvalue_csr;
6625
6626 END IF; /* p_stop_value if */
6627
6628 --x_adjusted_int_value := trunc(x_adjusted_int_value);
6629 x_adjusted_int_value := x_adjusted_int_value;
6630
6631 IF G_DEBUG = 'Y' THEN
6632 AHL_DEBUG_PUB.Debug('End Adjust Interval Value');
6633 END IF;
6634
6635
6636 END Adjust_Interval_Value;
6637
6638 -----------------------------------------------------------------------------
6639 -- This will return the adjusted due date if the next due date overlaps two intervals.
6640 -- It will be used where the overflow condition occurs based on the interval's start
6641 -- date and stop date.
6642
6643 PROCEDURE Adjust_Due_Date ( p_mr_effectivity_id IN NUMBER,
6644 p_start_counter_rec IN counter_values_rec_type,
6645 p_start_due_date IN DATE,
6646 p_counter_rules_tbl IN counter_rules_tbl_type,
6647 p_interval_value IN NUMBER,
6648 p_stop_date IN DATE,
6649 p_due_date IN DATE,
6650 x_adjusted_due_date OUT NOCOPY DATE,
6651 x_adjusted_due_ctr OUT NOCOPY NUMBER,
6652 x_nxt_interval_found OUT NOCOPY BOOLEAN)
6653
6654 IS
6655
6656 l_return_val BOOLEAN;
6657
6658 l_start_counter_tbl counter_values_tbl_type;
6659 l_stop_counter_tbl counter_values_tbl_type;
6660
6661 l_forecast_days NUMBER;
6662 l_temp_due_date DATE;
6663 l_next_due_counter_remain NUMBER;
6664 l_remaining_ctr_fraction NUMBER;
6665 -- l_remaining_ctr_value NUMBER;
6666
6667 l_start_date DATE;
6668 l_stop_date DATE;
6669 l_interval_value NUMBER;
6670 l_adjusted_due_ctr NUMBER;
6671
6672 -- get the next interval record for the provided stop value.
6673 CURSOR ahl_mr_intervaldate_csr (p_mr_effectivity_id IN NUMBER,
6674 p_counter_id IN NUMBER,
6675 p_stop_date IN DATE) IS
6676 /* SELECT INT.start_date, INT.stop_date,
6677 INT.interval_value
6678 FROM ahl_mr_intervals INT, cs_counters_v CTR, cs_counters_v CN
6679 WHERE INT.counter_id = CTR.counter_id AND
6680 CTR.name = CN.name AND
6681 INT.mr_effectivity_id = p_mr_effectivity_id AND
6682 CN.counter_id = p_counter_id AND
6683 trunc(INT.start_date) = trunc(p_stop_date);
6684 */
6685
6686 --Priyan
6687 --Query being changed due to performance related fixes
6688 --Refer Bug # 4918744
6689 --Changes the usage of CS_COUNTERS_V to CSI_COUNTER_TEMPLATE_VL
6690
6691 SELECT
6692 INT.START_DATE,
6693 INT.STOP_DATE,
6694 INT.INTERVAL_VALUE
6695 FROM
6696 AHL_MR_INTERVALS INT,
6697 CSI_COUNTER_TEMPLATE_VL CTR,
6698 --CSI_COUNTER_TEMPLATE_VL CN --bug# 5918525
6699 csi_counters_vl CN
6700 WHERE
6701 INT.COUNTER_ID = CTR.COUNTER_ID
6702 --AND CTR.NAME = CN.NAME --bug# 5918525
6703 AND CTR.NAME = CN.counter_template_name
6704 AND INT.MR_EFFECTIVITY_ID = P_MR_EFFECTIVITY_ID
6705 AND CN.COUNTER_ID = P_COUNTER_ID
6706 AND TRUNC(INT.START_DATE) = TRUNC(P_STOP_DATE) ;
6707
6708 BEGIN
6709
6710 IF G_DEBUG = 'Y' THEN
6711 AHL_DEBUG_PUB.Debug('Start Adjust Due Date');
6712 END IF;
6713
6714 IF (trunc(p_due_date) <= trunc(p_stop_date)) THEN
6715 x_adjusted_due_date := p_due_date;
6716 x_nxt_interval_found := TRUE;
6717 ELSE
6718 l_start_counter_tbl(1) := p_start_counter_rec;
6719
6720 -- Get counter values for stop date.
6721 Get_Due_At_Counter_Values (p_last_due_date => p_start_due_date,
6722 p_last_due_counter_val_tbl => l_start_counter_tbl,
6723 p_due_date => p_stop_date,
6724 p_counter_rules_tbl => p_counter_rules_tbl,
6725 x_due_at_counter_val_tbl => l_stop_counter_tbl,
6726 x_return_value => l_return_val);
6727
6728 IF NOT(l_return_val) THEN
6729 x_adjusted_due_date := p_due_date;
6730 x_nxt_interval_found := FALSE;
6731 ELSE
6732 l_next_due_counter_remain := l_stop_counter_tbl(1).counter_value - p_start_counter_rec.counter_value;
6733 l_adjusted_due_ctr := l_next_due_counter_remain;
6734 l_remaining_ctr_fraction := 1 - (l_next_due_counter_remain/p_interval_value);
6735
6736 -- Get next record to match this interval.
6737
6738 OPEN ahl_mr_intervalDate_csr (p_mr_effectivity_id,
6739 p_start_counter_rec.counter_id,
6740 p_stop_date+1);
6741 FETCH ahl_mr_intervalDate_csr INTO l_start_date, l_stop_date, l_interval_value;
6742 IF (ahl_mr_intervalDate_csr%NOTFOUND) THEN
6743 -- Fix for bug# 3461118.
6744 x_adjusted_due_date := p_due_date;
6745 x_nxt_interval_found := FALSE;
6746 ELSE
6747
6748 l_next_due_counter_remain := trunc(l_remaining_ctr_fraction * l_interval_value);
6749 x_nxt_interval_found := TRUE;
6750
6751 -- Based on forecast get the due date.
6752 Get_Date_from_UF ( p_counter_remain => l_next_due_counter_remain,
6753 p_counter_uom_code => p_start_counter_rec.uom_code,
6754 p_counter_rules_tbl => p_counter_rules_tbl,
6755 p_start_date => p_stop_date,
6756 x_due_date => l_temp_due_date );
6757 -- l_temp_due_date is with respect to sysdate.
6758 IF (l_temp_due_date IS NULL) THEN
6759 x_adjusted_due_date := p_due_date;
6760 ELSE
6761 x_adjusted_due_date := l_temp_due_date;
6762 x_adjusted_due_ctr := l_adjusted_due_ctr + l_next_due_counter_remain;
6763 END IF;
6764 END IF; /* end ahl_mr_intervalDate_csr if */
6765 CLOSE ahl_mr_intervalDate_csr;
6766 END IF;
6767 END IF;
6768
6769 IF G_DEBUG = 'Y' THEN
6770 AHL_DEBUG_PUB.Debug('End Adjust Interval Value');
6771 END IF;
6772
6773
6774 END Adjust_Due_Date;
6775
6776 -----------------------------------------------------------------------------
6777 -- This procedure will return due date based on the next interval(if exists),
6778 -- whenever an interval is not found for the current start/stop values or dates.
6779 -- Added parameter p_dependent_mr_flag to fix bug# 6711228.
6780 -- Added parameter p_mr_accomplish_exists and p_last_due_mr_interval_id to fix
6781 -- bug# 6858788. Commented p_last_accomplishment_date and will instead use p_mr_accomplish_exists.
6782 PROCEDURE Get_DueDate_from_NxtInterval(p_applicable_mrs_rec IN applicable_mrs_rec_type,
6783 p_repetivity_flag IN VARCHAR2,
6784 p_mr_effectivity_id IN NUMBER,
6785 p_current_ctr_rec IN Counter_values_rec_type,
6786 p_current_ctr_at_date IN DATE,
6787 p_counter_rules_tbl IN Counter_rules_tbl_type,
6788 p_start_int_match_at_ctr IN NUMBER,
6789 p_last_accomplish_ctr_val IN NUMBER,
6790 --p_last_accomplishment_date IN DATE,
6791 p_dependent_mr_flag IN BOOLEAN,
6792 p_mr_accomplish_exists IN BOOLEAN,
6793 p_last_due_mr_interval_id IN NUMBER,
6794 x_next_due_date_rec OUT NOCOPY next_due_date_rec_type,
6795 x_mr_interval_found OUT NOCOPY BOOLEAN,
6796 x_return_val OUT NOCOPY BOOLEAN)
6797 IS
6798
6799 CURSOR ahl_next_interval_ctr_csr (p_mr_effectivity_id IN NUMBER,
6800 --p_counter_id IN NUMBER,
6801 p_counter_name IN VARCHAR2,
6802 p_counter_value IN NUMBER) IS
6803 /*
6804 SELECT INT.mr_interval_id, INT.start_date, INT.stop_date,
6805 INT.start_value, INT.stop_value, INT.counter_id,
6806 INT.interval_value, INT.tolerance_after, INT.tolerance_before
6807 -- Replaced cs_counters_v with cs_counters to fix perf bug# 3786647.
6808 --FROM ahl_mr_intervals INT, cs_counters_v CTR, cs_counters_v CN
6809 FROM ahl_mr_intervals INT, cs_counters CTR, cs_counters CN
6810 WHERE INT.counter_id = CTR.counter_id AND
6811 CTR.name = CN.name AND
6812 INT.mr_effectivity_id = p_mr_effectivity_id AND
6813 CN.counter_id = p_counter_id AND
6814 INT.start_value > p_counter_value
6815 ORDER BY INT.start_value;
6816 */
6817
6818 --Priyan
6819 --Query being changed due to performance related fixes
6820 --Refer Bug # 4918744
6821 --Changes the usage of CS_COUNTERS_V to CSI_COUNTER_TEMPLATE_VL
6822 -- select first row only.
6823 SELECT *
6824 FROM (
6825 SELECT
6826 INT.MR_INTERVAL_ID,
6827 INT.START_DATE,
6828 INT.STOP_DATE,
6829 INT.START_VALUE,
6830 INT.STOP_VALUE,
6831 INT.COUNTER_ID,
6832 INT.INTERVAL_VALUE,
6833 INT.TOLERANCE_AFTER,
6834 INT.TOLERANCE_BEFORE,
6835 INT.EARLIEST_DUE_VALUE,
6836 INT.CALC_DUEDATE_RULE_CODE -- added for ER 7415856
6837 FROM
6838 AHL_MR_INTERVALS INT,
6839 CSI_COUNTER_TEMPLATE_VL CTR --,
6840 --CSI_COUNTER_TEMPLATE_VL CN --bug# 5918525
6841 --csi_counters_vl CN
6842 WHERE
6843 INT.COUNTER_ID = CTR.COUNTER_ID
6844 -- AND CTR.NAME = CN.NAME --bug# 5918525
6845 --AND CTR.NAME = CN.counter_template_name
6846 AND CTR.NAME = p_counter_name
6847 AND INT.MR_EFFECTIVITY_ID = P_MR_EFFECTIVITY_ID
6848 --AND CN.COUNTER_ID = P_COUNTER_ID
6849 AND INT.START_VALUE > P_COUNTER_VALUE
6850 ORDER BY
6851 INT.START_VALUE ASC
6852 )
6853 WHERE ROWNUM < 2;
6854
6855 CURSOR ahl_next_interval_date_csr (p_mr_effectivity_id IN NUMBER,
6856 --p_counter_id IN NUMBER,
6857 p_counter_name IN VARCHAR2,
6858 p_start_date IN DATE) IS
6859
6860 /*SELECT INT.mr_interval_id, INT.start_date, INT.stop_date,
6861 INT.tolerance_after, INT.tolerance_before, INT.interval_value
6862 -- Replaced cs_counters_v with cs_counters to fix perf bug# 3786647.
6863 --FROM ahl_mr_intervals INT, cs_counters_v CTR, cs_counters_v CN
6864 FROM ahl_mr_intervals INT, cs_counters CTR, cs_counters CN
6865 WHERE INT.counter_id = CTR.counter_id AND
6866 CTR.name = CN.name AND
6867 INT.mr_effectivity_id = p_mr_effectivity_id AND
6868 CN.counter_id = p_counter_id AND
6869 INT.start_date > p_start_date
6870 ORDER BY INT.start_date;
6871 */
6872
6873 --Priyan
6874 --Query being changed due to performance related fixes
6875 --Refer Bug # 4918744
6876 --Changes the usage of CS_COUNTERS_V to CSI_COUNTER_TEMPLATE_VL
6877 -- select first row only.
6878 SELECT *
6879 FROM (
6880 SELECT
6881 INT.MR_INTERVAL_ID,
6882 INT.START_DATE,
6883 INT.STOP_DATE,
6884 INT.TOLERANCE_AFTER,
6885 INT.TOLERANCE_BEFORE,
6886 INT.INTERVAL_VALUE,
6887 INT.EARLIEST_DUE_VALUE,
6888 INT.CALC_DUEDATE_RULE_CODE -- added for ER 7415856
6889 FROM
6890 AHL_MR_INTERVALS INT,
6891 CSI_COUNTER_TEMPLATE_VL CTR --,
6892 --CSI_COUNTER_TEMPLATE_VL CN --bug# 5918525
6893 --csi_counters_vl CN
6894 WHERE
6895 INT.COUNTER_ID = CTR.COUNTER_ID
6896 --AND CTR.NAME = CN.NAME --bug# 5918525
6897 --AND CTR.NAME = CN.counter_template_name
6898 AND CTR.NAME = p_counter_name
6899 AND INT.MR_EFFECTIVITY_ID = P_MR_EFFECTIVITY_ID
6900 --AND CN.COUNTER_ID = P_COUNTER_ID
6901 AND INT.START_DATE > P_START_DATE
6902 ORDER BY
6903 INT.START_DATE ASC
6904 )
6905 WHERE ROWNUM < 2;
6906
6907
6908 l_counter_remain NUMBER;
6909 l_counter_due_date DATE; -- due date calculated using start-value of interval.
6910 l_current_ctr_tbl counter_values_tbl_type;
6911 l_next_interval_ctr_rec ahl_next_interval_ctr_csr%ROWTYPE;
6912 l_next_interval_date_rec ahl_next_interval_date_csr%ROWTYPE;
6913 l_return_val BOOLEAN;
6914 l_due_counter_tbl counter_values_tbl_type;
6915 l_ctr_based BOOLEAN; -- indicates if due date is based on start-value of interval.
6916 l_date_based BOOLEAN; -- indicates if due date is based on start-date of interval.
6917
6918 l_date_due_date DATE;
6919 l_due_at_counter NUMBER;
6920
6921 l_mr_interval_found BOOLEAN := FALSE; -- set to true if a future interval is found.
6922
6923 -- Added to fix bug#4224867.
6924 l_date_based_counter_remain NUMBER;
6925 l_ctr_based_counter_remain NUMBER;
6926
6927 -- Added to fix bug# 6358940.
6928 l_next_due_date_rec next_due_date_rec_type;
6929 l_ctr_due_at_counter_value NUMBER;
6930
6931 BEGIN
6932
6933 IF G_DEBUG = 'Y' THEN
6934 AHL_DEBUG_PUB.Debug('Start Get_DueDate_from_NxtInterval');
6935 AHL_DEBUG_PUB.Debug('Input Counter ID:' || p_current_ctr_rec.counter_id);
6936 AHL_DEBUG_PUB.Debug('Input Counter Name:' || p_current_ctr_rec.counter_name);
6937 AHL_DEBUG_PUB.Debug('Input Counter start value:' || p_start_int_match_at_ctr);
6938 END IF;
6939
6940 -- Initialize.
6941 x_return_val := TRUE;
6942 l_ctr_based := FALSE; -- indicates if due date is based on start-value of interval.
6943 l_date_based := FALSE; -- indicates if due date is based on start-date of interval.
6944
6945 -- initialize.
6946 x_next_due_date_rec := l_next_due_date_rec;
6947
6948 -- Find interval greater than the counter value.
6949 OPEN ahl_next_interval_ctr_csr(p_mr_effectivity_id,
6950 --p_current_ctr_rec.counter_id,
6951 p_current_ctr_rec.counter_name,
6952 p_start_int_match_at_ctr);
6953 FETCH ahl_next_interval_ctr_csr INTO l_next_interval_ctr_rec;
6954 IF (ahl_next_interval_ctr_csr%FOUND) THEN
6955 l_mr_interval_found := TRUE;
6956
6957 l_counter_remain := l_next_interval_ctr_rec.start_value - p_current_ctr_rec.counter_value;
6958 l_ctr_due_at_counter_value := l_next_interval_ctr_rec.start_value;
6959
6960 -- Added for ER 7415856
6961 -- if rule code is set as INTERVAL then add interval to due counter value.
6962 IF (l_next_interval_ctr_rec.calc_duedate_rule_code = 'INTERVAL') THEN
6963 l_counter_remain := l_next_interval_ctr_rec.start_value + l_next_interval_ctr_rec.interval_value
6964 - p_current_ctr_rec.counter_value;
6965 l_ctr_due_at_counter_value := l_next_interval_ctr_rec.start_value
6966 + l_next_interval_ctr_rec.interval_value;
6967 END IF;
6968
6969 -- Added to fix bug# 6358940
6970 -- here start value will not be a null value.
6971 IF (l_next_interval_ctr_rec.earliest_due_value IS NOT NULL
6972 AND p_repetivity_flag = 'N') THEN
6973 IF (p_mr_accomplish_exists = TRUE AND p_dependent_mr_flag = FALSE) THEN
6974 -- MR accomplishment exists.
6975 IF (p_last_accomplish_ctr_val >= l_next_interval_ctr_rec.earliest_due_value) THEN
6976 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_ctr_rec.interval_value
6977 - p_current_ctr_rec.counter_value;
6978 l_ctr_due_at_counter_value := p_last_accomplish_ctr_val
6979 + l_next_interval_ctr_rec.interval_value;
6980
6981 END IF;
6982 END IF;
6983 ELSIF (l_next_interval_ctr_rec.earliest_due_value IS NULL AND p_repetivity_flag = 'N' AND
6984 p_mr_accomplish_exists = TRUE AND p_dependent_mr_flag = FALSE) THEN
6985 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_ctr_rec.interval_value
6986 - p_current_ctr_rec.counter_value;
6987 l_ctr_due_at_counter_value := p_last_accomplish_ctr_val
6988 + l_next_interval_ctr_rec.interval_value;
6989
6990 END IF;
6991
6992 -- Added to fix bug# 6858788(for repetity).
6993 IF (p_repetivity_flag = 'Y' AND p_last_due_mr_interval_id = l_next_interval_ctr_rec.mr_interval_id) THEN
6994 -- same interval threshold as previous due date calculation. Use
6995 -- interval value rather than start value.
6996 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_ctr_rec.interval_value
6997 - p_current_ctr_rec.counter_value;
6998 l_ctr_due_at_counter_value := p_last_accomplish_ctr_val
6999 + l_next_interval_ctr_rec.interval_value;
7000 -- case where last and current triggered intervals do not match. Ex: where group MR triggers.
7001 ELSIF (p_repetivity_flag = 'Y' AND l_next_interval_ctr_rec.earliest_due_value IS NOT NULL) THEN
7002 IF (p_last_accomplish_ctr_val >= l_next_interval_ctr_rec.earliest_due_value) THEN
7003 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_ctr_rec.interval_value
7004 - p_current_ctr_rec.counter_value;
7005 l_ctr_due_at_counter_value := p_last_accomplish_ctr_val + l_next_interval_ctr_rec.interval_value;
7006 END IF;
7007 ELSIF (p_repetivity_flag = 'Y' AND l_next_interval_ctr_rec.earliest_due_value IS NULL) THEN
7008 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_ctr_rec.interval_value
7009 - p_current_ctr_rec.counter_value;
7010 l_ctr_due_at_counter_value := p_last_accomplish_ctr_val + l_next_interval_ctr_rec.interval_value;
7011
7012 END IF;
7013
7014 IF G_DEBUG = 'Y' THEN
7015 AHL_DEBUG_PUB.Debug('Found future interval with start value:' || l_next_interval_ctr_rec.start_value);
7016 AHL_DEBUG_PUB.Debug('Last due interval ID:' || p_last_due_mr_interval_id);
7017 AHL_DEBUG_PUB.Debug('Current interval ID:' || l_next_interval_ctr_rec.mr_interval_id);
7018 AHL_DEBUG_PUB.Debug('p_last_accomplish_ctr_val:' || p_last_accomplish_ctr_val);
7019 AHL_DEBUG_PUB.Debug('p_current_ctr_rec.counter_value:' || p_current_ctr_rec.counter_value);
7020 AHL_DEBUG_PUB.Debug('l_next_interval_date_rec.interval_value:' || l_next_interval_ctr_rec.interval_value);
7021 AHL_DEBUG_PUB.Debug('counter remain:' || l_counter_remain);
7022 END IF;
7023
7024 -- l_counter_remain can be negative. Fix bug# 6739599.
7025 IF (l_counter_remain > 0) THEN
7026 -- calculate due date based on forecast.
7027 get_date_from_uf(l_counter_remain,
7028 p_current_ctr_rec.uom_code,
7029 p_counter_rules_tbl,
7030 p_current_ctr_at_date,
7031 l_counter_due_date);
7032 ELSIF (l_counter_remain = 0) THEN
7033 l_counter_due_date := trunc(sysdate);
7034 ELSIF (l_counter_remain < 0) THEN
7035 -- Due date = counter reading date.
7036 get_ctr_date_for_reading (p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
7037 p_counter_id => p_current_ctr_rec.counter_id,
7038 p_counter_value => l_ctr_due_at_counter_value,
7039 x_ctr_record_date => l_counter_due_date,
7040 x_return_val => l_return_val);
7041 IF NOT(l_return_val) THEN
7042 l_counter_due_date := trunc(sysdate);
7043 END IF;
7044
7045 END IF;
7046
7047 --dbms_output.put_line ('due date by forecast' || l_due_date );
7048
7049 /* commented to fix bug# 6907562.
7050 -- Check the due date value.
7051 IF (l_counter_due_date IS NULL) THEN
7052 CLOSE ahl_next_interval_ctr_csr;
7053 x_return_val := FALSE;
7054 RETURN;
7055 END IF;
7056 */
7057
7058 -- fix bug# 4224867.
7059 l_ctr_based_counter_remain := l_counter_remain;
7060
7061 END IF; -- ahl_next_ctr_interval_csr found.
7062
7063 -- Now check for existence of interval, based on date range.
7064 OPEN ahl_next_interval_date_csr(p_mr_effectivity_id,
7065 --p_current_ctr_rec.counter_id,
7066 p_current_ctr_rec.counter_name,
7067 p_current_ctr_at_date);
7068 FETCH ahl_next_interval_date_csr INTO l_next_interval_date_rec;
7069 IF (ahl_next_interval_date_csr%FOUND) THEN
7070 l_mr_interval_found := TRUE;
7071
7072 -- Added to fix bug# 6358940
7073 -- here start date will not be a null value.
7074 IF (l_next_interval_date_rec.earliest_due_value IS NOT NULL AND p_repetivity_flag = 'N') AND
7075 (p_mr_accomplish_exists = TRUE AND p_dependent_mr_flag = FALSE) AND -- MR accomplishment exists.
7076 (p_last_accomplish_ctr_val >= l_next_interval_date_rec.earliest_due_value) THEN
7077 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_date_rec.interval_value
7078 - p_current_ctr_rec.counter_value;
7079 l_due_at_counter := p_last_accomplish_ctr_val
7080 + l_next_interval_date_rec.interval_value;
7081
7082 ELSIF (l_next_interval_date_rec.earliest_due_value IS NULL AND p_repetivity_flag = 'N' AND
7083 p_mr_accomplish_exists = TRUE AND p_dependent_mr_flag = FALSE) THEN
7084 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_date_rec.interval_value
7085 - p_current_ctr_rec.counter_value;
7086 l_due_at_counter := p_last_accomplish_ctr_val
7087 + l_next_interval_date_rec.interval_value;
7088
7089 -- added to fix bug# 6858788(consider repetivity = Y).
7090 ELSIF (p_repetivity_flag = 'Y' AND p_last_due_mr_interval_id = l_next_interval_date_rec.mr_interval_id) THEN
7091 -- same interval threshold as previous due date calculation. Use
7092 -- interval value rather than start value.
7093 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_date_rec.interval_value
7094 - p_current_ctr_rec.counter_value;
7095 l_due_at_counter := p_last_accomplish_ctr_val
7096 + l_next_interval_date_rec.interval_value;
7097 -- added to fix bug# 6858788(consider repetivity = Y) where last and current interval triggered
7098 -- are not the same..
7099 ELSIF (l_next_interval_date_rec.earliest_due_value IS NOT NULL AND p_repetivity_flag = 'Y') AND
7100 (p_last_accomplish_ctr_val >= l_next_interval_date_rec.earliest_due_value) THEN
7101 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_date_rec.interval_value
7102 - p_current_ctr_rec.counter_value;
7103 l_due_at_counter := p_last_accomplish_ctr_val
7104 + l_next_interval_date_rec.interval_value;
7105 ELSIF (l_next_interval_date_rec.earliest_due_value IS NULL AND p_repetivity_flag = 'Y') THEN
7106 l_counter_remain := p_last_accomplish_ctr_val + l_next_interval_date_rec.interval_value
7107 - p_current_ctr_rec.counter_value;
7108 l_due_at_counter := p_last_accomplish_ctr_val
7109 + l_next_interval_date_rec.interval_value;
7110
7111 ELSE
7112 --IF (ahl_next_interval_ctr_csr%FOUND) THEN
7113 -- Find the counter value as of l_next_interval_date_rec.start_date.
7114 l_current_ctr_tbl(1) := p_current_ctr_rec;
7115 Get_Due_At_Counter_Values (p_last_due_date => p_current_ctr_at_date,
7116 p_last_due_counter_val_tbl => l_current_ctr_tbl,
7117 p_due_date => l_next_interval_date_rec.start_date,
7118 p_counter_rules_tbl => p_counter_rules_tbl,
7119 x_due_at_counter_val_tbl => l_due_counter_tbl,
7120 x_return_value => l_return_val);
7121 IF NOT(l_return_val) THEN
7122 CLOSE ahl_next_interval_date_csr;
7123 CLOSE ahl_next_interval_ctr_csr;
7124 -- set return values.
7125 x_return_val := FALSE;
7126 x_next_due_date_rec.due_date := l_counter_due_date;
7127 x_next_due_date_rec.tolerance_after := l_next_interval_ctr_rec.tolerance_after;
7128 x_next_due_date_rec.tolerance_before := l_next_interval_ctr_rec.tolerance_before;
7129 x_next_due_date_rec.mr_interval_id := l_next_interval_ctr_rec.mr_interval_id;
7130 x_next_due_date_rec.due_at_counter_value := null;
7131 x_next_due_date_rec.counter_remain := null;
7132
7133 x_mr_interval_found := l_mr_interval_found;
7134
7135 RETURN;
7136 END IF;
7137
7138 -- Add interval to the counter value and get the due date for this.
7139 -- 11/01/07: due date should be l_next_interval_date_rec.start_date.
7140 l_counter_remain := l_due_counter_tbl(1).counter_value
7141 -- + l_next_interval_date_rec.interval_value
7142 - p_current_ctr_rec.counter_value;
7143
7144 l_due_at_counter := l_due_counter_tbl(1).counter_value;
7145 --+ l_next_interval_date_rec.interval_value;
7146
7147 -- Added for ER 7415856
7148 -- if rule code is set as INTERVAL then add interval to due counter value.
7149 IF (l_next_interval_date_rec.calc_duedate_rule_code = 'INTERVAL') THEN
7150 l_counter_remain := l_due_counter_tbl(1).counter_value + l_next_interval_date_rec.interval_value
7151 - p_current_ctr_rec.counter_value;
7152 l_due_at_counter := l_due_counter_tbl(1).counter_value
7153 + l_next_interval_date_rec.interval_value;
7154 END IF;
7155
7156 END IF;
7157
7158 IF G_DEBUG = 'Y' THEN
7159 AHL_DEBUG_PUB.Debug('Found future interval with start date:' || to_char(l_next_interval_date_rec.start_date,'DD-MON-YYYY'));
7160 AHL_DEBUG_PUB.Debug('counter remain:' || l_counter_remain);
7161 AHL_DEBUG_PUB.Debug('l_ctr_due_at_counter_value:' || l_ctr_due_at_counter_value);
7162 AHL_DEBUG_PUB.Debug('p_last_accomplish_ctr_val:' || p_last_accomplish_ctr_val);
7163 AHL_DEBUG_PUB.Debug('earliest_due_value:' || l_next_interval_date_rec.earliest_due_value);
7164 END IF;
7165
7166 -- calculate due date based on forecast.
7167 get_date_from_uf(l_counter_remain,
7168 p_current_ctr_rec.uom_code,
7169 p_counter_rules_tbl,
7170 p_current_ctr_at_date,
7171 l_date_due_date);
7172
7173 --dbms_output.put_line ('due date by forecast' || l_date_due_date );
7174
7175 /* commented to fix bug# 6907562.
7176 -- Check the due date value.
7177 IF (l_date_due_date IS NULL) THEN
7178 CLOSE ahl_next_interval_ctr_csr;
7179 x_return_val := FALSE;
7180 RETURN;
7181 END IF;
7182 */
7183
7184 -- fix bug# 4224867.
7185 l_date_based_counter_remain := l_counter_remain;
7186
7187 IF (ahl_next_interval_ctr_csr%FOUND) THEN
7188 -- Pick one of l_date_due_date OR l_counter_due_date
7189 -- as the due_date based on whichever_first_code.
7190 -- Added null due date checks to fix bug# 6907562.
7191 IF (l_counter_due_date IS NULL OR l_date_due_date IS NULL) THEN
7192 IF (validate_for_duedate_reset(l_date_due_date,
7193 l_date_based_counter_remain,
7194 l_counter_due_date,
7195 p_current_ctr_rec.counter_id,
7196 l_ctr_based_counter_remain) = 'Y') THEN
7197 l_date_based := TRUE;
7198 ELSE
7199 l_ctr_based := TRUE;
7200 END IF;
7201 ELSE
7202
7203 IF (p_applicable_mrs_rec.whichever_first_code = 'FIRST') THEN
7204 IF (l_counter_due_date <= l_date_due_date) THEN
7205 l_ctr_based := TRUE;
7206 ELSE
7207 l_date_based := TRUE;
7208 END IF;
7209 ELSE --whichever_first_code = 'LAST'
7210 IF (l_counter_due_date < l_date_due_date) THEN
7211 l_date_based := TRUE;
7212 ELSE
7213 l_ctr_based := TRUE;
7214 END IF;
7215 END IF; -- whichever first code.
7216 END IF; -- l_counter_due_date IS NULL
7217 ELSE
7218 -- Here due_date = start_date counter + interval.
7219 l_date_based := TRUE;
7220 END IF; -- ahl_next_interval_ctr_csr.
7221 ELSIF (ahl_next_interval_ctr_csr%FOUND) THEN
7222 l_ctr_based := TRUE;
7223 END IF; -- ahl_next_interval_date_csr.
7224
7225 CLOSE ahl_next_interval_ctr_csr;
7226 CLOSE ahl_next_interval_date_csr;
7227
7228 -- set output parameters.
7229 IF (l_ctr_based) THEN
7230 x_next_due_date_rec.due_date := l_counter_due_date;
7231 x_next_due_date_rec.tolerance_after := l_next_interval_ctr_rec.tolerance_after;
7232 x_next_due_date_rec.tolerance_before := l_next_interval_ctr_rec.tolerance_before;
7233 x_next_due_date_rec.mr_interval_id := l_next_interval_ctr_rec.mr_interval_id;
7234 --x_next_due_date_rec.due_at_counter_value := l_next_interval_ctr_rec.start_value;
7235 x_next_due_date_rec.due_at_counter_value := l_ctr_due_at_counter_value;
7236 x_next_due_date_rec.counter_remain := l_ctr_based_counter_remain;
7237
7238 /* commenting this out as this causes next repetity to be over interval
7239 * value (fix for bug# 6858788)
7240 -- Fix for bug# 6739599. l_counter_due_date can be a past date.
7241 IF (l_counter_due_date > trunc(sysdate)) THEN
7242 -- Check if the counter value on the due date is less than the due counter value.
7243 -- If less, add a day to the due date. This would ensure that the MR is performed not before
7244 -- the due counter value.
7245 l_current_ctr_tbl(1) := p_current_ctr_rec;
7246 Get_Due_At_Counter_Values (p_last_due_date => p_current_ctr_at_date,
7247 p_last_due_counter_val_tbl => l_current_ctr_tbl,
7248 p_due_date => l_counter_due_date,
7249 p_counter_rules_tbl => p_counter_rules_tbl,
7250 x_due_at_counter_val_tbl => l_due_counter_tbl,
7251 x_return_value => l_return_val);
7252
7253 IF (l_due_counter_tbl(1).counter_value < l_next_interval_ctr_rec.start_value) THEN
7254 l_counter_due_date := l_counter_due_date + 1;
7255 Get_Due_At_Counter_Values (p_last_due_date => p_current_ctr_at_date,
7256 p_last_due_counter_val_tbl => l_current_ctr_tbl,
7257 p_due_date => l_counter_due_date,
7258 p_counter_rules_tbl => p_counter_rules_tbl,
7259 x_due_at_counter_val_tbl => l_due_counter_tbl,
7260 x_return_value => l_return_val);
7261 IF NOT(l_return_val) THEN -- forecast not available.
7262 x_return_val := FALSE;
7263 RETURN;
7264 END IF;
7265
7266 --x_next_due_date_rec.due_at_counter_value := l_due_counter_tbl(1).counter_value;
7267 x_next_due_date_rec.due_date := l_counter_due_date;
7268 END IF;
7269 END IF; -- l_counter_due_date > trunc(sysdate)
7270 */
7271 ELSIF (l_date_based) THEN
7272
7273 x_next_due_date_rec.due_date := l_date_due_date;
7274 x_next_due_date_rec.tolerance_after := l_next_interval_date_rec.tolerance_after;
7275 x_next_due_date_rec.tolerance_before := l_next_interval_date_rec.tolerance_before;
7276 x_next_due_date_rec.mr_interval_id := l_next_interval_date_rec.mr_interval_id;
7277 x_next_due_date_rec.due_at_counter_value := l_due_at_counter;
7278 x_next_due_date_rec.counter_remain := l_date_based_counter_remain;
7279 END IF;
7280
7281 x_mr_interval_found := l_mr_interval_found;
7282
7283 IF G_DEBUG = 'Y' THEN
7284 AHL_DEBUG_PUB.Debug('End Get_DueDate_from_NxtInterval');
7285 END IF;
7286
7287 END Get_DueDate_from_NxtInterval;
7288
7289 -----------------------------------------------------------------------------
7290 -- Apply the counter ratio factor to convert a given counter value at a
7291 -- component level to the root instance. This is needed as forecast is only
7292 -- defined at root instance.
7293
7294 FUNCTION Apply_Counter_Ratio ( p_counter_remain IN NUMBER,
7295 p_counter_uom_code IN VARCHAR2,
7296 p_counter_rules_tbl IN counter_rules_tbl_type)
7297 RETURN NUMBER IS
7298
7299 l_counter_remain NUMBER := p_counter_remain;
7300
7301 BEGIN
7302
7303 IF G_DEBUG = 'Y' THEN
7304 AHL_DEBUG_PUB.Debug('Start Apply Counter Ratio');
7305 END IF;
7306
7307 -- Loop through p_counter_rules_tbl.
7308 IF (p_counter_rules_tbl.COUNT > 0) THEN
7309 FOR i IN p_counter_rules_tbl.FIRST..p_counter_rules_tbl.LAST LOOP
7310 IF (p_counter_rules_tbl(i).uom_code = p_counter_uom_code) THEN
7311 l_counter_remain := p_counter_remain / p_counter_rules_tbl(i).ratio;
7312 END IF;
7313 END LOOP;
7314 END IF;
7315
7316 IF G_DEBUG = 'Y' THEN
7317 AHL_DEBUG_PUB.Debug('End Apply Counter Ratio');
7318 END IF;
7319
7320 RETURN l_counter_remain;
7321
7322 END Apply_Counter_Ratio;
7323
7324 -------------------------------------------------------------------------------
7325 -- Apply the counter ratio factor to convert a given counter value at a root
7326 -- instance level to the component. This is needed as forecast is only defined
7327 -- at root instance.
7328
7329 FUNCTION Apply_ReverseCounter_Ratio ( p_counter_remain IN NUMBER,
7330 p_counter_uom_code IN VARCHAR2,
7331 p_counter_rules_tbl IN counter_rules_tbl_type)
7332 RETURN NUMBER IS
7333
7334 l_counter_remain NUMBER := p_counter_remain;
7335
7336 BEGIN
7337
7338 IF G_DEBUG = 'Y' THEN
7339 AHL_DEBUG_PUB.Debug('Start Apply Reverse Counter Ratio');
7340 END IF;
7341
7342
7343 -- Loop through p_counter_rules_tbl.
7344 IF (p_counter_rules_tbl.COUNT > 0) THEN
7345 FOR i IN p_counter_rules_tbl.FIRST..p_counter_rules_tbl.LAST LOOP
7346 IF (p_counter_rules_tbl(i).uom_code = p_counter_uom_code) THEN
7347 l_counter_remain := p_counter_remain * p_counter_rules_tbl(i).ratio;
7348 END IF;
7349 END LOOP;
7350 END IF;
7351
7352 IF G_DEBUG = 'Y' THEN
7353 AHL_DEBUG_PUB.Debug('End Apply Reverse Counter Ratio');
7354 END IF;
7355
7356 RETURN l_counter_remain;
7357
7358 END Apply_ReverseCounter_Ratio;
7359
7360 ------------------------------------------------------------------------------
7361 -- To process the decendents in case the mr is a group MR.
7362
7363 PROCEDURE Process_GroupMR (p_applicable_mrs_rec IN applicable_mrs_rec_type,
7364 p_new_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE,
7365 p_unit_effectivity_tbl IN unit_effectivity_tbl_type,
7366 p_old_UE_forecast_sequence IN NUMBER := -1)
7367
7368 IS
7369
7370 -- Read applicable group table for validation.
7371 -- In this table mr_header_id/csi_item_instance_id are parents
7372 -- and related_mr_header_id/related_csi_item_instance_id are children.
7373 CURSOR ahl_applicable_grp_csr( p_item_instance_id IN NUMBER,
7374 p_mr_header_id IN NUMBER,
7375 p_level IN NUMBER) IS
7376
7377 SELECT mr_header_id, csi_item_instance_id,
7378 related_mr_header_id,
7379 related_csi_item_instance_id
7380 FROM ahl_applicable_mr_relns
7381 WHERE level = p_level
7382 START WITH mr_header_id = p_mr_header_id AND
7383 csi_item_instance_id = p_item_instance_id AND
7384 orig_mr_header_id = p_mr_header_id AND
7385 orig_csi_item_instance_id = p_item_instance_id AND
7386 relationship_code = 'PARENT'
7387 CONNECT BY PRIOR related_mr_header_id = mr_header_id AND
7388 PRIOR related_csi_item_instance_id = csi_item_instance_id AND
7389 orig_mr_header_id = p_mr_header_id AND
7390 orig_csi_item_instance_id = p_item_instance_id AND
7391 relationship_code = 'PARENT'
7392 ORDER BY level, mr_header_id, csi_item_instance_id;
7393
7394 -- Read applicable group table for updates.
7395 CURSOR ahl_applicable1_grp_csr( p_item_instance_id IN NUMBER,
7396 p_mr_header_id IN NUMBER) IS
7397
7398 SELECT mr_header_id, csi_item_instance_id, related_mr_header_id,
7399 related_csi_item_instance_id
7400 FROM ahl_applicable_mr_relns
7401 START WITH mr_header_id = p_mr_header_id AND
7402 csi_item_instance_id = p_item_instance_id AND
7403 orig_mr_header_id = p_mr_header_id AND
7404 orig_csi_item_instance_id = p_item_instance_id AND
7405 relationship_code = 'PARENT'
7406 CONNECT BY PRIOR related_mr_header_id = mr_header_id AND
7407 PRIOR related_csi_item_instance_id = csi_item_instance_id AND
7408 orig_mr_header_id = p_mr_header_id AND
7409 orig_csi_item_instance_id = p_item_instance_id AND
7410 relationship_code = 'PARENT'
7411 ORDER BY level, mr_header_id, csi_item_instance_id;
7412
7413 -- for reading unit effectivity table.
7414 CURSOR ahl_ue_relns_csr ( p_unit_effectivity_id IN NUMBER, p_level IN NUMBER ) IS
7415 SELECT ue_id, related_ue_id
7416 FROM ahl_ue_relationships relns
7417 WHERE level = p_level
7418 START WITH ue_id = p_unit_effectivity_id AND
7419 relationship_code = 'PARENT'
7420 CONNECT BY PRIOR related_ue_id = ue_id AND
7421 originator_ue_id = p_unit_effectivity_id AND
7422 relationship_code = 'PARENT'
7423 ORDER BY level;
7424
7425 -- get related unit effectivities details.
7426 CURSOR ahl_ue_csr ( p_ue_id IN NUMBER,
7427 p_related_ue_id IN NUMBER ) IS
7428 SELECT ue1.mr_header_id, ue1.csi_item_instance_id,
7429 ue2.mr_header_id related_mr_header_id,
7430 ue2.csi_item_instance_id related_csi_item_instance_id
7431 --FROM ahl_unit_effectivities_app_v ue1, ahl_unit_effectivities_app_v ue2
7432 FROM ahl_unit_effectivities_b ue1, ahl_unit_effectivities_b ue2
7433 WHERE ue1.unit_effectivity_id = p_ue_id AND
7434 ue2.unit_effectivity_id = p_related_ue_id;
7435
7436 -- To check if mr has a preceding mr.
7437 CURSOR ahl_appl_mr_csr (p_item_instance_id IN NUMBER,
7438 p_mr_header_id IN NUMBER) IS
7439 SELECT 'x'
7440 FROM ahl_applicable_mrs
7441 WHERE csi_item_instance_id = p_item_instance_id AND
7442 mr_header_id = p_mr_header_id AND
7443 implement_status_code <> 'OPTIONAL_DO_NOT_IMPLEMENT' AND
7444 preceding_mr_header_id IS NOT NULL;
7445
7446 l_new_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
7447 l_initialize_ue_rec ahl_temp_unit_effectivities%ROWTYPE;
7448
7449 l_junk VARCHAR2(1);
7450 l_visit_end_date DATE;
7451 l_unit_effectivity_id NUMBER;
7452 l_ue_id NUMBER;
7453 l_related_ue_id NUMBER;
7454
7455 TYPE ue_details_rec_type IS RECORD (
7456 mr_header_id NUMBER,
7457 csi_item_instance_id NUMBER,
7458 related_mr_header_id NUMBER,
7459 related_csi_item_instance_id NUMBER,
7460 match_flag VARCHAR2(1));
7461
7462 l_ue_details_rec ue_details_rec_type;
7463
7464 TYPE l_ue_details_tbl_type IS TABLE OF ue_details_rec_type INDEX BY BINARY_INTEGER;
7465
7466 l_ue_details_tbl l_ue_details_tbl_type;
7467 l_grp_details_tbl l_ue_details_tbl_type;
7468
7469 l_grp_match BOOLEAN;
7470 l_level NUMBER;
7471 l_reln_found BOOLEAN;
7472 l_appl_grp_found BOOLEAN;
7473
7474 i NUMBER;
7475
7476 l_visit_status VARCHAR2(30);
7477
7478 BEGIN
7479
7480 IF G_DEBUG = 'Y' THEN
7481 AHL_DEBUG_PUB.Debug('Start Process Group MR');
7482 END IF;
7483
7484 l_grp_match := FALSE; /* set default to be "no group" available to match against in ahl_unit_effectitivities. */
7485
7486 IF (p_old_UE_forecast_sequence <> -1) THEN
7487 -- match the group tree under unit_effectivity_id in unit_effectivity_tbl(l_old_UE_forecast_sequence)
7488 -- with the one in ahl_applicable_mr_relns.
7489
7490 l_level := 0; /* tree level */
7491 l_unit_effectivity_id := p_unit_effectivity_tbl(p_old_UE_forecast_sequence).unit_effectivity_id;
7492
7493 l_grp_match := TRUE;
7494 l_reln_found := TRUE; /* ue_relns record found */
7495 l_appl_grp_found := TRUE; /* applicable grp mrs found */
7496
7497 -- Check if workorder already created.
7498 l_visit_status := AHL_UMP_UTIL_PKG.get_Visit_Status (l_unit_effectivity_id);
7499
7500 -- when UE is on shop floor or UE status is INIT-DUE, skip group MR comparison.
7501 -- This will be done later in flush_from_temp_table proc.
7502 IF (p_unit_effectivity_tbl(p_old_UE_forecast_sequence).status_code) = 'INIT-DUE'
7503 OR (nvl(l_visit_status,'x') IN ('RELEASED','CLOSED')) THEN
7504 null; -- for init-due status skip group MR comparison. This will be done later in flush_from_temp_table proc.
7505 -- We need the UE id inserted as the First Due info needs to be copied to new UE
7506 ELSE
7507
7508 WHILE ( ((l_reln_found) OR (l_appl_grp_found)) AND (l_grp_match = TRUE)) LOOP
7509
7510 l_level := l_level + 1;
7511 --dbms_output.put_line('level:' || l_level);
7512 i := 1;
7513 FOR l_ue_relns_rec IN ahl_ue_relns_csr(l_unit_effectivity_id, l_level) LOOP
7514 OPEN ahl_ue_csr(l_ue_relns_rec.ue_id, l_ue_relns_rec.related_ue_id);
7515 FETCH ahl_ue_csr INTO l_ue_details_tbl(i).mr_header_id,
7516 l_ue_details_tbl(i).csi_item_instance_id,
7517 l_ue_details_tbl(i).related_mr_header_id,
7518 l_ue_details_tbl(i).related_csi_item_instance_id;
7519 IF (ahl_ue_csr%NOTFOUND) THEN
7520 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_RELN_NOTFOUND');
7521 FND_MESSAGE.Set_Token('UE_ID',l_ue_relns_rec.ue_id);
7522 FND_MESSAGE.Set_Token('RELATED_UE_ID', l_ue_relns_rec.related_ue_id);
7523 FND_MSG_PUB.ADD;
7524 CLOSE ahl_ue_csr;
7525 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7526 END IF;
7527 --dbms_output.put_line ('found ue relns');
7528
7529 l_ue_details_tbl(i).match_flag := 'N';
7530 i := i + 1;
7531 CLOSE ahl_ue_csr;
7532 END LOOP;
7533
7534 IF (l_ue_details_tbl.COUNT > 0 ) THEN
7535 l_reln_found := TRUE;
7536 ELSE
7537 l_reln_found := FALSE;
7538 END IF;
7539 --dbms_output.put_line('count ue tbl' || l_ue_details_tbl.COUNT);
7540
7541 -- from applicable_mrs_group.
7542 i := 1;
7543 FOR l_appl_grp_rec IN ahl_applicable_grp_csr(p_applicable_mrs_rec.csi_item_instance_id,
7544 p_applicable_mrs_rec.mr_header_id,
7545 l_level)
7546 LOOP
7547 l_grp_details_tbl(i).mr_header_id := l_appl_grp_rec.mr_header_id;
7548 l_grp_details_tbl(i).csi_item_instance_id := l_appl_grp_rec.csi_item_instance_id;
7549 l_grp_details_tbl(i).related_mr_header_id := l_appl_grp_rec.related_mr_header_id;
7550 l_grp_details_tbl(i).related_csi_item_instance_id := l_appl_grp_rec.related_csi_item_instance_id;
7551 l_grp_details_tbl(i).match_flag := 'N';
7552 i := i + 1;
7553 END LOOP;
7554
7555 IF (l_grp_details_tbl.COUNT > 0 ) THEN
7556 l_appl_grp_found := TRUE;
7557 ELSE
7558 l_appl_grp_found := FALSE;
7559 END IF;
7560 --dbms_output.put_line('count grp tbl' || l_grp_details_tbl.COUNT);
7561
7562 -- Now compare l_grp_details_tbl with l_ue_details_tbl.
7563 IF (l_grp_details_tbl.COUNT > 0 ) THEN
7564 FOR i IN l_grp_details_tbl.FIRST..l_grp_details_tbl.LAST LOOP
7565 -- match if entry present in l_ue_details_tbl.
7566
7567 IF (l_ue_details_tbl.COUNT > 0 ) THEN
7568 FOR j IN l_ue_details_tbl.FIRST..l_ue_details_tbl.LAST LOOP
7569 IF (l_ue_details_tbl(j).mr_header_id = l_grp_details_tbl(i).mr_header_id AND
7570 l_ue_details_tbl(j).csi_item_instance_id = l_grp_details_tbl(i).csi_item_instance_id AND
7571 l_ue_details_tbl(j).related_csi_item_instance_id = l_grp_details_tbl(i).related_csi_item_instance_id AND
7572 l_ue_details_tbl(j).related_mr_header_id = l_grp_details_tbl(i).related_mr_header_id AND
7573 l_ue_details_tbl(j).match_flag = 'N' AND
7574 l_grp_details_tbl(i).match_flag = 'N') THEN
7575 --l_ue_details_tbl.DELETE(j);
7576 --l_grp_details_tbl.DELETE(i);
7577 l_ue_details_tbl(j).match_flag := 'Y';
7578 l_grp_details_tbl(i).match_flag := 'Y';
7579 EXIT;
7580 END IF;
7581 END LOOP; /* ue_details */
7582 END IF; /* count - ue_details */
7583 END LOOP; /* grp_details */
7584 END IF; /* count - grp_details */
7585
7586 -- delete records from table where match flag is Y.
7587 IF (l_ue_details_tbl.COUNT > 0 ) THEN
7588 FOR j IN l_ue_details_tbl.FIRST..l_ue_details_tbl.LAST LOOP
7589 IF (l_ue_details_tbl(j).match_flag = 'Y') THEN
7590 l_ue_details_tbl.DELETE(j);
7591 END IF;
7592 END LOOP;
7593 END IF;
7594
7595 IF (l_grp_details_tbl.COUNT > 0 ) THEN
7596 FOR i IN l_grp_details_tbl.FIRST..l_grp_details_tbl.LAST LOOP
7597 IF (l_grp_details_tbl(i).match_flag = 'Y') THEN
7598 l_grp_details_tbl.DELETE(i);
7599 END IF;
7600 END LOOP;
7601 END IF;
7602
7603 IF (l_ue_details_tbl.COUNT <= 0) AND (l_grp_details_tbl.COUNT <= 0) THEN
7604 l_grp_match := TRUE;
7605
7606 ELSE
7607 l_grp_match := FALSE;
7608
7609 END IF;
7610
7611 END LOOP; /* while - level */
7612 END IF; -- status_code
7613
7614 END IF; -- p_old_UE_forecast_sequence
7615
7616 -- if trees match, then
7617 -- update the temp table record for orig MR with visit_end_date and unit_effectivity ID.
7618 IF (p_old_UE_forecast_sequence IS NOT NULL AND l_grp_match = TRUE) THEN
7619
7620 -- get visit end date from unit_effectivity_tbl for l_old_UE_Forecast_sequence.
7621 l_visit_end_date := p_unit_effectivity_tbl(p_old_UE_forecast_sequence).visit_end_date;
7622 l_new_unit_effectivity_rec.unit_effectivity_id :=
7623 p_unit_effectivity_tbl(p_old_UE_forecast_sequence).unit_effectivity_id;
7624
7625 ELSE
7626 l_visit_end_date := null;
7627 END IF;
7628
7629 -- construct temporary unit effectivity for group top node.
7630
7631 l_new_unit_effectivity_rec.due_date := p_new_unit_effectivity_rec.due_date;
7632 l_new_unit_effectivity_rec.mr_interval_id := p_new_unit_effectivity_rec.mr_interval_id;
7633 l_new_unit_effectivity_rec.mr_effectivity_id := p_new_unit_effectivity_rec.mr_effectivity_id;
7634 l_new_unit_effectivity_rec.due_counter_value := p_new_unit_effectivity_rec.due_counter_value;
7635 l_new_unit_effectivity_rec.csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
7636 l_new_unit_effectivity_rec.mr_header_id := p_applicable_mrs_rec.mr_header_id;
7637 l_new_unit_effectivity_rec.repetitive_mr_flag := p_new_unit_effectivity_rec.repetitive_mr_flag;
7638 l_new_unit_effectivity_rec.visit_end_date := l_visit_end_date;
7639 l_new_unit_effectivity_rec.forecast_sequence := p_new_unit_effectivity_rec.forecast_sequence;
7640 -- to indicate group.
7641 l_new_unit_effectivity_rec.orig_csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
7642 l_new_unit_effectivity_rec.orig_mr_header_id := p_applicable_mrs_rec.mr_header_id;
7643 l_new_unit_effectivity_rec.orig_forecast_sequence := p_new_unit_effectivity_rec.forecast_sequence;
7644 -- Added for ER# 2636001.
7645 l_new_unit_effectivity_rec.earliest_due_date := p_new_unit_effectivity_rec.earliest_due_date;
7646 l_new_unit_effectivity_rec.latest_due_date := p_new_unit_effectivity_rec.latest_due_date;
7647 l_new_unit_effectivity_rec.counter_id := p_new_unit_effectivity_rec.counter_id;
7648
7649 l_new_unit_effectivity_rec.tolerance_flag := p_new_unit_effectivity_rec.tolerance_flag;
7650 l_new_unit_effectivity_rec.tolerance_before := p_new_unit_effectivity_rec.tolerance_before;
7651 l_new_unit_effectivity_rec.tolerance_after := p_new_unit_effectivity_rec.tolerance_after;
7652
7653
7654 -- write into temp table.
7655 Create_temp_unit_effectivity(l_new_unit_effectivity_rec);
7656
7657 -- Read group MR tree and apply details from p_next_due_rec_type.
7658 FOR l_mr_grp_rec IN ahl_applicable1_grp_csr(p_applicable_mrs_rec.csi_item_instance_id,
7659 p_applicable_mrs_rec.mr_header_id)
7660 LOOP
7661
7662 l_new_unit_effectivity_rec := l_initialize_ue_rec;
7663
7664 -- Build temp_unit_effectivity record and write into temporary table.
7665 -- fix bug#6530920: UOM remain issue for child MRs.
7666 l_new_unit_effectivity_rec.due_date := p_new_unit_effectivity_rec.due_date;
7667 l_new_unit_effectivity_rec.mr_interval_id := p_new_unit_effectivity_rec.mr_interval_id;
7668 l_new_unit_effectivity_rec.mr_effectivity_id := p_new_unit_effectivity_rec.mr_effectivity_id;
7669 l_new_unit_effectivity_rec.due_counter_value := p_new_unit_effectivity_rec.due_counter_value;
7670 l_new_unit_effectivity_rec.csi_item_instance_id := l_mr_grp_rec.related_csi_item_instance_id;
7671 l_new_unit_effectivity_rec.parent_csi_item_instance_id := l_mr_grp_rec.csi_item_instance_id;
7672 l_new_unit_effectivity_rec.mr_header_id := l_mr_grp_rec.related_mr_header_id;
7673 l_new_unit_effectivity_rec.parent_mr_header_id := l_mr_grp_rec.mr_header_id;
7674 l_new_unit_effectivity_rec.orig_csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
7675 l_new_unit_effectivity_rec.orig_mr_header_id := p_applicable_mrs_rec.mr_header_id;
7676 l_new_unit_effectivity_rec.orig_forecast_sequence := p_new_unit_effectivity_rec.forecast_sequence;
7677 l_new_unit_effectivity_rec.repetitive_mr_flag := p_new_unit_effectivity_rec.repetitive_mr_flag;
7678 l_new_unit_effectivity_rec.visit_end_date := l_visit_end_date;
7679 l_new_unit_effectivity_rec.earliest_due_date := p_new_unit_effectivity_rec.earliest_due_date;
7680 l_new_unit_effectivity_rec.latest_due_date := p_new_unit_effectivity_rec.latest_due_date;
7681 l_new_unit_effectivity_rec.counter_id := p_new_unit_effectivity_rec.counter_id;
7682
7683 l_new_unit_effectivity_rec.tolerance_flag := p_new_unit_effectivity_rec.tolerance_flag;
7684 l_new_unit_effectivity_rec.tolerance_before := p_new_unit_effectivity_rec.tolerance_before;
7685 l_new_unit_effectivity_rec.tolerance_after := p_new_unit_effectivity_rec.tolerance_after;
7686
7687 l_new_unit_effectivity_rec.unit_effectivity_id := null;
7688
7689 -- check if this mr has a preceding mr.
7690 OPEN ahl_appl_mr_csr (l_mr_grp_rec.related_csi_item_instance_id,
7691 l_mr_grp_rec.related_mr_header_id);
7692 FETCH ahl_appl_mr_csr INTO l_junk;
7693 IF (ahl_appl_mr_csr%FOUND) THEN
7694 l_new_unit_effectivity_rec.preceding_check_flag:= 'Y';
7695 ELSE
7696 l_new_unit_effectivity_rec.preceding_check_flag:= 'N';
7697 END IF;
7698 CLOSE ahl_appl_mr_csr;
7699
7700 -- write into temp table.
7701 Create_temp_unit_effectivity(l_new_unit_effectivity_rec);
7702
7703 END LOOP;
7704
7705 IF G_DEBUG = 'Y' THEN
7706 AHL_DEBUG_PUB.Debug('End Process GroupMR');
7707 END IF;
7708
7709 END Process_GroupMR;
7710
7711 -------------------------------------------------------------------------------------
7712 -- To process the dependent MRs based on the value of preceding MR.
7713
7714 PROCEDURE Process_PrecedingMR (p_applicable_mrs_rec IN applicable_mrs_rec_type,
7715 p_counter_rules_tbl IN counter_rules_tbl_type,
7716 p_current_usage_tbl IN counter_values_tbl_type)
7717 IS
7718
7719 -- Declare cursor to get all MRs that have preceding MR as that in applicable_mrs_rec.
7720 /* modified for performance
7721 CURSOR ahl_preceding_mr_csr (p_mr_header_id IN NUMBER,
7722 p_item_instance_id IN NUMBER) IS
7723 SELECT mr.mr_header_id,
7724 apmr.csi_item_instance_id,
7725 apmr.Implement_status_code,
7726 apmr.copy_accomplishment_code,
7727 apmr.show_repetitive_code,
7728 --apmr.preceding_mr_header_id, -- fix for bug# 5922149
7729 curr_mr.mr_header_id preceding_mr_header_id,
7730 apmr.descendent_count,
7731 mr.whichever_first_code,
7732 apmr.repetitive_flag
7733 FROM ahl_mr_headers_app_v mr, ahl_mr_headers_b curr_mr, ahl_applicable_mrs apmr
7734 --fix for bug number 5922149
7735 --WHERE mr.preceding_mr_header_id = curr_mr.mr_header_id AND
7736 WHERE mr.preceding_mr_header_id IN (SELECT t.mr_header_id FROM ahl_mr_headers_b t where t.title = curr_mr.title ) AND
7737 curr_mr.mr_header_id = p_mr_header_id AND
7738 apmr.mr_header_id = mr.mr_header_id AND
7739 -- Fix for bug# 6711228.
7740 -- validation moved to before this procedure call.
7741 -- curr_mr.implement_status_code = 'MANDATORY' AND
7742 trunc(sysdate) >= trunc(nvl(mr.effective_from, sysdate)) AND
7743 trunc(sysdate) <= trunc(nvl(mr.effective_to, sysdate+1)) AND
7744 apmr.csi_item_instance_id = p_item_instance_id;
7745 */
7746
7747 /* May20th 2011: rewrote query for SB Enhancements
7748 CURSOR ahl_preceding_mr_csr (p_curr_mr_title IN VARCHAR2,
7749 p_item_instance_id IN NUMBER) IS
7750 SELECT mr.mr_header_id,
7751 mr.version_number,
7752 apmr.csi_item_instance_id,
7753 apmr.Implement_status_code,
7754 apmr.copy_accomplishment_code,
7755 apmr.show_repetitive_code,
7756 --apmr.preceding_mr_header_id,
7757 apmr.descendent_count,
7758 mr.whichever_first_code,
7759 apmr.repetitive_flag,
7760 mr.title,
7761 mr.effective_from,
7762 mr.effective_to
7763 FROM ahl_mr_headers_app_v mr, ahl_applicable_mrs apmr
7764 WHERE mr.preceding_mr_header_id IN (SELECT t.mr_header_id FROM ahl_mr_headers_app_v t where t.title = p_curr_mr_title ) AND
7765 apmr.mr_header_id = mr.mr_header_id AND
7766 trunc(sysdate) >= trunc(nvl(mr.effective_from, sysdate)) AND
7767 --fix for bug# 9263774. Process prior MR versions.
7768 --trunc(sysdate) <= trunc(nvl(mr.effective_to, sysdate+1)) AND
7769 apmr.csi_item_instance_id = p_item_instance_id;
7770 */
7771
7772 -- SB Enh: an MR can be initiated by more than one MRs. Due date for the
7773 -- 'initiated By' MR will be later of all of the MR due dates.
7774 CURSOR ahl_dependent_mr_csr (p_curr_mr_header_id IN NUMBER,
7775 p_item_instance_id IN NUMBER) IS
7776 SELECT amr.related_mr_header_id mr_header_id,
7777 mr.version_number,
7778 apmr.csi_item_instance_id,
7779 apmr.Implement_status_code,
7780 apmr.copy_accomplishment_code,
7781 apmr.show_repetitive_code,
7782 apmr.descendent_count,
7783 mr.whichever_first_code,
7784 apmr.repetitive_flag,
7785 mr.title,
7786 mr.effective_from,
7787 mr.effective_to,
7788 apmr.terminate_trigger_check
7789 FROM ahl_mr_relationships amr, ahl_applicable_mrs apmr, ahl_mr_headers_b mr
7790 WHERE amr.mr_header_id = p_curr_mr_header_id
7791 AND amr.related_mr_header_id = apmr.mr_header_id
7792 AND amr.relationship_code = 'INITIATES'
7793 AND amr.related_mr_header_id = mr.mr_header_id
7794 AND apmr.csi_item_instance_id = p_item_instance_id
7795 -- select only those 'follow after' MRs if all parent MRs are processed.
7796 AND NOT EXISTS (SELECT 'x'
7797 FROM ahl_mr_relationships amr1, ahl_applicable_mrs apmr1
7798 WHERE amr1.related_mr_header_id = amr.related_mr_header_id
7799 AND amr1.mr_header_id = apmr1.mr_header_id
7800 AND amr1.relationship_code NOT IN ('TERMINATES')
7801 AND (nvl(apmr1.process_status_flag,'N') = 'N'
7802 -- initiating MR should either be mandatory OR should be accomplished
7803 OR (apmr1.accomplished_ue_id IS NULL AND apmr1.implement_status_code <> 'MANDATORY'))
7804 AND csi_item_instance_id = p_item_instance_id);
7805
7806 l_dependent_mr_rec applicable_mrs_rec_type;
7807
7808 k NUMBER := 0;
7809
7810 -- Added for SB Enh: select initiating MR's earliest due date.
7811 CURSOR get_prec_mr_duedate_csr (p_mr_header_id IN NUMBER,
7812 p_item_instance_id IN number) IS
7813 SELECT * FROM (
7814 SELECT due_date, visit_end_date
7815 FROM ahl_temp_unit_effectivities
7816 WHERE csi_item_instance_id = p_item_instance_id AND
7817 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1
7818 where mr1.title = (select mr2.title from ahl_mr_headers_b mr2
7819 where mr2.mr_header_id = p_mr_header_id)
7820 ) AND
7821 preceding_check_flag = 'N'
7822
7823 UNION
7824 SELECT due_date, visit_end_date
7825 FROM ahl_temp_unit_SR_deferrals
7826 WHERE csi_item_instance_id = p_item_instance_id AND
7827 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1
7828 where mr1.title = (select mr2.title from ahl_mr_headers_b mr2
7829 where mr2.mr_header_id = p_mr_header_id )
7830 )
7831 ORDER by due_date ASC
7832 )
7833 WHERE ROWNUM < 2;
7834
7835 -- get all preceding MRs.
7836 CURSOR get_preceding_mrs_csr (p_item_instance_id IN number,
7837 p_follow_mr_header_id IN number) IS
7838
7839 select amr.mr_header_id, apmr.accomplished_ue_id, apmr.process_status_flag
7840 from ahl_mr_relationships amr, ahl_applicable_mrs apmr
7841 where amr.mr_header_id = apmr.mr_header_id
7842 and amr.relationship_code = 'INITIATES'
7843 and amr.related_mr_header_id = p_follow_mr_header_id
7844 and apmr.csi_item_instance_id = p_item_instance_id;
7845
7846 l_due_date DATE;
7847 l_visit_end_date DATE;
7848 l_preceding_mr_hdr_id NUMBER;
7849 l_max_due_date DATE;
7850 l_acc_unit_effectivity_id NUMBER;
7851 l_acc_deferral_flag BOOLEAN;
7852 l_acc_status_code VARCHAR2(30);
7853 l_return_val BOOLEAN;
7854
7855 BEGIN
7856
7857 IF G_DEBUG = 'Y' THEN
7858 AHL_DEBUG_PUB.Debug('Start Process PrecedingMR');
7859 END IF;
7860
7861 -- Process mrs which are dependent on current mr and are applicable to the same item instance.
7862 --FOR l_appl_rec IN ahl_preceding_mr_csr(p_applicable_mrs_rec.mr_header_id,
7863 -- p_applicable_mrs_rec.csi_item_instance_id) LOOP
7864 -- Commented for SB Enh. With new model for SB Enh, we can use mr_header_id instead of title
7865 --FOR l_appl_rec IN ahl_preceding_mr_csr(p_applicable_mrs_rec.title,
7866 -- p_applicable_mrs_rec.csi_item_instance_id) LOOP
7867
7868 FOR l_appl_rec IN ahl_dependent_mr_csr(p_applicable_mrs_rec.mr_header_id,
7869 p_applicable_mrs_rec.csi_item_instance_id) LOOP
7870
7871 IF G_DEBUG = 'Y' THEN
7872 AHL_DEBUG_PUB.Debug('Found applicable dependent MR:CSI:' || l_appl_rec.MR_header_id || ':' || l_appl_rec.csi_item_instance_id);
7873 AHL_DEBUG_PUB.Debug('For applicable preceding MR:CSI:' || p_applicable_mrs_rec.MR_header_id || ':' || p_applicable_mrs_rec.csi_item_instance_id);
7874 END IF;
7875
7876 -- Added for SB Enh.
7877 -- Find the preceding MR Id based on max due/accomplished date across all preceding MRs.
7878 FOR preceding_mr_rec IN get_preceding_mrs_csr(l_appl_rec.csi_item_instance_id,
7879 l_appl_rec.MR_header_id) LOOP
7880 IF (nvl(preceding_mr_rec.process_status_flag,'N') <> 'Y') THEN
7881 l_preceding_mr_hdr_id := NULL;
7882 EXIT;
7883 END IF;
7884
7885 -- get first accomplishment or get calculated due date.
7886 IF (preceding_mr_rec.accomplished_ue_id IS NOT NULL) THEN
7887 -- get first accomplishment.
7888 AHL_UMP_UTIL_PKG.get_first_accomplishment(p_applicable_mrs_rec.csi_item_instance_id,
7889 preceding_mr_rec.mr_header_id,
7890 l_due_date,
7891 l_acc_unit_effectivity_id,
7892 l_acc_deferral_flag,
7893 l_acc_status_code,
7894 l_return_val);
7895 ELSE
7896 OPEN get_prec_mr_duedate_csr(preceding_mr_rec.MR_header_id,
7897 p_applicable_mrs_rec.csi_item_instance_id);
7898 FETCH get_prec_mr_duedate_csr INTO l_due_date, l_visit_end_date;
7899 CLOSE get_prec_mr_duedate_csr;
7900 -- if UE is assigned to visit, then consider l_visit_end_date
7901 -- added null check to fix bug# 13891719
7902 IF (l_visit_end_date IS NOT NULL) THEN
7903 l_due_date := l_visit_end_date;
7904 END IF;
7905 END IF;
7906
7907 IF (l_due_date IS NULL) THEN
7908 l_max_due_date := NULL;
7909 l_preceding_mr_hdr_id := preceding_mr_rec.mr_header_id;
7910 EXIT;
7911 ELSE
7912 -- compare with previous values
7913 IF (l_preceding_mr_hdr_id IS NULL) THEN
7914 l_preceding_mr_hdr_id := preceding_mr_rec.mr_header_id;
7915 l_max_due_date := l_due_date;
7916 ELSIF trunc(l_due_date) > trunc(l_max_due_date) THEN
7917 l_max_due_date := l_due_date;
7918 l_preceding_mr_hdr_id := preceding_mr_rec.mr_header_id;
7919 END IF;
7920 END IF;
7921 END LOOP;
7922
7923 -- process only if l_preceding_mr_hdr_id has been set.
7924 IF (l_preceding_mr_hdr_id IS NOT NULL) THEN
7925
7926 IF G_DEBUG = 'Y' THEN
7927 AHL_DEBUG_PUB.Debug('Calculated l_preceding_mr_hdr_id:' || l_preceding_mr_hdr_id);
7928 END IF;
7929 -- update ahl_applicable_mrs with preceding mr ID for further processing.
7930 UPDATE AHL_APPLICABLE_MRS
7931 SET PRECEDING_MR_HEADER_ID = l_preceding_mr_hdr_id
7932 WHERE csi_item_instance_id = l_appl_rec.csi_item_instance_id
7933 AND MR_header_id = l_appl_rec.MR_header_id;
7934
7935 -- Build applicable_mrs_rec.
7936 l_dependent_mr_rec.csi_item_instance_id := l_appl_rec.csi_item_instance_id;
7937 l_dependent_mr_rec.MR_header_id := l_appl_rec.MR_header_id;
7938 l_dependent_mr_rec.Implement_status_code := l_appl_rec.Implement_status_code;
7939 l_dependent_mr_rec.copy_accomplishment_code := l_appl_rec.copy_accomplishment_code;
7940 l_dependent_mr_rec.show_repetitive_code := l_appl_rec.show_repetitive_code;
7941 -- commented for SB Enh.
7942 -- l_dependent_mr_rec.preceding_mr_header_id := p_applicable_mrs_rec.mr_header_id;
7943 l_dependent_mr_rec.preceding_mr_header_id := l_preceding_mr_hdr_id;
7944 l_dependent_mr_rec.descendent_count := l_appl_rec.descendent_count;
7945 l_dependent_mr_rec.whichever_first_code := l_appl_rec.whichever_first_code;
7946 l_dependent_mr_rec.repetitive_flag := l_appl_rec.repetitive_flag;
7947 l_dependent_mr_rec.title := l_appl_rec.title;
7948 l_dependent_mr_rec.version_number := l_appl_rec.version_number;
7949 l_dependent_mr_rec.effective_to := l_appl_rec.effective_to;
7950 l_dependent_mr_rec.effective_from := l_appl_rec.effective_from;
7951
7952 -- added for bug# 9263774
7953 IF (l_dependent_mr_rec.effective_to < sysdate) THEN
7954 l_dependent_mr_rec.expired_mr_flag := 'Y';
7955 ELSE
7956 l_dependent_mr_rec.expired_mr_flag := 'N';
7957 END IF;
7958 -- added for SB Enh
7959 l_dependent_mr_rec.terminate_trigger_check := l_appl_rec.terminate_trigger_check;
7960
7961 IF G_DEBUG = 'Y' THEN
7962 AHL_DEBUG_PUB.Debug('Process_PrecedingMR: Build Effectivity for MR:CSI:' || l_appl_rec.MR_header_id ||':' || l_appl_rec.csi_item_instance_id);
7963 END IF;
7964
7965 Build_Effectivity (p_applicable_mrs_rec => l_dependent_mr_rec,
7966 p_current_usage_tbl => p_current_usage_tbl,
7967 p_counter_rules_tbl => p_counter_rules_tbl);
7968 END IF;
7969
7970 END LOOP;
7971
7972 IF G_DEBUG = 'Y' THEN
7973 AHL_DEBUG_PUB.Debug('End Process PrecedingMR');
7974 END IF;
7975
7976
7977 END Process_PrecedingMR;
7978
7979 --------------------------------------------------------------------------------
7980 -- To update the preceding_check_flag in the temporary unit effectivities table.
7981
7982 PROCEDURE Update_check_flag (p_applicable_mrs_rec IN applicable_mrs_rec_type,
7983 p_dependent_mr_flag IN BOOLEAN,
7984 p_next_due_date_rec IN next_due_date_rec_type)
7985 IS
7986
7987 l_preceding_check_flag VARCHAR2(1);
7988
7989 BEGIN
7990
7991 IF G_DEBUG = 'Y' THEN
7992 AHL_DEBUG_PUB.Debug('Start Update Check Flag');
7993 END IF;
7994
7995 IF (p_dependent_mr_flag) THEN
7996 /* i.e accomplishment is based on preceding MR */
7997 IF (p_next_due_date_rec.due_date IS NULL) THEN
7998 null; /* leave all preceding_check_flag = 'Y' */
7999 ELSE
8000 -- modified to fix bug# 9263774(due date calc for prior MR versions).
8001 UPDATE ahl_temp_unit_effectivities
8002 SET preceding_check_flag = 'N'
8003 WHERE csi_item_instance_id = p_applicable_mrs_rec.csi_item_instance_id
8004 --AND mr_header_id = p_applicable_mrs_rec.mr_header_id
8005 AND mr_header_id IN (select mr.mr_header_id
8006 from ahl_mr_headers_b mr
8007 where mr.title = p_applicable_mrs_rec.title)
8008 AND due_date >= p_next_due_date_rec.due_date;
8009 END IF;
8010 ELSE
8011 /* this MR has its accomplishments; update all records irrespective of due date */
8012 -- modified to fix bug# 9263774(due date calc for prior MR versions).
8013 UPDATE ahl_temp_unit_effectivities
8014 SET preceding_check_flag = 'N'
8015 WHERE csi_item_instance_id = p_applicable_mrs_rec.csi_item_instance_id
8016 --AND mr_header_id = p_applicable_mrs_rec.mr_header_id;
8017 AND mr_header_id IN (select mr.mr_header_id
8018 from ahl_mr_headers_b mr
8019 where mr.title = p_applicable_mrs_rec.title);
8020
8021 END IF;
8022
8023 IF G_DEBUG = 'Y' THEN
8024 AHL_DEBUG_PUB.Debug('End Update Check Flag');
8025 END IF;
8026
8027 END Update_check_flag;
8028
8029
8030 -----------------------------------------------------------
8031 -- To write a record into ahl_temp_unit_effectivities.
8032
8033 PROCEDURE Create_temp_unit_effectivity (X_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE)
8034
8035 IS
8036
8037 BEGIN
8038 IF G_DEBUG = 'Y' THEN
8039 AHL_DEBUG_PUB.Debug('Start Create Temporary Unit Effect');
8040 END IF;
8041
8042 -- insert into temporary table.
8043 insert into ahl_temp_unit_effectivities (
8044 csi_item_instance_id,
8045 MR_header_id,
8046 due_date,
8047 mr_interval_id,
8048 mr_effectivity_id,
8049 due_counter_value,
8050 parent_csi_item_instance_id,
8051 parent_mr_header_id,
8052 orig_csi_item_instance_id,
8053 orig_mr_header_id,
8054 orig_forecast_sequence,
8055 preceding_csi_item_instance_id,
8056 preceding_mr_header_id,
8057 preceding_forecast_seq,
8058 forecast_sequence,
8059 tolerance_before,
8060 tolerance_after,
8061 preceding_check_flag,
8062 unit_effectivity_id,
8063 repetitive_mr_flag,
8064 tolerance_flag,
8065 message_code,
8066 service_line_id,
8067 program_mr_header_id,
8068 earliest_due_date,
8069 latest_due_date,
8070 counter_id,
8071 visit_end_date,
8072 accomplish_trigger_type,
8073 loop_chain_seq_num,
8074 start_mr_header_id,
8075 start_lc_ue_id,
8076 -- JKJain, NR Analysis and Forecasting
8077 fleet_header_id)
8078 values (
8079 X_unit_effectivity_rec.csi_item_instance_id,
8080 X_unit_effectivity_rec.MR_header_id,
8081 X_unit_effectivity_rec.due_date,
8082 X_unit_effectivity_rec.mr_interval_id,
8083 X_unit_effectivity_rec.mr_effectivity_id,
8084 X_unit_effectivity_rec.due_counter_value,
8085 X_unit_effectivity_rec.parent_csi_item_instance_id,
8086 X_unit_effectivity_rec.parent_mr_header_id,
8087 X_unit_effectivity_rec.orig_csi_item_instance_id,
8088 X_unit_effectivity_rec.orig_mr_header_id,
8089 X_unit_effectivity_rec.orig_forecast_sequence,
8090 X_unit_effectivity_rec.preceding_csi_item_instance_id,
8091 X_unit_effectivity_rec.preceding_mr_header_id,
8092 X_unit_effectivity_rec.preceding_forecast_seq,
8093 X_unit_effectivity_rec.forecast_sequence,
8094 X_unit_effectivity_rec.tolerance_before,
8095 X_unit_effectivity_rec.tolerance_after,
8096 X_unit_effectivity_rec.preceding_check_flag,
8097 X_unit_effectivity_rec.unit_effectivity_id,
8098 X_unit_effectivity_rec.repetitive_mr_flag,
8099 X_unit_effectivity_rec.tolerance_flag,
8100 X_unit_effectivity_rec.message_code,
8101 X_unit_effectivity_rec.service_line_id,
8102 X_unit_effectivity_rec.program_mr_header_id,
8103 X_unit_effectivity_rec.earliest_due_date,
8104 X_unit_effectivity_rec.latest_due_date,
8105 X_unit_effectivity_rec.counter_id,
8106 X_unit_effectivity_rec.visit_end_date,
8107 X_unit_effectivity_rec.accomplish_trigger_type,
8108 X_unit_effectivity_rec.loop_chain_seq_num,
8109 X_unit_effectivity_rec.start_mr_header_id,
8110 X_unit_effectivity_rec.start_lc_ue_id,
8111 X_unit_effectivity_rec.fleet_header_id
8112 );
8113
8114 IF G_DEBUG = 'Y' THEN
8115 AHL_DEBUG_PUB.Debug('End Create Temp Unit Effect.');
8116 END IF;
8117
8118 END Create_temp_unit_effectivity;
8119
8120
8121 ---------------------------------------------------------------------------
8122 -- To log error messages into a log file if called from concurrent process.
8123
8124 PROCEDURE log_error_messages IS
8125
8126 l_msg_count NUMBER;
8127 l_msg_index_out NUMBER;
8128 l_msg_data VARCHAR2(2000);
8129
8130 BEGIN
8131
8132 IF G_DEBUG = 'Y' THEN
8133 AHL_DEBUG_PUB.Debug('Start log error messages');
8134 END IF;
8135
8136 -- Standard call to get message count.
8137 l_msg_count := FND_MSG_PUB.Count_Msg;
8138
8139 FOR i IN 1..l_msg_count LOOP
8140 FND_MSG_PUB.get (
8141 p_msg_index => i,
8142 p_encoded => FND_API.G_FALSE,
8143 p_data => l_msg_data,
8144 p_msg_index_out => l_msg_index_out );
8145
8146 fnd_file.put_line(FND_FILE.LOG, 'Err message-'||l_msg_index_out||':' || l_msg_data);
8147 IF G_DEBUG = 'Y' THEN
8148 AHL_DEBUG_PUB.Debug('Err message-'||l_msg_index_out||':' || substr(l_msg_data,1,240));
8149 END IF;
8150
8151 END LOOP;
8152
8153 IF G_DEBUG = 'Y' THEN
8154 AHL_DEBUG_PUB.Debug('End log error messages');
8155 END IF;
8156
8157
8158 END log_error_messages;
8159
8160 -----------------------------------------------------------------------
8161 -- Function : Calls FMP and populates the AHL_APPLICABLE_MRS table
8162 -- for preventive maintenance installation.
8163 -- Pre-reqs :
8164 -- Parameters :
8165 --
8166 -- PopulatePM_Appl_MRs Parameters:
8167 -- p_csi_ii_id IN csi item instance id Required
8168 --
8169 --
8170 -- End of Comments.
8171
8172 PROCEDURE PopulatePM_Appl_MRs (
8173 p_csi_ii_id IN NUMBER,
8174 x_return_status OUT NOCOPY VARCHAR2,
8175 x_msg_count OUT NOCOPY NUMBER,
8176 x_msg_data OUT NOCOPY VARCHAR2,
8177 x_UnSch_programs_tbl OUT NOCOPY PMprogram_tbl_type)
8178
8179 IS
8180 l_api_version CONSTANT NUMBER := 1.0;
8181 l_appl_activities_tbl AHL_FMP_PVT.applicable_activities_tbl_type;
8182 l_appl_programs_tbl AHL_FMP_PVT.applicable_programs_tbl_type;
8183 l_pm_install_flag VARCHAR2(1);
8184
8185 l_duplicate_pgm_flag BOOLEAN;
8186 l_pgm_index NUMBER;
8187 l_UnSch_programs_tbl PMprogram_tbl_type;
8188
8189 l_activity_sch_exists_flag BOOLEAN;
8190
8191 BEGIN
8192
8193 IF G_DEBUG = 'Y' THEN
8194 AHL_DEBUG_PUB.debug('Start of PopulatePM_Appl_MRs');
8195 END IF;
8196
8197 -- call api to fetch all applicable mrs for PM installation.
8198 AHL_FMP_PVT.get_pm_applicable_mrs(
8199 p_api_version => l_api_version,
8200 p_init_msg_list => FND_API.G_FALSE,
8201 p_commit => FND_API.G_FALSE,
8202 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
8203 x_return_status => x_return_status,
8204 x_msg_count => x_msg_count,
8205 x_msg_data => x_msg_data,
8206 p_item_instance_id => p_csi_ii_id,
8207 x_applicable_activities_tbl => l_appl_activities_tbl,
8208 x_applicable_programs_tbl => l_appl_programs_tbl);
8209
8210
8211 -- Raise errors if exceptions occur
8212 IF (x_return_status = FND_API.G_RET_STS_ERROR) THEN
8213 RAISE FND_API.G_EXC_ERROR;
8214 ELSIF (x_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
8215 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8216 END IF;
8217
8218 -- initialize.
8219 l_pgm_index := 0;
8220
8221 -- Read programs table.
8222 IF (l_appl_programs_tbl.COUNT > 0) THEN
8223
8224 FOR i IN l_appl_programs_tbl.FIRST..l_appl_programs_tbl.LAST LOOP
8225
8226 l_activity_sch_exists_flag := TRUE;
8227
8228 -- find the corressponding activities in l_appl_activities_tbl for the program.
8229 IF (l_appl_activities_tbl.COUNT > 0) THEN
8230 FOR j IN l_appl_activities_tbl.FIRST..l_appl_activities_tbl.LAST LOOP
8231 IF (l_appl_activities_tbl(j).service_line_id = l_appl_programs_tbl(i).service_line_id)
8232 THEN
8233
8234 INSERT INTO AHL_APPLICABLE_MRS (
8235 CSI_ITEM_INSTANCE_ID,
8236 MR_HEADER_ID,
8237 MR_EFFECTIVITY_ID,
8238 REPETITIVE_FLAG ,
8239 SHOW_REPETITIVE_CODE,
8240 IMPLEMENT_STATUS_CODE,
8241 WHICHEVER_FIRST_CODE,
8242 SERVICE_LINE_ID,
8243 PROGRAM_MR_HEADER_ID,
8244 CONTRACT_START_DATE,
8245 CONTRACT_END_DATE,
8246 COVERAGE_IMP_LEVEL,
8247 PM_SCHEDULE_EXISTS)
8248 VALUES ( l_appl_activities_tbl(j).ITEM_INSTANCE_ID,
8249 l_appl_activities_tbl(j).MR_HEADER_ID,
8250 l_appl_activities_tbl(j).MR_EFFECTIVITY_ID,
8251 l_appl_activities_tbl(j).REPETITIVE_FLAG,
8252 l_appl_activities_tbl(j).SHOW_REPETITIVE_CODE,
8253 l_appl_activities_tbl(j).IMPLEMENT_STATUS_CODE,
8254 l_appl_activities_tbl(j).WHICHEVER_FIRST_CODE,
8255 l_appl_activities_tbl(j).SERVICE_LINE_ID,
8256 l_appl_activities_tbl(j).PROGRAM_MR_HEADER_ID,
8257 l_appl_programs_tbl(i).SERVICE_START_DATE,
8258 l_appl_programs_tbl(i).SERVICE_END_DATE,
8259 l_appl_programs_tbl(i).COVERAGE_TYPE_IMP_LEVEL,
8260 nvl(l_appl_activities_tbl(j).ACT_SCHEDULE_EXISTS,'N')
8261 );
8262 -- Set activity_sch_exists_flag if any of the activities does
8263 -- not have a schedule.
8264 IF (nvl(l_appl_activities_tbl(j).act_schedule_exists,'N') = 'N') THEN
8265 l_activity_sch_exists_flag := FALSE;
8266 END IF;
8267 END IF;
8268
8269 IF G_DEBUG = 'Y' THEN
8270 AHL_DEBUG_PUB.debug('Successfully inserted for Act ID:' || l_appl_activities_tbl(j).MR_HEADER_ID);
8271 END IF;
8272
8273 END LOOP; -- next activities record.
8274 END IF; -- activity COUNT.
8275
8276 -- If this program does not have a schedule, add this program to table l_UnSch_programs_tbl
8277 -- if it is unique.
8278 IF (NOT(l_activity_sch_exists_flag) AND
8279 l_appl_programs_tbl(i).mr_effectivity_id IS NOT NULL) THEN
8280
8281 l_duplicate_pgm_flag := FALSE;
8282 -- Check if this program already exists in the table.
8283 IF (l_UnSch_programs_tbl.COUNT > 0) THEN
8284 FOR j IN l_UnSch_programs_tbl.FIRST..l_UnSch_programs_tbl.LAST LOOP
8285 IF (l_UnSch_programs_tbl(j).program_mr_header_id = l_appl_programs_tbl(i).PM_program_id) THEN
8286 l_duplicate_pgm_flag := TRUE;
8287 EXIT;
8288 END IF;
8289 END LOOP; -- chk next program.
8290 END IF; -- count > 0.
8291
8292 -- if not duplicate add to program table.
8293 IF NOT(l_duplicate_pgm_flag) THEN
8294 l_pgm_index := l_pgm_index + 1;
8295 l_UnSch_programs_tbl(l_pgm_index).program_mr_header_id := l_appl_programs_tbl(i).PM_program_id;
8296 l_UnSch_programs_tbl(l_pgm_index).mr_effectivity_id := l_appl_programs_tbl(i).mr_effectivity_id;
8297 IF G_DEBUG = 'Y' THEN
8298 AHL_DEBUG_PUB.debug('Successfully added Program to l_UnSch_programs_tbl:index:value:' || i || ':' ||
8299 l_UnSch_programs_tbl(l_pgm_index).program_mr_header_id);
8300 END IF;
8301
8302 END IF;
8303
8304 END IF;
8305 END LOOP; -- next program record.
8306 END IF; -- count > 0.
8307
8308 -- set output parameter.
8309 x_unsch_programs_tbl := l_UnSch_programs_tbl;
8310
8311 IF G_DEBUG = 'Y' THEN
8312 AHL_DEBUG_PUB.debug('End of PopulatePM_Appl_MRs');
8313 END IF;
8314
8315 END PopulatePM_Appl_MRs;
8316
8317 ----------------------------------------------------------------------------------
8318 -- Process Unit for PM(preventive maintenance) installation.
8319 PROCEDURE Process_PM_Unit(p_csi_item_instance_id IN NUMBER,
8320 p_UnSch_programs_tbl IN PMprogram_tbl_type) IS
8321
8322 l_current_usage_tbl counter_values_tbl_type;
8323 /* contains current counter usage */
8324
8325 BEGIN
8326
8327 IF G_DEBUG = 'Y' THEN
8328 AHL_DEBUG_PUB.Debug('Start of Process_PM_Unit procedure');
8329 END IF;
8330
8331 -- Get current usage of all the counters defined for the item instance.
8332 get_Current_Usage (p_csi_item_instance_id,
8333 l_current_usage_tbl);
8334
8335 -- Calculate program end date for all MR's where program is not scheduled.
8336 Calc_program_end_dates (p_UnSch_programs_tbl,
8337 l_current_usage_tbl);
8338
8339 -- Process records with program dates scheduled.
8340 Process_PMSch_Activities;
8341
8342 -- Process records with no program dates.
8343 Process_PMUnSch_Activities(l_current_usage_tbl);
8344
8345 -- Assign existing unit_effectivity ID's that have not been accomplished
8346 -- to the newly created ones in the temporary table.
8347 Assign_Unit_effectivity_IDs;
8348
8349 IF G_DEBUG = 'Y' THEN
8350 AHL_DEBUG_PUB.Debug('End of Process_PM_Unit procedure');
8351 END IF;
8352
8353 END Process_PM_Unit;
8354
8355
8356 --------------------------------------------------------------------------------
8357
8358 -- To calculate the program end dates for all contracts with no due date schedule.
8359 PROCEDURE Calc_Program_End_Dates(p_UnSch_programs_tbl IN PMprogram_tbl_type,
8360 p_current_usage_tbl IN counter_values_tbl_type) IS
8361
8362 -- get all programs which have no schedules.
8363 CURSOR ahl_cont_not_scheduled_csr IS
8364 SELECT DISTINCT appl.program_mr_header_id, mr.whichever_first_code
8365 FROM ahl_applicable_mrs appl, ahl_mr_headers_b mr
8366 -- replaced ahl_mr_headers_app_v with ahl_mr_headers_b as ahl_applicable_mrs has
8367 -- the filter of application_usg_code.
8368 WHERE appl.program_mr_header_id = mr.mr_header_id
8369 AND pm_schedule_exists = 'N';
8370
8371 -- get details of program effectivity.
8372 CURSOR ahl_program_eff_csr (p_mr_effectivity_id IN NUMBER) IS
8373 SELECT mr_effectivity_id, program_duration, program_duration_uom_code,
8374 threshold_date
8375 FROM ahl_mr_effectivities
8376 where mr_effectivity_id = p_mr_effectivity_id;
8377
8378 -- get all intervals for an effectivity.
8379 CURSOR ahl_mr_interval_csr (p_mr_effectivity_id IN NUMBER) IS
8380 SELECT start_value, stop_value, counter_id, counter_name, mr_interval_id
8381 FROM ahl_mr_intervals_v
8382 WHERE mr_effectivity_id = p_mr_effectivity_id;
8383
8384 l_effectivity_rec ahl_program_eff_csr%ROWTYPE;
8385
8386 l_counter_rules_tbl counter_rules_tbl_type;
8387
8388 l_program_due_date DATE;
8389 l_program_calender_days NUMBER;
8390 l_UnSch_program_tbl PMprogram_tbl_type;
8391 l_upd_SQLstmt_str VARCHAR2(2000);
8392
8393 l_program_expire_flag BOOLEAN;
8394 /* indicates if a program has expired. */
8395
8396 l_current_ctr_value NUMBER;
8397 l_counter_remain NUMBER;
8398 l_ctr_found BOOLEAN;
8399 l_current_ctr_uom VARCHAR2(3);
8400 l_due_days NUMBER;
8401 l_due_date DATE;
8402 l_tbl_index NUMBER;
8403 l_program_expired_flag BOOLEAN;
8404
8405 BEGIN
8406
8407 IF G_DEBUG = 'Y' THEN
8408 AHL_DEBUG_PUB.Debug('Start of CALC_PROGRAM_END_DATES procedure');
8409 END IF;
8410
8411 FOR program_rec IN ahl_cont_not_scheduled_csr LOOP
8412 -- Initialize variables.
8413 l_program_due_date := NULL;
8414 l_counter_remain := 0;
8415 l_program_calender_days := 0;
8416 l_UnSch_program_tbl.DELETE;
8417 l_tbl_index := 0;
8418
8419 IF G_DEBUG = 'Y' THEN
8420 AHL_DEBUG_PUB.Debug('Calculating program end date for:' || program_rec.program_mr_header_id);
8421 END IF;
8422
8423 -- build temporary table containing the effectivities associated to the program.
8424 IF (p_UnSch_programs_tbl.COUNT > 0) THEN
8425 FOR i IN p_UnSch_programs_tbl.FIRST..p_UnSch_programs_tbl.LAST LOOP
8426 IF (p_UnSch_programs_tbl(i).program_mr_header_id = program_rec.program_mr_header_id) THEN
8427 l_tbl_index := l_tbl_index + 1;
8428 l_UnSch_program_tbl(l_tbl_index) := p_UnSch_programs_tbl(i);
8429 --dbms_output.put_line('program id:' || l_UnSch_program_tbl(l_tbl_index).program_mr_header_id);
8430 END IF;
8431 END LOOP;
8432 END IF;
8433
8434 -- read effectivity attributes for the program.
8435 IF (l_UnSch_program_tbl.COUNT > 0) THEN
8436 FOR i IN l_UnSch_program_tbl.FIRST..l_UnSch_program_tbl.LAST LOOP
8437
8438 IF G_DEBUG = 'Y' THEN
8439 AHL_DEBUG_PUB.Debug('Processing for program effectivity-id:' || l_UnSch_program_tbl(l_tbl_index).mr_effectivity_id);
8440 END IF;
8441
8442 OPEN ahl_program_eff_csr (l_UnSch_program_tbl(i).mr_effectivity_id);
8443 FETCH ahl_program_eff_csr INTO l_effectivity_rec;
8444 IF (ahl_program_eff_csr%FOUND) THEN
8445 -- read intervals for the effectivity.
8446 FOR interval_rec IN ahl_mr_interval_csr(l_effectivity_rec.mr_effectivity_id) LOOP
8447
8448 IF G_DEBUG = 'Y' THEN
8449 AHL_DEBUG_PUB.Debug('Processing for interval:' || interval_rec.mr_interval_id);
8450 END IF;
8451
8452 -- Set current usage counter value.
8453 l_current_ctr_value := 0;
8454 l_ctr_found := FALSE;
8455 l_current_ctr_uom := NULL;
8456 -- Get the interval counter's value from l_current_usage_tbl.
8457 FOR i IN p_current_usage_tbl.FIRST..p_current_usage_tbl.LAST LOOP
8458 IF (p_current_usage_tbl(i).counter_name = interval_rec.counter_name) THEN
8459 l_current_ctr_value := p_current_usage_tbl(i).counter_value;
8460 l_current_ctr_uom := p_current_usage_tbl(i).uom_code;
8461 l_ctr_found := TRUE;
8462 EXIT;
8463 END IF;
8464 END LOOP;
8465
8466 IF (l_ctr_found) THEN
8467
8468 -- Check that the current counter value less than the program stop value.
8469 l_counter_remain := interval_rec.stop_value - l_current_ctr_value;
8470
8471 /* indicates if a program has expired. */
8472 l_program_expire_flag := FALSE;
8473
8474 -- Using forecast find the number of days to reach stop_value.
8475 IF (l_counter_remain > 0) THEN
8476 -- get date from forecast.
8477 get_date_from_uf(l_counter_remain,
8478 l_current_ctr_uom,
8479 l_counter_rules_tbl, -- empty table.
8480 sysdate,
8481 l_due_date);
8482
8483 -- Compare dates.
8484 IF (l_program_due_date IS NULL) THEN
8485 l_program_due_date := l_due_date;
8486 ELSE
8487 IF (l_due_date IS NOT NULL) THEN
8488 IF (program_rec.whichever_first_code = 'FIRST') THEN
8489 IF (trunc(l_program_due_date) > trunc(l_due_date)) THEN
8490 l_program_due_date := l_due_date;
8491 END IF;
8492 ELSE /* whichever_first_code = 'LAST' */
8493 IF (trunc(l_program_due_date) < trunc(l_due_date)) THEN
8494 l_program_due_date := l_due_date;
8495 END IF;
8496 END IF;
8497 END IF; -- due date null.
8498 END IF;
8499
8500 ELSE
8501 l_program_expire_flag := TRUE;
8502 -- if program expired for mr with whichever_code = FIRST, stop calculation.
8503 IF (program_rec.whichever_first_code = 'FIRST') THEN
8504 -- program expired for this instance.
8505 l_due_date := NULL;
8506 l_program_due_date := NULL;
8507 EXIT; -- exit intervals loop.
8508 END IF;
8509 END IF;
8510
8511 END IF; /* end l_ctr_found */
8512
8513 END LOOP; /* next interval_rec */
8514
8515 -- calculate due date using effectivity attributes.
8516 IF (program_rec.whichever_first_code = 'FIRST') AND (l_program_expired_flag) THEN
8517 -- program expired for this instance.
8518 null; -- do nothing.
8519 ELSIF (nvl(l_effectivity_rec.program_duration,0)) <> 0 AND
8520 l_effectivity_rec.program_duration_uom_code IS NOT NULL
8521 THEN
8522
8523 --dbms_output.put_line('effectivity duration:' ||l_effectivity_rec.program_duration );
8524 --dbms_output.put_line('effectivity duration:' ||l_effectivity_rec.program_duration_uom_code );
8525
8526 IF (l_effectivity_rec.program_duration_uom_code = 'YR') THEN
8527 l_due_days := trunc(ADD_MONTHS(trunc(SYSDATE), 12 * l_effectivity_rec.program_duration)) - trunc(SYSDATE);
8528 ELSIF (l_effectivity_rec.program_duration_uom_code = 'MTH') THEN
8529 l_due_days := trunc(ADD_MONTHS(trunc(SYSDATE), l_effectivity_rec.program_duration)) - trunc(SYSDATE);
8530 ELSIF (l_effectivity_rec.program_duration_uom_code = 'WK') THEN
8531 l_due_days := 7 * l_effectivity_rec.program_duration;
8532 ELSIF (l_effectivity_rec.program_duration_uom_code = 'DAY') THEN
8533 l_due_days := l_effectivity_rec.program_duration;
8534 END IF;
8535
8536 --dbms_output.put_line('due days are:' || l_due_days );
8537
8538 -- Compare the due days.
8539 IF (l_program_calender_days = 0) THEN
8540 l_program_calender_days := l_due_days;
8541 ELSIF (program_rec.whichever_first_code = 'FIRST') THEN
8542 IF (l_program_calender_days > l_due_days) THEN
8543 l_program_calender_days := l_due_days;
8544 END IF;
8545 ELSE /* whichever_first_code = 'LAST' */
8546 IF (l_program_calender_days < l_due_days) THEN
8547 l_program_calender_days := l_due_days;
8548 END IF;
8549 END IF;
8550
8551 END IF; /* effectivity_rec.program_duration */
8552
8553 END IF; /* effectivity_rec found */
8554 CLOSE ahl_program_eff_csr;
8555
8556 -- chk for program expired.
8557 IF (program_rec.whichever_first_code = 'FIRST') AND (l_program_expired_flag) THEN
8558 -- program expired for this instance.
8559 l_program_due_date := NULL;
8560 EXIT; -- exit program table loop.
8561 END IF;
8562
8563 END LOOP; /* program table */
8564 END IF; /* count */
8565
8566 IF G_DEBUG = 'Y' THEN
8567 AHL_DEBUG_PUB.Debug('Program end date:' || l_program_due_date );
8568 AHL_DEBUG_PUB.Debug('Program calender days:' || l_program_calender_days );
8569 END IF;
8570
8571 -- Update record in ahl_applicable_mrs with the calculated program end date.
8572 IF (l_program_expired_flag) THEN
8573 -- For this case, set program end date = sysdate -1.
8574 l_upd_SQLstmt_str := 'UPDATE ahl_applicable_mrs' ||
8575 ' SET program_end_date = :1' ||
8576 ' WHERE program_mr_header_id = :2'||
8577 ' AND PM_schedule_exists = :3';
8578
8579 IF G_DEBUG = 'Y' THEN
8580 AHL_DEBUG_PUB.Debug('Expire SQL string:' || l_upd_SQLstmt_str);
8581 END IF;
8582
8583 EXECUTE IMMEDIATE l_upd_SQLstmt_str USING SYSDATE - 1,
8584 program_rec.program_mr_header_id,
8585 'N';
8586 ELSE
8587
8588 -- dbms_output.put_line('Not expired');
8589 -- set program end date = least of (program_calculated_date, contract_start + calender_days, contract_end_date)
8590 --UPDATE ahl_applicable_mrs
8591 --SET program_end_date = LEAST (nvl(l_program_due_date,contract_end_date),
8592 -- decode(l_program_calender_days,0, contract_end_date, contract_start_date + l_program_calender_days),
8593 -- contract_end_date)
8594 --WHERE program_mr_header_id = program_rec.program_mr_header_id
8595 -- AND PM_schedule_exists = 'N';
8596
8597 -- for whichever_last, pick greatest of l_program_calender_days+ contract start date
8598 -- and l_program_due_date.
8599
8600 IF (program_rec.whichever_first_code = 'FIRST') THEN
8601
8602 l_upd_SQLstmt_str := 'UPDATE ahl_applicable_mrs' ||
8603 ' SET program_end_date = LEAST (nvl(:1,contract_end_date),' ||
8604 ' decode(:2,0, contract_end_date, contract_start_date + :3),' ||
8605 ' contract_end_date)' ||
8606 ' WHERE program_mr_header_id = :4' ||
8607 ' AND PM_schedule_exists = :5';
8608 ELSE
8609
8610 l_upd_SQLstmt_str := 'UPDATE ahl_applicable_mrs' ||
8611 ' SET program_end_date = LEAST ( GREATEST (nvl(:1,contract_end_date),' ||
8612 ' decode(:2,0, contract_end_date, contract_start_date + :3)),' ||
8613 ' contract_end_date)' ||
8614 ' WHERE program_mr_header_id = :4' ||
8615 ' AND PM_schedule_exists = :5';
8616 END IF;
8617
8618
8619 IF G_DEBUG = 'Y' THEN
8620 AHL_DEBUG_PUB.Debug('SQL string:' || l_upd_SQLstmt_str);
8621 END IF;
8622
8623 EXECUTE IMMEDIATE l_upd_SQLstmt_str USING l_program_due_date,
8624 l_program_calender_days,
8625 l_program_calender_days,
8626 program_rec.program_mr_header_id,
8627 'N';
8628 END IF;
8629
8630 END LOOP; /* next program rec */
8631
8632 IF G_DEBUG = 'Y' THEN
8633 AHL_DEBUG_PUB.Debug('End of CALC_PROGRAM_END_DATES procedure');
8634 END IF;
8635
8636 END Calc_Program_End_Dates;
8637
8638 --------------------------------------------------
8639 -- Process records with contract dates scheduled.
8640 PROCEDURE Process_PMSch_Activities IS
8641
8642 -- get distinct activities for which due dates have been scheduled for the service.
8643 CURSOR ahl_sch_activity_csr IS
8644 SELECT DISTINCT mr_header_id, csi_item_instance_id, service_line_id,
8645 program_mr_header_id, contract_end_date, program_end_date,
8646 show_repetitive_code,
8647 repetitive_flag
8648 FROM ahl_applicable_mrs
8649 WHERE pm_schedule_exists = 'Y';
8650
8651 -- Fix for FP bug# 6327241. We should be able to process multiple contracts.
8652 /*
8653 -- get program which have service dates scheduled in the order of importance
8654 -- and contract_start_date. Process only the first one.
8655 CURSOR ahl_cont_scheduled_csr(p_mr_header_id IN NUMBER) IS
8656 SELECT mr_header_id, service_line_id, mr_effectivity_id,
8657 program_mr_header_id, contract_end_date, program_end_date
8658 FROM ahl_applicable_mrs
8659 WHERE mr_header_id = p_mr_header_id
8660 AND pm_schedule_exists = 'Y'
8661 ORDER BY coverage_imp_level , contract_start_date;
8662 */
8663
8664 -- Temporary fix for bug# 3022915.
8665 -- Get due date associated to the accomplishment date.
8666 /*
8667 -- fix for FP bug# 5223862.
8668 CURSOR ahl_due_date_csr(p_accomplishment_date IN DATE,
8669 p_mr_header_id IN NUMBER,
8670 p_csi_item_instance_id IN NUMBER) IS
8671 SELECT due_date
8672 FROM ahl_unit_effectivities_b
8673 WHERE mr_header_id = p_mr_header_id
8674 AND csi_item_instance_id = p_csi_item_instance_id
8675 AND trunc(accomplished_date) = trunc(p_accomplishment_date)
8676 AND status_code IN ('ACCOMPLISHED','INIT-ACCOMPLISHED','TERMINATED')
8677 ORDER BY due_date desc;
8678 */
8679
8680 -- Added filter by service_line_id to avoid issues caused by oks bug - 4574548
8681 -- wherein SRs associated to higher due dates are accomplished before lesser
8682 -- due date and the contract may have expired/terminated.
8683 -- 08/01/2012 changed order by clause to fix bug# 14588580 (avoid data fixes)
8684 CURSOR ahl_due_date_csr(--p_accomplishment_date IN DATE,
8685 p_mr_header_id IN NUMBER,
8686 p_csi_item_instance_id IN NUMBER,
8687 p_service_line_id IN NUMBER) IS
8688 SELECT due_date, accomplished_date
8689 FROM ahl_unit_effectivities_b
8690 WHERE mr_header_id = p_mr_header_id
8691 AND csi_item_instance_id = p_csi_item_instance_id
8692 AND service_line_id = p_service_line_id
8693 --AND trunc(accomplished_date) = trunc(p_accomplishment_date)
8694 AND status_code IN ('ACCOMPLISHED','INIT-ACCOMPLISHED','TERMINATED')
8695 --ORDER BY accomplished_date desc, due_date desc;
8696 ORDER BY due_date desc;
8697
8698 --l_cont_scheduled_rec ahl_cont_scheduled_csr%ROWTYPE;
8699 /* record structure holding the service line and program details. */
8700
8701 l_due_date DATE;
8702 l_first_array_index NUMBER;
8703 l_forecast_sequence NUMBER := 0;
8704
8705 -- parameters needed to call OKS API.
8706 l_pm_schedule_tbl OKS_PM_ENTITLEMENTS_PUB.pm_sch_tbl_type;
8707 l_inp_sch_rec OKS_PM_ENTITLEMENTS_PUB.inp_sch_rec;
8708 l_return_status VARCHAR2(1);
8709 l_msg_count NUMBER;
8710 l_msg_data VARCHAR2(2000);
8711
8712
8713 l_del_SQLstmt_str VARCHAR2(2000);
8714
8715 l_temp_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
8716 /* record structure to hold the activity and due date details */
8717
8718 -- Added to fix bug# 3546136.
8719 l_temp_ue_initrec ahl_temp_unit_effectivities%ROWTYPE;
8720
8721 -- parameters needed to call get_accomplishment_details.
8722 l_last_accomplishment_date DATE;
8723 l_last_acc_counter_val_tbl counter_values_tbl_type;
8724 l_current_usage_tbl counter_values_tbl_type;
8725 l_counter_rules_tbl counter_rules_tbl_type;
8726 l_dependent_mr_flag BOOLEAN;
8727 l_get_preceding_next_due BOOLEAN;
8728 l_applicable_mrs_rec applicable_mrs_rec_type;
8729 l_one_time_mr_flag BOOLEAN;
8730 l_last_due_date DATE;
8731
8732 -- Added for bug# 6711228
8733 l_no_forecast_flag BOOLEAN;
8734 l_mr_accomplish_exists BOOLEAN;
8735
8736 BEGIN
8737
8738 IF G_DEBUG = 'Y' THEN
8739 AHL_DEBUG_PUB.Debug('Start of PROCESS_PMSCH_ACTIVITIES procedure');
8740 END IF;
8741
8742 FOR sch_activity_rec IN ahl_sch_activity_csr LOOP
8743
8744 IF G_DEBUG = 'Y' THEN
8745 AHL_DEBUG_PUB.Debug('Processing for:' || sch_activity_rec.mr_header_id);
8746 AHL_DEBUG_PUB.Debug('Processing for Item Instance:' || sch_activity_rec.csi_item_instance_id);
8747 AHL_DEBUG_PUB.Debug('Processing for Repetitive flag:' || sch_activity_rec.repetitive_flag);
8748 AHL_DEBUG_PUB.Debug('Processing for SHow Repetitive code:' || sch_activity_rec.show_repetitive_code);
8749 END IF;
8750
8751 -- initialize forecast sequence for the activity.
8752 l_forecast_sequence := 0;
8753
8754 -- Fix for FP bug# 6327241. We should be able to process multiple contracts.
8755 /*
8756 OPEN ahl_cont_scheduled_csr(sch_activity_rec.mr_header_id);
8757 FETCH ahl_cont_scheduled_csr INTO l_cont_scheduled_rec;
8758 IF (ahl_cont_scheduled_csr%NOTFOUND) THEN
8759 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_PMPROGRAM_NOTFOUND');
8760 FND_MESSAGE.Set_Token('PMPROGRAM',sch_activity_rec.mr_header_id);
8761 FND_MSG_PUB.ADD;
8762 CLOSE ahl_cont_scheduled_csr;
8763 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8764 END IF;
8765
8766 -- check for existence of accomplishments.
8767
8768 -- initialize.
8769 l_one_time_mr_flag := FALSE;
8770
8771 -- build applicable_mrs_rec.
8772 l_applicable_mrs_rec.mr_header_id := sch_activity_rec.mr_header_id;
8773 l_applicable_mrs_rec.csi_item_instance_id := sch_activity_rec.csi_item_instance_id;
8774 l_applicable_mrs_rec.repetitive_flag := sch_activity_rec.repetitive_flag;
8775
8776 -- Check if accomplishment details exist.
8777 Get_accomplishment_details(p_applicable_mrs_rec => l_applicable_mrs_rec,
8778 p_current_usage_tbl => l_current_usage_tbl,
8779 p_counter_rules_tbl => l_counter_rules_tbl,
8780 x_accomplishment_date => l_last_accomplishment_date,
8781 x_last_acc_counter_val_tbl => l_last_acc_counter_val_tbl,
8782 x_one_time_mr_flag => l_one_time_mr_flag,
8783 x_dependent_mr_flag => l_dependent_mr_flag,
8784 x_get_preceding_next_due => l_get_preceding_next_due,
8785 x_mr_accomplish_exists => l_mr_accomplish_exists,
8786 x_no_forecast_flag => l_no_forecast_flag );
8787
8788 -- No need to check l_no_forecast_flag as this does not apply to PM flow.
8789 -- call OKS API to get due dates and process them in case one_time_mr_flag = false.
8790 IF NOT(l_one_time_mr_flag) THEN
8791 */
8792 -- get due date associated to the accomplishment date.
8793 OPEN ahl_due_date_csr (--l_last_accomplishment_date,
8794 sch_activity_rec.mr_header_id,
8795 sch_activity_rec.csi_item_instance_id,
8796 sch_activity_rec.service_line_id);
8797 FETCH ahl_due_date_csr INTO l_last_due_date, l_last_accomplishment_date;
8798 IF (ahl_due_date_csr%FOUND) THEN
8799 IF (l_last_accomplishment_date IS NOT NULL) THEN
8800 IF G_DEBUG = 'Y' THEN
8801 AHL_DEBUG_PUB.debug('l_last_accomplishment_date:' || l_last_accomplishment_date);
8802 END IF;
8803
8804 /* Fix for FP bug# 6327241
8805 -- get due date associated to the accomplishment date.
8806 OPEN ahl_due_date_csr (l_last_accomplishment_date,
8807 sch_activity_rec.mr_header_id,
8808 sch_activity_rec.csi_item_instance_id,
8809 l_cont_scheduled_rec.service_line_id);
8810 FETCH ahl_due_date_csr INTO l_last_due_date;
8811 CLOSE ahl_due_date_csr;
8812 */
8813 IF (l_last_due_date IS NOT NULL) THEN
8814 IF G_DEBUG = 'Y' THEN
8815 AHL_DEBUG_PUB.Debug('l_last_due_date is not null:' || l_last_due_date);
8816 END IF;
8817
8818 l_last_accomplishment_date := l_last_due_date + 1;
8819 END IF;
8820 ELSE
8821 l_last_accomplishment_date := NULL;
8822 END IF;
8823 ELSE
8824 l_last_accomplishment_date := NULL;
8825 END IF;
8826 CLOSE ahl_due_date_csr;
8827
8828 l_inp_sch_rec.service_line_id := sch_activity_rec.service_line_id;
8829 l_inp_sch_rec.program_id := sch_activity_rec.program_mr_header_id;
8830 l_inp_sch_rec.activity_id := sch_activity_rec.mr_header_id;
8831 l_inp_sch_rec.schedule_start_date := l_last_accomplishment_date;
8832 l_inp_sch_rec.schedule_end_date := G_last_day_of_window; /* uptill rolling window */
8833
8834 -- Call contracts API to get due dates.
8835 OKS_PM_ENTITLEMENTS_PUB.Get_PM_Schedule (
8836 p_api_version => 1.0,
8837 p_init_msg_list => OKC_API.G_FALSE,
8838 p_sch_rec => l_inp_sch_rec,
8839 x_return_status => l_return_status,
8840 x_msg_count => l_msg_count,
8841 x_msg_data => l_msg_data,
8842 x_pm_schedule => l_pm_schedule_tbl);
8843
8844 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
8845 RAISE FND_API.G_EXC_ERROR;
8846 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
8847 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8848 END IF;
8849
8850 IF G_DEBUG = 'Y' THEN
8851 AHL_DEBUG_PUB.debug('Service Line ID: ' || l_inp_sch_rec.service_line_id);
8852 AHL_DEBUG_PUB.debug('Program ID: ' || l_inp_sch_rec.program_id);
8853 AHL_DEBUG_PUB.debug('Activity ID: ' || l_inp_sch_rec.activity_id);
8854 AHL_DEBUG_PUB.debug('Start Date: ' || to_char(l_inp_sch_rec.schedule_start_date, 'DD-MON-YYYY HH24:MI:SS'));
8855 AHL_DEBUG_PUB.debug('End Date: ' || to_char(l_inp_sch_rec.schedule_end_date, 'DD-MON-YYYY HH24:MI:SS'));
8856 AHL_DEBUG_PUB.debug('Count of l_pm_schedule_tbl is: ' || l_pm_schedule_tbl.count);
8857
8858 IF (l_pm_schedule_tbl.count > 0 ) THEN
8859 for i in l_pm_schedule_tbl.first..l_pm_schedule_tbl.last loop
8860 AHL_DEBUG_PUB.debug('Serv Line for ' || i ||':' || l_pm_schedule_tbl(i).service_line_id);
8861 AHL_DEBUG_PUB.debug('Sch ON for ' || i ||':' || l_pm_schedule_tbl(i).schedule_on);
8862 AHL_DEBUG_PUB.debug('Sch Start for ' || i ||':' || l_pm_schedule_tbl(i).schedule_from);
8863 AHL_DEBUG_PUB.debug('Sch End for ' || i ||':' || l_pm_schedule_tbl(i).schedule_to);
8864 end loop;
8865 END IF;
8866 END IF;
8867
8868 -- Write due dates into ahl temporary table.
8869 IF (l_pm_schedule_tbl.COUNT > 0) THEN
8870 l_first_array_index := l_pm_schedule_tbl.FIRST;
8871 /* date associated to this index will be set as 'next due' occurrence */
8872
8873 FOR i IN l_pm_schedule_tbl.FIRST..l_pm_schedule_tbl.LAST LOOP
8874
8875 -- initialize.
8876 l_due_date := NULL;
8877 l_temp_unit_effectivity_rec := l_temp_ue_initrec;
8878
8879 IF (l_pm_schedule_tbl(i).schedule_on IS NOT NULL) AND
8880 (l_pm_schedule_tbl(i).schedule_on <> FND_API.G_MISS_DATE) THEN
8881 l_due_date := l_pm_schedule_tbl(i).schedule_on;
8882 ELSIF (l_pm_schedule_tbl(i).schedule_to IS NOT NULL) AND
8883 (l_pm_schedule_tbl(i).schedule_to <> FND_API.G_MISS_DATE) THEN
8884 l_due_date := l_pm_schedule_tbl(i).schedule_to;
8885 END IF;
8886
8887 -- write into temporary table if due date is not null.
8888 IF (l_due_date IS NOT NULL) THEN
8889
8890 -- Build temporary table record.
8891 l_temp_unit_effectivity_rec.due_date := l_due_date;
8892 l_temp_unit_effectivity_rec.csi_item_instance_id := sch_activity_rec.csi_item_instance_id;
8893 l_temp_unit_effectivity_rec.mr_header_id := sch_activity_rec.mr_header_id;
8894 l_temp_unit_effectivity_rec.program_mr_header_id := sch_activity_rec.program_mr_header_id;
8895 l_temp_unit_effectivity_rec.service_line_id := sch_activity_rec.service_line_id;
8896 -- Added for ER# 2636001.
8897 IF (l_pm_schedule_tbl(i).schedule_from IS NOT NULL AND
8898 l_pm_schedule_tbl(i).schedule_from <> FND_API.G_MISS_DATE) THEN
8899 l_temp_unit_effectivity_rec.earliest_due_date := l_pm_schedule_tbl(i).schedule_from;
8900 END IF;
8901 IF (l_pm_schedule_tbl(i).schedule_to IS NOT NULL AND
8902 l_pm_schedule_tbl(i).schedule_to <> FND_API.G_MISS_DATE) THEN
8903 l_temp_unit_effectivity_rec.latest_due_date := l_pm_schedule_tbl(i).schedule_to;
8904 END IF;
8905
8906 -- increment forecast sequence.
8907 l_forecast_sequence := l_forecast_sequence + 1;
8908 l_temp_unit_effectivity_rec.forecast_sequence := l_forecast_sequence;
8909
8910 -- set repetitive mr flag.
8911 IF (i = l_first_array_index) THEN
8912 l_temp_unit_effectivity_rec.repetitive_mr_flag := 'N';
8913 ELSE
8914 l_temp_unit_effectivity_rec.repetitive_mr_flag := 'Y';
8915 END IF;
8916
8917 -- create record in temporary table.
8918 Create_Temp_Unit_Effectivity (l_temp_unit_effectivity_rec);
8919
8920 END IF;
8921
8922 -- Check show_repetitive_code value.
8923 -- If it is = 'NEXT' then exit loop as repetities need not be shown in UMP.
8924 IF (sch_activity_rec.show_repetitive_code = 'NEXT') THEN
8925 EXIT;
8926 END IF;
8927
8928 END LOOP; /* next record from pm_schedule */
8929
8930 END IF; /* count */
8931 --END IF; /* one time mr flag */
8932
8933 -- Delete duplicate programs/contracts for this mr_header_id if they exist.
8934 l_del_SQLstmt_str := 'DELETE FROM ahl_applicable_mrs' ||
8935 ' WHERE mr_header_id = :1 AND pm_schedule_exists = ''N'' '||
8936 ' AND service_line_id <> :2';
8937
8938 IF G_DEBUG = 'Y' THEN
8939 AHL_DEBUG_PUB.Debug('SQL string:' || l_del_SQLstmt_str);
8940 END IF;
8941
8942 EXECUTE IMMEDIATE l_del_SQLstmt_str USING sch_activity_rec.mr_header_id,
8943 sch_activity_rec.service_line_id;
8944
8945 --CLOSE ahl_cont_scheduled_csr;
8946 END LOOP; /* for ahl_sch_program_csr */
8947
8948 IF G_DEBUG = 'Y' THEN
8949 AHL_DEBUG_PUB.debug('End of PROCESS_PMSCH_ACTIVITIES procedure');
8950 END IF;
8951
8952 END Process_PMSch_Activities;
8953 ----------------------------------------------------------
8954
8955 PROCEDURE Process_PMUnSch_Activities(p_current_usage_tbl IN counter_values_tbl_type)
8956 IS
8957
8958 -- get all programs which have no contract dates scheduled.
8959 CURSOR ahl_UnSch_activity_csr IS
8960 SELECT DISTINCT appl.mr_header_id,
8961 appl.csi_item_instance_id,
8962 appl.whichever_first_code,
8963 appl.repetitive_flag,
8964 appl.show_repetitive_code,
8965 mr.effective_to,
8966 mr.effective_from
8967 FROM ahl_applicable_mrs appl, ahl_mr_headers_b mr
8968 WHERE appl.mr_header_id = mr.mr_header_id AND
8969 appl.pm_schedule_exists = 'N';
8970
8971 l_last_day_of_window DATE;
8972 l_next_due_flag BOOLEAN;
8973 l_last_due_date DATE;
8974 l_due_date DATE;
8975 l_forecast_sequence NUMBER;
8976 l_return_value BOOLEAN;
8977 l_contract_found_flag BOOLEAN;
8978 l_contract_override_due_date DATE;
8979 l_cont_override_earliest_due DATE;
8980 l_cont_override_latest_due DATE;
8981
8982 -- parameter for calculate_due_date procedure.
8983 l_next_due_date_rec next_due_date_rec_type;
8984
8985 l_program_mr_header_id NUMBER;
8986 l_service_line_id NUMBER;
8987 l_contract_start_date DATE;
8988
8989 -- parameters to call get_accomplishment_details procedure.
8990 l_counter_rules_tbl counter_rules_tbl_type;
8991 l_last_accomplishment_date DATE;
8992 l_last_acc_counter_val_tbl counter_values_tbl_type;
8993 l_dependent_mr_flag BOOLEAN;
8994 l_get_preceding_next_due BOOLEAN;
8995 l_one_time_mr_flag BOOLEAN;
8996 l_last_due_counter_val_tbl counter_values_tbl_type;
8997 l_due_at_counter_val_tbl counter_values_tbl_type;
8998
8999 l_applicable_mrs_rec applicable_mrs_rec_type;
9000
9001 l_temp_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
9002 l_temp_ue_initrec ahl_temp_unit_effectivities%ROWTYPE;
9003
9004 -- Added for bug# 6711228
9005 l_no_forecast_flag BOOLEAN;
9006 l_mr_accomplish_exists BOOLEAN;
9007
9008 -- Added to fix bug# 6858788.
9009 l_last_due_mr_interval_id NUMBER;
9010
9011 -- Added to fix bug# 8994566
9012 l_accomplished_ue_id NUMBER;
9013
9014 BEGIN
9015
9016 IF G_DEBUG = 'Y' THEN
9017 AHL_DEBUG_PUB.Debug('Start of process_pmunsch_activities procedure');
9018 END IF;
9019
9020 FOR appl_mrs_rec IN ahl_UnSch_activity_csr LOOP
9021
9022 -- initialize.
9023 l_forecast_sequence := 0;
9024
9025 -- build applicable_mrs_rec.
9026 l_applicable_mrs_rec.mr_header_id := appl_mrs_rec.mr_header_id;
9027 l_applicable_mrs_rec.csi_item_instance_id := appl_mrs_rec.csi_item_instance_id;
9028 l_applicable_mrs_rec.whichever_first_code := appl_mrs_rec.whichever_first_code;
9029 l_applicable_mrs_rec.repetitive_flag := appl_mrs_rec.repetitive_flag;
9030 l_applicable_mrs_rec.show_repetitive_code := appl_mrs_rec.show_repetitive_code;
9031 l_applicable_mrs_rec.effective_to := appl_mrs_rec.effective_to;
9032 l_applicable_mrs_rec.effective_from := appl_mrs_rec.effective_from;
9033
9034 IF G_DEBUG = 'Y' THEN
9035 AHL_DEBUG_PUB.Debug('Processing for:' || appl_mrs_rec.mr_header_id);
9036 END IF;
9037
9038 -- Set last accomplishment details.
9039 Get_accomplishment_details(p_applicable_mrs_rec => l_applicable_mrs_rec,
9040 p_current_usage_tbl => p_current_usage_tbl,
9041 p_counter_rules_tbl => l_counter_rules_tbl, -- empty table. n/a for PM installation.
9042 x_accomplishment_date => l_last_accomplishment_date,
9043 x_last_acc_counter_val_tbl => l_last_acc_counter_val_tbl,
9044 x_one_time_mr_flag => l_one_time_mr_flag,
9045 x_dependent_mr_flag => l_dependent_mr_flag,
9046 x_get_preceding_next_due => l_get_preceding_next_due,
9047 x_mr_accomplish_exists => l_mr_accomplish_exists,
9048 x_no_forecast_flag => l_no_forecast_flag,
9049 x_accomplished_ue_id => l_accomplished_ue_id);
9050
9051 IF G_DEBUG = 'Y' THEN
9052 AHL_DEBUG_PUB.Debug('Start of process_pmunsch_activities procedure');
9053 END IF;
9054
9055 -- No need to check l_no_forecast_flag as this does not apply to PM flow.
9056 -- Check for one time MR case and process otherwise only.
9057 IF NOT(l_one_time_mr_flag) THEN
9058 --dbms_output.put_line('Not one time MR');
9059
9060 -- Calculate next due date.
9061 -- Added parameter p_dependent_mr_flag to fix bug# 6711228. Issue does
9062 -- not impact PM calculation.
9063 Calculate_Due_Date (p_repetivity_flag => 'N',
9064 p_applicable_mrs_rec => l_applicable_mrs_rec,
9065 p_current_usage_tbl => p_current_usage_tbl,
9066 p_counter_rules_tbl => l_counter_rules_tbl, -- empty table. n/a for PM installation.
9067 p_last_due_date => l_last_accomplishment_date,
9068 p_last_due_counter_val_tbl => l_last_acc_counter_val_tbl,
9069 p_dependent_mr_flag => l_dependent_mr_flag,
9070 p_mr_accomplish_exists => l_mr_accomplish_exists,
9071 x_next_due_date_rec => l_next_due_date_rec);
9072 IF G_DEBUG = 'Y' THEN
9073 AHL_DEBUG_PUB.Debug('Aft calculate_due_date nextdue');
9074 AHL_DEBUG_PUB.Debug('due date is ' || l_next_due_date_rec.DUE_DATE);
9075 END IF;
9076
9077 l_next_due_flag := TRUE;
9078 /* next due mr calculation. */
9079
9080 -- set last due_date values to current values.
9081 l_last_due_date := sysdate;
9082 l_last_due_counter_val_tbl := p_current_usage_tbl;
9083
9084 -- process next due and repetivity.
9085 LOOP
9086
9087 -- initialize program and service line for the calculated due date.
9088 l_program_mr_header_id := NULL;
9089 l_service_line_id := NULL;
9090 l_contract_found_flag := FALSE;
9091 l_contract_override_due_date := NULL;
9092
9093 -- Set due_date from l_next_due_date_rec.
9094 l_due_date := l_next_due_date_rec.DUE_DATE;
9095
9096 IF (l_next_due_flag = TRUE) OR
9097 -- In the case of next-due, if l_due_date is null, get the earliest
9098 -- contract date and program available for the activity; else if
9099 -- l_due_date is not null, get the appropriate contract.
9100 (l_next_due_flag = FALSE AND l_due_date IS NOT NULL AND
9101 trunc(l_due_date) <= trunc(g_last_day_of_window))
9102 -- In the case of repetity and l_due_date is not null.
9103 THEN
9104
9105 -- get program and service_line_id for the due date calculated.
9106 get_PMprogram(p_csi_item_instance_id => appl_mrs_rec.csi_item_instance_id,
9107 p_mr_header_id => appl_mrs_rec.mr_header_id,
9108 p_last_due_date => l_last_due_date,
9109 p_due_date => l_due_date,
9110 p_earliest_due => l_next_due_date_rec.earliest_due_date,
9111 p_latest_due => l_next_due_date_rec.latest_due_date,
9112 x_program_mr_header_id => l_program_mr_header_id,
9113 x_service_line_id => l_service_line_id,
9114 x_contract_override_due_date => l_contract_override_due_date,
9115 x_cont_override_earliest_due => l_cont_override_earliest_due,
9116 x_cont_override_latest_due => l_cont_override_latest_due,
9117 x_contract_found_flag => l_contract_found_flag);
9118
9119 -- write into temporary table if contract found.
9120 IF (l_contract_found_flag) THEN
9121
9122 IF G_DEBUG = 'Y' THEN
9123 AHL_DEBUG_PUB.debug('contract found for due date:' ||l_due_date);
9124 AHL_DEBUG_PUB.debug('contract found with override date:' || l_contract_override_due_date);
9125 AHL_DEBUG_PUB.debug('contract found with override earliest:' || l_cont_override_earliest_due);
9126 AHL_DEBUG_PUB.debug('contract found with override latest:' || l_cont_override_latest_due);
9127 END IF;
9128
9129 IF (l_contract_override_due_date IS NOT NULL) THEN
9130
9131 l_next_due_date_rec.due_date := l_contract_override_due_date;
9132 l_due_date := l_contract_override_due_date;
9133
9134 -- set due counter value and related data to null; as we do not know
9135 -- the triggered counter value as on l_contract_override_due_date.
9136 l_next_due_date_rec.due_at_counter_value := null;
9137 l_next_due_date_rec.mr_effectivity_id := null;
9138 l_next_due_date_rec.mr_interval_id := null;
9139 l_next_due_date_rec.tolerance_flag := null;
9140 l_next_due_date_rec.tolerance_before := null;
9141 l_next_due_date_rec.tolerance_after := null;
9142 l_next_due_date_rec.message_code := null;
9143 l_next_due_date_rec.counter_id := null;
9144
9145 END IF;
9146
9147 -- Added for ER# 2636001.
9148 IF (l_cont_override_earliest_due IS NOT NULL) THEN
9149 l_next_due_date_rec.earliest_due_date := l_cont_override_earliest_due;
9150 END IF;
9151 IF (l_cont_override_latest_due IS NOT NULL) THEN
9152 l_next_due_date_rec.latest_due_date := l_cont_override_latest_due;
9153 END IF;
9154
9155 -- Build temporary table record.
9156 l_temp_unit_effectivity_rec := l_temp_ue_initrec; -- initialize.
9157
9158 l_temp_unit_effectivity_rec.due_date := l_due_date;
9159 l_temp_unit_effectivity_rec.csi_item_instance_id := appl_mrs_rec.csi_item_instance_id;
9160 l_temp_unit_effectivity_rec.mr_header_id := appl_mrs_rec.mr_header_id;
9161 l_temp_unit_effectivity_rec.program_mr_header_id := l_program_mr_header_id;
9162 l_temp_unit_effectivity_rec.service_line_id := l_service_line_id;
9163 l_temp_unit_effectivity_rec.mr_effectivity_id := l_next_due_date_rec.mr_effectivity_id;
9164 l_temp_unit_effectivity_rec.mr_interval_id := l_next_due_date_rec.mr_interval_id;
9165 l_temp_unit_effectivity_rec.due_counter_value := l_next_due_date_rec.due_at_counter_value;
9166 l_temp_unit_effectivity_rec.tolerance_flag := l_next_due_date_rec.tolerance_flag;
9167 l_temp_unit_effectivity_rec.tolerance_before := l_next_due_date_rec.tolerance_before;
9168 l_temp_unit_effectivity_rec.tolerance_after := l_next_due_date_rec.tolerance_after;
9169 l_temp_unit_effectivity_rec.message_code := l_next_due_date_rec.message_code;
9170 l_temp_unit_effectivity_rec.preceding_check_flag:= 'N';
9171 --Added for ER# 2636001.
9172 l_temp_unit_effectivity_rec.earliest_due_date := l_next_due_date_rec.earliest_due_date;
9173 l_temp_unit_effectivity_rec.latest_due_date := l_next_due_date_rec.latest_due_date;
9174 -- Added to fix bug#
9175 l_temp_unit_effectivity_rec.counter_id := l_next_due_date_rec.counter_id;
9176
9177 -- increment forecast sequence.
9178 l_forecast_sequence := l_forecast_sequence + 1;
9179 l_temp_unit_effectivity_rec.forecast_sequence := l_forecast_sequence;
9180
9181 -- set repetivity based on next_due_flag.
9182 IF (l_next_due_flag) THEN
9183 l_temp_unit_effectivity_rec.repetitive_mr_flag := 'N';
9184 ELSE
9185 l_temp_unit_effectivity_rec.repetitive_mr_flag := 'Y';
9186 END IF;
9187
9188 -- create record in temporary table.
9189 Create_Temp_Unit_Effectivity (l_temp_unit_effectivity_rec);
9190
9191 -- Set next due flag to FALSE after writing record into temporary unit_effectivity.
9192 IF (l_next_due_flag) THEN
9193 l_next_due_flag := FALSE;
9194 END IF;
9195
9196 -- Added to fix bug# 6858788
9197 l_last_due_mr_interval_id := l_next_due_date_rec.mr_interval_id;
9198
9199 END IF; -- l_contract_found_flag.
9200
9201 END IF; --l_next_due_flag
9202
9203 -- exit to process next activity.
9204 EXIT WHEN (l_next_due_flag = FALSE AND l_next_due_date_rec.DUE_DATE IS NULL) OR -- calculate_due_date returns null.
9205 (l_next_due_flag = FALSE AND trunc(l_next_due_date_rec.DUE_DATE) > trunc(g_last_day_of_window)) OR
9206 (l_next_due_date_rec.due_date IS NOT NULL AND appl_mrs_rec.effective_to IS NOT NULL AND trunc(l_next_due_date_rec.due_date) > trunc(appl_mrs_rec.effective_to)) OR
9207 (l_next_due_flag = FALSE AND appl_mrs_rec.show_repetitive_code = 'NEXT') OR
9208 (l_contract_found_flag = FALSE); -- contract not available.
9209
9210 -- If due date is a past date, then set it to sysdate.
9211 -- This will happen only when calculating next-due date.
9212 IF (trunc(l_due_date) < trunc(sysdate)) THEN
9213 l_due_date := sysdate;
9214 END IF;
9215
9216 IF G_DEBUG = 'Y' THEN
9217 AHL_DEBUG_PUB.Debug('Processing for repetivity');
9218 AHL_DEBUG_PUB.Debug('l_last_due_date: '|| l_last_due_date);
9219 AHL_DEBUG_PUB.Debug('l_due_date: '|| l_due_date);
9220 IF (l_last_due_counter_val_tbl.COUNT > 0) THEN
9221 FOR i in l_last_due_counter_val_tbl.FIRST..l_last_due_counter_val_tbl.LAST LOOP
9222 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_last_due_counter_val_tbl(i).counter_value || 'ID: ' || l_last_due_counter_val_tbl(i).counter_id);
9223 END LOOP;
9224 END IF;
9225 END IF;
9226
9227
9228 -- get all counter values as on l_due_date.
9229 Get_Due_at_Counter_Values (p_last_due_date => l_last_due_date,
9230 p_last_due_counter_val_tbl => l_last_due_counter_val_tbl,
9231 p_due_date => l_due_date,
9232 p_counter_rules_tbl => l_counter_rules_tbl,
9233 x_due_at_counter_val_tbl => l_due_at_counter_val_tbl,
9234 x_return_value => l_return_value);
9235
9236 IF NOT(l_return_value) THEN -- no forecast case.
9237 --dbms_output.put_line('l_return_value is false');
9238 EXIT;
9239 END IF;
9240
9241 -- set current values to previous values.
9242 l_last_due_date := l_due_date;
9243 l_last_due_counter_val_tbl := l_due_at_counter_val_tbl;
9244
9245 IF G_DEBUG = 'Y' THEN
9246 AHL_DEBUG_PUB.Debug('AFter get_due_at_counter_values');
9247 AHL_DEBUG_PUB.Debug('l_last_due_date: '|| l_last_due_date);
9248 AHL_DEBUG_PUB.Debug('l_due_date: '|| l_due_date);
9249 IF (l_due_at_counter_val_tbl.COUNT) > 0 THEN
9250 FOR i in l_due_at_counter_val_tbl.FIRST..l_due_at_counter_val_tbl.LAST LOOP
9251 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_due_at_counter_val_tbl(i).counter_value || 'ID: ' || l_due_at_counter_val_tbl(i).counter_id);
9252 end loop;
9253 END IF;
9254 END IF;
9255
9256 -- Calculate next due date.
9257 Calculate_Due_Date (p_repetivity_flag => 'Y',
9258 p_applicable_mrs_rec => l_applicable_mrs_rec,
9259 p_current_usage_tbl => p_current_usage_tbl,
9260 p_counter_rules_tbl => l_counter_rules_tbl,
9261 p_last_due_date => l_last_due_date,
9262 p_last_due_counter_val_tbl => l_last_due_counter_val_tbl,
9263 p_mr_accomplish_exists => l_mr_accomplish_exists,
9264 p_last_due_mr_interval_id => l_last_due_mr_interval_id,
9265 x_next_due_date_rec => l_next_due_date_rec);
9266
9267 IF G_DEBUG = 'Y' THEN
9268 AHL_DEBUG_PUB.Debug('aft calculate_due_date - repetivity');
9269 AHL_DEBUG_PUB.Debug('due date is ' || l_next_due_date_rec.DUE_DATE);
9270 END IF;
9271
9272 -- Check if calculated date is same as last due date. If they are the same then, add one day.
9273 IF (l_next_due_date_rec.due_date IS NOT NULL) THEN
9274 IF (trunc(l_last_due_date) = trunc(l_next_due_date_rec.due_date)) THEN
9275 l_next_due_date_rec.due_date := l_next_due_date_rec.due_date + 1;
9276 l_next_due_date_rec.EARLIEST_DUE_DATE := NULL;
9277 l_next_due_date_rec.latest_due_date := NULL;
9278
9279 IF G_DEBUG = 'Y' THEN
9280 AHL_DEBUG_PUB.Debug('Adding one day to l_next_due_date_rec.due_date:' || l_next_due_date_rec.due_date);
9281 END IF;
9282
9283 --IF G_DEBUG = 'Y' THEN
9284 -- AHL_DEBUG_PUB.Debug('Exiting build effectivity as last due = due date');
9285 --END IF;
9286 --EXIT;
9287 END IF;
9288 END IF;
9289
9290 END LOOP; /* process repetivity. */
9291
9292 END IF; /* one time mr */
9293
9294 END LOOP; /* ahl_UnSch_contracts_csr */
9295
9296 IF G_DEBUG = 'Y' THEN
9297 AHL_DEBUG_PUB.debug('End of process_pmunsch_activities procedure');
9298 END IF;
9299
9300 END Process_PMUnSch_Activities;
9301
9302 ---------------------------------------------
9303 -- Procedure to find the service_line_id and program for a calculated due_date.
9304 -- The calculated due_date may be overridden by the contract/program dates.
9305 -- Also the earliest due and latest due date will get adjusted if they are not
9306 -- within the contract and program start/end dates.
9307
9308 PROCEDURE Get_PMprogram(p_csi_item_instance_id IN NUMBER,
9309 p_mr_header_id IN NUMBER,
9310 p_last_due_date IN DATE,
9311 p_due_date IN DATE,
9312 p_earliest_due IN DATE,
9313 p_latest_due IN DATE,
9314 x_program_mr_header_id OUT NOCOPY NUMBER,
9315 x_service_line_id OUT NOCOPY NUMBER,
9316 x_contract_override_due_date OUT NOCOPY DATE,
9317 x_cont_override_earliest_due OUT NOCOPY DATE,
9318 x_cont_override_latest_due OUT NOCOPY DATE,
9319 x_contract_found_flag OUT NOCOPY BOOLEAN)
9320 IS
9321
9322 -- get contract/program for a given due date.
9323 CURSOR ahl_contract_exists_csr(p_mr_header_id IN NUMBER,
9324 p_due_date IN DATE) IS
9325 SELECT program_mr_header_id,
9326 service_line_id, contract_start_date, contract_end_date, program_end_date
9327 FROM ahl_applicable_mrs
9328 WHERE mr_header_id = p_mr_header_id
9329 AND pm_schedule_exists = 'N'
9330 AND trunc(program_end_date) >= trunc(p_due_date) -- eliminate expired programs.
9331 AND trunc(p_due_date) >= trunc(contract_start_date)
9332 AND trunc(p_due_date) <= LEAST(trunc(contract_end_date), nvl(trunc(program_end_date),trunc(contract_end_date)))
9333 ORDER BY contract_start_date;
9334
9335 -- get the next contract (if available).
9336 CURSOR ahl_next_contract_csr (p_mr_header_id IN NUMBER,
9337 p_due_date IN DATE) IS
9338 SELECT program_mr_header_id,
9339 service_line_id,
9340 contract_start_date, contract_end_date, program_end_date
9341 FROM ahl_applicable_mrs
9342 WHERE pm_schedule_exists = 'N'
9343 AND trunc(program_end_date) >= trunc(p_due_date) -- eliminate expired programs.
9344 AND mr_header_id = p_mr_header_id
9345 AND trunc(p_due_date) <= trunc(contract_start_date)
9346 ORDER BY contract_start_date;
9347
9348
9349 l_program_mr_header_id NUMBER;
9350 /* program header id for the due date. */
9351
9352 l_service_line_id NUMBER;
9353 /* service line id for the due date. */
9354
9355 l_due_date DATE := p_due_date;
9356
9357 l_contract_start_date DATE;
9358 l_program_end_date DATE;
9359 l_contract_end_date DATE;
9360
9361 l_contract_override_due_date DATE := NULL;
9362 -- this is set only if there exists no contract for the
9363 -- input due date but there is a contract that starts at
9364 -- a later date.
9365
9366
9367 BEGIN
9368
9369 IF G_DEBUG = 'Y' THEN
9370 AHL_DEBUG_PUB.debug('Start of Get_PMprogram procedure for MR:Due Date is: ' ||
9371 p_mr_header_id || ':' || p_due_date);
9372 END IF;
9373
9374 -- Initialize.
9375 x_program_mr_header_id := NULL;
9376 x_service_line_id := NULL;
9377 x_contract_override_due_date := NULL;
9378 x_contract_found_flag := FALSE;
9379 x_cont_override_earliest_due := NULL;
9380 x_cont_override_latest_due := NULL;
9381
9382 -- if p_due_date is null, set it = sysdate; so that it picks ups the earliest contract.
9383 IF (l_due_date IS NULL) THEN
9384 l_due_date := sysdate;
9385 END IF;
9386
9387 -- Check if calculated due date belongs to any contracts.
9388 OPEN ahl_contract_exists_csr (p_mr_header_id,
9389 l_due_date);
9390 FETCH ahl_contract_exists_csr INTO l_program_mr_header_id,
9391 l_service_line_id,
9392 l_contract_start_date,
9393 l_contract_end_date,
9394 l_program_end_date;
9395 IF (ahl_contract_exists_csr%FOUND) THEN
9396 x_program_mr_header_id := l_program_mr_header_id;
9397 x_service_line_id := l_service_line_id;
9398 x_contract_override_due_date := NULL;
9399 x_contract_found_flag := TRUE;
9400
9401 -- In the case due_date is null, return sysdate as due date.
9402 IF (p_due_date IS NULL) THEN
9403 x_contract_override_due_date := l_due_date;
9404 END IF;
9405 -- Added for ER# 2636001.
9406 IF (trunc(p_earliest_due) < trunc(l_contract_start_date)) THEN
9407 x_cont_override_earliest_due := l_contract_start_date;
9408 END IF;
9409 -- if program end date not available, then replace with contract end date.
9410 IF (trunc(p_latest_due) > LEAST(trunc(l_contract_end_date),
9411 trunc(nvl(l_program_end_date, l_contract_end_date))))
9412 THEN
9413 x_cont_override_latest_due := LEAST(trunc(l_contract_end_date),
9414 trunc(nvl(l_program_end_date,l_contract_end_date)));
9415 END IF;
9416
9417 ELSE
9418 -- Look for next contract if exists.
9419 OPEN ahl_next_contract_csr (p_mr_header_id, l_due_date);
9420 FETCH ahl_next_contract_csr INTO l_program_mr_header_id,
9421 l_service_line_id,
9422 l_contract_start_date,
9423 l_contract_end_date,
9424 l_program_end_date;
9425 IF (ahl_next_contract_csr%FOUND) THEN
9426 x_program_mr_header_id := l_program_mr_header_id;
9427 x_service_line_id := l_service_line_id;
9428 x_contract_override_due_date := l_contract_start_date;
9429 x_contract_found_flag := TRUE;
9430
9431 -- Added for ER# 2636001.
9432 IF (trunc(p_earliest_due) < trunc(l_contract_start_date)) THEN
9433 x_cont_override_earliest_due := l_contract_start_date;
9434 END IF;
9435 -- if program end date not available, then replace with contract end date.
9436 IF (trunc(p_latest_due) > LEAST(trunc(l_contract_end_date),
9437 trunc(nvl(l_program_end_date, l_contract_end_date))))
9438 THEN
9439 x_cont_override_latest_due := LEAST(trunc(l_contract_end_date),
9440 trunc(nvl(l_program_end_date,l_contract_end_date)));
9441 END IF;
9442
9443 END IF;
9444
9445 CLOSE ahl_next_contract_csr;
9446 END IF;
9447 CLOSE ahl_contract_exists_csr;
9448
9449 IF G_DEBUG = 'Y' THEN
9450 IF NOT(x_contract_found_flag) THEN
9451 AHL_DEBUG_PUB.debug('Contract Not Found');
9452 END IF;
9453 AHL_DEBUG_PUB.debug('End of Get_PMprogram procedure');
9454 END IF;
9455
9456 END Get_PMprogram;
9457
9458 -------------------------------------------------------------
9459 -- After creation of all maintenance requirements for the instance in the temporary table,
9460 -- assign unit effectivity IDs from existing un-accomplished maintenance requirements
9461 -- belonging to the same instance from ahl_unit_effectivities_b.
9462 PROCEDURE Assign_Unit_Effectivity_IDs IS
9463
9464 -- Added service_line_id to fix FP bug# 5481605.
9465 -- read temporary table sequentially.
9466 CURSOR ahl_mr_header_csr IS
9467 SELECT DISTINCT mr_header_id, csi_item_instance_id, service_line_id
9468 FROM ahl_temp_unit_effectivities;
9469
9470 -- retrieve current unit effectivity records.
9471 CURSOR ahl_unit_effectivity_csr (p_csi_item_instance_id IN NUMBER,
9472 p_mr_header_id IN NUMBER,
9473 p_service_line_id IN NUMBER,
9474 p_appl_usg_code IN VARCHAR2) IS
9475 SELECT ue.unit_effectivity_id
9476 FROM ahl_unit_effectivities_b UE
9477 WHERE mr_header_id = p_mr_header_id
9478 AND csi_item_instance_id = p_csi_item_instance_id
9479 AND application_usg_code = p_appl_usg_code
9480 AND service_line_id = p_service_line_id
9481 AND (UE.Status_code IS NULL OR status_code IN ('INIT-DUE','DEFERRED'))
9482 --ORDER BY forecast_sequence ASC;
9483 ORDER BY unit_effectivity_id ASC; -- fix FP bug# 5481605.
9484
9485 CURSOR ahl_temp_effectivity_csr(p_csi_item_instance_id IN NUMBER,
9486 p_mr_header_id IN NUMBER,
9487 p_service_line_id IN NUMBER) IS
9488 SELECT unit_effectivity_id
9489 FROM ahl_temp_unit_effectivities
9490 WHERE mr_header_id = p_mr_header_id
9491 AND csi_item_instance_id = p_csi_item_instance_id
9492 AND service_line_id = p_service_line_id
9493 FOR UPDATE OF unit_effectivity_id
9494 ORDER BY forecast_sequence ASC;
9495
9496 l_unit_effectivity_id NUMBER;
9497
9498 l_ue_id_tbl nbr_tbl_type;
9499 l_appl_usg_code ahl_unit_effectivities_b.application_usg_code%TYPE;
9500
9501 BEGIN
9502
9503 IF G_DEBUG = 'Y' THEN
9504 AHL_DEBUG_PUB.debug('Start of assign_unit_effectivity_ids procedure');
9505 END IF;
9506
9507 -- Application usage code.
9508 l_appl_usg_code := FND_PROFILE.VALUE('AHL_APPLN_USAGE');
9509
9510 -- For each mr_header_id assign the unit effectivity IDs.
9511 -- note: All mr's are for one item instance only.
9512
9513 FOR mr_header_rec IN ahl_mr_header_csr LOOP
9514 --dbms_output.put_line('Processing for:' || mr_header_rec.mr_header_id);
9515
9516 -- Added service_line_id to fix FP bug# 5481605.
9517 -- open temporary table cursor.
9518 OPEN ahl_temp_effectivity_csr(mr_header_rec.csi_item_instance_id,
9519 mr_header_rec.mr_header_id,
9520 mr_header_rec.service_line_id);
9521
9522 -- loop through all unit_effectivity records.
9523 /*FOR unit_effectivity_rec IN ahl_unit_effectivity_csr(mr_header_rec.csi_item_instance_id,
9524 mr_header_rec.mr_header_id,
9525 mr_header_rec.service_line_id)
9526 */
9527 OPEN ahl_unit_effectivity_csr(mr_header_rec.csi_item_instance_id,
9528 mr_header_rec.mr_header_id,
9529 mr_header_rec.service_line_id,
9530 l_appl_usg_code);
9531
9532 LOOP
9533 FETCH ahl_unit_effectivity_csr BULK COLLECT INTO l_ue_id_tbl LIMIT 1000;
9534 EXIT WHEN (l_ue_id_tbl.count = 0);
9535
9536 IF (l_ue_id_tbl.count > 0) THEN
9537 FOR i IN l_ue_id_tbl.FIRST..l_ue_id_tbl.LAST LOOP
9538
9539 -- Fetch record from temporary table.
9540 FETCH ahl_temp_effectivity_csr INTO l_unit_effectivity_id;
9541 IF (ahl_temp_effectivity_csr%NOTFOUND) THEN
9542 -- exit ahl_unit_effectivity_csr loop as no more records to assign.
9543 EXIT;
9544 ELSE
9545
9546 --dbms_output.put_line('found ue.unit_effectivity_id:' || unit_effectivity_rec.unit_effectivity_id);
9547
9548 --l_unit_effectivity_id := unit_effectivity_rec.unit_effectivity_id;
9549 l_unit_effectivity_id := l_ue_id_tbl(i);
9550
9551 -- update record.
9552
9553 UPDATE ahl_temp_unit_effectivities
9554 SET unit_effectivity_id = l_unit_effectivity_id
9555 WHERE CURRENT OF ahl_temp_effectivity_csr;
9556 END IF; -- ahl_temp_effectivity_csr%NOTFOUND
9557 END LOOP; -- l_ue_id_tbl.FIRST
9558 END IF; -- l_ue_id_tbl.count > 0
9559
9560 IF (ahl_temp_effectivity_csr%NOTFOUND) THEN
9561 EXIT; -- exit ahl_unit_effectivity_csr LOOP
9562 END IF;
9563
9564 l_ue_id_tbl.DELETE;
9565
9566 END LOOP; -- ahl_unit_effectivity_csr
9567 CLOSE ahl_temp_effectivity_csr;
9568 CLOSE ahl_unit_effectivity_csr;
9569
9570 END LOOP; -- ahl_mr_header_csr.
9571
9572 IF G_DEBUG = 'Y' THEN
9573 AHL_DEBUG_PUB.debug('End of assign_unit_effectivity_ids procedure');
9574 END IF;
9575
9576 END Assign_Unit_Effectivity_IDs;
9577
9578 -------------------------------------------------------------
9579 -- Procedure to calculate due date based on deferral details.
9580 PROCEDURE Get_Deferred_Due_Date (p_unit_effectivity_id IN NUMBER,
9581 p_deferral_threshold_tbl IN counter_values_tbl_type,
9582 x_due_date OUT NOCOPY DATE,
9583 x_return_status OUT NOCOPY VARCHAR2,
9584 x_msg_data OUT NOCOPY VARCHAR2,
9585 x_msg_count OUT NOCOPY NUMBER)
9586 IS
9587
9588 -- Get Unit Effectivity details.
9589 -- added inventory_item_id, inv_master_organization_id to fix bug# 9284692
9590 CURSOR ahl_unit_effectivity_csr (p_unit_effectivity_id IN NUMBER) IS
9591 SELECT ue.csi_item_instance_id, ue.mr_header_id, cii.inventory_item_id,
9592 cii.inv_master_organization_id
9593 FROM ahl_unit_effectivities_app_v ue, csi_item_instances cii
9594 WHERE ue.unit_effectivity_id = p_unit_effectivity_id
9595 AND ue.csi_item_instance_id = cii.instance_id;
9596
9597 -- Get MR details.
9598 CURSOR ahl_mr_headers_csr (p_mr_header_id IN NUMBER) IS
9599 SELECT whichever_first_code
9600 FROM ahl_mr_headers_app_v
9601 WHERE mr_header_id = p_mr_header_id;
9602
9603 -- get the configuration structure.(G_config_node_tbl).
9604 CURSOR csi_reln_csr ( p_csi_item_instance_id IN NUMBER) IS
9605 SELECT position_reference
9606 FROM csi_ii_relationships
9607 WHERE subject_id = p_csi_item_instance_id
9608 AND relationship_type_code = 'COMPONENT-OF'
9609 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
9610 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1));
9611
9612 -- get the counter usage
9613 CURSOR cs_ctr_counter_csr (--p_csi_item_instance_id IN NUMBER,
9614 p_counter_id IN NUMBER) IS
9615 /*
9616 SELECT nvl(net_reading, 0)
9617 FROM csi_cp_counters_v
9618 WHERE customer_product_id = p_csi_item_instance_id
9619 AND counter_id = p_counter_id;
9620 */
9621
9622 /*
9623 SELECT nvl(cv.net_reading,0) net_reading
9624 FROM csi_counter_values_v cv
9625 WHERE cv.counter_id = p_counter_id
9626 AND cv.counter_id IN (select counter_id
9627 from csi_counter_associations cca
9628 where source_object_code = 'CP'
9629 AND source_object_id = p_csi_item_instance_id
9630 AND cca.counter_id = cv.counter_id)
9631 AND rownum < 2;
9632 */
9633 select nvl(ccr.net_reading,0) net_reading
9634 FROM csi_counters_b cc, csi_counter_readings ccr
9635 WHERE cc.counter_id = p_counter_id
9636 and ccr.counter_value_id = cc.CTR_VAL_MAX_SEQ_NO;
9637
9638 i NUMBER;
9639 l_csi_item_instance_id NUMBER;
9640 l_root_csi_instance_id NUMBER;
9641 l_mr_header_id NUMBER;
9642 l_uc_header_id NUMBER;
9643 l_calc_due_date DATE;
9644 l_due_date DATE;
9645 l_whichever_first_code ahl_mr_headers_app_v.whichever_first_code%TYPE;
9646 l_inv_master_organization_id number;
9647 l_inventory_item_id number;
9648 l_position_reference VARCHAR2(30);
9649 l_counter_rules_tbl counter_rules_tbl_type;
9650 l_current_usage_tbl counter_values_tbl_type;
9651 l_counter_value number;
9652 l_counter_remain number;
9653
9654 BEGIN
9655
9656 -- Set return status.
9657 x_return_status := FND_API.G_RET_STS_SUCCESS;
9658
9659 -- Enable Debug.
9660 IF G_DEBUG = 'Y' THEN
9661 AHL_DEBUG_PUB.enable_debug;
9662 END IF;
9663
9664 -- Add debug mesg.
9665 IF G_DEBUG = 'Y' THEN
9666 AHL_DEBUG_PUB.debug('Begin private API:' || G_PKG_NAME || '.' || 'Get_Deferred_Due_Date');
9667 AHL_DEBUG_PUB.debug('Dump of input parameters:');
9668 AHL_DEBUG_PUB.debug('Unit Effectivity ID:' || p_unit_effectivity_id);
9669 AHL_DEBUG_PUB.debug('Count on p_deferral_threshold_tbl:' || p_deferral_threshold_tbl.COUNT);
9670 END IF;
9671
9672 -- Validate input parameters.
9673 IF (p_unit_effectivity_id IS NULL OR p_unit_effectivity_id = FND_API.G_MISS_NUM) THEN
9674 FND_MESSAGE.Set_Name('AHL','AHL_UMP_DEF_UE_NULL');
9675 FND_MSG_PUB.ADD;
9676 RAISE FND_API.G_EXC_ERROR;
9677 ELSE
9678 OPEN ahl_unit_effectivity_csr (p_unit_effectivity_id);
9679 FETCH ahl_unit_effectivity_csr INTO l_csi_item_instance_id, l_mr_header_id,
9680 l_inventory_item_id, l_inv_master_organization_id;
9681 IF (ahl_unit_effectivity_csr%NOTFOUND) THEN
9682 FND_MESSAGE.Set_Name('AHL','AHL_UMP_DEF_UE_INVALID');
9683 FND_MESSAGE.Set_Token('UE_ID', p_unit_effectivity_id);
9684 FND_MSG_PUB.ADD;
9685 RAISE FND_API.G_EXC_ERROR;
9686 END IF;
9687 END IF;
9688
9689 IF (l_mr_header_id IS NOT NULL) THEN
9690 -- get MR details from ahl_mr_headers.
9691 OPEN ahl_mr_headers_csr(l_mr_header_id);
9692 FETCH ahl_mr_headers_csr INTO l_whichever_first_code;
9693 IF (ahl_mr_headers_csr%NOTFOUND) THEN
9694 FND_MESSAGE.Set_Name('AHL','AHL_UMP_DEF_MR_INVALID');
9695 FND_MESSAGE.Set_Token('UE_ID', p_unit_effectivity_id);
9696 FND_MSG_PUB.ADD;
9697 RAISE FND_API.G_EXC_ERROR;
9698 END IF;
9699 CLOSE ahl_mr_headers_csr;
9700 ELSE
9701 -- SR case.
9702 l_whichever_first_code := 'FIRST';
9703 END IF;
9704
9705 IF G_DEBUG = 'Y' THEN
9706 AHL_DEBUG_PUB.debug('Step 1');
9707 AHL_DEBUG_PUB.debug('MR Header ID:' || l_mr_header_id);
9708 AHL_DEBUG_PUB.debug('CSI Item Instance ID:' || l_csi_item_instance_id);
9709 AHL_DEBUG_PUB.debug('Inventory Item ID:' || l_inventory_item_id);
9710 AHL_DEBUG_PUB.debug('INV master Org ID:' || l_inv_master_organization_id);
9711 END IF;
9712
9713 -- Get Unit and Master Config IDs if available.
9714 -- Find the root item instance.
9715 l_root_csi_instance_id := Get_RootInstanceID(l_csi_item_instance_id);
9716
9717 -- Get master and unit configuration for the root item instance.
9718 Get_Unit_Master_ConfigIDs (l_root_csi_instance_id,
9719 l_uc_header_id, G_master_config_id);
9720
9721 IF G_DEBUG = 'Y' THEN
9722 AHL_DEBUG_PUB.debug('Step 2');
9723 END IF;
9724
9725 -- Check for errors.
9726 IF FND_MSG_PUB.Count_msg > 0 THEN
9727 RAISE FND_API.G_EXC_ERROR;
9728 END IF;
9729
9730 IF G_DEBUG = 'Y' THEN
9731 AHL_DEBUG_PUB.debug('Step 3');
9732 END IF;
9733
9734 -- Get utilization forecast for the unit/part.
9735 Get_Utilization_Forecast (l_root_csi_instance_id,
9736 l_uc_header_id,
9737 l_inventory_item_id,
9738 l_inv_master_organization_id,
9739 G_forecast_details_tbl);
9740
9741 IF G_DEBUG = 'Y' THEN
9742 AHL_DEBUG_PUB.debug('Step 4');
9743 AHL_DEBUG_PUB.debug('Count on util forecast tbl:' || G_forecast_details_tbl.count);
9744 END IF;
9745
9746 -- Get the position installed in.
9747 OPEN csi_reln_csr(l_csi_item_instance_id);
9748 FETCH csi_reln_csr INTO l_position_reference;
9749 IF (csi_reln_csr%NOTFOUND) THEN
9750 l_position_reference := G_master_config_id;
9751 END IF;
9752 CLOSE csi_reln_csr;
9753
9754 IF G_DEBUG = 'Y' THEN
9755 AHL_DEBUG_PUB.debug('Step 5');
9756 END IF;
9757
9758 -- Build counter rules ratio if node is not root node.
9759 IF (G_master_config_id IS NOT NULL AND l_position_reference IS NOT NULL) THEN
9760 build_Counter_Ratio(l_position_reference,
9761 l_csi_item_instance_id,
9762 G_master_config_id,
9763 l_counter_rules_tbl);
9764 END IF;
9765
9766 IF G_DEBUG = 'Y' THEN
9767 AHL_DEBUG_PUB.debug('Step 6');
9768 END IF;
9769
9770 -- Calculate counter_remain and call get_date_from_uf.
9771 IF (p_deferral_threshold_tbl.COUNT > 0) THEN
9772 FOR i IN p_deferral_threshold_tbl.FIRST..p_deferral_threshold_tbl.LAST LOOP
9773 -- get current usage
9774 --OPEN cs_ctr_counter_csr(l_csi_item_instance_id, p_deferral_threshold_tbl(i).counter_id);
9775 OPEN cs_ctr_counter_csr(p_deferral_threshold_tbl(i).counter_id);
9776 FETCH cs_ctr_counter_csr INTO l_counter_value;
9777 IF (cs_ctr_counter_csr%NOTFOUND) THEN
9778 IF G_DEBUG = 'Y' THEN
9779 AHL_DEBUG_PUB.debug('Step 7');
9780 END IF;
9781 l_counter_value := 0;
9782 END IF;
9783
9784 CLOSE cs_ctr_counter_csr;
9785
9786 IF G_DEBUG = 'Y' THEN
9787 AHL_DEBUG_PUB.debug('l_counter_value:' || l_counter_value);
9788 END IF;
9789
9790 -- Get due date for counter remain.
9791 l_counter_remain := p_deferral_threshold_tbl(i).counter_value - l_counter_value;
9792
9793 IF G_DEBUG = 'Y' THEN
9794 AHL_DEBUG_PUB.debug('l_counter_remain:' || l_counter_remain);
9795 END IF;
9796
9797 -- get date from forecast.
9798 get_date_from_uf(l_counter_remain,
9799 p_deferral_threshold_tbl(i).uom_code,
9800 l_counter_rules_tbl,
9801 sysdate,
9802 l_due_date);
9803
9804 IF (l_due_date IS NULL) THEN
9805 l_calc_due_date := NULL;
9806 EXIT;
9807 ELSIF (l_calc_due_date IS NULL) THEN
9808 l_calc_due_date := l_due_date;
9809 ELSIF (l_whichever_first_code = 'FIRST') THEN
9810 IF (trunc(l_due_date) < trunc(l_calc_due_date)) THEN
9811 l_calc_due_date := l_due_date;
9812 END IF;
9813 ELSIF (l_whichever_first_code = 'LAST') THEN
9814 IF (trunc(l_due_date) > trunc(l_calc_due_date)) THEN
9815 l_calc_due_date := l_due_date;
9816 END IF;
9817 END IF;
9818
9819 END LOOP;
9820 END IF;
9821 x_due_date := l_calc_due_date;
9822
9823 -- Standard call to get message count and if count is 1, get message info
9824 FND_MSG_PUB.Count_And_Get
9825 ( p_count => x_msg_count,
9826 p_data => x_msg_data,
9827 p_encoded => fnd_api.g_false
9828 );
9829
9830 --
9831 EXCEPTION
9832 WHEN FND_API.G_EXC_ERROR THEN
9833 x_return_status := FND_API.G_RET_STS_ERROR;
9834 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
9835 p_data => x_msg_data,
9836 p_encoded => fnd_api.g_false);
9837
9838 -- Disable debug
9839 AHL_DEBUG_PUB.disable_debug;
9840
9841 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
9842 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9843 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
9844 p_data => x_msg_data,
9845 p_encoded => fnd_api.g_false);
9846
9847 -- Disable debug
9848 AHL_DEBUG_PUB.disable_debug;
9849
9850 WHEN OTHERS THEN
9851
9852 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9853 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
9854 fnd_msg_pub.add_exc_msg(p_pkg_name => G_PKG_NAME,
9855 p_procedure_name => 'Get_Deferred_Due_Date',
9856 p_error_text => SUBSTR(SQLERRM,1,240));
9857 END IF;
9858 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
9859 p_data => x_msg_data,
9860 p_encoded => fnd_api.g_false);
9861
9862
9863 -- Disable debug
9864 AHL_DEBUG_PUB.disable_debug;
9865
9866 END Get_Deferred_Due_Date;
9867 ------------------------------------------------------------------
9868
9869 -- Get the latest recorded counter reading for a given date.
9870 PROCEDURE get_ctr_reading_for_date (p_csi_item_instance_id IN NUMBER,
9871 p_counter_id IN NUMBER,
9872 p_reading_date IN DATE,
9873 x_net_reading OUT NOCOPY NUMBER) IS
9874
9875 -- get the latest reading recorded for a counter on any given date.
9876 CURSOR cs_ctr_reading_csr(p_csi_item_instance_id IN NUMBER,
9877 p_counter_id IN NUMBER,
9878 p_reading_date IN DATE) IS
9879 /*SELECT net_reading
9880 FROM cs_ctr_counter_values_v cv, cs_counter_groups cg
9881 WHERE cv.counter_group_id = cg.counter_group_id
9882 AND cg.source_object_code = 'CP'
9883 AND cg.source_object_id = p_csi_item_instance_id
9884 AND cv.counter_id = p_counter_id
9885 AND trunc(VALUE_TIMESTAMP) <= trunc(p_reading_date)
9886 ORDER BY cv.value_timestamp desc; */
9887
9888 --priyan
9889 --Query being changed due to performance related fixes
9890 --Refer Bug # 4918744
9891
9892 /* Commented out to fix bug# 6445866. In R12, IB is not instantiating
9893 * counter groups in CS_CSI_COUNTER_GROUPS.
9894 SELECT --DISTINCT
9895 CCR.NET_READING
9896 FROM
9897 CSI_COUNTERS_VL CC,
9898 --CS_COUNTER_GROUPS CCA,
9899 --priyan
9900 --changes for Bug #5207990.
9901 CS_CSI_COUNTER_GROUPS CCA,
9902 CSI_COUNTER_READINGS CCR
9903 WHERE
9904 CC.DEFAULTED_GROUP_ID (+) = CCA.COUNTER_GROUP_ID
9905 AND CCA.SOURCE_OBJECT_CODE = 'CP'
9906 AND CCR.COUNTER_ID = CC.COUNTER_ID
9907 AND CCA.SOURCE_OBJECT_ID = P_CSI_ITEM_INSTANCE_ID
9908 AND CC.COUNTER_ID = P_COUNTER_ID
9909 AND TRUNC(CCR.VALUE_TIMESTAMP) <= TRUNC(P_READING_DATE)
9910 ORDER BY
9911 CCR.VALUE_TIMESTAMP DESC;
9912
9913 */
9914
9915 SELECT * FROM (
9916 SELECT CCR.NET_READING
9917 FROM
9918 CSI_COUNTER_READINGS CCR
9919 WHERE
9920 CCR.COUNTER_ID = P_COUNTER_ID
9921 AND nvl(CCR.disabled_flag,'N') = 'N'
9922 AND TRUNC(CCR.VALUE_TIMESTAMP) <= TRUNC(P_READING_DATE)
9923 ORDER BY
9924 CCR.VALUE_TIMESTAMP DESC
9925 )
9926 WHERE rownum < 2;
9927
9928
9929 l_net_reading NUMBER;
9930
9931 BEGIN
9932
9933 IF G_DEBUG = 'Y' THEN
9934 AHL_DEBUG_PUB.debug('Start of get_ctr_reading_for_date');
9935 END IF;
9936
9937 OPEN cs_ctr_reading_csr(p_csi_item_instance_id,
9938 p_counter_id,
9939 p_reading_date);
9940 FETCH cs_ctr_reading_csr INTO l_net_reading;
9941 IF (cs_ctr_reading_csr%NOTFOUND) THEN
9942 l_net_reading := 0;
9943 END IF;
9944 CLOSE cs_ctr_reading_csr;
9945
9946 x_net_reading := l_net_reading;
9947
9948 IF G_DEBUG = 'Y' THEN
9949 AHL_DEBUG_PUB.debug('End of get_ctr_reading_for_date');
9950 END IF;
9951
9952 END get_ctr_reading_for_date;
9953 -----------------------------------------------------------------------
9954
9955 -- Get the earliest date on which a given reading was recorded.
9956 PROCEDURE get_ctr_date_for_reading (p_csi_item_instance_id IN NUMBER,
9957 p_counter_id IN NUMBER,
9958 p_counter_value IN NUMBER,
9959 x_ctr_record_date OUT NOCOPY DATE,
9960 x_return_val OUT NOCOPY BOOLEAN) IS
9961
9962
9963 -- get the earliest reading for which the given counter value exceeds.
9964 CURSOR cs_ctr_reading_csr(p_csi_item_instance_id IN NUMBER,
9965 p_counter_id IN NUMBER,
9966 p_counter_value IN NUMBER) IS
9967 /*
9968 SELECT value_timestamp
9969 FROM cs_ctr_counter_values_v cv, cs_counter_groups cg
9970 WHERE cv.counter_group_id = cg.counter_group_id
9971 AND cg.source_object_code = 'CP'
9972 AND cg.source_object_id = p_csi_item_instance_id
9973 AND cv.counter_id = p_counter_id
9974 AND nvl(cv.net_reading,0) >= p_counter_value
9975 ORDER BY value_timestamp asc;
9976 */
9977
9978 --priyan
9979 --Query being changed due to performance related fixes
9980 --Refer Bug # 4918744
9981
9982 /* Commented out to fix bug# 6445866. In R12, IB is not instantiating
9983 * counter groups in CS_CSI_COUNTER_GROUPS.
9984
9985 SELECT --DISTINCT
9986 CCR.VALUE_TIMESTAMP
9987 FROM
9988 CSI_COUNTERS_VL CC,
9989 --CS_COUNTER_GROUPS CCA,
9990 --priyan
9991 --Refer Bug # 5207990 for changes.
9992 CS_CSI_COUNTER_GROUPS CCA,
9993 CSI_COUNTER_READINGS CCR
9994 WHERE
9995 CC.DEFAULTED_GROUP_ID (+) = CCA.COUNTER_GROUP_ID
9996 AND CCA.SOURCE_OBJECT_CODE = 'CP'
9997 AND CCR.COUNTER_ID = CC.COUNTER_ID
9998 AND CCA.SOURCE_OBJECT_ID = P_CSI_ITEM_INSTANCE_ID
9999 AND CC.COUNTER_ID = P_COUNTER_ID
10000 AND NVL(CCR.NET_READING,0) >= P_COUNTER_VALUE
10001 ORDER BY
10002 CCR.VALUE_TIMESTAMP ASC;
10003 */
10004
10005 SELECT * FROM (
10006 SELECT CCR.VALUE_TIMESTAMP
10007 FROM CSI_COUNTER_READINGS CCR
10008 WHERE CCR.COUNTER_ID = P_COUNTER_ID
10009 AND nvl(disabled_flag,'N') = 'N'
10010 AND NVL(CCR.NET_READING,0) >= P_COUNTER_VALUE
10011 ORDER BY CCR.VALUE_TIMESTAMP ASC
10012 )
10013 WHERE rownum < 2;
10014
10015 l_ctr_record_date DATE;
10016 l_return_val BOOLEAN := TRUE;
10017
10018 BEGIN
10019
10020
10021 IF G_DEBUG = 'Y' THEN
10022 AHL_DEBUG_PUB.debug('Start of get_ctr_date_for_reading');
10023 END IF;
10024
10025 OPEN cs_ctr_reading_csr (p_csi_item_instance_id,
10026 p_counter_id,
10027 p_counter_value);
10028 FETCH cs_ctr_reading_csr INTO l_ctr_record_date;
10029 IF (cs_ctr_reading_csr%NOTFOUND) THEN
10030 l_return_val := FALSE;
10031 l_ctr_record_date := NULL;
10032 END IF;
10033 CLOSE cs_ctr_reading_csr;
10034
10035 x_ctr_record_date := l_ctr_record_date;
10036 x_return_val := l_return_val;
10037
10038 IF G_DEBUG = 'Y' THEN
10039 AHL_DEBUG_PUB.debug('End of get_ctr_date_for_reading');
10040 END IF;
10041
10042 END get_ctr_date_for_reading;
10043
10044 -------------------------------------------------------------------------------
10045 -- Calculate due date for all deferred unit effectivities.
10046 PROCEDURE Process_Deferred_UE (p_csi_item_instance_id IN NUMBER,
10047 p_current_usage_tbl IN counter_values_tbl_type,
10048 p_counter_rules_tbl IN counter_rules_tbl_type)
10049 IS
10050
10051 -- get all deferred unit effectivity records for the instance and MR.
10052 CURSOR ahl_deferred_ue_csr (p_csi_item_instance_id IN NUMBER,
10053 p_appln_usage_code IN VARCHAR2) IS
10054
10055 SELECT
10056 UE.UNIT_EFFECTIVITY_ID,
10057 UE.OBJECT_TYPE,
10058 UE.CSI_ITEM_INSTANCE_ID,
10059 UE.MR_HEADER_ID,
10060 UE.STATUS_CODE,
10061 UE.DEFER_FROM_UE_ID,
10062 nvl(MR.whichever_first_code, 'FIRST') whichever_first_code,
10063 UDF.unit_deferral_type, UE.CS_INCIDENT_ID, UDF.DEFERRAL_EFFECTIVE_ON,
10064 UDF.AFFECT_DUE_CALC_FLAG, UDF.SET_DUE_DATE, UDF.unit_deferral_id,
10065 MR.title
10066 FROM ahl_unit_effectivities_b UE, ahl_unit_deferrals_b UDF, ahl_mr_headers_b MR
10067 WHERE UE.defer_from_ue_id = UDF.unit_effectivity_id
10068 AND UE.mr_header_id = MR.mr_header_id(+)
10069 AND UE.csi_item_instance_id = p_csi_item_instance_id
10070 AND UE.application_usg_code = p_appln_usage_code
10071 AND status_code IS NULL
10072 --AND defer_from_ue_id IS NOT NULL -- not required as joining table ahl_unit_deferrals_b
10073 AND UDF.unit_deferral_type IN ('DEFERRAL', 'MEL','CDL')
10074 AND NOT EXISTS (SELECT 'x'
10075 FROM ahl_ue_relationships
10076 WHERE related_ue_id = UE.unit_effectivity_id
10077 AND relationship_code = 'PARENT')
10078 AND UDF.approval_status_code = 'DEFERRED'
10079 ORDER BY DEFERRAL_EFFECTIVE_ON ASC;
10080
10081 /* Commented as we retrieve this info in ahl_deferred_ue_csr
10082 -- Get deferral detail from ahl_unit_deferrals.
10083 CURSOR ahl_unit_deferral_csr (p_deferred_from_ue_id IN NUMBER) IS
10084 SELECT AFFECT_DUE_CALC_FLAG, SET_DUE_DATE, unit_deferral_id, deferral_effective_on
10085 FROM ahl_unit_deferrals_b
10086 WHERE unit_effectivity_id = p_deferred_from_ue_id
10087 AND unit_deferral_type = 'DEFERRAL';
10088 */
10089
10090 -- Get threshold details.
10091 CURSOR ahl_unit_threshold_csr (p_unit_deferral_id IN NUMBER) IS
10092 SELECT counter_id, counter_value, ctr_value_type_code
10093 FROM ahl_unit_thresholds
10094 WHERE unit_deferral_id = p_unit_deferral_id;
10095
10096 -- Read applicable relns table for group MR details.
10097 CURSOR ahl_applicable_grp_csr( p_item_instance_id IN NUMBER,
10098 p_mr_header_id IN NUMBER) IS
10099
10100 SELECT related_mr_header_id,
10101 related_csi_item_instance_id,
10102 csi_item_instance_id parent_csi_item_instance_id,
10103 mr_header_id parent_mr_header_id
10104 FROM ahl_applicable_mr_relns
10105 START WITH mr_header_id = p_mr_header_id AND
10106 csi_item_instance_id = p_item_instance_id AND
10107 orig_mr_header_id = p_mr_header_id AND
10108 orig_csi_item_instance_id = p_item_instance_id AND
10109 relationship_code = 'PARENT'
10110 CONNECT BY PRIOR related_mr_header_id = mr_header_id AND
10111 PRIOR related_csi_item_instance_id = csi_item_instance_id AND
10112 orig_mr_header_id = p_mr_header_id AND
10113 orig_csi_item_instance_id = p_item_instance_id AND
10114 relationship_code = 'PARENT'
10115 ORDER BY level;
10116
10117 -- check repair category for time limit.
10118 cursor get_repair_category_csr(p_cs_incident_id IN NUMBER)
10119 is
10120 select nvl(repair_time,0), cs.expected_resolution_date
10121 from ahl_repair_categories rc, cs_incidents_all_b cs
10122 where rc.sr_urgency_id(+) = cs.incident_urgency_id
10123 and cs.incident_id = p_cs_incident_id;
10124
10125 -- Read immediate children of the SR.
10126 CURSOR ahl_ue_reln_csr (p_ue_id IN NUMBER) IS
10127 SELECT ue.unit_effectivity_id, ue.status_code,
10128 UE.CSI_ITEM_INSTANCE_ID, UE.MR_HEADER_ID
10129 FROM ahl_ue_relationships uer, ahl_unit_effectivities_b ue
10130 WHERE ue.unit_effectivity_id = uer.related_ue_id
10131 AND uer.ue_id = p_ue_id;
10132
10133 --
10134 l_due_at_counter_value NUMBER;
10135 --l_affect_due_date_calc VARCHAR2(1);
10136 l_set_due_date DATE;
10137 l_unit_deferral_id NUMBER;
10138 l_deferral_effective_on DATE;
10139 l_net_reading NUMBER;
10140 l_due_date DATE;
10141 l_counter_read_date DATE;
10142
10143 l_counter_remain NUMBER;
10144 l_current_ctr_value NUMBER;
10145 k NUMBER;
10146 l_return_val BOOLEAN;
10147
10148 l_calc_due_date DATE;
10149 l_calc_counter_id NUMBER;
10150 l_calc_tolerance_flag ahl_unit_effectivities_app_v.tolerance_flag%TYPE;
10151 l_calc_message_code ahl_unit_effectivities_app_v.message_code%TYPE;
10152 l_calc_due_counter_value NUMBER;
10153
10154 l_visit_start_date DATE;
10155 l_visit_end_date DATE;
10156 l_visit_assign_code fnd_lookups.lookup_code%TYPE;
10157
10158 l_grp_match VARCHAR2(1);
10159 l_grp_match1 VARCHAR2(1);
10160
10161 l_unit_deferral_type VARCHAR2(30);
10162 l_repair_time NUMBER;
10163 l_expected_resolutn_date DATE;
10164
10165 l_visit_status ahl_visits_b.status_code%TYPE;
10166
10167 -- Added for SB Enh.
10168 l_junk VARCHAR2(1);
10169 CURSOR check_applicable_mr(p_mr_title IN VARCHAR2, p_item_instance_id IN NUMBER) IS
10170 SELECT 'x'
10171 FROM ahl_applicable_mrs
10172 WHERE csi_item_instance_id = p_item_instance_id
10173 AND mr_header_id IN (select mr_header_id from ahl_mr_headers_b where title = p_mr_title);
10174
10175 BEGIN
10176
10177 IF G_DEBUG = 'Y' THEN
10178 AHL_DEBUG_PUB.debug('Start of process_Deferred_ue');
10179 END IF;
10180
10181 -- get all open deferred unit effectivities.
10182 FOR unit_effectivity_rec IN ahl_deferred_ue_csr(p_csi_item_instance_id, G_application_usg_code) LOOP
10183
10184 IF G_DEBUG = 'Y' THEN
10185 AHL_DEBUG_PUB.debug('Processing ..ID:' || unit_effectivity_rec.unit_effectivity_id);
10186 AHL_DEBUG_PUB.debug('Processing ..unit_deferral_type:' || unit_effectivity_rec.unit_deferral_type);
10187 END IF;
10188
10189 -- Initialize.
10190 l_calc_due_date := null;
10191 --l_calc_counter_id,
10192 l_calc_due_counter_value := null;
10193 l_calc_tolerance_flag := null;
10194 l_calc_message_code := null;
10195
10196 IF (unit_effectivity_rec.unit_deferral_type = 'DEFERRAL') THEN
10197
10198 -- added for SB Enh. MR can be terminated due to accomplish trigger.
10199 -- validate MR exists in applicable MRs table.
10200 OPEN check_applicable_mr(unit_effectivity_rec.title, p_csi_item_instance_id);
10201 FETCH check_applicable_mr INTO l_junk;
10202 IF (check_applicable_mr%NOTFOUND) THEN
10203 CLOSE check_applicable_mr;
10204 CONTINUE; -- next record.
10205 END IF;
10206 CLOSE check_applicable_mr;
10207
10208 -- get deferral details.
10209 l_set_due_date := unit_effectivity_rec.set_due_date;
10210 l_unit_deferral_id := unit_effectivity_rec.unit_deferral_id;
10211 l_deferral_effective_on := unit_effectivity_rec.deferral_effective_on;
10212
10213 /*
10214 OPEN ahl_unit_deferral_csr(unit_effectivity_rec.defer_from_ue_id);
10215 FETCH ahl_unit_deferral_csr INTO l_affect_due_date_calc, l_set_due_date, l_unit_deferral_id,
10216 l_deferral_effective_on;
10217 IF (ahl_unit_deferral_csr%NOTFOUND) THEN
10218 CLOSE ahl_unit_deferral_csr;
10219 FND_MESSAGE.Set_Name('AHL','AHL_UMP_DEF_NOTFOUND');
10220 FND_MESSAGE.Set_Token('UE_ID',unit_effectivity_rec.defer_from_ue_id);
10221 FND_MSG_PUB.ADD;
10222 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
10223 END IF;
10224
10225 CLOSE ahl_unit_deferral_csr;
10226 */
10227 -- process threshold details for this deferral.
10228 FOR threshold_rec IN ahl_unit_threshold_csr(l_unit_deferral_id) LOOP
10229 l_due_at_counter_value := threshold_rec.counter_value;
10230 l_counter_remain := 0;
10231 l_current_ctr_value := 0;
10232 k := 0;
10233 -- search for the current counter value in p_current_usage_tbl.
10234 IF (p_current_usage_tbl.COUNT > 0) THEN
10235 FOR i IN p_current_usage_tbl.FIRST..p_current_usage_tbl.LAST LOOP
10236 IF (p_current_usage_tbl(i).counter_id = threshold_rec.counter_id) THEN
10237 l_current_ctr_value := p_current_usage_tbl(i).counter_value;
10238 k := i;
10239 EXIT;
10240 END IF;
10241 END LOOP;
10242
10243 IF G_DEBUG = 'Y' THEN
10244 AHL_DEBUG_PUB.debug('In threshold rec with current usg > 0: ctr val:eff on:ctr type:' || l_current_ctr_value ||':' || l_deferral_effective_on || ':' || threshold_rec.ctr_value_type_code);
10245
10246 END IF;
10247
10248 -- Calculate counter remain.
10249 IF (threshold_rec.ctr_value_type_code = 'DEFER_BY') THEN
10250 -- get counter usage as on deferral_effective_on date.
10251 get_ctr_reading_for_datetime (p_csi_item_instance_id => p_csi_item_instance_id,
10252 p_counter_id => p_current_usage_tbl(k).counter_id,
10253 p_reading_date => l_deferral_effective_on,
10254 x_net_reading => l_net_reading);
10255
10256 -- add net reading to the threshold value.
10257 l_due_at_counter_value := l_net_reading + l_due_at_counter_value;
10258 END IF; -- defer by.
10259
10260 l_counter_remain := l_due_at_counter_value - l_current_ctr_value;
10261
10262 --dbms_output.put_line ('After reading:ctr remain' || l_counter_remain);
10263
10264 -- calculate due date from forecast.
10265 IF (l_counter_remain > 0) THEN
10266 --dbms_output.put_line ('counter remain greater than zero');
10267 -- get date from forecast.
10268 get_date_from_uf(l_counter_remain,
10269 p_current_usage_tbl(k).uom_code,
10270 p_counter_rules_tbl,
10271 null, /* start date = sysdate */
10272 l_due_date);
10273 ELSIF (l_counter_remain < 0) THEN
10274 --dbms_output.put_line ('counter remain less than zero');
10275 -- Due date = counter reading date.
10276 get_ctr_date_for_reading (p_csi_item_instance_id => p_csi_item_instance_id,
10277 p_counter_id => p_current_usage_tbl(k).counter_id,
10278 p_counter_value => l_due_at_counter_value,
10279 x_ctr_record_date => l_counter_read_date,
10280 x_return_val => l_return_val);
10281
10282 IF NOT(l_return_val) THEN
10283 l_due_date := sysdate;
10284 ELSE
10285 l_due_date := l_counter_read_date;
10286 END IF;
10287
10288 ELSIF (l_counter_remain = 0) THEN /* due_date = sysdate */
10289 --dbms_output.put_line ('counter remain is zero');
10290 l_due_date := sysdate;
10291 END IF; -- counter remain.
10292
10293 -- For MR type, based on whichever first code, set calculated due date.
10294 -- For SR type, whichever first code = 'FIRST'.
10295 IF (l_due_date IS NULL) THEN
10296 l_calc_due_date := NULL;
10297 l_calc_counter_id := p_current_usage_tbl(k).counter_id;
10298 l_calc_due_counter_value := l_due_at_counter_value;
10299 EXIT;
10300 ELSIF (l_calc_due_date IS NULL) THEN
10301 l_calc_due_date := l_due_date;
10302 l_calc_counter_id := p_current_usage_tbl(k).counter_id;
10303 l_calc_due_counter_value := l_due_at_counter_value;
10304 ELSE
10305 IF (unit_effectivity_rec.whichever_first_code = 'FIRST') THEN
10306 IF (trunc(l_due_date) < trunc(l_calc_due_date)) THEN
10307 l_calc_due_date := l_due_date;
10308 l_calc_counter_id := p_current_usage_tbl(k).counter_id;
10309 l_calc_due_counter_value := l_due_at_counter_value;
10310 END IF;
10311 ELSE -- whichever_first_code = 'LAST'
10312 IF (trunc(l_due_date) > trunc(l_calc_due_date)) THEN
10313 l_calc_due_date := l_due_date;
10314 l_calc_counter_id := p_current_usage_tbl(k).counter_id;
10315 l_calc_due_counter_value := l_due_at_counter_value;
10316 END IF;
10317 END IF;
10318 END IF;
10319
10320 --dbms_output.put_line ('Bl_calc_due_date:' || l_calc_due_date);
10321 --dbms_output.put_line ('Bset_due_date:' || l_set_due_date);
10322 --dbms_output.put_line ('Bdue_ctr_val:' || l_calc_due_counter_value);
10323 --dbms_output.put_line ('BcounterID:' || l_calc_counter_id);
10324
10325 END IF; -- current_usage_tbl.
10326 END LOOP; -- threshold rec.
10327
10328 IF G_DEBUG = 'Y' THEN
10329 AHL_DEBUG_PUB.debug('l_calc_due_date:' || l_calc_due_date);
10330 AHL_DEBUG_PUB.debug('set_due_date:' || l_set_due_date);
10331 AHL_DEBUG_PUB.debug('due_ctr_val:' || l_calc_due_counter_value);
10332 AHL_DEBUG_PUB.debug('counterID:' || l_calc_counter_id);
10333 END IF;
10334
10335 -- Check calculated due date against set_due_date.
10336 IF (l_calc_due_date IS NOT NULL AND l_set_due_date IS NOT NULL) THEN
10337 IF (unit_effectivity_rec.whichever_first_code = 'FIRST') THEN
10338 IF (trunc(l_set_due_date) < trunc(l_calc_due_date)) THEN
10339 l_calc_due_date := l_set_due_date;
10340 l_calc_counter_id := null;
10341 l_calc_due_counter_value := null;
10342 END IF;
10343 ELSE -- whichever_first_code = 'LAST'
10344 IF (trunc(l_set_due_date) > trunc(l_calc_due_date)) THEN
10345 l_calc_due_date := l_set_due_date;
10346 l_calc_counter_id := null;
10347 l_calc_due_counter_value := null;
10348 END IF;
10349 END IF;
10350 ELSIF (l_set_due_date IS NOT NULL) THEN
10351 l_calc_due_date := l_set_due_date;
10352 l_calc_counter_id := null;
10353 l_calc_due_counter_value := null;
10354 END IF;
10355
10356 END IF; -- unit_effectivity_rec.unit_deferral_type = 'DEFERRAL
10357
10358
10359 -- Added for R12: MEL/CDL due date.
10360 IF (unit_effectivity_rec.unit_deferral_type = 'MEL'
10361 OR unit_effectivity_rec.unit_deferral_type = 'CDL') THEN
10362
10363 -- fix bug# 5217126. This variable is inserted into the temp table.
10364 l_deferral_effective_on := unit_effectivity_rec.deferral_effective_on;
10365
10366 IF G_DEBUG = 'Y' THEN
10367 AHL_DEBUG_PUB.debug('Calculating due date for MEL/CDL');
10368 AHL_DEBUG_PUB.debug('Deferral Eff on:' || unit_effectivity_rec.DEFERRAL_EFFECTIVE_ON);
10369 AHL_DEBUG_PUB.debug('Processing ..object type:' || unit_effectivity_rec.object_type);
10370 END IF;
10371
10372 -- validate repair category.
10373 -- Added expected_resolution_date to fix bug# 5217126.
10374 OPEN get_repair_category_csr(unit_effectivity_rec.cs_incident_id);
10375 FETCH get_repair_category_csr INTO l_repair_time, l_expected_resolutn_date;
10376 IF (get_repair_category_csr%NOTFOUND) THEN
10377 --l_calc_due_date := NULL;
10378 FND_MESSAGE.Set_Name('AHL','AHL_PUE_INCIDENT_ID_MISSING');
10379 FND_MESSAGE.Set_Token('CS_INC_ID',unit_effectivity_rec.cs_incident_id);
10380 FND_MSG_PUB.ADD;
10381 RAISE FND_API.G_EXC_ERROR;
10382 ELSE
10383
10384 IF l_repair_time <> 0 AND
10385 unit_effectivity_rec.DEFERRAL_EFFECTIVE_ON IS NOT NULL
10386 THEN
10387 l_calc_due_date := unit_effectivity_rec.DEFERRAL_EFFECTIVE_ON +
10388 trunc(l_repair_time/24);
10389 ELSE
10390 -- fix for bug# 5217126.
10391 l_calc_due_date := l_expected_resolutn_date;
10392 END IF;
10393
10394 END IF; -- get_repair_category_csr%NOTFOUND
10395 CLOSE get_repair_category_csr;
10396
10397 IF G_DEBUG = 'Y' THEN
10398 AHL_DEBUG_PUB.debug('MEL/CDL:Calculated due date is:' || l_calc_due_date);
10399 AHL_DEBUG_PUB.debug('MEL/CDL:DEFERRAL_EFFECTIVE_ON:' || l_deferral_effective_on);
10400 END IF;
10401
10402 END IF; -- unit_effectivity_rec.unit_deferral_type = 'MEL'
10403
10404 -- Call visit work package to get visit end date if unit effectivity has been assigned to a visit.
10405 AHL_UMP_UTIL_PKG.get_visit_details (unit_effectivity_rec.unit_effectivity_id,
10406 l_visit_start_date,
10407 l_visit_end_date,
10408 l_visit_assign_code);
10409
10410 /*
10411 IF (l_visit_end_date IS NOT NULL AND l_calc_due_date IS NOT NULL) THEN
10412 IF G_DEBUG = 'Y' THEN
10413 AHL_DEBUG_PUB.Debug('Visit assigned:End Date:' || l_visit_end_date);
10414 END IF;
10415
10416 IF (trunc(l_visit_end_date) < trunc(l_calc_due_date)) THEN
10417 l_calc_tolerance_flag := 'Y';
10418 l_calc_message_code := 'TOLERANCE-BEFORE';
10419 END IF;
10420 END IF;
10421 */
10422
10423 IF (l_visit_start_date IS NOT NULL AND l_calc_due_date IS NOT NULL) THEN
10424 IF G_DEBUG = 'Y' THEN
10425 AHL_DEBUG_PUB.Debug('Visit assigned: Start Date:' || l_visit_start_date);
10426 END IF;
10427 IF (trunc(l_visit_start_date) > trunc(l_calc_due_date)) THEN
10428 l_calc_tolerance_flag := 'Y';
10429 l_calc_message_code := 'TOLERANCE-EXCEEDED';
10430 END IF;
10431 END IF;
10432
10433 IF ( l_calc_due_date IS NOT NULL) THEN
10434 IF (trunc(l_calc_due_date) < trunc(sysdate)) THEN
10435 l_calc_tolerance_flag := 'Y';
10436 l_calc_message_code := 'TOLERANCE-EXCEEDED';
10437 END IF;
10438 END IF;
10439
10440 --dbms_output.put_line ('Al_calc_due_date:' || l_calc_due_date);
10441 --dbms_output.put_line ('Aset_due_date:' || l_set_due_date);
10442 --dbms_output.put_line ('Adue_ctr_val:' || l_calc_due_counter_value);
10443
10444
10445 -- Check if workorder already created.
10446 l_visit_status := AHL_UMP_UTIL_PKG.get_Visit_Status(unit_effectivity_rec.unit_effectivity_id);
10447
10448 IF (nvl(l_visit_status,'X') IN ('RELEASED','CLOSED')) THEN
10449 -- if UE is on shop floor then keep UE structure as is.
10450 l_grp_match := 'Y';
10451 ELSE
10452 IF (unit_effectivity_rec.object_type = 'MR') THEN
10453
10454 Match_Group_MR (p_orig_csi_item_instance_id => unit_effectivity_rec.csi_item_instance_id,
10455 p_orig_mr_header_id => unit_effectivity_rec.mr_header_id,
10456 p_unit_effectivity_id => unit_effectivity_rec.unit_effectivity_id,
10457 x_group_match_flag => l_grp_match);
10458
10459 ELSE
10460 l_grp_match := 'Y';
10461 -- For SR case, for each child group MR associated match the group MR.
10462 FOR ahl_ue_reln_rec IN ahl_ue_reln_csr(unit_effectivity_rec.unit_effectivity_id) LOOP
10463 IF (ahl_ue_reln_rec.status_code = 'MR-TERMINATE') THEN
10464 -- skip mr-terminated records.
10465 l_grp_match1 := 'Y';
10466 ELSE
10467
10468 Match_Group_MR (p_orig_csi_item_instance_id => ahl_ue_reln_rec.csi_item_instance_id,
10469 p_orig_mr_header_id => ahl_ue_reln_rec.mr_header_id,
10470 p_unit_effectivity_id => ahl_ue_reln_rec.unit_effectivity_id,
10471 x_group_match_flag => l_grp_match1);
10472
10473 IF (l_grp_match1 = 'N') THEN
10474 l_grp_match := 'N';
10475 END IF;
10476
10477 END IF;
10478
10479 END LOOP;
10480
10481 END IF; -- unit_effectivity_rec.object_type
10482 END IF; -- l_visit_status
10483
10484
10485 IF G_DEBUG = 'Y' THEN
10486 AHL_DEBUG_PUB.Debug('Group Match flag:l_visit_status:' || l_grp_match || ':' || l_visit_status);
10487 END IF;
10488
10489 -- insert into deferral temp table.
10490 insert into ahl_temp_unit_SR_deferrals (
10491 unit_effectivity_id,
10492 object_type,
10493 csi_item_instance_id,
10494 mr_header_id,
10495 due_date,
10496 counter_id,
10497 due_counter_value,
10498 tolerance_flag,
10499 message_code,
10500 parent_csi_item_instance_id,
10501 parent_mr_header_id,
10502 orig_csi_item_instance_id,
10503 orig_mr_header_id,
10504 orig_unit_effectivity_id,
10505 visit_end_date,
10506 deferral_effective_on,
10507 affect_due_calc_flag,
10508 group_match_flag)
10509 VALUES (
10510 unit_effectivity_rec.unit_effectivity_id,
10511 unit_effectivity_rec.object_type,
10512 unit_effectivity_rec.csi_item_instance_id,
10513 unit_effectivity_rec.mr_header_id,
10514 l_calc_due_date,
10515 l_calc_counter_id,
10516 l_calc_due_counter_value,
10517 l_calc_tolerance_flag,
10518 l_calc_message_code,
10519 null,
10520 null,
10521 null,
10522 null,
10523 null,
10524 l_visit_end_date,
10525 l_deferral_effective_on,
10526 --l_affect_due_date_calc,
10527 unit_effectivity_rec.AFFECT_DUE_CALC_FLAG,
10528 l_grp_match);
10529
10530 -- Insert all child MRs for group MR.
10531 FOR ahl_applicable_grp_rec IN ahl_applicable_grp_csr(unit_effectivity_rec.csi_item_instance_id,
10532 unit_effectivity_rec.mr_header_id)
10533 LOOP
10534 -- insert into deferral temp table.
10535 insert into ahl_temp_unit_SR_deferrals (
10536 unit_effectivity_id,
10537 object_type,
10538 csi_item_instance_id,
10539 mr_header_id,
10540 due_date,
10541 due_counter_value,
10542 tolerance_flag,
10543 message_code,
10544 parent_csi_item_instance_id,
10545 parent_mr_header_id,
10546 orig_csi_item_instance_id,
10547 orig_mr_header_id,
10548 orig_unit_effectivity_id,
10549 visit_end_date,
10550 deferral_effective_on,
10551 affect_due_calc_flag,
10552 group_match_flag)
10553 VALUES (
10554 null,
10555 'MR',
10556 ahl_applicable_grp_rec.related_csi_item_instance_id,
10557 ahl_applicable_grp_rec.related_mr_header_id,
10558 l_calc_due_date,
10559 l_calc_due_counter_value,
10560 l_calc_tolerance_flag,
10561 l_calc_message_code,
10562 ahl_applicable_grp_rec.parent_csi_item_instance_id,
10563 ahl_applicable_grp_rec.parent_mr_header_id,
10564 unit_effectivity_rec.csi_item_instance_id,
10565 unit_effectivity_rec.mr_header_id,
10566 unit_effectivity_rec.unit_effectivity_id,
10567 l_visit_end_date,
10568 l_deferral_effective_on,
10569 --l_affect_due_date_calc,
10570 unit_effectivity_rec.AFFECT_DUE_CALC_FLAG,
10571 l_grp_match);
10572
10573 END LOOP;
10574 --fix for bug#5217126
10575 --CLOSE ahl_unit_deferral_csr;
10576
10577 END LOOP; -- unit effectivity rec.
10578
10579 IF G_DEBUG = 'Y' THEN
10580 AHL_DEBUG_PUB.debug('End of process_Deferred_ue');
10581 END IF;
10582
10583 END Process_Deferred_UE;
10584 -----------------------------------------------
10585
10586 -- Explode SR's having MRs for calculating MR due dates.
10587 PROCEDURE Process_SR_UE (p_csi_item_instance_id IN NUMBER) IS
10588
10589 CURSOR ahl_ue_sr_csr (p_csi_item_instance_id IN NUMBER,
10590 p_appln_usg_code IN VARCHAR2) IS
10591 SELECT
10592 UE.UNIT_EFFECTIVITY_ID,
10593 UE.OBJECT_TYPE,
10594 UE.CSI_ITEM_INSTANCE_ID,
10595 UE.MR_HEADER_ID,
10596 UE.STATUS_CODE,
10597 UE.DUE_DATE,
10598 UE.DUE_COUNTER_VALUE
10599 FROM ahl_unit_effectivities_b UE
10600 WHERE UE.OBJECT_TYPE = 'SR'
10601 AND UE.application_usg_code = p_appln_usg_code
10602 AND defer_from_ue_id IS NULL
10603 AND csi_item_instance_id = p_csi_item_instance_id
10604 -- added init-due status as part of USAF: Complex Assembly enhancements
10605 AND (status_code IS NULL OR status_code = 'INIT-DUE');
10606
10607
10608 -- Read applicable relns table for group MR details.
10609 CURSOR ahl_applicable_grp_csr( p_item_instance_id IN NUMBER,
10610 p_mr_header_id IN NUMBER) IS
10611
10612 SELECT related_mr_header_id,
10613 related_csi_item_instance_id,
10614 csi_item_instance_id parent_csi_item_instance_id,
10615 mr_header_id parent_mr_header_id
10616 FROM ahl_applicable_mr_relns
10617 START WITH mr_header_id = p_mr_header_id AND
10618 csi_item_instance_id = p_item_instance_id AND
10619 orig_mr_header_id = p_mr_header_id AND
10620 orig_csi_item_instance_id = p_item_instance_id AND
10621 relationship_code = 'PARENT'
10622 CONNECT BY PRIOR related_mr_header_id = mr_header_id AND
10623 PRIOR related_csi_item_instance_id = csi_item_instance_id AND
10624 orig_mr_header_id = p_mr_header_id AND
10625 orig_csi_item_instance_id = p_item_instance_id AND
10626 relationship_code = 'PARENT'
10627 ORDER BY level;
10628
10629
10630 -- Read immediate children of the SR.
10631 CURSOR ahl_ue_reln_csr (p_ue_id IN NUMBER) IS
10632 SELECT ue.unit_effectivity_id, ue.status_code,
10633 UE.CSI_ITEM_INSTANCE_ID, UE.MR_HEADER_ID
10634 FROM ahl_ue_relationships uer, ahl_unit_effectivities_app_v ue
10635 WHERE ue.unit_effectivity_id = uer.related_ue_id
10636 AND uer.ue_id = p_ue_id;
10637
10638
10639 l_calc_tolerance_flag ahl_unit_effectivities_app_v.tolerance_flag%TYPE;
10640 l_calc_message_code ahl_unit_effectivities_app_v.message_code%TYPE;
10641
10642 l_visit_start_date DATE;
10643 l_visit_end_date DATE;
10644 l_visit_assign_code fnd_lookups.lookup_code%TYPE;
10645
10646 l_grp_match VARCHAR2(1);
10647 l_grp_match1 VARCHAR2(1);
10648
10649 l_visit_status ahl_visits_b.status_code%TYPE;
10650
10651 -- added for Complx Assy Enh
10652 l_due_date DATE;
10653 l_due_counter_value NUMBER;
10654 l_counter_id NUMBER;
10655
10656 BEGIN
10657
10658 IF G_DEBUG = 'Y' THEN
10659 AHL_DEBUG_PUB.debug('Start of Process_SR_UE');
10660 END IF;
10661
10662 -- Get all UE's with object-type = SR.
10663 FOR ahl_ue_sr_rec IN ahl_ue_sr_csr(p_csi_item_instance_id, G_application_usg_code) LOOP
10664
10665 -- Start USAF: Complx Assy Enh: calculate due date if NR status is INIT-DUE.
10666 IF (ahl_ue_sr_rec.status_code = 'INIT-DUE') THEN
10667 Calculate_NR_due_date(p_unit_effectivity_id => ahl_ue_sr_rec.unit_effectivity_id,
10668 x_due_date => l_due_date,
10669 x_due_counter_value => l_due_counter_value,
10670 x_counter_id => l_counter_id);
10671 ELSE
10672 l_due_date := ahl_ue_sr_rec.due_date;
10673 l_due_counter_value := ahl_ue_sr_rec.due_counter_value;
10674 l_counter_id := null;
10675 END IF;
10676
10677 -- Call visit work package to get visit end date if unit effectivity has been assigned to a visit.
10678 AHL_UMP_UTIL_PKG.get_visit_details (ahl_ue_sr_rec.unit_effectivity_id,
10679 l_visit_start_date,
10680 l_visit_end_date,
10681 l_visit_assign_code);
10682
10683 IF (l_visit_end_date IS NOT NULL AND ahl_ue_sr_rec.due_date IS NOT NULL) THEN
10684 IF G_DEBUG = 'Y' THEN
10685 AHL_DEBUG_PUB.Debug('Visit assigned:End Date:' || l_visit_end_date);
10686 END IF;
10687
10688 IF (trunc(l_visit_end_date) < trunc(ahl_ue_sr_rec.due_date )) THEN
10689 l_calc_tolerance_flag := 'Y';
10690 l_calc_message_code := 'TOLERANCE-BEFORE';
10691 END IF;
10692 END IF;
10693
10694 IF (l_visit_start_date IS NOT NULL AND ahl_ue_sr_rec.due_date IS NOT NULL) THEN
10695 IF G_DEBUG = 'Y' THEN
10696 AHL_DEBUG_PUB.Debug('Visit assigned:Start Date:' || l_visit_start_date);
10697 END IF;
10698
10699 IF (trunc(l_visit_start_date) > trunc(ahl_ue_sr_rec.due_date )) THEN
10700 l_calc_tolerance_flag := 'Y';
10701 l_calc_message_code := 'TOLERANCE-EXCEEDED';
10702 END IF;
10703 END IF;
10704
10705 -- Check if workorder already created.
10706 l_visit_status := AHL_UMP_UTIL_PKG.get_Visit_Status(ahl_ue_sr_rec.unit_effectivity_id);
10707
10708 IF (nvl(l_visit_status,'X') IN ('RELEASED','CLOSED')) THEN
10709 -- if UE is on shop floor then keep UE structure as is.
10710 l_grp_match := 'Y';
10711 ELSE
10712 -- initialize.
10713 l_grp_match := 'Y';
10714
10715 -- For each group MR associated match the group MR.
10716 FOR ahl_ue_reln_rec IN ahl_ue_reln_csr(ahl_ue_sr_rec.unit_effectivity_id) LOOP
10717 IF (ahl_ue_reln_rec.status_code = 'MR-TERMINATE') THEN
10718 -- skip mr-terminated records.
10719 l_grp_match1 := 'Y';
10720 ELSE
10721
10722 Match_Group_MR (p_orig_csi_item_instance_id => ahl_ue_reln_rec.csi_item_instance_id,
10723 p_orig_mr_header_id => ahl_ue_reln_rec.mr_header_id,
10724 p_unit_effectivity_id => ahl_ue_reln_rec.unit_effectivity_id,
10725 x_group_match_flag => l_grp_match1);
10726
10727 IF (l_grp_match1 = 'N') THEN
10728 l_grp_match := 'N';
10729 END IF;
10730 END IF;
10731
10732 END LOOP;
10733 END IF; --l_visit_status
10734
10735 -- Write SR UE into temporary table.
10736 insert into ahl_temp_unit_SR_deferrals (
10737 unit_effectivity_id,
10738 object_type,
10739 csi_item_instance_id,
10740 mr_header_id,
10741 due_date,
10742 due_counter_value,
10743 counter_id,
10744 tolerance_flag,
10745 message_code,
10746 parent_csi_item_instance_id,
10747 parent_mr_header_id,
10748 orig_mr_header_id,
10749 orig_csi_item_instance_id,
10750 orig_unit_effectivity_id,
10751 visit_end_date,
10752 deferral_effective_on,
10753 affect_due_calc_flag,
10754 group_match_flag)
10755 VALUES (
10756 ahl_ue_sr_rec.unit_effectivity_id,
10757 ahl_ue_sr_rec.object_type,
10758 ahl_ue_sr_rec.csi_item_instance_id,
10759 null,
10760 --ahl_ue_sr_rec.due_date,
10761 --ahl_ue_sr_rec.due_counter_value,
10762 l_due_date,
10763 l_due_counter_value,
10764 l_counter_id,
10765 l_calc_tolerance_flag,
10766 l_calc_message_code,
10767 null,
10768 null,
10769 null,
10770 null,
10771 null,
10772 l_visit_end_date,
10773 null,
10774 'Y',
10775 l_grp_match);
10776
10777
10778 -- Write child MRs into temporary table.
10779
10780 FOR ahl_applicable_grp_rec IN ahl_applicable_grp_csr(ahl_ue_sr_rec.csi_item_instance_id,
10781 ahl_ue_sr_rec.mr_header_id)
10782 LOOP
10783 -- insert into deferral temp table.
10784 insert into ahl_temp_unit_SR_deferrals (
10785 unit_effectivity_id,
10786 object_type,
10787 csi_item_instance_id,
10788 mr_header_id,
10789 due_date,
10790 due_counter_value,
10791 tolerance_flag,
10792 message_code,
10793 parent_csi_item_instance_id,
10794 parent_mr_header_id,
10795 orig_csi_item_instance_id,
10796 orig_mr_header_id,
10797 orig_unit_effectivity_id,
10798 visit_end_date,
10799 deferral_effective_on,
10800 affect_due_calc_flag,
10801 group_match_flag)
10802 VALUES (
10803 null,
10804 null,
10805 ahl_applicable_grp_rec.related_csi_item_instance_id,
10806 ahl_applicable_grp_rec.related_mr_header_id,
10807 ahl_ue_sr_rec.due_date,
10808 ahl_ue_sr_rec.due_counter_value,
10809 l_calc_tolerance_flag,
10810 l_calc_message_code,
10811 ahl_applicable_grp_rec.parent_csi_item_instance_id,
10812 ahl_applicable_grp_rec.parent_mr_header_id,
10813 ahl_ue_sr_rec.csi_item_instance_id,
10814 ahl_ue_sr_rec.mr_header_id,
10815 ahl_ue_sr_rec.unit_effectivity_id,
10816 l_visit_end_date,
10817 null,
10818 'Y',
10819 l_grp_match);
10820
10821 END LOOP;
10822
10823 END LOOP;
10824
10825 IF G_DEBUG = 'Y' THEN
10826 AHL_DEBUG_PUB.debug('End of Process_SR_UE');
10827 END IF;
10828
10829 END Process_SR_UE;
10830
10831 -----------------------------------------------
10832
10833 -- Match if current UE group MR matches the applicable group MR.
10834 PROCEDURE Match_Group_MR (p_orig_csi_item_instance_id IN NUMBER,
10835 p_orig_mr_header_id IN NUMBER,
10836 p_unit_effectivity_id IN NUMBER,
10837 x_group_match_flag OUT NOCOPY VARCHAR2)
10838 IS
10839
10840 -- Get all child UE's for a given unit effectivity.
10841 CURSOR ahl_ue_relns_csr (p_unit_effectivity_id IN NUMBER) IS
10842 SELECT related_ue_id, ue_id, level
10843 FROM ahl_ue_relationships
10844 START WITH ue_id = p_unit_effectivity_id
10845 AND relationship_code = 'PARENT'
10846 CONNECT BY PRIOR related_ue_id = ue_id
10847 AND relationship_code = 'PARENT'
10848 ORDER BY level;
10849
10850 -- get unit effectivities details.
10851 CURSOR ahl_ue_csr ( p_ue_id IN NUMBER,
10852 p_related_ue_id IN NUMBER ) IS
10853 SELECT ue1.mr_header_id, ue1.csi_item_instance_id,
10854 ue2.mr_header_id related_mr_header_id,
10855 ue2.csi_item_instance_id related_csi_item_instance_id
10856 FROM ahl_unit_effectivities_b ue1, ahl_unit_effectivities_b ue2
10857 WHERE ue1.unit_effectivity_id = p_ue_id AND
10858 ue2.unit_effectivity_id = p_related_ue_id;
10859
10860 -- Read applicable relns table for group MR details.
10861 CURSOR ahl_applicable_grp_csr( p_item_instance_id IN NUMBER,
10862 p_mr_header_id IN NUMBER) IS
10863
10864 SELECT mr_header_id, csi_item_instance_id,
10865 related_mr_header_id,
10866 related_csi_item_instance_id, level
10867 FROM ahl_applicable_mr_relns
10868 START WITH mr_header_id = p_mr_header_id AND
10869 csi_item_instance_id = p_item_instance_id AND
10870 orig_mr_header_id = p_mr_header_id AND
10871 orig_csi_item_instance_id = p_item_instance_id AND
10872 relationship_code = 'PARENT'
10873 CONNECT BY PRIOR related_mr_header_id = mr_header_id AND
10874 PRIOR related_csi_item_instance_id = csi_item_instance_id AND
10875 orig_mr_header_id = p_mr_header_id AND
10876 orig_csi_item_instance_id = p_item_instance_id AND
10877 relationship_code = 'PARENT'
10878 ORDER BY level;
10879
10880
10881 TYPE ue_details_rec_type IS RECORD (
10882 mr_header_id NUMBER,
10883 csi_item_instance_id NUMBER,
10884 related_mr_header_id NUMBER,
10885 related_csi_item_instance_id NUMBER,
10886 level NUMBER,
10887 unit_effectivity_id NUMBER,
10888 match_flag VARCHAR2(1));
10889
10890 l_ue_details_rec ue_details_rec_type;
10891
10892 TYPE l_ue_details_tbl_type IS TABLE OF ue_details_rec_type INDEX BY BINARY_INTEGER;
10893
10894 l_ue_details_tbl l_ue_details_tbl_type;
10895 l_grp_details_tbl l_ue_details_tbl_type;
10896 i NUMBER;
10897
10898 BEGIN
10899
10900 IF G_DEBUG = 'Y' THEN
10901 AHL_DEBUG_PUB.debug('Start of Match_Group_MR');
10902 END IF;
10903
10904 -- Match the ue relations tree with the group applicablilty tree.
10905 i := 1;
10906 FOR ahl_ue_relns_rec in ahl_ue_relns_csr(p_unit_effectivity_id) LOOP
10907 OPEN ahl_ue_csr(ahl_ue_relns_rec.ue_id, ahl_ue_relns_rec.related_ue_id);
10908 FETCH ahl_ue_csr INTO l_ue_details_tbl(i).mr_header_id,
10909 l_ue_details_tbl(i).csi_item_instance_id,
10910 l_ue_details_tbl(i).related_mr_header_id,
10911 l_ue_details_tbl(i).related_csi_item_instance_id;
10912 IF (ahl_ue_csr%NOTFOUND) THEN
10913 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_RELN_NOTFOUND');
10914 FND_MESSAGE.Set_Token('UE_ID',ahl_ue_relns_rec.ue_id);
10915 FND_MESSAGE.Set_Token('RELATED_UE_ID', ahl_ue_relns_rec.related_ue_id);
10916 FND_MSG_PUB.ADD;
10917 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
10918 END IF;
10919
10920 l_ue_details_tbl(i).level := ahl_ue_relns_rec.level;
10921 l_ue_details_tbl(i).unit_effectivity_id := ahl_ue_relns_rec.related_ue_id;
10922 l_ue_details_tbl(i).match_flag := 'N';
10923
10924 --dbms_output.put_line ('found ue relns');
10925 i := i + 1;
10926 CLOSE ahl_ue_csr;
10927 END LOOP;
10928
10929 i := 1;
10930 -- from applicable_mrs_relations.
10931 FOR l_appl_grp_rec IN ahl_applicable_grp_csr(p_orig_csi_item_instance_id,
10932 p_orig_mr_header_id)
10933
10934 LOOP
10935 l_grp_details_tbl(i).mr_header_id := l_appl_grp_rec.mr_header_id;
10936 l_grp_details_tbl(i).csi_item_instance_id := l_appl_grp_rec.csi_item_instance_id;
10937 l_grp_details_tbl(i).related_mr_header_id := l_appl_grp_rec.related_mr_header_id;
10938 l_grp_details_tbl(i).related_csi_item_instance_id := l_appl_grp_rec.related_csi_item_instance_id;
10939 l_grp_details_tbl(i).level := l_appl_grp_rec.level;
10940 l_grp_details_tbl(i).match_flag := 'N';
10941 i := i + 1;
10942 END LOOP;
10943
10944 -- Now compare l_grp_details_tbl with l_ue_details_tbl.
10945 IF (l_grp_details_tbl.COUNT > 0) THEN
10946 FOR i IN l_grp_details_tbl.FIRST..l_grp_details_tbl.LAST LOOP
10947 -- match if entry present in l_ue_details_tbl.
10948 IF (l_ue_details_tbl.COUNT > 0 ) THEN
10949 FOR j IN l_ue_details_tbl.FIRST..l_ue_details_tbl.LAST LOOP
10950 IF (l_ue_details_tbl(j).mr_header_id = l_grp_details_tbl(i).mr_header_id AND
10951 l_ue_details_tbl(j).csi_item_instance_id = l_grp_details_tbl(i).csi_item_instance_id AND
10952 l_ue_details_tbl(j).related_csi_item_instance_id = l_grp_details_tbl(i).related_csi_item_instance_id AND
10953 l_ue_details_tbl(j).related_mr_header_id = l_grp_details_tbl(i).related_mr_header_id AND
10954 l_ue_details_tbl(j).level = l_grp_details_tbl(i).level AND
10955 l_ue_details_tbl(j).match_flag = 'N' AND
10956 l_grp_details_tbl(i).match_flag = 'N') THEN
10957 --l_ue_details_tbl.DELETE(j);
10958 --l_grp_details_tbl.DELETE(i);
10959 l_ue_details_tbl(j).match_flag := 'Y';
10960 l_grp_details_tbl(i).match_flag := 'Y';
10961 EXIT;
10962 END IF;
10963 END LOOP; /* ue_details */
10964 END IF; /* count - ue_details */
10965 END LOOP; /* grp_details */
10966 END IF; /* count - grp_details */
10967
10968 -- delete records from table where match flag is Y.
10969 IF (l_ue_details_tbl.COUNT > 0 ) THEN
10970 FOR j IN l_ue_details_tbl.FIRST..l_ue_details_tbl.LAST LOOP
10971 IF (l_ue_details_tbl(j).match_flag = 'Y') THEN
10972 l_ue_details_tbl.DELETE(j);
10973 END IF;
10974 END LOOP;
10975 END IF;
10976
10977 IF (l_grp_details_tbl.COUNT > 0 ) THEN
10978 FOR i IN l_grp_details_tbl.FIRST..l_grp_details_tbl.LAST LOOP
10979 IF (l_grp_details_tbl(i).match_flag = 'Y') THEN
10980 l_grp_details_tbl.DELETE(i);
10981 END IF;
10982 END LOOP;
10983 END IF;
10984
10985 IF (l_ue_details_tbl.COUNT = 0) AND (l_grp_details_tbl.COUNT = 0) THEN
10986 x_group_match_flag := 'Y';
10987
10988 ELSE
10989 x_group_match_flag := 'N';
10990
10991 END IF;
10992
10993 IF G_DEBUG = 'Y' THEN
10994 AHL_DEBUG_PUB.debug('End of Match_Group_MR');
10995 END IF;
10996
10997 END Match_Group_MR;
10998
10999 -----------------------------------------------
11000
11001 PROCEDURE Process_Unplanned_UE(p_csi_item_instance_id IN NUMBER,
11002 p_current_usage_tbl IN counter_values_tbl_type,
11003 p_counter_rules_tbl IN counter_rules_tbl_type) IS
11004
11005 -- Read Unplanned MRs.(only top nodes)
11006 CURSOR ahl_unplanned_ue_csr(p_csi_item_instance_id IN NUMBER,
11007 p_appln_usage_code IN VARCHAR2) IS
11008 SELECT ue.mr_header_id,
11009 ue.csi_item_instance_id,
11010 ue.unit_effectivity_id,
11011 ue.status_code
11012 FROM ahl_unit_effectivities_b ue
11013 /*
11014 WHERE NOT EXISTS ( SELECT 'x'
11015 --FROM ahl_ue_relationships uer, ahl_unit_effectivities_app_v ue1
11016 FROM ahl_ue_relationships uer, ahl_unit_effectivities_b ue1
11017 WHERE uer.related_ue_id = ue.unit_effectivity_id AND
11018 uer.originator_ue_id = ue1.unit_effectivity_id AND
11019 ue1.object_type <> 'SR' )
11020 */
11021 -- pick up only top nodes.
11022 WHERE NOT EXISTS (SELECT 'x'
11023 FROM ahl_ue_relationships uer
11024 WHERE uer.related_ue_id = ue.unit_effectivity_id
11025 AND relationship_code = 'PARENT')
11026 AND ue.csi_item_instance_id = p_csi_item_instance_id
11027 AND ue.application_usg_code = p_appln_usage_code
11028 AND nvl(ue.manually_planned_flag,'N') = 'Y'
11029 AND ue.object_type = 'MR'
11030 AND ue.defer_from_ue_id IS NULL
11031 AND (ue.status_code IS NULL OR ue.status_code = 'EXCEPTION');
11032
11033 -- modified to check for end date as part of fix for bug# 9263774.
11034 -- added select columns for SB Enh.
11035 CURSOR ahl_applicable_mr_csr (p_csi_item_instance_id IN NUMBER,
11036 p_mr_header_id IN NUMBER) IS
11037 SELECT 'x'
11038 FROM ahl_applicable_mrs appl, ahl_mr_headers_b mr
11039 WHERE appl.mr_header_id = p_mr_header_id AND
11040 appl.csi_item_instance_id = p_csi_item_instance_id AND
11041 appl.mr_header_id = mr.mr_header_id AND
11042 trunc(sysdate) <= trunc(nvl(mr.effective_to,sysdate+1));
11043
11044 -- Cursor to get all details of a unit effectivity record.
11045 CURSOR ahl_unit_effectivity_csr ( p_unit_effectivity_id IN NUMBER) IS
11046 SELECT
11047 UNIT_EFFECTIVITY_ID ,
11048 CSI_ITEM_INSTANCE_ID,
11049 MR_INTERVAL_ID,
11050 MR_EFFECTIVITY_ID ,
11051 MR_HEADER_ID,
11052 STATUS_CODE ,
11053 DUE_DATE ,
11054 DUE_COUNTER_VALUE ,
11055 FORECAST_SEQUENCE ,
11056 REPETITIVE_MR_FLAG ,
11057 TOLERANCE_FLAG ,
11058 REMARKS ,
11059 MESSAGE_CODE ,
11060 PRECEDING_UE_ID ,
11061 DATE_RUN ,
11062 SET_DUE_DATE ,
11063 ACCOMPLISHED_DATE ,
11064 CANCEL_REASON_CODE,
11065 EARLIEST_DUE_DATE,
11066 LATEST_DUE_DATE,
11067 SERVICE_LINE_ID,
11068 PROGRAM_MR_HEADER_ID,
11069 defer_from_ue_id,
11070 cs_incident_id,
11071 qa_collection_id,
11072 orig_deferral_ue_id,
11073 application_usg_code,
11074 object_type,
11075 counter_id,
11076 manually_planned_flag,
11077 LOG_SERIES_CODE,
11078 LOG_SERIES_NUMBER, FLIGHT_NUMBER, MEL_CDL_TYPE_CODE,
11079 POSITION_PATH_ID,
11080 ATA_CODE, UNIT_CONFIG_HEADER_ID,
11081 ATTRIBUTE_CATEGORY ,
11082 ATTRIBUTE1,
11083 ATTRIBUTE2 ,
11084 ATTRIBUTE3 ,
11085 ATTRIBUTE4 ,
11086 ATTRIBUTE5 ,
11087 ATTRIBUTE6 ,
11088 ATTRIBUTE7 ,
11089 ATTRIBUTE8 ,
11090 ATTRIBUTE9 ,
11091 ATTRIBUTE10,
11092 ATTRIBUTE11 ,
11093 ATTRIBUTE12 ,
11094 ATTRIBUTE13 ,
11095 ATTRIBUTE14 ,
11096 ATTRIBUTE15 ,
11097 OBJECT_VERSION_NUMBER
11098 FROM ahl_unit_effectivities_vl
11099 WHERE unit_effectivity_id = p_unit_effectivity_id
11100 FOR UPDATE OF message_code NOWAIT;
11101
11102 -- Read group from ahl_ue_relationships.
11103 CURSOR decendent_csr (p_unit_effectivity_id IN NUMBER) IS
11104 SELECT related_ue_id
11105 FROM ahl_ue_relationships
11106 WHERE relationship_code = 'PARENT' AND
11107 originator_ue_id = p_unit_effectivity_id;
11108
11109 l_exception_flag BOOLEAN;
11110 l_grp_match_flag VARCHAR2(1);
11111 l_message_code ahl_unit_effectivities_b.message_code%TYPE;
11112 l_status_code ahl_unit_effectivities_b.status_code%TYPE;
11113 l_junk VARCHAR2(1);
11114
11115 l_ue_rec ahl_unit_effectivity_csr%ROWTYPE;
11116
11117 l_visit_status VARCHAR2(30);
11118
11119 -- Added for SB Enh. Process unplanned 'chain' MRs.
11120 l_applicable_mr_rec applicable_mrs_rec_type;
11121
11122 CURSOR chain_appl_mr_csr (p_csi_item_instance_id IN NUMBER) IS
11123 SELECT DISTINCT mr.Title,
11124 mr.version_number,
11125 appl.mr_header_id,
11126 appl.Implement_status_code,
11127 appl.copy_accomplishment_code,
11128 appl.repetitive_flag,
11129 appl.show_repetitive_code,
11130 appl.descendent_count,
11131 mr.whichever_first_code,
11132 mr.effective_to,
11133 mr.effective_from,
11134 appl.terminate_trigger_check,
11135 appl.accomplish_trigger_type,
11136 appl.loop_chain_seq_num
11137 FROM ahl_applicable_mrs appl, ahl_mr_headers_b mr
11138 WHERE appl.csi_item_instance_id = p_csi_item_instance_id AND
11139 appl.mr_header_id = mr.mr_header_id AND
11140 trunc(sysdate) <= trunc(nvl(mr.effective_to,sysdate+1)) AND
11141 appl.Implement_status_code = 'OPTIONAL_DO_NOT_IMPLEMENT' AND
11142 appl.accomplish_trigger_type = 'CHAIN' AND
11143 appl.mr_header_id = appl.start_mr_header_id;
11144
11145 l_lc_mr_tbl loop_chain_MR_tbl_type;
11146 BEGIN
11147
11148 IF G_DEBUG = 'Y' THEN
11149 AHL_DEBUG_PUB.debug('Start of Process_Unplanned_UE');
11150 END IF;
11151
11152 -- Loop through all Unplanned MRs.
11153 FOR ahl_unplanned_ue_rec IN ahl_unplanned_ue_csr(p_csi_item_instance_id,G_application_usg_code) LOOP
11154 -- initialize.
11155 l_exception_flag := FALSE;
11156
11157 -- Check if workorder already created.
11158 l_visit_status := AHL_UMP_UTIL_PKG.get_Visit_Status (ahl_unplanned_ue_rec.unit_effectivity_id);
11159
11160 -- only if visit is in planning status we must mark an exception.
11161 -- if visit is already on the floor, we do nothing.
11162 IF (nvl(l_visit_status,'X') NOT IN ('RELEASED','CLOSED')) THEN
11163
11164 -- Check if top node applicable.
11165 OPEN ahl_applicable_mr_csr(ahl_unplanned_ue_rec.csi_item_instance_id,
11166 ahl_unplanned_ue_rec.mr_header_id);
11167 FETCH ahl_applicable_mr_csr INTO l_junk;
11168 IF (ahl_applicable_mr_csr%FOUND) THEN
11169 --Match the group.
11170 Match_Group_MR (p_orig_csi_item_instance_id => ahl_unplanned_ue_rec.csi_item_instance_id,
11171 p_orig_mr_header_id => ahl_unplanned_ue_rec.mr_header_id,
11172 p_unit_effectivity_id => ahl_unplanned_ue_rec.unit_effectivity_id,
11173 x_group_match_flag => l_grp_match_flag);
11174
11175 IF (l_grp_match_flag = 'N') THEN
11176 l_exception_flag := TRUE;
11177 END IF;
11178 ELSE
11179 l_exception_flag := TRUE;
11180 END IF; -- ahl_applicable_mr_csr found chk.
11181 CLOSE ahl_applicable_mr_csr;
11182
11183 IF G_DEBUG = 'Y' THEN
11184 AHL_DEBUG_PUB.debug('Group Match Flag for UE:' || ahl_unplanned_ue_rec.unit_effectivity_id || 'is:' ||
11185 l_grp_match_flag);
11186 END IF;
11187
11188 -- If exception, then update the UE status to exception.
11189 -- If no longer an exception, then update the UE status to NULL.
11190 IF ((ahl_unplanned_ue_rec.status_code IS NULL) AND (l_exception_flag = TRUE)) OR
11191 ((ahl_unplanned_ue_rec.status_code = 'EXCEPTION') AND (l_exception_flag = FALSE)) THEN
11192
11193 OPEN ahl_unit_effectivity_csr(ahl_unplanned_ue_rec.unit_effectivity_id);
11194 FETCH ahl_unit_effectivity_csr INTO l_ue_rec;
11195 IF (ahl_unit_effectivity_csr%NOTFOUND) THEN
11196 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_UE_NOTFOUND');
11197 FND_MESSAGE.Set_Token('UE_ID',l_ue_rec.unit_effectivity_id);
11198 FND_MSG_PUB.ADD;
11199 -- dbms_output.put_line('unit effectivity not found for ue id' ||l_ue_rec.unit_effectivity_id );
11200 ClOSE ahl_unit_effectivity_csr;
11201 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
11202 ELSE
11203 -- set UE attributes.
11204 IF (ahl_unplanned_ue_rec.status_code IS NULL) AND (l_exception_flag = TRUE) THEN
11205 IF G_DEBUG = 'Y' THEN
11206 AHL_DEBUG_PUB.Debug('Updating Unplanned UE..' || l_ue_rec.unit_effectivity_id || ' to an exception');
11207 END IF;
11208 -- update unit effectivity.
11209 l_message_code := 'VISIT-ASSIGN';
11210 l_status_code := 'EXCEPTION';
11211 ELSE
11212 IF G_DEBUG = 'Y' THEN
11213 AHL_DEBUG_PUB.Debug('Updating Unplanned UE..' || l_ue_rec.unit_effectivity_id || ' from an exception');
11214 END IF;
11215 -- update unit effectivity.
11216 l_message_code := NULL;
11217 l_status_code := NULL;
11218 END IF;
11219 ClOSE ahl_unit_effectivity_csr;
11220
11221 -- Update unit effectivity.
11222 AHL_UNIT_EFFECTIVITIES_PKG.Update_Row(
11223 X_UNIT_EFFECTIVITY_ID => l_ue_rec.unit_effectivity_id,
11224 X_CSI_ITEM_INSTANCE_ID => l_ue_rec.csi_item_instance_id,
11225 X_MR_INTERVAL_ID => l_ue_rec.mr_interval_id,
11226 X_MR_EFFECTIVITY_ID => l_ue_rec.mr_effectivity_id,
11227 X_MR_HEADER_ID => l_ue_rec.mr_header_id,
11228 X_STATUS_CODE => l_status_code,
11229 X_DUE_DATE => l_ue_rec.due_date,
11230 X_DUE_COUNTER_VALUE => l_ue_rec.due_counter_value,
11231 X_FORECAST_SEQUENCE => l_ue_rec.forecast_sequence,
11232 X_REPETITIVE_MR_FLAG => l_ue_rec.repetitive_mr_flag,
11233 X_TOLERANCE_FLAG => l_ue_rec.tolerance_flag,
11234 X_REMARKS => l_ue_rec.remarks,
11235 X_MESSAGE_CODE => l_message_code,
11236 X_PRECEDING_UE_ID => l_ue_rec.preceding_ue_id,
11237 X_DATE_RUN => sysdate,
11238 X_SET_DUE_DATE => l_ue_rec.set_due_date,
11239 X_ACCOMPLISHED_DATE => l_ue_rec.accomplished_date,
11240 X_SERVICE_LINE_ID => l_ue_rec.service_line_id,
11241 X_PROGRAM_MR_HEADER_ID => l_ue_rec.program_mr_header_id,
11242 X_CANCEL_REASON_CODE => l_ue_rec.cancel_reason_code,
11243 X_EARLIEST_DUE_DATE => l_ue_rec.earliest_due_date,
11244 X_LATEST_DUE_DATE => l_ue_rec.latest_due_date,
11245 X_defer_from_ue_id => l_ue_rec.defer_from_ue_id,
11246 X_cs_incident_id => l_ue_rec.cs_incident_id,
11247 X_qa_collection_id => l_ue_rec.qa_collection_id,
11248 X_orig_deferral_ue_id => l_ue_rec.orig_deferral_ue_id,
11249 X_application_usg_code => l_ue_rec.application_usg_code,
11250 X_object_type => l_ue_rec.object_type,
11251 X_counter_id => l_ue_rec.counter_id,
11252 X_MANUALLY_PLANNED_FLAG => l_ue_rec.MANUALLY_PLANNED_FLAG,
11253 X_LOG_SERIES_CODE => l_ue_rec.log_series_code,
11254 X_LOG_SERIES_NUMBER => l_ue_rec.log_series_number,
11255 X_FLIGHT_NUMBER => l_ue_rec.flight_number,
11256 X_MEL_CDL_TYPE_CODE => l_ue_rec.mel_cdl_type_code,
11257 X_POSITION_PATH_ID => l_ue_rec.position_path_id,
11258 X_ATA_CODE => l_ue_rec.ATA_CODE,
11259 X_UNIT_CONFIG_HEADER_ID => l_ue_rec.unit_config_header_id,
11260 X_ATTRIBUTE_CATEGORY => l_ue_rec.attribute_category,
11261 X_ATTRIBUTE1 => l_ue_rec.attribute1,
11262 X_ATTRIBUTE2 => l_ue_rec.attribute2,
11263 X_ATTRIBUTE3 => l_ue_rec.attribute3,
11264 X_ATTRIBUTE4 => l_ue_rec.attribute4,
11265 X_ATTRIBUTE5 => l_ue_rec.attribute5,
11266 X_ATTRIBUTE6 => l_ue_rec.attribute6,
11267 X_ATTRIBUTE7 => l_ue_rec.attribute7,
11268 X_ATTRIBUTE8 => l_ue_rec.attribute8,
11269 X_ATTRIBUTE9 => l_ue_rec.attribute9,
11270 X_ATTRIBUTE10 => l_ue_rec.attribute10,
11271 X_ATTRIBUTE11 => l_ue_rec.attribute11,
11272 X_ATTRIBUTE12 => l_ue_rec.attribute12,
11273 X_ATTRIBUTE13 => l_ue_rec.attribute13,
11274 X_ATTRIBUTE14 => l_ue_rec.attribute14,
11275 X_ATTRIBUTE15 => l_ue_rec.attribute15,
11276 X_OBJECT_VERSION_NUMBER => l_ue_rec.object_version_number + 1,
11277 X_LAST_UPDATE_DATE => sysdate,
11278 X_LAST_UPDATED_BY => fnd_global.user_id,
11279 X_LAST_UPDATE_LOGIN => fnd_global.login_id);
11280
11281 -- Now update all the child MRs status too.
11282 FOR ue_reln_rec IN decendent_csr(ahl_unplanned_ue_rec.unit_effectivity_id) LOOP
11283
11284 OPEN ahl_unit_effectivity_csr (ue_reln_rec.related_ue_id);
11285 FETCH ahl_unit_effectivity_csr INTO l_ue_rec;
11286 IF (ahl_unit_effectivity_csr%FOUND) THEN
11287 AHL_UNIT_EFFECTIVITIES_PKG.Update_Row(
11288 X_UNIT_EFFECTIVITY_ID => l_ue_rec.unit_effectivity_id,
11289 X_CSI_ITEM_INSTANCE_ID => l_ue_rec.csi_item_instance_id,
11290 X_MR_INTERVAL_ID => l_ue_rec.mr_interval_id,
11291 X_MR_EFFECTIVITY_ID => l_ue_rec.mr_effectivity_id,
11292 X_MR_HEADER_ID => l_ue_rec.mr_header_id,
11293 X_STATUS_CODE => l_status_code,
11294 X_DUE_DATE => l_ue_rec.due_date,
11295 X_DUE_COUNTER_VALUE => l_ue_rec.due_counter_value,
11296 X_FORECAST_SEQUENCE => l_ue_rec.forecast_sequence,
11297 X_REPETITIVE_MR_FLAG => l_ue_rec.repetitive_mr_flag,
11298 X_TOLERANCE_FLAG => l_ue_rec.tolerance_flag,
11299 X_REMARKS => l_ue_rec.remarks,
11300 X_MESSAGE_CODE => l_message_code,
11301 X_PRECEDING_UE_ID => l_ue_rec.preceding_ue_id,
11302 X_DATE_RUN => sysdate,
11303 X_SET_DUE_DATE => l_ue_rec.set_due_date,
11304 X_ACCOMPLISHED_DATE => l_ue_rec.accomplished_date,
11305 X_SERVICE_LINE_ID => l_ue_rec.service_line_id,
11306 X_PROGRAM_MR_HEADER_ID => l_ue_rec.program_mr_header_id,
11307 X_CANCEL_REASON_CODE => l_ue_rec.cancel_reason_code,
11308 X_EARLIEST_DUE_DATE => l_ue_rec.earliest_due_date,
11309 X_LATEST_DUE_DATE => l_ue_rec.latest_due_date,
11310 X_defer_from_ue_id => l_ue_rec.defer_from_ue_id,
11311 X_cs_incident_id => l_ue_rec.cs_incident_id,
11312 X_qa_collection_id => l_ue_rec.qa_collection_id,
11313 X_orig_deferral_ue_id => l_ue_rec.orig_deferral_ue_id,
11314 X_application_usg_code => l_ue_rec.application_usg_code,
11315 X_object_type => l_ue_rec.object_type,
11316 X_counter_id => l_ue_rec.counter_id,
11317 X_MANUALLY_PLANNED_FLAG => l_ue_rec.MANUALLY_PLANNED_FLAG,
11318 X_LOG_SERIES_CODE => l_ue_rec.log_series_code,
11319 X_LOG_SERIES_NUMBER => l_ue_rec.log_series_number,
11320 X_FLIGHT_NUMBER => l_ue_rec.flight_number,
11321 X_MEL_CDL_TYPE_CODE => l_ue_rec.mel_cdl_type_code,
11322 X_POSITION_PATH_ID => l_ue_rec.position_path_id,
11323 X_ATA_CODE => l_ue_rec.ATA_CODE,
11324 X_UNIT_CONFIG_HEADER_ID => l_ue_rec.unit_config_header_id,
11325 X_ATTRIBUTE_CATEGORY => l_ue_rec.attribute_category,
11326 X_ATTRIBUTE1 => l_ue_rec.attribute1,
11327 X_ATTRIBUTE2 => l_ue_rec.attribute2,
11328 X_ATTRIBUTE3 => l_ue_rec.attribute3,
11329 X_ATTRIBUTE4 => l_ue_rec.attribute4,
11330 X_ATTRIBUTE5 => l_ue_rec.attribute5,
11331 X_ATTRIBUTE6 => l_ue_rec.attribute6,
11332 X_ATTRIBUTE7 => l_ue_rec.attribute7,
11333 X_ATTRIBUTE8 => l_ue_rec.attribute8,
11334 X_ATTRIBUTE9 => l_ue_rec.attribute9,
11335 X_ATTRIBUTE10 => l_ue_rec.attribute10,
11336 X_ATTRIBUTE11 => l_ue_rec.attribute11,
11337 X_ATTRIBUTE12 => l_ue_rec.attribute12,
11338 X_ATTRIBUTE13 => l_ue_rec.attribute13,
11339 X_ATTRIBUTE14 => l_ue_rec.attribute14,
11340 X_ATTRIBUTE15 => l_ue_rec.attribute15,
11341 X_OBJECT_VERSION_NUMBER => l_ue_rec.object_version_number + 1,
11342 X_LAST_UPDATE_DATE => sysdate,
11343 X_LAST_UPDATED_BY => fnd_global.user_id,
11344 X_LAST_UPDATE_LOGIN => fnd_global.login_id);
11345 ELSE
11346 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_UE_NOTFOUND');
11347 FND_MESSAGE.Set_Token('UE_ID',l_ue_rec.unit_effectivity_id);
11348 FND_MSG_PUB.ADD;
11349 -- dbms_output.put_line('descendent mr not found for ue id');
11350 ClOSE ahl_unit_effectivity_csr;
11351 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
11352 END IF;
11353 ClOSE ahl_unit_effectivity_csr;
11354 END LOOP; -- decendent_csr
11355
11356 END IF; -- ahl_unit_effectivity_csr%NOTFOUND chk.
11357 END IF; -- unplanned status code check.
11358 END IF; -- l_visit_status
11359
11360 END LOOP; -- next unplanned MR.
11361
11362 -- Added for SB Enh to process unplanned chain MRs.
11363 FOR l_chain_appl_mr_rec IN chain_appl_mr_csr(p_csi_item_instance_id) LOOP
11364 l_applicable_mr_rec.csi_item_instance_id := p_csi_item_instance_id;
11365 l_applicable_mr_rec.MR_header_id := l_chain_appl_mr_rec.MR_header_id;
11366 l_applicable_mr_rec.title := l_chain_appl_mr_rec.title;
11367 l_applicable_mr_rec.version_number := l_chain_appl_mr_rec.version_number;
11368 l_applicable_mr_rec.Implement_status_code := l_chain_appl_mr_rec.Implement_status_code;
11369 l_applicable_mr_rec.copy_accomplishment_code := l_chain_appl_mr_rec.copy_accomplishment_code;
11370 l_applicable_mr_rec.repetitive_flag := l_chain_appl_mr_rec.repetitive_flag;
11371 l_applicable_mr_rec.show_repetitive_code := l_chain_appl_mr_rec.show_repetitive_code;
11372 --l_applicable_mr_rec.preceding_mr_header_id := l_chain_appl_mr_rec.preceding_mr_header_id;
11373 l_applicable_mr_rec.descendent_count := l_chain_appl_mr_rec.descendent_count;
11374 l_applicable_mr_rec.whichever_first_code := l_chain_appl_mr_rec.whichever_first_code;
11375 l_applicable_mr_rec.effective_to := l_chain_appl_mr_rec.effective_to;
11376 l_applicable_mr_rec.effective_from := l_chain_appl_mr_rec.effective_from;
11377
11378 -- added for bug# 9263774
11379 IF (l_applicable_mr_rec.effective_to < sysdate) THEN
11380 l_applicable_mr_rec.expired_mr_flag := 'Y';
11381 ELSE
11382 l_applicable_mr_rec.expired_mr_flag := 'N';
11383 END IF;
11384
11385 -- Added for SB Effectivity Enh
11386 l_applicable_mr_rec.terminate_trigger_check := l_chain_appl_mr_rec.terminate_trigger_check;
11387 l_applicable_mr_rec.accomplish_trigger_type := l_chain_appl_mr_rec.accomplish_trigger_type;
11388 l_applicable_mr_rec.loop_chain_seq_num := l_chain_appl_mr_rec.loop_chain_seq_num;
11389
11390 Process_Chain_Init(p_applicable_mrs_rec => l_applicable_mr_rec,
11391 p_current_usage_tbl => p_current_usage_tbl,
11392 p_counter_rules_tbl => p_counter_rules_tbl,
11393 x_loop_chain_MR_tbl => l_lc_mr_tbl);
11394 END LOOP;
11395
11396 IF (G_DEBUG = 'Y') THEN
11397 AHL_DEBUG_PUB.debug('End of Process_Unplanned_UE');
11398 END IF;
11399
11400 END Process_Unplanned_UE;
11401
11402
11403 -----------------------------------------------
11404
11405 -- Procedure to calculate counter values at a given forecasted date for Reliability Fwk use.
11406 PROCEDURE Get_Forecasted_Counter_Values(
11407 x_return_status OUT NOCOPY VARCHAR2,
11408 x_msg_data OUT NOCOPY VARCHAR2,
11409 x_msg_count OUT NOCOPY NUMBER,
11410 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
11411 p_csi_item_instance_id IN NUMBER, -- Instance Id
11412 p_forecasted_date IN DATE,
11413 x_counter_values_tbl OUT NOCOPY counter_values_tbl_type) -- Forecasted Counter Vals.
11414 IS
11415
11416 l_csi_item_instance_id NUMBER;
11417 l_uc_header_id NUMBER;
11418 l_inventory_item_id NUMBER;
11419 l_inv_master_organization_id NUMBER;
11420 i NUMBER;
11421
11422 l_current_usage_tbl counter_values_tbl_type;
11423 /* contains current counter usage */
11424
11425 l_counter_rules_tbl counter_rules_tbl_type;
11426 /* contains current counter rules for the position */
11427
11428 l_due_at_counter_val_tbl counter_values_tbl_type;
11429 /* local variable to hold due at p_forecasted_date ctr values. */
11430
11431 l_return_value BOOLEAN;
11432 l_expired_flag VARCHAR2(1);
11433
11434 BEGIN
11435
11436 IF G_DEBUG = 'Y' THEN
11437 AHL_DEBUG_PUB.Debug('Start API Get_Forecasted_Counter_Values');
11438 END IF;
11439
11440 -- Initialize message list if p_init_msg_list is set to TRUE
11441 IF FND_API.To_Boolean(p_init_msg_list) THEN
11442 FND_MSG_PUB.Initialize;
11443 END IF;
11444
11445 -- Initialize Procedure return status to success
11446 x_return_status := FND_API.G_RET_STS_SUCCESS;
11447
11448 -- Enable Debug.
11449 IF G_DEBUG = 'Y' THEN
11450 AHL_DEBUG_PUB.enable_debug;
11451 END IF;
11452
11453 -- Add debug mesg.
11454 IF G_DEBUG = 'Y' THEN
11455 AHL_DEBUG_PUB.debug('Begin private API:' || G_PKG_NAME || '.' || 'Get_Forcasted_Counter_Values');
11456
11457 -- Dump input parameters.
11458 AHL_DEBUG_PUB.debug(' Csi Item instance ID:' || p_csi_item_instance_id);
11459 AHL_DEBUG_PUB.debug(' Forecasted Date:' || p_forecasted_date);
11460
11461 END IF;
11462
11463 -- validate item instance.
11464 Validate_item_instance(p_csi_item_instance_id, l_inventory_item_id,
11465 l_inv_master_organization_id, l_expired_flag);
11466
11467
11468 IF (l_expired_flag = 'Y') THEN
11469 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_INST_EXPIRED');
11470 FND_MESSAGE.Set_Token('NUMBER', p_csi_item_instance_id);
11471 FND_MSG_PUB.ADD;
11472 --dbms_output.put_line('Instance has expired');
11473 END IF;
11474
11475 IF FND_MSG_PUB.Count_msg > 0 THEN
11476 RAISE FND_API.G_EXC_ERROR;
11477 END IF;
11478
11479 -- set instance variable.
11480 l_csi_item_instance_id := p_csi_item_instance_id;
11481
11482
11483 -- Set configuration variables based on installation type.
11484 -- If item instance is not top node, find the root item instance.
11485 l_csi_item_instance_id := Get_RootInstanceID(l_csi_item_instance_id);
11486
11487 -- Get master and unit configuration IDs if they exist for this item instance.
11488 Get_Unit_Master_ConfigIDs (l_csi_item_instance_id,
11489 l_uc_header_id, G_master_config_id);
11490
11491 -- Check for errors.
11492 IF FND_MSG_PUB.Count_msg > 0 THEN
11493 RAISE FND_API.G_EXC_ERROR;
11494 END IF;
11495
11496 -- Build the Configuration tree structure.(G_config_node_tbl).
11497 Build_Config_Tree(l_csi_item_instance_id, G_master_config_id, G_CONFIG_NODE_TBL);
11498
11499 -- Add debug mesg.
11500 IF G_DEBUG = 'Y' THEN
11501 AHL_DEBUG_PUB.debug(' Count on Config Node Tbl:' || G_config_node_tbl.COUNT);
11502 AHL_DEBUG_PUB.debug(' Root Node:' || l_csi_item_instance_id );
11503 AHL_DEBUG_PUB.debug(' Unit Config ID:' || l_uc_header_id);
11504 AHL_DEBUG_PUB.debug(' Master Config ID:' || G_master_config_id);
11505 END IF;
11506
11507 -- Read applicable utilization forecast for the configuration.
11508 Get_Utilization_Forecast (l_csi_item_instance_id,
11509 l_uc_header_id,
11510 l_inventory_item_id,
11511 l_inv_master_organization_id,
11512 G_forecast_details_tbl);
11513
11514 -- Build counter rules ratio if node is not root node.
11515 IF (G_master_config_id IS NOT NULL AND p_csi_item_instance_id <> l_csi_item_instance_id) THEN
11516 IF (G_config_node_tbl.count > 0) THEN
11517 FOR j IN G_config_node_tbl.FIRST..G_config_node_tbl.LAST LOOP
11518 IF (G_config_node_tbl(j).csi_item_instance_id = p_csi_item_instance_id) THEN
11519 i := j;
11520 END IF;
11521 END LOOP;
11522 END IF; -- G_config_node_tbl.count.
11523 build_Counter_Ratio(G_config_node_tbl(i).position_reference,
11524 G_config_node_tbl(i).csi_item_instance_id,
11525 G_master_config_id,
11526 l_counter_rules_tbl);
11527 END IF; -- G_master_config_id IS NOT NULL.
11528
11529 -- Get current usage for all the counters defined for the item instance.
11530 get_Current_Usage (p_csi_item_instance_id,
11531 l_current_usage_tbl);
11532
11533
11534 -- get all counter values as on p_forecasted_date.
11535 Get_Due_at_Counter_Values (p_last_due_date => sysdate,
11536 p_last_due_counter_val_tbl => l_current_usage_tbl,
11537 p_due_date => p_forecasted_date,
11538 p_counter_rules_tbl => l_counter_rules_tbl,
11539 x_due_at_counter_val_tbl => l_due_at_counter_val_tbl,
11540 x_return_value => l_return_value);
11541
11542 IF G_DEBUG = 'Y' THEN
11543 AHL_DEBUG_PUB.Debug('AFter get_due_at_counter_values');
11544 AHL_DEBUG_PUB.Debug('l_last_due_date: '|| sysdate);
11545 AHL_DEBUG_PUB.Debug('l_due_date: '|| p_forecasted_date);
11546 IF (l_due_at_counter_val_tbl.COUNT) > 0 THEN
11547 for i in l_due_at_counter_val_tbl.FIRST..l_due_at_counter_val_tbl.LAST LOOP
11548 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_due_at_counter_val_tbl(i).counter_value || 'ID: ' || l_due_at_counter_val_tbl(i).counter_id);
11549 end loop;
11550 END IF; -- count.
11551 END IF; -- Debug = Y
11552
11553 IF NOT(l_return_value) THEN
11554 RAISE FND_API.G_EXC_ERROR; /* no forecast available */
11555 ELSE
11556 x_counter_values_tbl := l_due_at_counter_val_tbl;
11557 END IF;
11558
11559 -- Standard call to get message count and if count is 1, get message info
11560 FND_MSG_PUB.Count_And_Get
11561 ( p_count => x_msg_count,
11562 p_data => x_msg_data,
11563 p_encoded => fnd_api.g_false
11564 );
11565
11566 IF G_DEBUG = 'Y' THEN
11567 AHL_DEBUG_PUB.Debug('End API Get_Forecasted_Counter_Values');
11568 END IF;
11569
11570 --
11571 EXCEPTION
11572 WHEN FND_API.G_EXC_ERROR THEN
11573 x_return_status := FND_API.G_RET_STS_ERROR;
11574 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
11575 p_data => x_msg_data,
11576 p_encoded => fnd_api.g_false);
11577
11578 -- Disable debug
11579 AHL_DEBUG_PUB.disable_debug;
11580
11581 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
11582 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
11583 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
11584 p_data => x_msg_data,
11585 p_encoded => fnd_api.g_false);
11586
11587 -- Disable debug
11588 AHL_DEBUG_PUB.disable_debug;
11589
11590 WHEN OTHERS THEN
11591 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
11592 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
11593 fnd_msg_pub.add_exc_msg(p_pkg_name => G_PKG_NAME,
11594 p_procedure_name => 'Get_Forecasted_Counter_Values',
11595 p_error_text => SUBSTR(SQLERRM,1,240));
11596 END IF;
11597 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
11598 p_data => x_msg_data,
11599 p_encoded => fnd_api.g_false);
11600
11601 -- Disable debug
11602 AHL_DEBUG_PUB.disable_debug;
11603
11604 END Get_Forecasted_Counter_Values;
11605 ----------------------------------------------
11606 -- Added in R12 to fix bug# 4224867.
11607 -- find usage forecast for a given date.
11608 PROCEDURE get_usage_for_date(p_due_date IN DATE,
11609 p_counter_uom_code IN VARCHAR2,
11610 p_counter_rules_tbl IN Counter_rules_tbl_type,
11611 x_usage_per_day OUT NOCOPY NUMBER)
11612 IS
11613 l_next_index NUMBER;
11614
11615 BEGIN
11616
11617 x_usage_per_day := 0;
11618
11619 -- Read g_forecast_details_tbl to get forecast values.
11620 l_next_index := G_forecast_details_tbl.FIRST;
11621
11622 IF (l_next_index IS NOT NULL) THEN
11623 FOR i IN G_forecast_details_tbl.FIRST..G_forecast_details_tbl.LAST LOOP
11624 IF (G_forecast_details_tbl(i).uom_code = p_counter_uom_code) AND
11625 (trunc(G_forecast_details_tbl(i).start_date) <= trunc(p_due_date) AND
11626 trunc(p_due_date) <= trunc(nvl(G_forecast_details_tbl(i).end_date,p_due_date)))
11627 THEN
11628 x_usage_per_day := G_forecast_details_tbl(i).usage_per_day;
11629 EXIT;
11630 END IF;
11631 END LOOP;
11632 END IF;
11633
11634 --dbms_output.put_line ('counter remain input to forecast' || l_counter_remain );
11635 --dbms_output.put_line ('counter uom' ||p_counter_uom_code);
11636
11637 x_usage_per_day := Apply_ReverseCounter_Ratio ( x_usage_per_day,
11638 p_counter_uom_code,
11639 p_counter_rules_tbl);
11640
11641
11642 END get_usage_for_date;
11643 ----------------------------------------------
11644 -- Added to fix bug# 6875650.
11645 -- Get the latest recorded counter reading for a given datetime.
11646 PROCEDURE get_ctr_reading_for_datetime (p_csi_item_instance_id IN NUMBER,
11647 p_counter_id IN NUMBER,
11648 p_reading_date IN DATE,
11649 x_net_reading OUT NOCOPY NUMBER) IS
11650
11651 -- get the latest reading recorded for a counter on any given date.
11652 CURSOR cs_ctr_reading_csr(p_csi_item_instance_id IN NUMBER,
11653 p_counter_id IN NUMBER,
11654 p_reading_date IN DATE) IS
11655 SELECT * FROM (
11656 SELECT CCR.NET_READING
11657 FROM
11658 CSI_COUNTER_READINGS CCR
11659 WHERE
11660 CCR.COUNTER_ID = P_COUNTER_ID
11661 AND nvl(disabled_flag,'N') = 'N'
11662 AND CCR.VALUE_TIMESTAMP <= P_READING_DATE
11663 ORDER BY CCR.VALUE_TIMESTAMP DESC
11664 )
11665 WHERE ROWNUM < 2;
11666
11667 l_net_reading NUMBER;
11668
11669 BEGIN
11670
11671 IF G_DEBUG = 'Y' THEN
11672 AHL_DEBUG_PUB.debug('Start of get_ctr_reading_for_datetime');
11673 END IF;
11674
11675 OPEN cs_ctr_reading_csr(p_csi_item_instance_id,
11676 p_counter_id,
11677 p_reading_date);
11678 FETCH cs_ctr_reading_csr INTO l_net_reading;
11679 IF (cs_ctr_reading_csr%NOTFOUND) THEN
11680 l_net_reading := 0;
11681 END IF;
11682 CLOSE cs_ctr_reading_csr;
11683
11684 x_net_reading := l_net_reading;
11685
11686 IF G_DEBUG = 'Y' THEN
11687 AHL_DEBUG_PUB.debug('End of get_ctr_reading_for_datetime');
11688 END IF;
11689
11690 END get_ctr_reading_for_datetime;
11691
11692 ----------------------------------------------
11693 -- added to fix bug# 6907562.
11694 -- function that compares previous due date and uom remain with current values
11695 -- and return Y is the current due date replaces the prev one.
11696 FUNCTION validate_for_duedate_reset(p_due_date IN DATE,
11697 p_uom_remain IN NUMBER,
11698 p_prev_due_date IN DATE,
11699 p_prev_counter_id IN NUMBER,
11700 p_prev_uom_remain IN NUMBER)
11701 RETURN VARCHAR2 IS
11702 l_return_status VARCHAR2(1);
11703
11704 BEGIN
11705 IF G_DEBUG = 'Y' THEN
11706 AHL_DEBUG_PUB.debug('Start of validate_for_duedate_reset');
11707 END IF;
11708
11709 l_return_status := 'N';
11710 IF (p_due_date IS NULL) THEN
11711 -- check if p_prev_counter_id is null or not. If null then this is first due date calculation.
11712 IF (p_prev_counter_id IS NULL) THEN
11713 l_return_status := 'Y';
11714 ELSE
11715 -- check prior date; it could either be null or not null.
11716 IF (p_prev_due_date IS NULL) THEN
11717 -- trigger ctr based on uom remain.
11718 IF (p_uom_remain < p_prev_uom_remain) THEN
11719 l_return_status := 'Y';
11720 END IF;
11721 ELSE -- p_prev_due_date is not null.
11722 -- check UOM remaining.
11723 IF (p_prev_uom_remain <= 0 AND p_uom_remain > 0) OR
11724 (p_prev_uom_remain < p_uom_remain AND p_uom_remain < 0) THEN
11725 null; -- do nothing
11726 ELSE
11727 l_return_status := 'Y';
11728 END IF; -- p_prev_uom_remain < 0
11729 END IF; -- p_prev_due_date
11730 END IF; -- p_prev_counter_id
11731 ELSE -- p_due_date is not null.
11732 IF (p_prev_due_date IS NULL) THEN
11733 IF (p_prev_counter_id IS NULL) THEN
11734 -- this is first time due due calculation.
11735 l_return_status := 'Y';
11736 ELSE
11737 -- prior due date is a null due date.
11738 -- swap based on uom remain.
11739 IF (p_uom_remain < p_prev_uom_remain AND p_prev_uom_remain < 0) OR
11740 (p_uom_remain <= 0 AND p_prev_uom_remain > 0) THEN
11741 l_return_status := 'Y';
11742 END IF;
11743 END IF; -- p_prev_counter_id
11744 END IF; -- p_prev_due_date
11745 END IF; -- p_due_date
11746
11747 IF G_DEBUG = 'Y' THEN
11748 AHL_DEBUG_PUB.debug('End of validate_for_duedate_reset');
11749 END IF;
11750
11751 RETURN l_return_status;
11752
11753 END validate_for_duedate_reset;
11754
11755 -----------------------------------------------
11756 -- Added procedure to replace call to ahl_fmp_pvt.get_mr_affected_items for Prev. Maint
11757 -- Called when processing based on MR invoked through concurrent program.
11758 -- Perf fix for bug# 5093064.
11759 PROCEDURE Process_PM_MR_Affected_Items(
11760 p_commit IN VARCHAR2 := FND_API.G_FALSE,
11761 x_msg_count OUT NOCOPY NUMBER,
11762 x_msg_data OUT NOCOPY VARCHAR2,
11763 x_return_status OUT NOCOPY VARCHAR2,
11764 p_mr_header_id IN NUMBER,
11765 p_old_mr_header_id IN NUMBER := NULL,
11766 p_concurrent_flag IN VARCHAR2 := 'N',
11767 p_num_of_workers IN NUMBER := 10)
11768
11769 IS
11770
11771 l_msg_count NUMBER;
11772 l_return_status VARCHAR2(1);
11773 l_msg_data VARCHAR2(30);
11774 i NUMBER;
11775 l_debug VARCHAR2(1) := AHL_DEBUG_PUB.is_log_enabled;
11776 l_master_org_id NUMBER;
11777 l_mr_header_id NUMBER;
11778
11779 l_csi_min_id NUMBER;
11780 l_csi_max_id NUMBER;
11781 l_csi_eff_min_id NUMBER;
11782 l_csi_eff_max_id NUMBER;
11783 l_num_workers NUMBER;
11784 l_end_csi_id NUMBER;
11785 l_start_csi_id NUMBER;
11786 l_step NUMBER;
11787 l_req_id NUMBER;
11788 l_count NUMBER;
11789 l_total_count NUMBER := 0;
11790
11791 l_csi_inst_tbl nbr_tbl_type;
11792
11793 --check whether the given mr exists
11794 CURSOR check_mr_exists(c_mr_header_id number)
11795 IS
11796 SELECT mr_header_id
11797 FROM ahl_mr_headers_app_v
11798 WHERE mr_header_id = c_mr_header_id;
11799
11800 --get all the MR effectivity definitions for a given MR
11801 CURSOR get_mr_effect(c_mr_header_id NUMBER)
11802 IS
11803 SELECT mr_header_id, mr_effectivity_id, inventory_item_id
11804 FROM ahl_mr_effectivities_app_v
11805 WHERE mr_header_id = c_mr_header_id;
11806
11807 -- get master org id.
11808 CURSOR get_master_org_id_csr (c_inventory_item_id IN NUMBER)
11809 IS
11810 SELECT itm.organization_id
11811 FROM mtl_system_items_b itm, mtl_parameters mtl
11812 WHERE itm.inventory_item_id = c_inventory_item_id
11813 AND itm.organization_id = mtl.organization_id
11814 AND mtl.master_organization_id = mtl.organization_id;
11815
11816 -- Get min/max instance ID for a given INV ID.
11817 CURSOR get_minmax_inst_csr(c_inventory_item_id IN NUMBER,
11818 c_inventory_org_id IN NUMBER)
11819 IS
11820 SELECT min(instance_id), max(instance_id), count(instance_id)
11821 FROM csi_item_instances
11822 WHERE inventory_item_id = c_inventory_item_id
11823 AND inv_master_organization_id = c_inventory_org_id
11824 AND SYSDATE between trunc(nvl(active_start_date,sysdate)) and
11825 trunc(nvl(active_end_date,sysdate+1))
11826 GROUP BY inventory_item_id, inv_master_organization_id;
11827
11828 -- get instances when mr_header_id is provided.
11829 CURSOR get_inst( p_mr_header_id IN NUMBER,
11830 c_start_inst_id IN NUMBER,
11831 c_end_inst_id IN NUMBER)
11832 IS
11833 SELECT cii.instance_id
11834 FROM csi_item_instances cii, ahl_mr_effectivities mre, mtl_system_items_b msi
11835 WHERE cii.inventory_item_id = msi.inventory_item_id
11836 AND cii.inv_master_organization_id = msi.organization_id
11837 AND cii.inventory_item_id = mre.inventory_item_id
11838 AND mre.mr_header_id = p_mr_header_id
11839 AND SYSDATE between trunc(nvl(cii.active_start_date,sysdate)) and
11840 trunc(nvl(cii.active_end_date,sysdate+1))
11841 AND cii.instance_id >= c_start_inst_id
11842 AND cii.instance_id <= c_end_inst_id;
11843
11844 BEGIN
11845
11846 IF l_debug = 'Y' THEN
11847 AHL_DEBUG_PUB.enable_debug;
11848 AHL_DEBUG_PUB.debug('Begin private API: AHL_UMP_PROCESSUNIT_PVT.PROCESS_PM_MR_AFFECTED_ITEMS');
11849 END IF;
11850
11851 -- Check whether the mr_header_id exists --
11852 OPEN check_mr_exists(p_mr_header_id);
11853 FETCH check_mr_exists INTO l_mr_header_id;
11854 IF check_mr_exists%NOTFOUND THEN
11855 CLOSE check_mr_exists;
11856 FND_MESSAGE.SET_NAME('AHL','AHL_FMP_INVALID_MR');
11857 FND_MSG_PUB.ADD;
11858 RAISE FND_API.G_EXC_ERROR;
11859 END IF;
11860 CLOSE check_mr_exists;
11861
11862 IF l_debug = 'Y' THEN
11863 AHL_DEBUG_PUB.debug(' Phase 1');
11864 END IF;
11865
11866 -- validate # of workers.
11867 l_num_workers := p_num_of_workers;
11868
11869 IF (p_num_of_workers > 30) THEN
11870 l_num_workers := 30;
11871 END IF;
11872
11873 IF l_debug = 'Y' THEN
11874 AHL_DEBUG_PUB.debug(' Phase 2:l_num_workers:' || l_num_workers);
11875 END IF;
11876
11877 FOR l_mr_effect IN get_mr_effect(p_mr_header_id)
11878 LOOP
11879 IF (l_mr_effect.inventory_item_id IS NOT NULL) THEN
11880
11881 IF l_debug = 'Y' THEN
11882 AHL_DEBUG_PUB.debug(' Phase 3:Inv Item ID:' || l_mr_effect.inventory_item_id);
11883 END IF;
11884
11885 --DBMS_OUTPUT.put_line('API1: Come here in case 1B and l_index is: '||l_index);
11886
11887 AHL_FMP_COMMON_PVT.validate_item(x_return_status => l_return_status,
11888 x_msg_data => l_msg_data,
11889 p_item_number => NULL,
11890 p_x_inventory_item_id => l_mr_effect.inventory_item_id);
11891 IF (l_return_status = 'S') THEN
11892
11893 IF l_debug = 'Y' THEN
11894 AHL_DEBUG_PUB.debug('Phase 4: Inv Item ID is Valid');
11895 END IF;
11896 -- get master organization id.
11897 OPEN get_master_org_id_csr(l_mr_effect.inventory_item_id);
11898 FETCH get_master_org_id_csr INTO l_master_org_id;
11899 IF (get_master_org_id_csr%NOTFOUND) THEN
11900 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_MASORG_NOTFOUND');
11901 FND_MESSAGE.Set_Token('INV_ID',l_mr_effect.inventory_item_id);
11902 FND_MSG_PUB.ADD;
11903 --DBMS_OUTPUT.put_line('Master org not found for inventory item:' || l_mr_effect.inventory_item_id);
11904 ClOSE get_master_org_id_csr;
11905 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
11906 END IF;
11907 CLOSE get_master_org_id_csr;
11908
11909 OPEN get_minmax_inst_csr(l_mr_effect.inventory_item_id,l_master_org_id);
11910 FETCH get_minmax_inst_csr INTO l_csi_eff_min_id, l_csi_eff_max_id, l_count;
11911 IF (get_minmax_inst_csr%FOUND) THEN
11912 IF ((l_csi_min_id IS NULL) OR (l_csi_eff_min_id < l_csi_min_id)) THEN
11913 l_csi_min_id := l_csi_eff_min_id;
11914 END IF;
11915
11916 IF ((l_csi_max_id IS NULL) OR (l_csi_max_id < l_csi_eff_max_id)) THEN
11917 l_csi_max_id := l_csi_eff_max_id;
11918 END IF;
11919 l_total_count := l_count + l_total_count;
11920
11921 END IF;
11922 CLOSE get_minmax_inst_csr;
11923
11924 IF l_debug = 'Y' THEN
11925 AHL_DEBUG_PUB.debug(' Phase 5:csi_min:csi_max:count:' || l_csi_min_id || ':' || l_csi_max_id || ':' ||
11926 l_total_count);
11927 END IF;
11928
11929 END IF; -- l_return_status = 'S'
11930 END IF; -- l_mr_effect.inventory_item_id IS NOT NULL
11931 END LOOP; -- l_mr_effect
11932
11933 IF (p_concurrent_flag = 'Y') THEN
11934 -- launch workers after assigning instance range.
11935 IF (l_num_workers < 15) THEN
11936 Instance_Split_BTree(p_csi_max_id => l_csi_max_id,
11937 p_csi_min_id => l_csi_min_id,
11938 p_num_workers => p_num_of_workers,
11939 p_mr_header_id => p_mr_header_id,
11940 p_total_inst_count => l_total_count);
11941 ELSE
11942 Instance_Split_Sequential(p_csi_max_id => l_csi_max_id,
11943 p_csi_min_id => l_csi_min_id,
11944 p_num_workers => p_num_of_workers,
11945 p_mr_header_id => p_mr_header_id);
11946
11947 END IF;
11948 ELSE
11949 -- process all instances.
11950 OPEN get_inst(p_mr_header_id, l_csi_min_id, l_csi_max_id);
11951 LOOP
11952
11953 FETCH get_inst BULK COLLECT INTO l_csi_inst_tbl LIMIT 1000;
11954 IF (l_csi_inst_tbl.count > 0) THEN
11955 -- call process unit for all instances.
11956
11957 FOR i IN l_csi_inst_tbl.FIRST..l_csi_inst_tbl.LAST LOOP
11958 -- Call Process Unit for the item instance.
11959 Process_Unit (
11960 p_commit => FND_API.G_TRUE,
11961 p_init_msg_list => FND_API.G_TRUE,
11962 x_msg_count => x_msg_count,
11963 x_msg_data => x_msg_data,
11964 x_return_status => x_return_status,
11965 p_csi_item_instance_id => l_csi_inst_tbl(i),
11966 p_concurrent_flag => 'N');
11967
11968 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11969 EXIT;
11970 END IF;
11971
11972 END LOOP; -- l_csi_inst_tbl.FIRST
11973 END IF; -- l_csi_inst_tbl.count
11974 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11975 EXIT;
11976 END IF;
11977
11978 EXIT WHEN get_inst%NOTFOUND;
11979 END LOOP; -- get_inst.
11980 CLOSE get_inst;
11981 END IF; -- p_concurrent_flag
11982
11983 END Process_PM_MR_Affected_Items;
11984
11985 ----------------------------------------------
11986 -- Split instance range into blocks based on instance IDs.
11987 PROCEDURE Instance_Split_Sequential(p_csi_max_id in NUMBER,
11988 p_csi_min_id IN NUMBER,
11989 p_num_workers IN NUMBER,
11990 p_mr_header_id IN NUMBER)
11991 IS
11992
11993 l_debug VARCHAR2(1) := AHL_DEBUG_PUB.is_log_enabled;
11994
11995 l_csi_min_id NUMBER;
11996 l_csi_max_id NUMBER;
11997 l_csi_eff_min_id NUMBER;
11998 l_csi_eff_max_id NUMBER;
11999 l_num_workers NUMBER;
12000 l_end_csi_id NUMBER;
12001 l_start_csi_id NUMBER;
12002 l_step NUMBER;
12003 l_req_id NUMBER;
12004
12005 BEGIN
12006
12007 l_num_workers := p_num_workers;
12008 l_csi_min_id := p_csi_min_id;
12009 l_csi_max_id := p_csi_max_id;
12010
12011 -- split the instances based on # of workers and launch seperate concurrent
12012 -- programs to process a group of instances.
12013 IF (l_csi_max_id IS NOT NULL) AND (l_csi_min_id IS NOT NULL) THEN
12014 l_step := round((l_csi_max_id - l_csi_min_id) / l_num_workers);
12015
12016 IF (l_step < 1) THEN
12017 l_step := l_csi_max_id - l_csi_min_id;
12018 l_num_workers := 1;
12019 END IF;
12020
12021 l_start_csi_id := l_csi_min_id;
12022
12023 IF l_debug = 'Y' THEN
12024 AHL_DEBUG_PUB.debug('l_step:' || l_step || 'start csi: end csi' || l_start_csi_id || ':' || l_end_csi_id);
12025 END IF;
12026
12027 -- loop through
12028 WHILE (l_start_csi_id < l_csi_max_id) LOOP
12029 l_end_csi_id := l_start_csi_id + l_step;
12030 IF (l_end_csi_id > l_csi_max_id) THEN
12031 l_end_csi_id := l_csi_max_id;
12032 END IF;
12033
12034 IF l_debug = 'Y' THEN
12035 AHL_DEBUG_PUB.debug('Loop start csi: end csi' || l_start_csi_id || ':' || l_end_csi_id);
12036 END IF;
12037
12038 -- launch BUE worker request.
12039 l_req_id := fnd_request.submit_request('AHL','AHLWUEFF',NULL,NULL,FALSE, p_mr_header_id, l_start_csi_id, l_end_csi_id);
12040
12041 IF (l_req_id = 0 OR l_req_id IS NULL) THEN
12042 IF l_debug = 'Y' THEN
12043 AHL_DEBUG_PUB.debug('Tried to submit concurrent request but failed');
12044 END IF;
12045 fnd_file.put_line(FND_FILE.LOG, 'Failed submit concurrent request');
12046 fnd_file.new_line(FND_FILE.LOG,1);
12047 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12048
12049 ELSE
12050 fnd_file.put_line(FND_FILE.LOG, 'Concurrent request ID:' || l_req_id || ' launched to process instances between:' || l_start_csi_id || ' and ' || l_end_csi_id);
12051
12052 IF l_debug = 'Y' THEN
12053 AHL_DEBUG_PUB.debug('Concurrent request ID:' || l_req_id || ' launched to process instances between:' || l_start_csi_id || ' and ' || l_end_csi_id);
12054 END IF;
12055 END IF;
12056
12057 l_start_csi_id := l_end_csi_id + 1;
12058
12059 END LOOP;
12060 END IF;
12061
12062 END Instance_Split_Sequential;
12063
12064 ----------------------------------------------
12065 -- Split instances based on instance count.
12066 PROCEDURE Instance_Split_BTree(p_csi_max_id in NUMBER,
12067 p_csi_min_id IN NUMBER,
12068 p_num_workers IN NUMBER,
12069 p_mr_header_id IN NUMBER,
12070 p_total_inst_count IN NUMBER)
12071 IS
12072
12073 l_debug VARCHAR2(1) := AHL_DEBUG_PUB.is_log_enabled;
12074 l_step number;
12075 l_start_csi_id number;
12076 l_launched_workers number;
12077 l_mid_point_inst_id number;
12078 l_count number;
12079 l_req_id number;
12080 l_end_csi_id number;
12081 l_begin_count_csi_id number;
12082
12083 l_tol_after number;
12084 l_tol_bef number;
12085
12086 l_num_workers number;
12087
12088 cursor csi_inst_count_csr (p_start_inst_id in number,
12089 p_end_inst_id in number,
12090 p_mr_header_id in number) IS
12091 SELECT count(instance_id)
12092 FROM csi_item_instances csi, ahl_mr_effectivities me
12093 WHERE csi.instance_id >= p_start_inst_id and csi.instance_id <= p_end_inst_id
12094 AND csi.inventory_item_id = me.inventory_item_id
12095 AND me.mr_header_id = p_mr_header_id
12096 AND SYSDATE between trunc(nvl(active_start_date,sysdate)) and
12097 trunc(nvl(active_end_date,sysdate+1));
12098
12099 BEGIN
12100 IF l_debug = 'Y' THEN
12101 AHL_DEBUG_PUB.debug('Start of procedure: Instance_Split_BTree');
12102 AHL_DEBUG_PUB.debug('p_mr_header_id:' || p_mr_header_id);
12103 AHL_DEBUG_PUB.debug('p_num_workers:' || p_num_workers);
12104 AHL_DEBUG_PUB.debug('p_csi_max_id:' || p_csi_max_id);
12105 AHL_DEBUG_PUB.debug('p_csi_min_id:' || p_csi_min_id);
12106 AHL_DEBUG_PUB.debug('p_total_inst_count:' || p_total_inst_count);
12107 END IF;
12108
12109 l_num_workers := p_num_workers;
12110
12111 IF (p_total_inst_count > 0 ) THEN
12112 IF (l_num_workers = 1) THEN
12113 -- launch BUE worker request.
12114 l_req_id := fnd_request.submit_request('AHL','AHLWUEFF',NULL,NULL,FALSE, p_mr_header_id,
12115 p_csi_min_id, p_csi_max_id);
12116
12117 IF (l_req_id = 0 OR l_req_id IS NULL) THEN
12118 IF l_debug = 'Y' THEN
12119 AHL_DEBUG_PUB.debug('Tried to submit concurrent request but failed');
12120 END IF;
12121 fnd_file.put_line(FND_FILE.LOG, 'Failed submit concurrent request');
12122 fnd_file.new_line(FND_FILE.LOG,1);
12123 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12124
12125 ELSE
12126 fnd_file.put_line(FND_FILE.LOG, 'Concurrent request ID:' || l_req_id || ' launched to process instances between:' || p_csi_min_id || ' and ' || p_csi_min_id);
12127
12128 IF l_debug = 'Y' THEN
12129 AHL_DEBUG_PUB.debug('Concurrent request ID:' || l_req_id || ' launched to process instances between:' || p_csi_min_id || ' and ' || p_csi_min_id);
12130 END IF;
12131 END IF;
12132
12133 ELSE
12134 -- find optimal and tolerant count of instances and hence the start and
12135 -- end instance ID for each worker.
12136 l_step := round(p_total_inst_count/l_num_workers);
12137 IF (l_step = 0) THEN
12138 l_num_workers := p_total_inst_count;
12139 l_step := 1;
12140 END IF;
12141 l_tol_bef := l_step - trunc((0.1 * l_step));
12142 l_tol_after := l_step + trunc((0.1 * l_step));
12143
12144 IF l_debug = 'Y' THEN
12145 AHL_DEBUG_PUB.debug('l_step:' || l_step);
12146 AHL_DEBUG_PUB.debug('l_tol_bef:' || l_tol_bef);
12147 AHL_DEBUG_PUB.debug('l_tol_after:' || l_tol_after);
12148 END IF;
12149
12150 --dbms_output.put_line('l_Step:' || l_step);
12151 --dbms_output.put_line('l_tol_minus:' || l_tol_bef);
12152 --dbms_output.put_line('l_tol_plus:' || l_tol_after);
12153
12154 -- use binary search logic to find the start and end points for every worker.
12155 l_begin_count_csi_id := p_csi_min_id;
12156 l_start_csi_id := p_csi_min_id;
12157 l_end_csi_id := p_csi_max_id;
12158
12159 l_launched_workers := 0;
12160
12161 --l_mid_point_inst_id := trunc((p_csi_min_id + p_csi_max_id) / 2);
12162 l_mid_point_inst_id := p_csi_max_id; -- start with full interval.
12163
12164 WHILE (l_launched_workers < l_num_workers) loop
12165
12166 WHILE (true) LOOP
12167
12168 IF l_debug = 'Y' THEN
12169 AHL_DEBUG_PUB.debug('Start loop:l_begin_count_csi_id:' || l_begin_count_csi_id);
12170 AHL_DEBUG_PUB.debug('l_start_csi_id:' || l_start_csi_id);
12171 AHL_DEBUG_PUB.debug('l_mid_point_inst_id:' || l_mid_point_inst_id);
12172 --dbms_output.put_line('l_start_csi_id:' || l_start_csi_id);
12173 --dbms_output.put_line('l_mid_point_inst_id:' || l_mid_point_inst_id);
12174 END IF;
12175
12176 OPEN csi_inst_count_csr(l_begin_count_csi_id, l_mid_point_inst_id, p_mr_header_id);
12177 FETCH csi_inst_count_csr INTO l_count;
12178 CLOSE csi_inst_count_csr;
12179
12180 IF l_debug = 'Y' THEN
12181 AHL_DEBUG_PUB.debug('l_count:' || l_count);
12182 END IF;
12183 -- dbms_output.put_line('l_count:' || l_count);
12184
12185 IF (l_count >= l_tol_bef AND l_count <= l_tol_after) THEN
12186
12187 l_launched_workers := l_launched_workers + 1;
12188
12189 -- launch BUE worker request.
12190 l_req_id := fnd_request.submit_request('AHL','AHLWUEFF',NULL,NULL,FALSE, p_mr_header_id,
12191 l_begin_count_csi_id, l_mid_point_inst_id);
12192
12193 --dbms_output.put_line('new l_launched_workers:' || l_launched_workers);
12194 --dbms_output.put_line('newB l_begin_count_csi_id:' || l_begin_count_csi_id);
12195 --dbms_output.put_line('newB l_mid_point_inst_id:' || l_mid_point_inst_id);
12196
12197 IF (l_req_id = 0 OR l_req_id IS NULL) THEN
12198 IF l_debug = 'Y' THEN
12199 AHL_DEBUG_PUB.debug('Tried to submit concurrent request but failed');
12200 END IF;
12201 fnd_file.put_line(FND_FILE.LOG, 'Failed submit concurrent request');
12202 fnd_file.new_line(FND_FILE.LOG,1);
12203 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12204
12205 ELSE
12206 fnd_file.put_line(FND_FILE.LOG, 'Concurrent request ID:' || l_req_id ||
12207 ' launched to process instances between:' || l_begin_count_csi_id || ' and ' ||
12208 l_mid_point_inst_id);
12209
12210 IF l_debug = 'Y' THEN
12211 AHL_DEBUG_PUB.debug('Concurrent request ID:' || l_req_id ||
12212 ' launched to process instances between:' || l_begin_count_csi_id || ' and ' ||
12213 l_mid_point_inst_id);
12214 END IF;
12215 END IF;
12216 IF (l_launched_workers = l_num_workers - 1) THEN
12217 -- launch last worker.
12218 l_begin_count_csi_id := l_mid_point_inst_id + 1;
12219 l_mid_point_inst_id := p_csi_max_id;
12220 l_launched_workers := l_launched_workers + 1;
12221 l_req_id := fnd_request.submit_request('AHL','AHLWUEFF',NULL,NULL,FALSE, p_mr_header_id,
12222 l_begin_count_csi_id, l_mid_point_inst_id);
12223 IF (l_req_id = 0 OR l_req_id IS NULL) THEN
12224 IF l_debug = 'Y' THEN
12225 AHL_DEBUG_PUB.debug('Tried to submit concurrent request but failed');
12226 END IF;
12227 fnd_file.put_line(FND_FILE.LOG, 'Failed submit concurrent request');
12228 fnd_file.new_line(FND_FILE.LOG,1);
12229 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12230
12231 ELSE
12232 fnd_file.put_line(FND_FILE.LOG, 'Concurrent request ID:' || l_req_id ||
12233 ' launched to process instances between:' || l_begin_count_csi_id || ' and ' ||
12234 l_mid_point_inst_id);
12235
12236 IF l_debug = 'Y' THEN
12237 AHL_DEBUG_PUB.debug('Concurrent request ID:' || l_req_id ||
12238 ' launched to process instances between:' || l_begin_count_csi_id || ' and ' ||
12239 l_mid_point_inst_id);
12240 END IF;
12241 END IF; -- l_req_id = 0 OR ..
12242 END IF;
12243 EXIT;
12244 ELSIF (l_count < l_step) THEN
12245 l_start_csi_id := l_mid_point_inst_id;
12246 l_mid_point_inst_id := trunc((l_mid_point_inst_id + l_end_csi_id) /2);
12247 --dbms_output.put_line('new l_mid_point_inst_id:<' || l_mid_point_inst_id);
12248 ELSIF (l_count > l_step) THEN
12249 l_end_csi_id := l_mid_point_inst_id;
12250 l_mid_point_inst_id := trunc((l_mid_point_inst_id + l_start_csi_id)/2);
12251 --dbms_output.put_line('new l_mid_point_inst_id:>' || l_mid_point_inst_id);
12252
12253 END IF; -- l_count >= l_tol_bef..
12254 END LOOP; -- WHILE (true)
12255 -- initialize begin, start and end points for next worker.
12256 l_begin_count_csi_id := l_mid_point_inst_id+1;
12257 l_start_csi_id := l_mid_point_inst_id+1;
12258 l_end_csi_id := p_csi_max_id;
12259 l_mid_point_inst_id := trunc((l_start_csi_id + l_end_csi_id) / 2);
12260 END LOOP;
12261
12262 END IF;
12263 END IF;
12264
12265 IF l_debug = 'Y' THEN
12266 AHL_DEBUG_PUB.debug('End of procedure: Instance_Split_BTree');
12267 END IF;
12268
12269 END Instance_Split_BTree;
12270
12271 ----------------------------------------------
12272 -- PM Build unit Effectivities worker concurrent program.
12273 PROCEDURE Process_Unit_Range (
12274 errbuf OUT NOCOPY VARCHAR2,
12275 retcode OUT NOCOPY NUMBER,
12276 p_mr_header_id IN NUMBER,
12277 p_start_instance_id IN NUMBER,
12278 p_end_instance_id IN NUMBER)
12279 IS
12280
12281 -- get instances when mr_header_id is provided.
12282 CURSOR get_inst( p_mr_header_id IN NUMBER,
12283 c_start_inst_id IN NUMBER,
12284 c_end_inst_id IN NUMBER)
12285 IS
12286 SELECT cii.instance_id
12287 FROM csi_item_instances cii, ahl_mr_effectivities mre, mtl_system_items_b msi
12288 -- repalced mtl_system_items_kfv with mtl_system items_b.
12289 WHERE cii.inventory_item_id = msi.inventory_item_id
12290 AND cii.inv_master_organization_id = msi.organization_id
12291 AND cii.inventory_item_id = mre.inventory_item_id
12292 AND mre.mr_header_id = p_mr_header_id
12293 AND SYSDATE between trunc(nvl(cii.active_start_date,sysdate)) and
12294 trunc(nvl(cii.active_end_date,sysdate+1))
12295 AND cii.instance_id >= c_start_inst_id
12296 AND cii.instance_id <= c_end_inst_id;
12297
12298 -- get instances when no mr_header_id.
12299 CURSOR get_all_inst( c_start_inst_id IN NUMBER,
12300 c_end_inst_id IN NUMBER)
12301 IS
12302 SELECT cii.instance_id
12303 FROM csi_item_instances cii, ahl_mr_effectivities mre, mtl_system_items_b msi,
12304 (select mr_header_id
12305 from ahl_mr_headers_app_v
12306 where type_code = 'PROGRAM') mr
12307 WHERE cii.inventory_item_id = msi.inventory_item_id
12308 AND cii.inv_master_organization_id = msi.organization_id
12309 AND cii.inventory_item_id = mre.inventory_item_id
12310 AND mre.mr_header_id = mr.mr_header_id
12311 AND SYSDATE between trunc(nvl(cii.active_start_date,sysdate)) and
12312 trunc(nvl(cii.active_end_date,sysdate+1))
12313 AND cii.instance_id >= c_start_inst_id
12314 AND cii.instance_id <= c_end_inst_id;
12315
12316 l_msg_count NUMBER;
12317 l_msg_data VARCHAR2(3000);
12318 l_return_status VARCHAR2(1);
12319
12320 -- added for performance fix 6511501.
12321 TYPE nbr_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
12322 l_csi_inst_tbl nbr_tbl_type;
12323
12324 BEGIN
12325
12326 IF G_DEBUG = 'Y' THEN
12327 fnd_file.put_line(FND_FILE.LOG,'MR Header ID = '||p_mr_header_id);
12328 fnd_file.put_line(FND_FILE.LOG,'CSI Start Instance = '||p_start_instance_id);
12329 fnd_file.put_line(FND_FILE.LOG,'CSI End Instance = '||p_end_instance_id);
12330 fnd_file.put_line(FND_FILE.LOG,'Start Time:' || to_char(sysdate, 'Month DD, YYYY HH24:MI:SS'));
12331 fnd_file.new_line(FND_FILE.LOG,1);
12332 END IF;
12333
12334 -- initialize return status.
12335 retcode := 0;
12336 IF (p_mr_header_id IS NOT NULL) THEN
12337 OPEN get_inst(p_mr_header_id, p_start_instance_id, p_end_instance_id);
12338 ELSE
12339 OPEN get_all_inst(p_start_instance_id, p_end_instance_id);
12340 END IF;
12341
12342
12343 LOOP
12344 IF (p_mr_header_id IS NOT NULL) THEN
12345 FETCH get_inst BULK COLLECT INTO l_csi_inst_tbl LIMIT 1000;
12346 ELSE
12347 FETCH get_all_inst BULK COLLECT INTO l_csi_inst_tbl LIMIT 1000;
12348 END IF;
12349
12350 IF (l_csi_inst_tbl.count > 0) THEN
12351 -- call process unit for all instances.
12352 --FOR inst_rec IN get_inst(p_mr_header_id, p_start_instance_id, p_end_instance_id) LOOP
12353 FOR i IN l_csi_inst_tbl.FIRST..l_csi_inst_tbl.LAST LOOP
12354 -- Call Process Unit for the item instance.
12355 Process_Unit (
12356 p_commit => FND_API.G_TRUE,
12357 p_init_msg_list => FND_API.G_TRUE,
12358 x_msg_count => l_msg_count,
12359 x_msg_data => l_msg_data,
12360 x_return_status => l_return_status,
12361 p_csi_item_instance_id => l_csi_inst_tbl(i),
12362 --inst_rec.instance_id,
12363 p_concurrent_flag => 'Y');
12364
12365 l_msg_count := FND_MSG_PUB.Count_Msg;
12366 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS)
12367 THEN
12368 retcode := 2; -- error based only on return status
12369 ELSIF (l_msg_count > 0 AND l_return_status = FND_API.G_RET_STS_SUCCESS)
12370 THEN
12371 retcode := 1; -- warning based on return status + msg count
12372 END IF;
12373
12374 END LOOP; -- l_csi_inst_tbl.FIRST
12375 END IF; -- l_csi_inst_tbl.count
12376
12377 IF (p_mr_header_id IS NOT NULL) THEN
12378 EXIT WHEN get_inst%NOTFOUND;
12379 ELSE
12380 EXIT WHEN get_all_inst%NOTFOUND;
12381 END IF;
12382
12383 END LOOP; -- get_inst.
12384 IF (p_mr_header_id IS NOT NULL) THEN
12385 CLOSE get_inst;
12386 ELSE
12387 CLOSE get_all_inst;
12388 END IF;
12389
12390 IF G_DEBUG = 'Y' THEN
12391 fnd_file.new_line(FND_FILE.LOG,1);
12392 fnd_file.put_line(FND_FILE.LOG,'End Time:' || to_char(sysdate, 'Month DD, YYYY HH24:MI:SS'));
12393 END IF;
12394
12395 --
12396 EXCEPTION
12397 WHEN OTHERS THEN
12398 retcode := 2;
12399 errbuf := 'Process_Unit_Range:PM:OTHERS:' || substrb(sqlerrm,1,60);
12400
12401 END Process_Unit_Range;
12402
12403 ----------------------------------------------
12404 -- Added for performance bug# 6893404.
12405 PROCEDURE Split_Process_All_Instances(p_concurrent_flag IN VARCHAR2,
12406 p_commit_flag IN VARCHAR2,
12407 p_num_of_workers IN NUMBER,
12408 p_mr_header_id IN NUMBER,
12409 p_mtl_category_id IN NUMBER,
12410 p_process_option IN VARCHAR2,
12411 x_msg_count OUT NOCOPY NUMBER,
12412 x_msg_data OUT NOCOPY NUMBER,
12413 x_return_status OUT NOCOPY VARCHAR2)
12414 IS
12415
12416 l_req_id number;
12417 l_conc_req_id number;
12418 l_instance_id number;
12419
12420 l_num_of_workers number;
12421
12422 dml_errors EXCEPTION;
12423 PRAGMA EXCEPTION_INIT(dml_errors, -24381);
12424
12425 -- added for bug# 10185468
12426 l_err_mesg VARCHAR2(4000);
12427 l_return_status VARCHAR2(1);
12428
12429 BEGIN
12430
12431 IF G_debug = 'Y' THEN
12432 AHL_DEBUG_PUB.debug('Start Split_Process_All_Instances:p_concurrent_flag:' || p_concurrent_flag);
12433 AHL_DEBUG_PUB.debug('Input MR Header ID:' || p_mr_header_id);
12434 AHL_DEBUG_PUB.debug('Input p_num_of_workers:' || p_num_of_workers);
12435 END IF;
12436
12437 -- initialize return status.
12438 x_return_status := FND_API.G_RET_STS_SUCCESS;
12439
12440 IF (p_concurrent_flag = 'Y') THEN
12441 l_conc_req_id := fnd_global.conc_request_id;
12442 ELSE
12443 l_conc_req_id := fnd_global.session_id;
12444 END IF;
12445
12446 -- validate p_num_of_workers.
12447 l_num_of_workers := trunc(p_num_of_workers);
12448
12449 IF (l_num_of_workers IS NULL OR l_num_of_workers <= 0) THEN
12450 l_num_of_workers := 1;
12451 ELSIF l_num_of_workers > 30 THEN
12452 l_num_of_workers := 30;
12453 END IF;
12454
12455 Populate_BUE_Worker(p_conc_request_id => l_conc_req_id,
12456 p_concurrent_flag => p_concurrent_flag,
12457 p_mtl_category_id => p_mtl_category_id,
12458 p_process_option => p_process_option,
12459 errbuf => x_msg_data,
12460 x_return_status => x_return_status);
12461
12462 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12463 RETURN;
12464 END IF;
12465
12466 -- launch worker programs.
12467 IF (p_concurrent_flag = 'Y') THEN
12468 -- submit worker programs to process units.
12469 FOR i IN 1..l_num_of_workers LOOP
12470 l_req_id := fnd_request.submit_request('AHL','AHLWUEFF',NULL,NULL,FALSE, l_conc_req_id);
12471 IF (l_req_id = 0 OR l_req_id IS NULL) THEN
12472 IF G_debug = 'Y' THEN
12473 AHL_DEBUG_PUB.debug('Tried to submit concurrent request but failed');
12474 END IF;
12475 fnd_file.put_line(FND_FILE.LOG, 'Failed submit concurrent request');
12476 fnd_file.new_line(FND_FILE.LOG,1);
12477 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12478
12479 ELSE
12480 fnd_file.put_line(FND_FILE.LOG, 'Concurrent request ID:' || l_req_id );
12481 IF G_debug = 'Y' THEN
12482 AHL_DEBUG_PUB.debug('Concurrent request ID:' || l_req_id );
12483 END IF;
12484 END IF; -- l_req_id = 0 OR ..
12485
12486 END LOOP;
12487
12488 -- call cleanup BUE for previously failed deletes.
12489 Cleanup_BUE_Worker(p_parent_conc_request_id => l_conc_req_id,
12490 p_child_conc_request_id => NULL,
12491 x_return_status => l_return_status,
12492 x_errbuf => l_err_mesg);
12493 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12494 -- ignore error returned from this procedure
12495 -- log message in concurrent request log.
12496 fnd_file.put_line(FND_FILE.LOG, 'Warning: Error from Cleanup_BUE_Worker:' || l_err_mesg);
12497 END IF;
12498 ELSE
12499
12500 LOOP
12501 -- initialize return status.
12502 x_return_status := FND_API.G_RET_STS_SUCCESS;
12503
12504 Get_Next_BUE_Row(p_parent_conc_pgm_id => l_conc_req_id,
12505 p_conc_child_req_id => l_conc_req_id,
12506 x_return_status => x_return_status,
12507 errbuf => x_msg_data,
12508 x_item_instance_id => l_instance_id);
12509
12510 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12511 EXIT;
12512 END IF;
12513
12514 EXIT WHEN (l_instance_id IS NULL);
12515
12516 IF G_DEBUG = 'Y' THEN
12517 AHL_DEBUG_PUB.debug('Now processing..:' || l_instance_id);
12518 END IF;
12519
12520 -- Call Process Unit for the item instance.
12521 Process_Unit (
12522 p_commit => p_commit_flag,
12523 p_init_msg_list => FND_API.G_TRUE,
12524 x_msg_count => x_msg_count,
12525 x_msg_data => x_msg_data,
12526 x_return_status => x_return_status,
12527 p_csi_item_instance_id => l_instance_id,
12528 p_concurrent_flag => p_concurrent_flag,
12529 -- added sim plan for NR Analysis Enh.
12530 p_simulation_plan_id => G_SIMULATION_PLAN_ID);
12531
12532 IF ( x_return_status <> FND_API.G_RET_STS_SUCCESS) AND (p_commit_flag = FND_API.G_FALSE) THEN
12533 EXIT;
12534 END IF;
12535
12536 END LOOP;
12537
12538 -- cleanup worker table after processing.
12539 Cleanup_BUE_Worker(p_parent_conc_request_id => l_conc_req_id,
12540 p_child_conc_request_id => l_conc_req_id,
12541 x_return_status => l_return_status,
12542 x_errbuf => l_err_mesg);
12543 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12544 -- ignore error returned from this procedure
12545 IF G_DEBUG = 'Y' THEN
12546 AHL_DEBUG_PUB.debug('Warning: Error from Cleanup_BUE_Worker:' || l_err_mesg);
12547 END IF;
12548 END IF;
12549
12550 END IF;
12551
12552 IF G_debug = 'Y' THEN
12553 AHL_DEBUG_PUB.debug('End Split_Process_All_Instances:Return Status:' || x_return_status);
12554 END IF;
12555
12556 END Split_Process_All_Instances;
12557
12558 ----------------------------------------------
12559 -- BUE Worker program for AHL processing.
12560 -- Called from BUE concurrent pgm when all units option is chosen..
12561 -- or when BUE is run for an MR or MR revision.
12562 PROCEDURE Process_Unit_Range (errbuf OUT NOCOPY VARCHAR2,
12563 retcode OUT NOCOPY NUMBER,
12564 p_parent_conc_pgm_id IN NUMBER)
12565 IS
12566
12567 -- JKJain, NR Analysis and Forecasting
12568 CURSOR get_sim_plan_id (p_parent_conc_pgm_id IN NUMBER)
12569 IS
12570 SELECT simulation_plan_id
12571 FROM ahl_bue_worker_data
12572 WHERE parent_conc_request_id = p_parent_conc_pgm_id
12573 AND child_conc_request_id IS NULL;
12574
12575 l_simulation_plan_id NUMBER := NULL;
12576 -- End NR Analysis and Forecasting
12577
12578 l_instance_id NUMBER;
12579 l_conc_child_req_id NUMBER;
12580
12581 l_msg_count NUMBER;
12582 l_msg_data VARCHAR2(3000);
12583 l_return_status VARCHAR2(1);
12584
12585 BEGIN
12586
12587 fnd_file.put_line(FND_FILE.LOG,'Start time:' || to_char(sysdate, 'Month DD, YYYY HH24:MI:SS'));
12588
12589 G_DEBUG_LINE_NUM := 1;
12590
12591 -- initialize return status.
12592 retcode := 0;
12593
12594 l_conc_child_req_id := fnd_global.conc_request_id;
12595
12596 -- JKJain, NR Analysis and Forecasting
12597 --Fetch simulation_plan_id for the first record.
12598 OPEN get_sim_plan_id(p_parent_conc_pgm_id);
12599 FETCH get_sim_plan_id into l_simulation_plan_id;
12600 CLOSE get_sim_plan_id;
12601
12602 IF G_debug = 'Y' THEN
12603 AHL_DEBUG_PUB.debug('Start Process_Unit_Range for concurrent pgm ID:' || l_conc_child_req_id);
12604 AHL_DEBUG_PUB.debug('Parent concurrent pgm ID:' || p_parent_conc_pgm_id);
12605 -- JKJain, NR Analysis and Forecasting
12606 AHL_DEBUG_PUB.debug('Process_Unit_Range => p_simulation_plan_id :' || l_simulation_plan_id);
12607
12608 END IF;
12609
12610 -- AHL processing.
12611 LOOP
12612 -- initialize return status.
12613 l_return_status := FND_API.G_RET_STS_SUCCESS;
12614
12615 G_DEBUG_LINE_NUM := 10;
12616
12617 -- get next unit to process.
12618 Get_Next_BUE_Row(p_parent_conc_pgm_id => p_parent_conc_pgm_id,
12619 p_conc_child_req_id => l_conc_child_req_id,
12620 x_return_status => l_return_status,
12621 errbuf => errbuf,
12622 x_item_instance_id => l_instance_id);
12623
12624 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12625 EXIT;
12626 END IF;
12627
12628 EXIT WHEN (l_instance_id IS NULL);
12629
12630 fnd_file.new_line(FND_FILE.LOG,1);
12631 fnd_file.put_line(FND_FILE.LOG,'Now processing..:' || l_instance_id);
12632 fnd_file.put_line(FND_FILE.LOG,'Start time:' || to_char(sysdate, 'Month DD, YYYY HH24:MI:SS'));
12633
12634 G_DEBUG_LINE_NUM := 20;
12635
12636 -- Call Process Unit for the item instance.
12637 Process_Unit (
12638 p_commit => FND_API.G_TRUE,
12639 p_init_msg_list => FND_API.G_TRUE,
12640 x_msg_count => l_msg_count,
12641 x_msg_data => l_msg_data,
12642 x_return_status => l_return_status,
12643 p_csi_item_instance_id => l_instance_id,
12644 p_concurrent_flag => 'Y',
12645 -- JKJain, NR Analysis and Forecasting
12646 p_simulation_plan_id => l_simulation_plan_id);
12647
12648 fnd_file.put_line(FND_FILE.LOG,'End time:' || to_char(sysdate, 'Month DD, YYYY HH24:MI:SS'));
12649
12650 l_msg_count := FND_MSG_PUB.Count_Msg;
12651 IF (retcode <> 2 AND l_return_status <> FND_API.G_RET_STS_SUCCESS)
12652 THEN
12653 retcode := 2; -- error based only on return status
12654 ELSIF (retcode = 0 AND l_msg_count > 0 AND l_return_status = FND_API.G_RET_STS_SUCCESS)
12655 THEN
12656 retcode := 1; -- warning based on return status + msg count
12657 END IF;
12658
12659 END LOOP;
12660
12661 G_DEBUG_LINE_NUM := 30;
12662
12663 -- cleanup worker table after processing.
12664 Cleanup_BUE_Worker(p_parent_conc_request_id => p_parent_conc_pgm_id,
12665 p_child_conc_request_id => l_conc_child_req_id,
12666 x_return_status => l_return_status,
12667 x_errbuf => l_msg_data);
12668 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12669 -- ignore error returned from this procedure
12670 -- log message in concurrent request log.
12671 fnd_file.put_line(FND_FILE.LOG, 'Warning: Error from Cleanup_BUE_Worker:' || l_msg_data);
12672 retcode := 1; -- warning based on return status
12673 END IF;
12674
12675
12676 IF G_debug = 'Y' THEN
12677 AHL_DEBUG_PUB.debug('Concurrent pgm retcode:' || retcode);
12678 AHL_DEBUG_PUB.debug('Concurrent pgm l_return_status:' || l_return_status);
12679 AHL_DEBUG_PUB.debug('End Process_Unit_Range for concurrent pgm ID:' || l_conc_child_req_id);
12680 END IF;
12681
12682 --
12683 EXCEPTION
12684 WHEN FND_API.G_EXC_ERROR THEN
12685 retcode := 2;
12686 errbuf := 'Process_Unit_Range:EXC:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,60);
12687
12688 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
12689 retcode := 2;
12690 errbuf := 'Process_Unit_Range:UNEXP:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,60);
12691
12692 WHEN OTHERS THEN
12693 IF (SQLCODE = -54) THEN
12694 retcode := 1;
12695 errbuf := 'Process_Unit_Range:54:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,60);
12696 ELSIF (SQLCODE = -6519) THEN
12697 retcode := 1;
12698 errbuf := 'Process_Unit_Range:6519:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,60);
12699 ELSE
12700 retcode := 2;
12701 errbuf := 'Process_Unit_Range:OTH:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,60);
12702 END IF;
12703
12704 END Process_Unit_Range;
12705 ------------------------
12706 -- BUE Worker program for AHL processing.
12707 -- This procedure is called after a MR is revised.
12708 PROCEDURE Process_Unit_Range (errbuf OUT NOCOPY VARCHAR2,
12709 retcode OUT NOCOPY NUMBER,
12710 p_old_mr_header_id IN NUMBER,
12711 p_new_mr_header_id IN NUMBER)
12712
12713 IS
12714
12715 l_return_status varchar2(1);
12716 l_msg_count number;
12717 l_msg_data varchar2(2000);
12718
12719 BEGIN
12720
12721 fnd_file.put_line(FND_FILE.LOG,'Start time:' || to_char(sysdate, 'Month DD, YYYY HH24:MI:SS'));
12722
12723 IF G_debug = 'Y' THEN
12724 AHL_DEBUG_PUB.debug('Start Process_Unit_Range for MR: Old ID:New ID:' || p_old_mr_header_id || ':' || p_new_mr_header_id);
12725 END IF;
12726
12727 -- initialize return status.
12728 retcode := 0;
12729
12730 -- After commit call UMP BUE api to build UEs.
12731 AHL_UMP_PROCESSUNIT_PVT.Process_MRAffected_Units (
12732 p_commit => FND_API.G_TRUE,
12733 x_msg_count => l_msg_count,
12734 x_msg_data => l_msg_data,
12735 x_return_status => l_return_status, -- ignore status returned by this api.
12736 p_old_mr_header_id => p_old_mr_header_id,
12737 p_mr_header_id => p_new_mr_header_id,
12738 p_concurrent_flag => 'Y',
12739 p_num_of_workers => 5);
12740
12741 l_msg_count := FND_MSG_PUB.Count_Msg;
12742 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS)
12743 THEN
12744 retcode := 2; -- error based only on return status
12745 log_error_messages;
12746 ELSIF (l_msg_count > 0 AND l_return_status = FND_API.G_RET_STS_SUCCESS)
12747 THEN
12748 retcode := 1; -- warning based on return status + msg count
12749 log_error_messages;
12750 END IF;
12751
12752 IF G_debug = 'Y' THEN
12753 AHL_DEBUG_PUB.debug('End Process_Unit_Range for MR: retcode:' || retcode);
12754 END IF;
12755
12756 --
12757 EXCEPTION
12758 WHEN FND_API.G_EXC_ERROR THEN
12759 retcode := 2;
12760 errbuf := 'Process_Unit_Range:MR:EXC:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,60);
12761
12762 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
12763 retcode := 2;
12764 errbuf := 'Process_Unit_Range:MR:UNEXP:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,60);
12765
12766 WHEN OTHERS THEN
12767 IF (SQLCODE = -54) THEN
12768 retcode := 1;
12769 errbuf := 'Process_Unit_Range:54:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,70);
12770 ELSIF (SQLCODE = -6519) THEN
12771 retcode := 1;
12772 errbuf := 'Process_Unit_Range:6519:' || G_DEBUG_LINE_NUM || ':' || substrb(sqlerrm,1,70);
12773 ELSE
12774 retcode := 2;
12775 errbuf := 'Process_Unit_Range:MR:OTH:' || substrb(sqlerrm,1,60);
12776 END IF;
12777
12778 END Process_Unit_Range;
12779
12780 ------------------------
12781 -- Added for performance bug# 6893404.
12782 PROCEDURE Populate_BUE_Worker(p_conc_request_id IN NUMBER,
12783 p_concurrent_flag IN VARCHAR2,
12784 p_mtl_category_id IN NUMBER,
12785 p_process_option IN VARCHAR2,
12786 errbuf OUT NOCOPY VARCHAR2,
12787 x_return_status OUT NOCOPY VARCHAR2)
12788 IS
12789 PRAGMA AUTONOMOUS_TRANSACTION;
12790
12791 l_instance_id_tbl nbr_tbl_type;
12792 l_unit_name_tbl vchar_tbl_type;
12793
12794 -- get all valid uc headers
12795 -- It is possible to have UC with parent_uc_header_id as NULL but
12796 -- installed on a instance which is not a UC.
12797 -- see second issue reported in bug# 8326078
12798 CURSOR ahl_unit_config_header_csr IS
12799 SELECT csi_item_instance_id
12800 FROM ahl_unit_config_headers uc, csi_item_instances ii
12801 WHERE uc.csi_item_instance_id = ii.instance_id
12802 AND trunc(nvl(uc.active_start_date,sysdate)) <= trunc(sysdate)
12803 AND trunc(sysdate) < trunc(nvl(uc.active_end_date,sysdate+1))
12804 AND trunc(nvl(ii.active_start_date,sysdate)) <= trunc(sysdate)
12805 AND sysdate < nvl(ii.active_end_date,sysdate+1)
12806 AND unit_config_status_code <> 'DRAFT'
12807 AND parent_uc_header_id IS NULL
12808 AND NOT EXISTS (select 'x'
12809 from csi_ii_relationships iir
12810 where iir.relationship_type_code = 'COMPONENT-OF'
12811 and iir.subject_id = uc.csi_item_instance_id
12812 and trunc(nvl(iir.active_start_date, sysdate)) <= trunc(sysdate)
12813 and trunc(sysdate) < trunc(nvl(iir.active_end_date,sysdate+1))
12814 );
12815
12816 -- get all valid uc headers that match item category.
12817 -- It is possible to have UC with parent_uc_header_id as NULL but
12818 -- installed on a instance which is not a UC.
12819 -- see second issue reported in bug# 8326078
12820 CURSOR ahl_unit_itemcat_csr(p_mtl_category_id IN NUMBER) IS
12821 SELECT csi_item_instance_id
12822 FROM ahl_unit_config_headers uc, csi_item_instances ii
12823 WHERE uc.csi_item_instance_id = ii.instance_id
12824 AND trunc(nvl(uc.active_start_date,sysdate)) <= trunc(sysdate)
12825 AND trunc(sysdate) < trunc(nvl(uc.active_end_date,sysdate+1))
12826 AND trunc(nvl(ii.active_start_date,sysdate)) <= trunc(sysdate)
12827 AND sysdate < nvl(ii.active_end_date,sysdate+1)
12828 AND unit_config_status_code <> 'DRAFT'
12829 AND parent_uc_header_id IS NULL
12830 AND NOT EXISTS (select 'x'
12831 from csi_ii_relationships iir
12832 where iir.relationship_type_code = 'COMPONENT-OF'
12833 and iir.subject_id = uc.csi_item_instance_id
12834 and trunc(nvl(iir.active_start_date, sysdate)) <= trunc(sysdate)
12835 and trunc(sysdate) < trunc(nvl(iir.active_end_date,sysdate+1))
12836 )
12837 AND exists (select 'x'
12838 from mtl_category_set_valid_cats cs, mtl_item_categories itc,
12839 csi_item_instances cii2
12840 where cs.category_set_id = fnd_profile.value('AHL_BUE_ITEM_CATEGORY_SET')
12841 AND cs.category_set_id = itc.category_set_id
12842 AND cs.category_id = itc.category_id
12843 AND itc.category_id = p_mtl_category_id
12844 AND cii2.instance_id = uc.csi_item_instance_id
12845 AND itc.organization_id = cii2.inv_master_organization_id
12846 AND itc.inventory_item_id = cii2.inventory_item_id
12847 ); -- get units matching item category.
12848
12849
12850 -- get item instances matching inventory item id.
12851 -- when no item category and process option = 'Units or Components' or all
12852 CURSOR get_uc_item_inst_csr(p_opt_uc IN NUMBER) IS
12853 SELECT instance_id from
12854 (SELECT DISTINCT nvl(root_instance_id, instance_id) instance_id from
12855 (
12856 SELECT cii.instance_id,
12857 (select object_id from csi_ii_relationships parent
12858 where not exists (select 'x' from csi_ii_relationships
12859 where subject_id = parent.object_id and
12860 relationship_type_code = 'COMPONENT-OF' and
12861 trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate) and
12862 trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1)))
12863 start with parent.subject_id = cii.instance_id and
12864 parent.relationship_type_code = 'COMPONENT-OF' and
12865 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
12866 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
12867 connect by prior parent.object_id = parent.subject_id and
12868 parent.relationship_type_code = 'COMPONENT-OF' and
12869 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
12870 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
12871 ) Root_instance_id
12872
12873 FROM csi_item_instances cii, ahl_mr_effectivities mre
12874 WHERE mre.inventory_item_id = nvl(null, mre.inventory_item_id)
12875 AND mre.mr_header_id = nvl(null,mre.mr_header_id)
12876 -- added nvl conditions above as this seems to force use of index on
12877 -- ahl_mr_headers_b and also brings query cost down.
12878 AND mre.relationship_id is null
12879 AND mre.inventory_item_id = cii.inventory_item_id
12880 AND exists (SELECT 'x' from ahl_mr_headers_app_v MR
12881 WHERE MR.mr_header_id = mre.mr_header_id
12882 AND MR.program_type_code NOT IN ('MO_PROC')
12883 AND MR.version_number in (SELECT max(MRM.version_number)
12884 FROM ahl_mr_headers_app_v MRM
12885 WHERE mrm.title = mr.title
12886 AND SYSDATE between trunc(MR.effective_from)
12887 AND trunc(nvl(MR.effective_to,SYSDATE+1))
12888 AND mr_status_code='COMPLETE'
12889 )
12890 )
12891 AND trunc(nvl(cii.active_start_date, sysdate)) <= trunc(sysdate)
12892 AND trunc(sysdate) < trunc(nvl(cii.active_end_date, sysdate+1))
12893 )
12894 ) valid_inst
12895 WHERE /*(p_opt_uc = 1 AND exists (select 'x' from ahl_unit_config_headers
12896 where csi_item_instance_id = valid_inst.instance_id
12897 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
12898 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
12899 AND unit_config_status_code <> 'DRAFT'
12900 AND parent_uc_header_id IS NULL
12901 ) -- get UCs only.
12902 )
12903 OR */ -- this cursor is not used when p_opt_uc = 1
12904 -- get components.
12905 (p_opt_uc = 2 AND not exists (select 'x' from ahl_unit_config_headers
12906 where csi_item_instance_id = valid_inst.instance_id
12907 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
12908 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
12909 -- instance is a UC if in status draft.
12910 --AND unit_config_status_code <> 'DRAFT'
12911 --AND parent_uc_header_id IS NULL
12912 )
12913 )
12914 OR
12915 -- get all but ignore UCs as they have alredy been selected.
12916 (p_opt_uc = 0 AND not exists (select 'x' from ahl_unit_config_headers
12917 where csi_item_instance_id = valid_inst.instance_id
12918 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
12919 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
12920 -- instance is a UC if in status draft.
12921 --AND unit_config_status_code <> 'DRAFT'
12922 --AND parent_uc_header_id IS NULL
12923 )
12924 );
12925
12926 -- get item instances matching inventory item id, item cat and is a UC.
12927 -- when item category selected with process option of ALL, Units or Components.
12928 CURSOR get_uc_itemcat_inst_csr (p_mtl_category_id IN NUMBER,
12929 p_opt_uc IN NUMBER) IS
12930 SELECT instance_id from
12931 (SELECT DISTINCT nvl(root_instance_id, instance_id) instance_id from
12932 (
12933 SELECT cii.instance_id,
12934 (select object_id from csi_ii_relationships parent
12935 where not exists (select 'x' from csi_ii_relationships
12936 where subject_id = parent.object_id and
12937 relationship_type_code = 'COMPONENT-OF' and
12938 trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate) and
12939 trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1)))
12940 start with parent.subject_id = cii.instance_id and
12941 parent.relationship_type_code = 'COMPONENT-OF' and
12942 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
12943 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
12944 connect by prior parent.object_id = parent.subject_id and
12945 parent.relationship_type_code = 'COMPONENT-OF' and
12946 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
12947 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
12948 ) Root_instance_id
12949
12950 FROM csi_item_instances cii,
12951 (select distinct me.inventory_item_id
12952 from ahl_mr_headers_app_v mr, ahl_mr_effectivities me
12953 where mr.mr_header_id = me.mr_header_id AND
12954 mr.mr_status_code = 'COMPLETE' AND
12955 MR.program_type_code NOT IN ('MO_PROC') AND -- added in R12
12956 trunc(effective_from) <= trunc(sysdate) AND
12957 trunc(nvl(effective_to,sysdate)) >= trunc(sysdate)
12958 and me.inventory_item_id is not null
12959 ) mre
12960 WHERE trunc(nvl(cii.active_start_date, sysdate)) <= trunc(sysdate) AND
12961 trunc(sysdate) < trunc(nvl(cii.active_end_date, sysdate+1))
12962 AND mre.inventory_item_id = cii.inventory_item_id
12963 )
12964 ) valid_inst
12965 WHERE exists (select 'x'
12966 from mtl_category_set_valid_cats cs, mtl_item_categories itc,
12967 csi_item_instances cii2
12968 where cs.category_set_id = fnd_profile.value('AHL_BUE_ITEM_CATEGORY_SET')
12969 AND cs.category_set_id = itc.category_set_id
12970 AND cs.category_id = itc.category_id
12971 AND itc.category_id = p_mtl_category_id
12972 AND cii2.instance_id = valid_inst.instance_id
12973 AND itc.organization_id = cii2.inv_master_organization_id
12974 AND itc.inventory_item_id = cii2.inventory_item_id
12975 ) -- get root nodes matching item category.
12976
12977 AND ((p_opt_uc = 1 AND exists (select 'x' from ahl_unit_config_headers
12978 where csi_item_instance_id = valid_inst.instance_id
12979 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
12980 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
12981 AND unit_config_status_code <> 'DRAFT'
12982 AND parent_uc_header_id IS NULL
12983 ) -- get UCs only.
12984 )
12985 OR
12986 -- get components.
12987 (p_opt_uc = 2 AND not exists (select 'x' from ahl_unit_config_headers
12988 where csi_item_instance_id = valid_inst.instance_id
12989 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
12990 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
12991 -- instance is a UC if in status draft.
12992 --AND unit_config_status_code <> 'DRAFT'
12993 --AND parent_uc_header_id IS NULL
12994 )
12995 )
12996 OR
12997 -- when process option is ALL.
12998 -- get components in this case too as UC's have already been selected.
12999 (p_opt_uc = 0 AND not exists (select 'x' from ahl_unit_config_headers
13000 where csi_item_instance_id = valid_inst.instance_id
13001 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
13002 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
13003 -- instance is a UC if in status draft.
13004 --AND unit_config_status_code <> 'DRAFT'
13005 --AND parent_uc_header_id IS NULL
13006 )
13007 )
13008 );
13009
13010 -- added to fix bug#8543402
13011 -- check if UMP data exists for expired instances.
13012 CURSOR chk_expire_inst_csr IS
13013 SELECT cii.instance_id
13014 FROM csi_item_instances cii,
13015 (select distinct me.inventory_item_id
13016 from ahl_mr_headers_app_v mr, ahl_mr_effectivities me
13017 where mr.mr_header_id = me.mr_header_id AND
13018 mr.mr_status_code = 'COMPLETE' AND
13019 MR.program_type_code NOT IN ('MO_PROC') AND -- added in R12
13020 trunc(effective_from) <= trunc(sysdate) AND
13021 trunc(nvl(effective_to,sysdate)) >= trunc(sysdate)
13022 and me.inventory_item_id is not null
13023 ) mre
13024 WHERE cii.active_end_date <= sysdate
13025 AND mre.inventory_item_id = cii.inventory_item_id
13026 AND EXISTS (select 'x' from ahl_unit_effectivities_b UE
13027 where ue.csi_item_instance_id = cii.instance_id
13028 and (ue.status_code IS NULL OR ue.status_code IN ('INIT-DUE','EXCEPTION'))
13029 );
13030
13031 -- JKJain, NR Analysis and Forecasting
13032 -- get all valid uc headers in a simulation plan
13033 CURSOR get_sim_plan_uc_root_csr (c_simulation_plan_id IN NUMBER)IS
13034 SELECT distinct UC.csi_item_instance_id
13035 from AHL_UNIT_CONFIG_HEADERS UC, AHL_FLEET_UNIT_ASSOCS FU
13036 WHERE FU.simulation_plan_id = c_simulation_plan_id
13037 and UC.UNIT_CONFIG_HEADER_ID = FU.UNIT_CONFIG_HEADER_ID
13038 and nvl(FU.association_end,sysdate) >= sysdate ;
13039
13040 l_buffer_limit number := 5000;
13041 l_opt_uc number;
13042
13043 dml_errors EXCEPTION;
13044 PRAGMA EXCEPTION_INIT(dml_errors, -24381);
13045
13046 BEGIN
13047
13048 IF G_debug = 'Y' THEN
13049 AHL_DEBUG_PUB.debug('Start Populate_BUE_Worker for pgm ID:' || p_conc_request_id);
13050 AHL_DEBUG_PUB.debug('Concurrent flag:' || p_concurrent_flag);
13051 END IF;
13052
13053 -- initialize return status.
13054 x_return_status := FND_API.G_RET_STS_SUCCESS;
13055
13056 IF (p_process_option = 'AHL_BUE_ALL_COMPONENTS') THEN
13057 l_opt_uc := 2;
13058 -- JKJain, NR Analysis and Forecasting
13059 ELSIF (p_process_option = 'AHL_BUE_ALL_UNITS' OR G_PRIMARY_PLAN = 'N') THEN
13060 l_opt_uc := 1;
13061 ELSE
13062 l_opt_uc := 0; -- when opt is null or AHL_BUE_ALL
13063 END IF;
13064
13065 -- get all unit configurations.
13066 IF (l_opt_uc IN (0,1)) THEN
13067
13068 -- JKJain, NR Analysis and Forecasting
13069 IF (G_PRIMARY_PLAN = 'N') THEN
13070 OPEN get_sim_plan_uc_root_csr(G_SIMULATION_PLAN_ID);
13071 ELSIF (p_mtl_category_id IS NULL) THEN
13072 OPEN ahl_unit_config_header_csr;
13073 ELSE
13074 OPEN ahl_unit_itemcat_csr(p_mtl_category_id);
13075 END IF;
13076
13077 LOOP
13078 -- JKJain, NR Analysis and Forecasting
13079 IF (G_PRIMARY_PLAN = 'N') THEN
13080 FETCH get_sim_plan_uc_root_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13081 ELSIF (p_mtl_category_id IS NULL) THEN
13082 FETCH ahl_unit_config_header_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13083 ELSE
13084 FETCH ahl_unit_itemcat_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13085 END IF;
13086
13087 EXIT WHEN (l_instance_id_tbl.count = 0);
13088
13089 -- insert into BUE table.
13090 FORALL instance_indx IN l_instance_id_tbl.FIRST..l_instance_id_tbl.LAST
13091 INSERT INTO AHL_BUE_WORKER_DATA
13092 (parent_conc_request_id,
13093 csi_item_instance_id,
13094 child_conc_request_id,
13095 last_update_date,
13096 last_updated_by,
13097 creation_date,
13098 created_by,
13099 last_update_login,
13100 object_version_number,
13101 -- JKJain, NR Analysis and Forecasting
13102 simulation_plan_id) VALUES
13103 (p_conc_request_id,
13104 l_instance_id_tbl(instance_indx),
13105 null,
13106 sysdate,
13107 fnd_global.user_id,
13108 sysdate,
13109 fnd_global.user_id,
13110 fnd_global.conc_login_id,
13111 1,
13112 G_SIMULATION_PLAN_ID);
13113
13114 l_instance_id_tbl.DELETE;
13115
13116 END LOOP;
13117
13118 -- JKJain, NR Analysis and Forecasting
13119 IF (G_PRIMARY_PLAN = 'N') THEN
13120 CLOSE get_sim_plan_uc_root_csr;
13121 ELSIF (p_mtl_category_id IS NULL) THEN
13122 CLOSE ahl_unit_config_header_csr;
13123 ELSE
13124 CLOSE ahl_unit_itemcat_csr;
13125 END IF;
13126
13127 END IF; -- (l_opt_uc IN (0,1))
13128
13129 IF (l_opt_uc <> 1) THEN -- skip when only processing units.
13130 -- now process instances based on inventory_item_id.
13131 IF (p_mtl_category_id IS NULL) THEN
13132 OPEN get_uc_item_inst_csr(l_opt_uc);
13133 ELSE
13134 OPEN get_uc_itemcat_inst_csr(p_mtl_category_id, l_opt_uc);
13135 END IF;
13136
13137 LOOP
13138 IF (p_mtl_category_id IS NULL) THEN
13139 FETCH get_uc_item_inst_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13140 ELSE
13141 FETCH get_uc_itemcat_inst_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13142 END IF;
13143
13144 EXIT WHEN (l_instance_id_tbl.count = 0);
13145
13146 BEGIN
13147 -- insert into BUE table.
13148 FORALL instance_indx IN l_instance_id_tbl.FIRST..l_instance_id_tbl.LAST SAVE EXCEPTIONS
13149 INSERT INTO AHL_BUE_WORKER_DATA
13150 (parent_conc_request_id,
13151 csi_item_instance_id,
13152 child_conc_request_id,
13153 last_update_date,
13154 last_updated_by,
13155 creation_date,
13156 created_by,
13157 last_update_login,
13158 object_version_number,
13159 -- JKJain, NR Analysis and Forecasting
13160 simulation_plan_id) VALUES
13161 (p_conc_request_id,
13162 l_instance_id_tbl(instance_indx),
13163 null,
13164 sysdate,
13165 fnd_global.user_id,
13166 sysdate,
13167 fnd_global.user_id,
13168 fnd_global.conc_login_id,
13169 1,
13170 -- JKJain, NR Analysis and Forecasting
13171 G_SIMULATION_PLAN_ID);
13172
13173 EXCEPTION
13174 WHEN DML_ERRORS THEN
13175 IF (get_uc_item_inst_csr%ISOPEN) THEN
13176 CLOSE get_uc_item_inst_csr;
13177 END IF;
13178 IF (get_uc_itemcat_inst_csr%ISOPEN) THEN
13179 CLOSE get_uc_itemcat_inst_csr;
13180 END IF;
13181
13182 x_return_status := 'E';
13183
13184 IF (p_concurrent_flag = 'Y') THEN
13185 fnd_file.put_line(fnd_file.log, 'Following error(s) occured while inserting into table ahl_bue_worker_data');
13186 FOR j IN 1..sql%bulk_exceptions.count
13187 LOOP
13188 fnd_file.put_line(fnd_file.log, sql%bulk_exceptions(j).error_index || ', ' ||
13189 sqlerrm(-sql%bulk_exceptions(j).error_code) );
13190 END LOOP;
13191 END IF;
13192
13193 FND_MESSAGE.set_name('AHL', 'AHL_UMP_BUE_WORKER_ERR');
13194 FND_MSG_PUB.add;
13195 errbuf := FND_MSG_PUB.Get;
13196
13197 RETURN;
13198 END;
13199
13200 l_instance_id_tbl.DELETE;
13201
13202 END LOOP;
13203
13204 IF (p_mtl_category_id IS NULL) THEN
13205 CLOSE get_uc_item_inst_csr;
13206 ELSE
13207 CLOSE get_uc_itemcat_inst_csr;
13208 END IF;
13209 END IF; -- l_opt_uc
13210
13211 IF(G_PRIMARY_PLAN <> 'N') THEN -- bug 13739681
13212 -- process expired instances.
13213 l_instance_id_tbl.DELETE;
13214
13215 OPEN chk_expire_inst_csr;
13216 LOOP
13217 FETCH chk_expire_inst_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13218 EXIT WHEN (l_instance_id_tbl.count = 0);
13219
13220 BEGIN
13221 -- insert into BUE table.
13222 FORALL instance_indx IN l_instance_id_tbl.FIRST..l_instance_id_tbl.LAST SAVE EXCEPTIONS
13223 INSERT INTO AHL_BUE_WORKER_DATA
13224 (parent_conc_request_id,
13225 csi_item_instance_id,
13226 child_conc_request_id,
13227 last_update_date,
13228 last_updated_by,
13229 creation_date,
13230 created_by,
13231 last_update_login,
13232 object_version_number) VALUES
13233 (p_conc_request_id,
13234 l_instance_id_tbl(instance_indx),
13235 null,
13236 sysdate,
13237 fnd_global.user_id,
13238 sysdate,
13239 fnd_global.user_id,
13240 fnd_global.conc_login_id,
13241 1);
13242
13243 EXCEPTION
13244 WHEN DML_ERRORS THEN
13245 IF (chk_expire_inst_csr%ISOPEN) THEN
13246 CLOSE chk_expire_inst_csr;
13247 END IF;
13248
13249 x_return_status := 'E';
13250
13251 IF (p_concurrent_flag = 'Y') THEN
13252 fnd_file.put_line(fnd_file.log, 'Following error(s) occured while inserting into table ahl_bue_worker_data');
13253 FOR j IN 1..sql%bulk_exceptions.count
13254 LOOP
13255 fnd_file.put_line(fnd_file.log, sql%bulk_exceptions(j).error_index || ', ' ||
13256 sqlerrm(-sql%bulk_exceptions(j).error_code) );
13257 END LOOP;
13258 END IF;
13259
13260 FND_MESSAGE.set_name('AHL', 'AHL_UMP_BUE_WORKER_ERR');
13261 FND_MSG_PUB.add;
13262 errbuf := FND_MSG_PUB.Get;
13263
13264 RETURN;
13265 END;
13266
13267 l_instance_id_tbl.DELETE;
13268
13269 END LOOP;
13270 CLOSE chk_expire_inst_csr;
13271 END IF; -- G_PRIMARY_PLAN <> 'N'
13272
13273 -- delete duplicate rows.
13274 /* fix for performance bug# 16003176 (10g to 11g upgrade)
13275 DELETE FROM ahl_bue_worker_data
13276 WHERE parent_conc_request_id = p_conc_request_id
13277 AND rowid not in (SELECT MIN(rowid)
13278 FROM ahl_bue_worker_data
13279 WHERE parent_conc_request_id = p_conc_request_id
13280 GROUP BY csi_item_instance_id, parent_conc_request_id) ;
13281 */
13282 --DELETE FROM ahl_bue_worker_data wrk1
13283 --WHERE wrk1.parent_conc_request_id = p_conc_request_id
13284 -- AND wrk1.rowid > ANY ( SELECT wrk2.rowid
13285 -- FROM ahl_bue_worker_data wrk2
13286 -- WHERE wrk2.parent_conc_request_id = p_conc_request_id
13287 -- AND wrk2.csi_item_instance_id = wrk1.csi_item_instance_id) ;
13288
13289 --DELETE FROM ahl_bue_worker_data ad1
13290 --WHERE ad1.parent_conc_request_id = p_conc_request_id
13291 -- AND ad1.rowid not in (SELECT /*+ UNNEST INDEX(ad2 AHL_BUE_WORKER_DATA_N2) */ MIN(ad2.rowid)
13292 -- FROM ahl_bue_worker_data ad2
13293 -- WHERE ad2.parent_conc_request_id = p_conc_request_id
13294 -- GROUP BY ad2.csi_item_instance_id, ad2.parent_conc_request_id) ;
13295
13296 --delete /*+ rowid(a) use_nl(a) */
13297 -- from ahl_bue_worker_data a
13298 -- where rowid in
13299 -- (select /*+ unnest */ rowid
13300 -- from
13301 -- (select /*+ parallel(b) cardinality(b,10) */
13302 -- rowid, row_number() over (partition by
13303 -- csi_item_instance_id, parent_conc_request_id
13304 -- order by 1
13305 -- ) dup
13306 -- from ahl_bue_worker_data b
13307 -- where b.parent_conc_request_id = p_conc_request_id)
13308 -- where dup > 1);
13309
13310 DELETE /*+ parallel(a) */ FROM ahl_bue_worker_data a
13311 where a.parent_conc_request_id = p_conc_request_id
13312 and exists (select 'x' from ahl_bue_worker_data b
13313 where b.parent_conc_request_id = a.parent_conc_request_id
13314 and b.csi_item_instance_id = a.csi_item_instance_id
13315 and b.rowid > a.rowid);
13316
13317 -- save changes.
13318 COMMIT WORK;
13319
13320 IF G_debug = 'Y' THEN
13321 AHL_DEBUG_PUB.debug('Concurrent pgm x_return_status:' || x_return_status);
13322 AHL_DEBUG_PUB.debug('End Populate_BUE_Worker for pgm ID:' || p_conc_request_id);
13323 END IF;
13324
13325 END Populate_BUE_Worker;
13326
13327 -- Added for performance bug# 6893404.
13328 PROCEDURE Get_Next_BUE_Row(p_parent_conc_pgm_id IN NUMBER,
13329 p_conc_child_req_id IN NUMBER,
13330 x_return_status OUT NOCOPY VARCHAR2,
13331 errbuf OUT NOCOPY VARCHAR2,
13332 x_item_instance_id OUT NOCOPY NUMBER)
13333 IS
13334
13335 PRAGMA AUTONOMOUS_TRANSACTION;
13336
13337 -- added hint to resolve perf bug# 16003176
13338 CURSOR ahl_bue_worker_csr (p_parent_conc_pgm_id IN NUMBER)
13339 IS
13340 SELECT /*+ INDEX(BUEWD AHL_BUE_WORKER_DATA_N1) */ BUEWD.rowid, BUEWD.csi_item_instance_id, BUEWD.object_version_number
13341 FROM ahl_bue_worker_data BUEWD
13342 WHERE BUEWD.parent_conc_request_id = p_parent_conc_pgm_id
13343 AND BUEWD.child_conc_request_id IS NULL;
13344 --FOR UPDATE OF child_conc_request_id;
13345
13346 CURSOR bue_lock_row (p_rowid IN urowid, p_parent_conc_pgm_id IN NUMBER )
13347 IS
13348 SELECT rowid, csi_item_instance_id
13349 FROM ahl_bue_worker_data
13350 WHERE parent_conc_request_id = p_parent_conc_pgm_id
13351 AND child_conc_request_id IS NULL
13352 AND ROWID = p_rowid
13353 FOR UPDATE OF child_conc_request_id NOWAIT;
13354
13355 l_instance_id NUMBER;
13356
13357 record_locked EXCEPTION;
13358 pragma exception_init (record_locked, -54);
13359
13360 l_status NUMBER;
13361 l_rowid UROWID;
13362 l_object_version_number NUMBER;
13363
13364 BEGIN
13365 IF G_debug = 'Y' THEN
13366 AHL_DEBUG_PUB.debug('Start Get_Next_BUE_Row: Parent Conc Request ID:' || p_parent_conc_pgm_id);
13367 AHL_DEBUG_PUB.debug('Child Conc Request ID:' || p_conc_child_req_id);
13368 END IF;
13369
13370 --DBMS_LOCK.SLEEP(60);
13371
13372 -- get next unprocessed row.
13373 OPEN ahl_bue_worker_csr(p_parent_conc_pgm_id);
13374 LOOP
13375 l_status := 0;
13376 BEGIN
13377 FETCH ahl_bue_worker_csr INTO l_rowid, l_instance_id, l_object_version_number;
13378 IF (ahl_bue_worker_csr%FOUND) THEN
13379 -- lock row
13380 OPEN bue_lock_row(l_rowid, p_parent_conc_pgm_id);
13381 FETCH bue_lock_row into l_rowid, l_instance_id;
13382 IF (bue_lock_row%FOUND) THEN
13383 -- update only if ovn remains the same.
13384 UPDATE ahl_bue_worker_data
13385 set child_conc_request_id = p_conc_child_req_id,
13386 last_update_date = sysdate,
13387 object_version_number = object_version_number + 1,
13388 last_update_login = fnd_global.login_id,
13389 last_updated_by = fnd_global.user_id
13390 WHERE ROWID = l_rowid
13391 AND object_version_number = l_object_version_number;
13392 --WHERE CURRENT OF ahl_bue_worker_csr;
13393
13394 COMMIT WORK;
13395 ELSE
13396 l_status := 100;
13397 ROLLBACK;
13398 END IF;
13399 CLOSE bue_lock_row;
13400
13401 ELSE
13402 l_instance_id := NULL;
13403 ROLLBACK;
13404 END IF;
13405 EXCEPTION
13406 WHEN record_locked THEN
13407 -- select next row.
13408 l_status := -54;
13409 ROLLBACK;
13410 IF (bue_lock_row%ISOPEN) THEN
13411 CLOSE bue_lock_row;
13412 END IF;
13413
13414 WHEN NO_DATA_FOUND THEN
13415 -- select next row.
13416 l_status := 100;
13417 ROLLBACK;
13418 IF (bue_lock_row%ISOPEN) THEN
13419 CLOSE bue_lock_row;
13420 END IF;
13421
13422 WHEN OTHERS THEN
13423 ROLLBACK;
13424 l_status := SQLCODE;
13425 errbuf := 'Get_Next_BUE_Row:' || substrb(sqlerrm,1,60);
13426 l_instance_id := NULL;
13427 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
13428 IF (bue_lock_row%ISOPEN) THEN
13429 CLOSE bue_lock_row;
13430 END IF;
13431 END;
13432
13433 IF (l_status = 0) THEN
13434 -- success or end of rows.
13435 EXIT;
13436 ELSIF (l_status <> -54 AND l_status <> 100) THEN
13437 EXIT;
13438 END IF;
13439
13440 END LOOP; -- select next row.
13441
13442 CLOSE ahl_bue_worker_csr;
13443 x_item_instance_id := l_instance_id;
13444
13445 IF G_debug = 'Y' THEN
13446 AHL_DEBUG_PUB.debug('End Get_Next_BUE_Row: x_item_instance_id:' || x_item_instance_id);
13447 END IF;
13448
13449 EXCEPTION
13450 WHEN OTHERS THEN
13451 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
13452 errbuf := 'AHL_UMP_ProcessUnit_Pvt.Process.Get_Next_BUE_Row:' || SUBSTR(SQLERRM,1,240);
13453 x_item_instance_id := NULL;
13454
13455 END Get_Next_BUE_Row;
13456
13457 ------------------------------------------------------------------
13458 -- Added for performance bug# 6893404.
13459 -- procedure deletes the worker data after processing is complete.
13460 PROCEDURE Cleanup_BUE_Worker(p_parent_conc_request_id IN NUMBER,
13461 p_child_conc_request_id IN NUMBER,
13462 x_return_status OUT NOCOPY VARCHAR2,
13463 x_errbuf OUT NOCOPY VARCHAR2)
13464 IS
13465 PRAGMA AUTONOMOUS_TRANSACTION;
13466
13467 CURSOR get_undeleted_parents(p_conc_request_id IN NUMBER) IS
13468 SELECT DISTINCT parent_conc_request_id
13469 FROM ahl_bue_worker_data
13470 WHERE parent_conc_request_id <> p_conc_request_id;
13471
13472 CURSOR get_undeleted_child(p_conc_request_id IN NUMBER) IS
13473 SELECT DISTINCT child_conc_request_id
13474 FROM ahl_bue_worker_data
13475 WHERE parent_conc_request_id = p_conc_request_id
13476 AND child_conc_request_id IS NOT NULL;
13477
13478 CURSOR lock_child_rows(p_parent_conc_id IN NUMBER,
13479 p_child_conc_id IN NUMBER) IS
13480 SELECT rowid
13481 FROM ahl_bue_worker_data
13482 WHERE parent_conc_request_id = p_parent_conc_id
13483 AND child_conc_request_id = p_child_conc_id
13484 FOR UPDATE OF object_version_number NOWAIT;
13485
13486 CURSOR fnd_concur_csr(p_conc_req_id IN NUMBER) IS
13487 SELECT 'x'
13488 FROM fnd_concurrent_requests
13489 WHERE REQUEST_ID = p_conc_req_id;
13490
13491 record_locked EXCEPTION;
13492 pragma exception_init (record_locked, -54);
13493
13494 l_req_status boolean;
13495 l_rphase varchar2(80);
13496 l_rstatus varchar2(80);
13497 l_dphase varchar2(30);
13498 lc_dphase varchar2(30);
13499 l_dstatus varchar2(30);
13500 l_message varchar2(240);
13501
13502 l_buffer_limit number := 100;
13503
13504 TYPE urowid_tbl_type IS TABLE OF urowid INDEX BY BINARY_INTEGER;
13505
13506 l_rowid_tbl urowid_tbl_type;
13507 l_junk VARCHAR2(1);
13508
13509 BEGIN
13510
13511 IF G_debug = 'Y' THEN
13512 AHL_DEBUG_PUB.debug('Start Cleanup_BUE_Worker: Parent Conc Request ID:' || p_parent_conc_request_id);
13513 AHL_DEBUG_PUB.debug('Child Conc Request ID:' || p_child_conc_request_id);
13514 END IF;
13515
13516 IF (p_parent_conc_request_id IS NULL) THEN
13517 RETURN; -- do nothing
13518 END IF;
13519
13520 IF (p_child_conc_request_id IS NOT NULL) THEN
13521 G_DEBUG_LINE_NUM := 300;
13522 -- cleanup rows processed by this worker.
13523 DELETE from ahl_bue_worker_data
13524 WHERE parent_conc_request_id = p_parent_conc_request_id
13525 AND child_conc_request_id = p_child_conc_request_id ;
13526 COMMIT WORK;
13527 END IF;
13528
13529 IF (p_child_conc_request_id IS NULL) OR
13530 (p_child_conc_request_id IS NOT NULL AND p_child_conc_request_id = p_parent_conc_request_id) THEN
13531 -- this routine is executed by parent conc request. Modified due to ORA-00054 errors reported
13532 -- when workers are deleting the rows.
13533
13534 G_DEBUG_LINE_NUM := 310;
13535 -- cleanup any orphaned rows left from other parent requests.
13536 FOR undeleted_parent IN get_undeleted_parents(p_parent_conc_request_id) LOOP
13537 /* not needed - check only child conc request status
13538 -- check parent status.
13539 l_req_status := FND_CONCURRENT.GET_REQUEST_STATUS(request_id => undeleted_parent.parent_conc_request_id,
13540 --appl_shortname => 'AHL',
13541 --program => 'AHLUEFF',
13542 phase => l_rphase,
13543 status => l_rstatus,
13544 dev_phase => l_dphase,
13545 dev_status => l_dstatus,
13546 message => l_message);
13547 IF (l_req_status = TRUE) AND (l_dphase = 'COMPLETE' OR l_dphase IS NULL) THEN
13548 */
13549
13550 G_DEBUG_LINE_NUM := 312;
13551 -- delete all rows where child conc request is NULL and when parent concurrent does not exist in fnd_concurrent_request table.
13552 OPEN fnd_concur_csr(undeleted_parent.parent_conc_request_id);
13553 FETCH fnd_concur_csr INTO l_junk;
13554 IF (fnd_concur_csr%NOTFOUND) THEN
13555 G_DEBUG_LINE_NUM := 315;
13556
13557 DELETE FROM AHL_BUE_WORKER_DATA
13558 WHERE parent_conc_request_id = undeleted_parent.parent_conc_request_id
13559 AND child_conc_request_id IS NULL;
13560 COMMIT WORK;
13561 END IF;
13562 CLOSE fnd_concur_csr;
13563
13564 FOR undeleted_child IN get_undeleted_child(undeleted_parent.parent_conc_request_id) LOOP
13565 G_DEBUG_LINE_NUM := 320;
13566 l_req_status := FND_CONCURRENT.GET_REQUEST_STATUS(request_id => undeleted_child.child_conc_request_id,
13567 --appl_shortname => 'AHL',
13568 --program => 'AHLWUEFF',
13569 phase => l_rphase,
13570 status => l_rstatus,
13571 dev_phase => lc_dphase,
13572 dev_status => l_dstatus,
13573 message => l_message);
13574 IF NOT(l_req_status) THEN
13575 -- check if request exists in fnd_concurrent_requests table
13576 OPEN fnd_concur_csr(undeleted_child.child_conc_request_id);
13577 FETCH fnd_concur_csr INTO l_junk;
13578 IF (fnd_concur_csr%NOTFOUND) THEN
13579 G_DEBUG_LINE_NUM := 325;
13580 l_req_status := TRUE;
13581 lc_dphase := NULL;
13582 END IF;
13583 CLOSE fnd_concur_csr;
13584 END IF;
13585
13586 IF (l_req_status = TRUE) AND (lc_dphase = 'COMPLETE' OR lc_dphase IS NULL) THEN
13587 G_DEBUG_LINE_NUM := 330;
13588
13589 LOOP
13590 -- lock and delete rows for undeleted_child.child_conc_request_id.
13591 OPEN lock_child_rows(undeleted_parent.parent_conc_request_id,
13592 undeleted_child.child_conc_request_id);
13593 G_DEBUG_LINE_NUM := 340;
13594 FETCH lock_child_rows BULK COLLECT INTO l_rowid_tbl LIMIT l_buffer_limit;
13595 --EXIT WHEN (l_rowid_tbl.count = 0);
13596 IF (l_rowid_tbl.count = 0) THEN
13597 ROLLBACK;
13598 CLOSE lock_child_rows;
13599 EXIT;
13600 END IF;
13601
13602 G_DEBUG_LINE_NUM := 350;
13603
13604 BEGIN
13605 SAVEPOINT lock_child_rows_upd_s;
13606 FORALL j IN l_rowid_tbl.FIRST..l_rowid_tbl.LAST
13607 -- delete for parent concurrent.
13608 DELETE FROM ahl_bue_worker_data
13609 WHERE rowid = l_rowid_tbl(j);
13610
13611 COMMIT;
13612 --
13613 EXCEPTION
13614 WHEN OTHERS THEN
13615 rollback to lock_child_rows_upd_s;
13616 EXIT; -- abort delete for child.
13617 -- dbms_output.put_line('Record Locked');
13618 END;
13619
13620 l_rowid_tbl.delete;
13621 CLOSE lock_child_rows;
13622
13623 END LOOP;
13624 IF (lock_child_rows%ISOPEN) THEN
13625 CLOSE lock_child_rows;
13626 END IF;
13627
13628 END IF; -- l_req_status and lc_dphase
13629 END LOOP; -- undeleted_child IN
13630
13631 --END IF; -- (l_dphase = 'COMPLETE')
13632 END LOOP; -- undeleted_parent IN
13633 END IF; -- p_child_conc_request_id IS NULL
13634
13635 IF G_debug = 'Y' THEN
13636 AHL_DEBUG_PUB.debug('End Cleanup_BUE_Worker');
13637 END IF;
13638
13639 EXCEPTION
13640 WHEN record_locked THEN
13641 IF (lock_child_rows%ISOPEN) THEN
13642 CLOSE lock_child_rows;
13643 END IF;
13644 ROLLBACK;
13645 -- dbms_output.put_line('Record Locked');
13646
13647 WHEN OTHERS THEN
13648 ROLLBACK;
13649 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
13650 x_errbuf := 'AHL_UMP_ProcessUnit_Pvt.Process.Cleanup_BUE_Worker:line:' || G_DEBUG_LINE_NUM || ':' || SUBSTR(SQLERRM,1,240);
13651
13652 END Cleanup_BUE_Worker;
13653
13654 -- Added for performance bug# 6893404.
13655 PROCEDURE Populate_BUE_Worker_for_MR(p_conc_request_id IN NUMBER,
13656 p_mr_header_id IN NUMBER,
13657 p_concurrent_flag IN VARCHAR2,
13658 p_mtl_category_id IN NUMBER,
13659 p_process_option IN VARCHAR2,
13660 x_return_status OUT NOCOPY VARCHAR2)
13661 IS
13662 PRAGMA AUTONOMOUS_TRANSACTION;
13663
13664 -- get item instances that are either components
13665 -- or a UC when no item category and process option = Units or Components or all.
13666 CURSOR get_inst_csr (p_mr_header_id IN NUMBER,
13667 p_opt_uc IN NUMBER) IS
13668 SELECT instance_id from
13669 (SELECT DISTINCT nvl(root_instance_id, instance_id) instance_id from
13670 (
13671 SELECT cii.instance_id,
13672 (select object_id from csi_ii_relationships parent
13673 where not exists (select 'x' from csi_ii_relationships
13674 where subject_id = parent.object_id and
13675 relationship_type_code = 'COMPONENT-OF' and
13676 trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate) and
13677 trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1)))
13678 start with parent.subject_id = cii.instance_id and
13679 parent.relationship_type_code = 'COMPONENT-OF' and
13680 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
13681 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
13682 connect by prior parent.object_id = parent.subject_id and
13683 parent.relationship_type_code = 'COMPONENT-OF' and
13684 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
13685 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
13686 ) Root_instance_id
13687
13688 FROM csi_item_instances cii, ahl_mr_instances_temp mr
13689 WHERE trunc(nvl(cii.active_start_date, sysdate)) <= trunc(sysdate) AND
13690 trunc(sysdate) < trunc(nvl(cii.active_end_date, sysdate+1))
13691 AND mr.item_instance_id = cii.instance_id
13692 )
13693 ) valid_inst
13694 WHERE (p_opt_uc = 1 AND exists (select 'x' from ahl_unit_config_headers
13695 where csi_item_instance_id = valid_inst.instance_id
13696 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
13697 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
13698 AND unit_config_status_code <> 'DRAFT'
13699 AND parent_uc_header_id IS NULL
13700 ) -- get UCs only.
13701 )
13702 OR
13703 -- get components.
13704 (p_opt_uc = 2 AND not exists (select 'x' from ahl_unit_config_headers
13705 where csi_item_instance_id = valid_inst.instance_id
13706 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
13707 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
13708 -- instance is a UC if in status draft.
13709 --AND unit_config_status_code <> 'DRAFT'
13710 --AND parent_uc_header_id IS NULL
13711 )
13712 )
13713 OR
13714 -- get all but do not select draft UCs as Process Unit will raise error.
13715 (p_opt_uc = 0 AND not exists (select 'x' from ahl_unit_config_headers
13716 where csi_item_instance_id = valid_inst.instance_id
13717 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
13718 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
13719 AND unit_config_status_code = 'DRAFT'
13720 )
13721 );
13722
13723
13724 -- get item instances when item category selected with process option of ALL, Units or Components.
13725 CURSOR get_itemcat_inst_csr (p_mr_header_id IN NUMBER,
13726 p_mtl_category_id IN NUMBER,
13727 p_opt_uc IN NUMBER) IS
13728 SELECT instance_id from
13729 (SELECT DISTINCT nvl(root_instance_id, instance_id) instance_id from
13730 (
13731 SELECT cii.instance_id,
13732 (select object_id from csi_ii_relationships parent
13733 where not exists (select 'x' from csi_ii_relationships
13734 where subject_id = parent.object_id and
13735 relationship_type_code = 'COMPONENT-OF' and
13736 trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate) and
13737 trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1)))
13738 start with parent.subject_id = cii.instance_id and
13739 parent.relationship_type_code = 'COMPONENT-OF' and
13740 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
13741 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
13742 connect by prior parent.object_id = parent.subject_id and
13743 parent.relationship_type_code = 'COMPONENT-OF' and
13744 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
13745 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
13746 ) Root_instance_id
13747
13748 FROM csi_item_instances cii,ahl_mr_instances_temp mr
13749 WHERE trunc(nvl(cii.active_start_date, sysdate)) <= trunc(sysdate) AND
13750 trunc(sysdate) < trunc(nvl(cii.active_end_date, sysdate+1))
13751 AND mr.item_instance_id = cii.instance_id
13752 )
13753 ) valid_inst
13754 WHERE exists (select 'x'
13755 from mtl_category_set_valid_cats cs, mtl_item_categories itc,
13756 csi_item_instances cii2
13757 where cs.category_set_id = fnd_profile.value('AHL_BUE_ITEM_CATEGORY_SET')
13758 AND cs.category_set_id = itc.category_set_id
13759 AND cs.category_id = itc.category_id
13760 AND itc.category_id = p_mtl_category_id
13761 AND cii2.instance_id = valid_inst.instance_id
13762 AND itc.organization_id = cii2.inv_master_organization_id
13763 AND itc.inventory_item_id = cii2.inventory_item_id
13764 ) -- get root nodes matching item category.
13765 -- either UC or components.
13766 AND ((p_opt_uc = 1 AND exists (select 'x' from ahl_unit_config_headers
13767 where csi_item_instance_id = valid_inst.instance_id
13768 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
13769 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
13770 AND unit_config_status_code <> 'DRAFT'
13771 AND parent_uc_header_id IS NULL
13772 ) -- get UCs only.
13773 )
13774 OR
13775 -- get components.
13776 (p_opt_uc = 2 AND not exists (select 'x' from ahl_unit_config_headers
13777 where csi_item_instance_id = valid_inst.instance_id
13778 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
13779 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
13780 -- instance is a UC if in status draft.
13781 --AND unit_config_status_code <> 'DRAFT'
13782 --AND parent_uc_header_id IS NULL
13783 )
13784 )
13785 OR
13786 -- when process option is ALL. Ignore Draft UC's
13787 (p_opt_uc = 0 AND not exists (select 'x' from ahl_unit_config_headers
13788 where csi_item_instance_id = valid_inst.instance_id
13789 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
13790 AND trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1))
13791 AND unit_config_status_code = 'DRAFT'
13792 )
13793 )
13794 );
13795
13796
13797 -- get UEs for the MR that are not existing in BUE worker table.
13798 CURSOR get_extra_ue_na(p_mr_header_id IN NUMBER,
13799 p_conc_request_id IN NUMBER) IS
13800 SELECT csi_item_instance_id
13801 FROM (
13802 SELECT DISTINCT nvl(Root_instance_id, csi_item_instance_id) csi_item_instance_id
13803 FROM (
13804 SELECT DISTINCT UE.csi_item_instance_id,
13805 (select object_id from csi_ii_relationships parent
13806 where not exists (select 'x' from csi_ii_relationships
13807 where subject_id = parent.object_id and
13808 trunc(sysdate) < trunc(nvl(active_end_date,sysdate+1)))
13809 start with parent.subject_id = UE.CSI_ITEM_INSTANCE_ID and
13810 parent.relationship_type_code = 'COMPONENT-OF' and
13811 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
13812 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
13813 connect by prior parent.object_id = parent.subject_id and
13814 parent.relationship_type_code = 'COMPONENT-OF' and
13815 trunc(nvl(parent.active_start_date, sysdate)) <= trunc(sysdate) and
13816 trunc(sysdate) < trunc(nvl(parent.active_end_date, sysdate+1))
13817 ) Root_instance_id
13818
13819 FROM ahl_unit_effectivities_app_v UE
13820 WHERE UE.mr_header_id = p_mr_header_id
13821 AND (UE.status_code IS NULL OR UE.status_code IN ('INIT-DUE','EXCEPTION'))
13822 AND NOT EXISTS (Select 1
13823 FROM ahl_mr_instances_temp
13824 WHERE item_instance_id = ue.csi_item_instance_id)
13825 )
13826 ) valid_inst
13827 WHERE NOT EXISTS (Select 1
13828 FROM AHL_BUE_WORKER_DATA
13829 WHERE csi_item_instance_id = valid_inst.csi_item_instance_id
13830 AND parent_conc_request_id = p_conc_request_id) ;
13831
13832 l_relationship_tbl nbr_tbl_type;
13833 l_instance_id_tbl nbr_tbl_type;
13834
13835 l_opt number;
13836 l_opt_uc number;
13837
13838 l_buffer_limit number := 1000;
13839
13840 l_api_version number := 1.0;
13841 l_msg_count number;
13842 l_msg_data varchar2(4000);
13843
13844 dml_errors EXCEPTION;
13845 PRAGMA EXCEPTION_INIT(dml_errors, -24381);
13846
13847 l_mr_item_instances_tbl AHL_FMP_PVT.MR_ITEM_INSTANCE_TBL_TYPE;
13848
13849 BEGIN
13850
13851 IF G_debug = 'Y' THEN
13852 AHL_DEBUG_PUB.debug('Start Populate_BUE_Worker_for_MR: Input MR Header ID:' || p_mr_header_id);
13853 AHL_DEBUG_PUB.debug('Input Concurrent Flag:' || p_conc_request_id);
13854 AHL_DEBUG_PUB.debug('Input Conc Request ID:' || p_concurrent_flag);
13855 END IF;
13856
13857 -- initialize return status.
13858 x_return_status := FND_API.G_RET_STS_SUCCESS;
13859
13860 -- get instances applicable to the MR.
13861 -- this API will insert the applicable MRs into temp table ahl_mr_instances_temp
13862 AHL_FMP_PVT.GET_MR_AFFECTED_ITEMS (
13863 p_api_version => 1.0,
13864 p_init_msg_list => FND_API.G_TRUE,
13865 x_return_status => x_return_status,
13866 x_msg_count => l_msg_count,
13867 x_msg_data => l_msg_data,
13868 p_mr_header_id => p_mr_header_id,
13869 p_top_node_flag => 'N',
13870 p_unique_inst_flag => 'Y',
13871 -- JKJain, NR Analysis and Forecasting
13872 p_consider_fleet_flag => 'N',
13873 x_mr_item_inst_tbl => l_mr_item_instances_tbl );
13874
13875 IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
13876 ROLLBACK;
13877 RETURN;
13878 END IF;
13879
13880
13881 IF (p_process_option = 'AHL_BUE_ALL_COMPONENTS') THEN
13882 l_opt_uc := 2;
13883 ELSIF (p_process_option = 'AHL_BUE_ALL_UNITS') THEN
13884 l_opt_uc := 1;
13885 ELSE
13886 l_opt_uc := 0; -- when null or input is AHL_BUE_ALL
13887 END IF;
13888
13889 -- process effectivity
13890 IF (p_mtl_category_id IS NULL) THEN
13891 OPEN get_inst_csr(p_mr_header_id, l_opt_uc);
13892 ELSE
13893 OPEN get_itemcat_inst_csr(p_mr_header_id, p_mtl_category_id, l_opt_uc);
13894 END IF;
13895
13896 LOOP
13897 IF (p_mtl_category_id IS NULL) THEN
13898 FETCH get_inst_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13899 ELSE
13900 FETCH get_itemcat_inst_csr BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13901 END IF;
13902
13903 EXIT WHEN (l_instance_id_tbl.count = 0);
13904
13905 BEGIN
13906 -- insert into BUE table.
13907 FORALL instance_indx IN l_instance_id_tbl.FIRST..l_instance_id_tbl.LAST SAVE EXCEPTIONS
13908 INSERT INTO AHL_BUE_WORKER_DATA
13909 (parent_conc_request_id,
13910 csi_item_instance_id,
13911 child_conc_request_id,
13912 last_update_date,
13913 last_updated_by,
13914 creation_date,
13915 created_by,
13916 last_update_login,
13917 object_version_number) VALUES
13918 (p_conc_request_id,
13919 l_instance_id_tbl(instance_indx),
13920 null,
13921 sysdate,
13922 fnd_global.user_id,
13923 sysdate,
13924 fnd_global.user_id,
13925 fnd_global.conc_login_id,
13926 1);
13927
13928 EXCEPTION
13929 WHEN DML_ERRORS THEN
13930 IF (get_inst_csr%ISOPEN) THEN
13931 CLOSE get_inst_csr;
13932 END IF;
13933 IF (get_itemcat_inst_csr%ISOPEN) THEN
13934 CLOSE get_itemcat_inst_csr;
13935 END IF;
13936
13937 x_return_status := 'E';
13938
13939 IF (p_concurrent_flag = 'Y') THEN
13940 fnd_file.put_line(fnd_file.log, 'Following error(s) occured while inserting into table ahl_bue_worker_data');
13941 FOR j IN 1..sql%bulk_exceptions.count
13942 LOOP
13943 fnd_file.put_line(fnd_file.log, sql%bulk_exceptions(j).error_index || ', ' ||
13944 sqlerrm(-sql%bulk_exceptions(j).error_code) );
13945 END LOOP;
13946 END IF;
13947
13948 FND_MESSAGE.set_name('AHL', 'AHL_UMP_BUE_WORKER_ERR');
13949 FND_MSG_PUB.add;
13950
13951 RETURN;
13952 END;
13953
13954 l_instance_id_tbl.DELETE;
13955
13956 END LOOP;
13957
13958 IF (p_mtl_category_id IS NULL) THEN
13959 CLOSE get_inst_csr;
13960 ELSE
13961 CLOSE get_itemcat_inst_csr;
13962 END IF;
13963
13964 l_instance_id_tbl.DELETE;
13965
13966 -- process extra UE instances
13967 OPEN get_extra_ue_na(p_mr_header_id, p_conc_request_id);
13968 LOOP
13969 FETCH get_extra_ue_na BULK COLLECT INTO l_instance_id_tbl LIMIT l_buffer_limit;
13970 EXIT WHEN (l_instance_id_tbl.COUNT = 0);
13971 BEGIN
13972 -- insert into BUE table.
13973 FORALL instance_indx IN l_instance_id_tbl.FIRST..l_instance_id_tbl.LAST SAVE EXCEPTIONS
13974 INSERT INTO AHL_BUE_WORKER_DATA
13975 (parent_conc_request_id,
13976 csi_item_instance_id,
13977 child_conc_request_id,
13978 last_update_date,
13979 last_updated_by,
13980 creation_date,
13981 created_by,
13982 last_update_login,
13983 object_version_number) VALUES
13984 (p_conc_request_id,
13985 l_instance_id_tbl(instance_indx),
13986 null,
13987 sysdate,
13988 fnd_global.user_id,
13989 sysdate,
13990 fnd_global.user_id,
13991 fnd_global.conc_login_id,
13992 1);
13993
13994 EXCEPTION
13995 WHEN DML_ERRORS THEN
13996
13997 IF (get_extra_ue_na%ISOPEN) THEN
13998 CLOSE get_extra_ue_na;
13999 END IF;
14000 x_return_status := 'E';
14001
14002 IF (p_concurrent_flag = 'Y') THEN
14003 fnd_file.put_line(fnd_file.log, 'Following error(s) occured while inserting into table ahl_bue_worker_data');
14004 FOR j IN 1..sql%bulk_exceptions.count
14005 LOOP
14006 fnd_file.put_line(fnd_file.log, sql%bulk_exceptions(j).error_index || ', ' ||
14007 sqlerrm(-sql%bulk_exceptions(j).error_code) );
14008 END LOOP;
14009 END IF;
14010
14011 FND_MESSAGE.set_name('AHL', 'AHL_UMP_BUE_WORKER_ERR');
14012 FND_MSG_PUB.add;
14013
14014 RETURN;
14015 END;
14016
14017 l_instance_id_tbl.DELETE;
14018
14019 END LOOP;
14020 CLOSE get_extra_ue_na;
14021
14022 -- delete duplicate rows.
14023 /* fix for performance bug# 16003176 (10g to 11g upgrade)
14024 DELETE FROM ahl_bue_worker_data
14025 WHERE parent_conc_request_id = p_conc_request_id
14026 AND rowid not in (SELECT MIN(rowid)
14027 FROM ahl_bue_worker_data
14028 WHERE parent_conc_request_id = p_conc_request_id
14029 GROUP BY csi_item_instance_id, parent_conc_request_id) ;
14030 */
14031
14032 --DELETE FROM ahl_bue_worker_data wrk1
14033 --WHERE wrk1.parent_conc_request_id = p_conc_request_id
14034 -- AND wrk1.rowid > ANY ( SELECT wrk2.rowid
14035 -- FROM ahl_bue_worker_data wrk2
14036 -- WHERE wrk2.parent_conc_request_id = p_conc_request_id
14037 -- AND wrk2.csi_item_instance_id = wrk1.csi_item_instance_id) ;
14038
14039 --DELETE FROM ahl_bue_worker_data ad1
14040 --WHERE ad1.parent_conc_request_id = p_conc_request_id
14041 -- AND ad1.rowid not in (SELECT /*+ UNNEST INDEX(ad2 AHL_BUE_WORKER_DATA_N2) */ MIN(ad2.rowid)
14042 -- FROM ahl_bue_worker_data ad2
14043 -- WHERE ad2.parent_conc_request_id = p_conc_request_id
14044 -- GROUP BY ad2.csi_item_instance_id, ad2.parent_conc_request_id) ;
14045
14046 --delete /*+ rowid(a) use_nl(a) */
14047 -- from ahl_bue_worker_data a
14048 -- where rowid in
14049 -- (select /*+ unnest */ rowid
14050 -- from
14051 -- (select /*+ parallel(b) cardinality(b,10) */
14052 -- rowid, row_number() over (partition by
14053 -- csi_item_instance_id, parent_conc_request_id
14054 -- order by 1
14055 -- ) dup
14056 -- from ahl_bue_worker_data b
14057 -- where b.parent_conc_request_id = p_conc_request_id)
14058 -- where dup > 1);
14059
14060 DELETE /*+ parallel(a) */ FROM ahl_bue_worker_data a
14061 where a.parent_conc_request_id = p_conc_request_id
14062 and exists (select 'x' from ahl_bue_worker_data b
14063 where b.parent_conc_request_id = a.parent_conc_request_id
14064 and b.csi_item_instance_id = a.csi_item_instance_id
14065 and b.rowid > a.rowid);
14066
14067
14068 -- save changes.
14069 COMMIT WORK;
14070
14071 IF G_debug = 'Y' THEN
14072 AHL_DEBUG_PUB.debug('End Populate_BUE_Worker_for_MR: x_return_status:' || x_return_status);
14073 END IF;
14074
14075 END Populate_BUE_Worker_for_MR;
14076
14077 -- Added for performance bug# 6893404.
14078 FUNCTION get_latest_ctr_reading(p_counter_id IN NUMBER) RETURN NUMBER
14079 IS
14080
14081 -- get net reading.
14082 CURSOR get_ctr_reading_csr (p_counter_id IN NUMBER) IS
14083 SELECT * FROM
14084 (SELECT net_reading
14085 FROM csi_counter_readings
14086 WHERE counter_id = p_counter_id
14087 AND nvl(disabled_flag,'N') = 'N'
14088 ORDER BY value_timestamp desc)
14089 WHERE rownum < 2;
14090
14091 l_net_reading NUMBER;
14092
14093 BEGIN
14094
14095 OPEN get_ctr_reading_csr(p_counter_id);
14096 FETCH get_ctr_reading_csr INTO l_net_reading;
14097 IF (get_ctr_reading_csr%NOTFOUND) THEN
14098 l_net_reading := 0;
14099 END IF;
14100 CLOSE get_ctr_reading_csr;
14101
14102 RETURN l_net_reading;
14103
14104 END get_latest_ctr_reading;
14105 ----
14106
14107 -- procedure checks if forecast exists for all of instance's UOM and adds
14108 -- zero forecast row if missing forecast.
14109 PROCEDURE validate_uf_for_ctr(p_current_usage_tbl IN counter_values_tbl_type,
14110 p_x_forecast_details_tbl IN OUT NOCOPY forecast_details_tbl_type)
14111 IS
14112 l_last_index NUMBER;
14113 l_uom_found_flag BOOLEAN;
14114
14115 BEGIN
14116
14117 IF G_DEBUG = 'Y' THEN
14118 AHL_DEBUG_PUB.debug ('Start validate_uf_for_ctr');
14119 END IF;
14120
14121 l_last_index := p_x_forecast_details_tbl.LAST + 1;
14122
14123 IF (p_current_usage_tbl.COUNT > 0) THEN
14124 FOR j IN p_current_usage_tbl.FIRST..p_current_usage_tbl.LAST LOOP
14125 l_uom_found_flag := FALSE;
14126 IF (p_x_forecast_details_tbl.COUNT > 0) THEN
14127 FOR i IN p_x_forecast_details_tbl.FIRST..p_x_forecast_details_tbl.LAST LOOP
14128 IF (p_x_forecast_details_tbl(i).uom_code = p_current_usage_tbl(j).uom_code) THEN
14129 l_uom_found_flag := TRUE;
14130 EXIT;
14131 END IF;
14132 END LOOP; -- i
14133
14134 IF (l_uom_found_flag = FALSE) THEN
14135 p_x_forecast_details_tbl(l_last_index).uom_code := p_current_usage_tbl(j).uom_code;
14136 p_x_forecast_details_tbl(l_last_index).start_date := trunc(sysdate);
14137 p_x_forecast_details_tbl(l_last_index).end_date := NULL;
14138 p_x_forecast_details_tbl(l_last_index).usage_per_day := 0;
14139
14140 l_last_index := l_last_index + 1;
14141 END IF;
14142 END IF;
14143
14144 END LOOP; -- j
14145 END IF; -- p_current_usage_tbl.COUNT
14146
14147 IF G_DEBUG = 'Y' THEN
14148 AHL_DEBUG_PUB.debug ('Count on forecast_details' || p_x_forecast_details_tbl.COUNT);
14149
14150 IF (p_x_forecast_details_tbl.COUNT > 0) THEN
14151 FOR i IN p_x_forecast_details_tbl.FIRST..p_x_forecast_details_tbl.LAST LOOP
14152 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') Uom_Code' || p_x_forecast_details_tbl(i).uom_code);
14153 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') Start Date' || p_x_forecast_details_tbl(i).start_date);
14154 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') End Date' || p_x_forecast_details_tbl(i).end_date);
14155 AHL_DEBUG_PUB.debug('Forecast Record ('|| i || ') Usage' || p_x_forecast_details_tbl(i).usage_per_day);
14156 END LOOP;
14157 END IF;
14158 AHL_DEBUG_PUB.debug ('End validate_uf_for_ctr');
14159 END IF;
14160
14161 END validate_uf_for_ctr;
14162 --------------------------------------------------------------
14163 -- Added to fix bug# 9263774
14164 -- Process prior MR versions.
14165 PROCEDURE Process_Prior_MR_Version (p_applicable_mrs_rec IN applicable_mrs_rec_type,
14166 p_new_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE,
14167 p_unit_effectivity_tbl IN unit_effectivity_tbl_type,
14168 p_old_UE_forecast_sequence IN NUMBER)
14169 IS
14170
14171 -- for reading unit effectivity table.
14172 CURSOR ahl_ue_relns_csr ( p_unit_effectivity_id IN NUMBER ) IS
14173 SELECT ue_id, related_ue_id
14174 FROM ahl_ue_relationships relns
14175 START WITH ue_id = p_unit_effectivity_id AND
14176 relationship_code = 'PARENT'
14177 CONNECT BY PRIOR related_ue_id = ue_id AND
14178 originator_ue_id = p_unit_effectivity_id AND
14179 relationship_code = 'PARENT'
14180 ORDER BY level;
14181
14182 -- get related unit effectivities details.
14183 CURSOR ahl_ue_csr ( p_ue_id IN NUMBER,
14184 p_related_ue_id IN NUMBER ) IS
14185 SELECT ue1.mr_header_id, ue1.csi_item_instance_id,
14186 ue2.mr_header_id related_mr_header_id,
14187 ue2.csi_item_instance_id related_csi_item_instance_id
14188 --FROM ahl_unit_effectivities_app_v ue1, ahl_unit_effectivities_app_v ue2
14189 FROM ahl_unit_effectivities_b ue1, ahl_unit_effectivities_b ue2
14190 WHERE ue1.unit_effectivity_id = p_ue_id AND
14191 ue2.unit_effectivity_id = p_related_ue_id;
14192
14193
14194 -- To check if mr has a preceding mr.
14195 CURSOR ahl_appl_mr_csr (p_item_instance_id IN NUMBER,
14196 p_mr_header_id IN NUMBER) IS
14197 SELECT 'x'
14198 FROM ahl_applicable_mrs
14199 WHERE csi_item_instance_id = p_item_instance_id AND
14200 mr_header_id = p_mr_header_id AND
14201 implement_status_code <> 'OPTIONAL_DO_NOT_IMPLEMENT' AND
14202 --preceding_mr_header_id IS NOT NULL;
14203 accomplish_trigger_type = 'INITIATED_BY';
14204
14205 l_new_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
14206 l_initialize_ue_rec ahl_temp_unit_effectivities%ROWTYPE;
14207
14208 l_junk VARCHAR2(1);
14209 l_visit_end_date DATE;
14210
14211 l_visit_status VARCHAR2(30);
14212
14213 -- Added for bug# 9263774
14214 l_top_node_mr_id NUMBER;
14215 l_top_node_ue_id NUMBER;
14216 l_group_flag BOOLEAN;
14217
14218 l_mr_header_id NUMBER;
14219 l_csi_item_instance_id NUMBER;
14220 l_related_mr_header_id NUMBER;
14221 l_related_csi_item_instance_id NUMBER;
14222
14223 -- group UE check.
14224 CURSOR chk_grp_mr(p_ue_id IN NUMBER) IS
14225 SELECT 'x'
14226 FROM ahl_ue_relationships
14227 WHERE originator_ue_id = p_ue_id;
14228
14229 -- Added for SB Enh.
14230 -- for prior MR, retain accomplishment trigger details.
14231 CURSOR get_accomplish_trig_dtls(p_unit_effectivity_id in number) IS
14232 SELECT accomplish_trigger_type, loop_chain_seq_num, start_lc_ue_id
14233 FROM ahl_unit_effectivities_b
14234 WHERE unit_effectivity_id = p_unit_effectivity_id;
14235
14236
14237 BEGIN
14238
14239 IF G_DEBUG = 'Y' THEN
14240 AHL_DEBUG_PUB.Debug('Start Process Prior MR');
14241 END IF;
14242
14243 -- initialize - needed for preceding MR info.
14244 l_new_unit_effectivity_rec := p_new_unit_effectivity_rec;
14245
14246 -- update the temp table record for orig MR with visit_end_date and unit_effectivity ID.
14247 -- get visit end date from unit_effectivity_tbl for l_old_UE_Forecast_sequence.
14248 l_visit_end_date := p_unit_effectivity_tbl(p_old_UE_forecast_sequence).visit_end_date;
14249 l_new_unit_effectivity_rec.unit_effectivity_id :=
14250 p_unit_effectivity_tbl(p_old_UE_forecast_sequence).unit_effectivity_id;
14251
14252 -- construct temporary unit effectivity for top node.
14253
14254 l_new_unit_effectivity_rec.due_date := p_new_unit_effectivity_rec.due_date;
14255 l_new_unit_effectivity_rec.mr_interval_id := p_new_unit_effectivity_rec.mr_interval_id;
14256 l_new_unit_effectivity_rec.mr_effectivity_id := p_new_unit_effectivity_rec.mr_effectivity_id;
14257 l_new_unit_effectivity_rec.due_counter_value := p_new_unit_effectivity_rec.due_counter_value;
14258 l_new_unit_effectivity_rec.csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
14259 IF (p_applicable_mrs_rec.expired_mr_flag = 'Y') THEN
14260 l_new_unit_effectivity_rec.mr_header_id := p_applicable_mrs_rec.mr_header_id;
14261 ELSE
14262 l_new_unit_effectivity_rec.mr_header_id := p_unit_effectivity_tbl(p_old_UE_forecast_sequence).prior_mr_header_id;
14263 END IF;
14264
14265 l_new_unit_effectivity_rec.repetitive_mr_flag := p_new_unit_effectivity_rec.repetitive_mr_flag;
14266 l_new_unit_effectivity_rec.visit_end_date := l_visit_end_date;
14267 l_new_unit_effectivity_rec.forecast_sequence := p_new_unit_effectivity_rec.forecast_sequence;
14268
14269
14270 -- find out if this is a group MR.
14271 OPEN chk_grp_mr(l_new_unit_effectivity_rec.unit_effectivity_id);
14272 FETCH chk_grp_mr INTO l_junk;
14273 IF (chk_grp_mr%FOUND) THEN
14274 l_group_flag := TRUE;
14275 ELSE
14276 l_group_flag := FALSE;
14277 END IF;
14278 CLOSE chk_grp_mr;
14279
14280
14281 IF (l_group_flag) THEN
14282 -- to indicate group.
14283 l_new_unit_effectivity_rec.orig_csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
14284
14285 -- modified orig_mr_header_id for bug# 9263774
14286 l_new_unit_effectivity_rec.orig_mr_header_id := l_new_unit_effectivity_rec.mr_header_id;
14287 l_new_unit_effectivity_rec.orig_forecast_sequence := p_new_unit_effectivity_rec.forecast_sequence;
14288 END IF;
14289
14290 -- Added for ER# 2636001.
14291 l_new_unit_effectivity_rec.earliest_due_date := p_new_unit_effectivity_rec.earliest_due_date;
14292 l_new_unit_effectivity_rec.latest_due_date := p_new_unit_effectivity_rec.latest_due_date;
14293 l_new_unit_effectivity_rec.counter_id := p_new_unit_effectivity_rec.counter_id;
14294
14295 l_new_unit_effectivity_rec.tolerance_flag := p_new_unit_effectivity_rec.tolerance_flag;
14296 l_new_unit_effectivity_rec.tolerance_before := p_new_unit_effectivity_rec.tolerance_before;
14297 l_new_unit_effectivity_rec.tolerance_after := p_new_unit_effectivity_rec.tolerance_after;
14298
14299 -- Added for SB Enh
14300 OPEN get_accomplish_trig_dtls(l_new_unit_effectivity_rec.unit_effectivity_id);
14301 FETCH get_accomplish_trig_dtls INTO l_new_unit_effectivity_rec.accomplish_trigger_type, l_new_unit_effectivity_rec.loop_chain_seq_num,
14302 l_new_unit_effectivity_rec.start_lc_ue_id;
14303 CLOSE get_accomplish_trig_dtls;
14304 l_new_unit_effectivity_rec.start_mr_header_id := l_new_unit_effectivity_rec.mr_header_id;
14305 -- End SB Enh
14306
14307 -- write into temp table.
14308 Create_temp_unit_effectivity(l_new_unit_effectivity_rec);
14309
14310 l_top_node_mr_id := l_new_unit_effectivity_rec.mr_header_id;
14311 l_top_node_ue_id := l_new_unit_effectivity_rec.unit_effectivity_id;
14312
14313 IF (l_group_flag) THEN
14314 -- Read UE tree and apply details from p_next_due_rec_type.
14315 FOR l_ue_relns_rec IN ahl_ue_relns_csr(l_top_node_ue_id) LOOP
14316 OPEN ahl_ue_csr(l_ue_relns_rec.ue_id, l_ue_relns_rec.related_ue_id);
14317 FETCH ahl_ue_csr INTO l_mr_header_id,
14318 l_csi_item_instance_id,
14319 l_related_mr_header_id,
14320 l_related_csi_item_instance_id;
14321 IF (ahl_ue_csr%NOTFOUND) THEN
14322 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_RELN_NOTFOUND');
14323 FND_MESSAGE.Set_Token('UE_ID',l_ue_relns_rec.ue_id);
14324 FND_MESSAGE.Set_Token('RELATED_UE_ID', l_ue_relns_rec.related_ue_id);
14325 FND_MSG_PUB.ADD;
14326 CLOSE ahl_ue_csr;
14327 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
14328 END IF;
14329 CLOSE ahl_ue_csr;
14330
14331 l_new_unit_effectivity_rec := l_initialize_ue_rec;
14332
14333 -- Build temp_unit_effectivity record and write into temporary table.
14334
14335 l_new_unit_effectivity_rec.due_date := p_new_unit_effectivity_rec.due_date;
14336 l_new_unit_effectivity_rec.mr_interval_id := p_new_unit_effectivity_rec.mr_interval_id;
14337 l_new_unit_effectivity_rec.mr_effectivity_id := p_new_unit_effectivity_rec.mr_effectivity_id;
14338 l_new_unit_effectivity_rec.due_counter_value := p_new_unit_effectivity_rec.due_counter_value;
14339 l_new_unit_effectivity_rec.csi_item_instance_id := l_related_csi_item_instance_id;
14340 l_new_unit_effectivity_rec.parent_csi_item_instance_id := l_csi_item_instance_id;
14341 l_new_unit_effectivity_rec.mr_header_id := l_related_mr_header_id;
14342 l_new_unit_effectivity_rec.parent_mr_header_id := l_mr_header_id;
14343 l_new_unit_effectivity_rec.orig_csi_item_instance_id := p_applicable_mrs_rec.csi_item_instance_id;
14344 l_new_unit_effectivity_rec.orig_mr_header_id := l_top_node_mr_id;
14345 l_new_unit_effectivity_rec.orig_forecast_sequence := p_new_unit_effectivity_rec.forecast_sequence;
14346 l_new_unit_effectivity_rec.repetitive_mr_flag := p_new_unit_effectivity_rec.repetitive_mr_flag;
14347 l_new_unit_effectivity_rec.visit_end_date := l_visit_end_date;
14348 l_new_unit_effectivity_rec.earliest_due_date := p_new_unit_effectivity_rec.earliest_due_date;
14349 l_new_unit_effectivity_rec.latest_due_date := p_new_unit_effectivity_rec.latest_due_date;
14350 l_new_unit_effectivity_rec.counter_id := p_new_unit_effectivity_rec.counter_id;
14351
14352 l_new_unit_effectivity_rec.tolerance_flag := p_new_unit_effectivity_rec.tolerance_flag;
14353 l_new_unit_effectivity_rec.tolerance_before := p_new_unit_effectivity_rec.tolerance_before;
14354 l_new_unit_effectivity_rec.tolerance_after := p_new_unit_effectivity_rec.tolerance_after;
14355
14356 l_new_unit_effectivity_rec.unit_effectivity_id := null;
14357
14358 -- check if this mr has a preceding mr.
14359 OPEN ahl_appl_mr_csr (l_related_csi_item_instance_id,
14360 l_related_mr_header_id);
14361 FETCH ahl_appl_mr_csr INTO l_junk;
14362 IF (ahl_appl_mr_csr%FOUND) THEN
14363 l_new_unit_effectivity_rec.preceding_check_flag:= 'Y';
14364 ELSE
14365 l_new_unit_effectivity_rec.preceding_check_flag:= 'N';
14366 END IF;
14367 CLOSE ahl_appl_mr_csr;
14368
14369 -- write into temp table.
14370 Create_temp_unit_effectivity(l_new_unit_effectivity_rec);
14371
14372 END LOOP;
14373
14374 END IF;
14375
14376
14377 IF G_DEBUG = 'Y' THEN
14378 AHL_DEBUG_PUB.Debug('End Process PriorMR');
14379 END IF;
14380
14381
14382 END Process_Prior_MR_Version;
14383 ----------------------------------------------------
14384
14385 -- Get applicability for expired MRs.
14386 -- Added to fix bug# 9263774
14387 PROCEDURE Process_Appl_Expired_MRs
14388 IS
14389
14390 CURSOR get_mr_csr(p_item_instance_id IN NUMBER) IS
14391 SELECT csi_item_instance_id, (select mr_header_id from ahl_mr_headers_b mr
14392 where mr.title = exp_mr.title
14393 and mr.version_number = exp_mr.version_number) mr_header_id
14394 FROM
14395 (
14396 SELECT ue.csi_item_instance_id,
14397 mr.Title,
14398 max(mr.version_number) version_number
14399 FROM ahl_unit_effectivities_app_v UE, ahl_mr_headers_b mr
14400 -- pick up only top nodes.
14401 WHERE ue.mr_header_id = mr.mr_header_id
14402 AND NOT EXISTS (SELECT 'x'
14403 FROM ahl_ue_relationships uer
14404 WHERE uer.related_ue_id = ue.unit_effectivity_id
14405 AND relationship_code = 'PARENT')
14406 -- not applicable
14407 AND NOT EXISTS (SELECT 'x'
14408 FROM ahl_applicable_mrs aamr, ahl_mr_headers_b mr1
14409 WHERE aamr.csi_item_instance_id = ue.csi_item_instance_id
14410 AND aamr.mr_header_id = mr1.mr_header_id
14411 AND mr1.title = mr.title
14412 )
14413 AND ue.csi_item_instance_id = p_item_instance_id
14414 AND nvl(ue.manually_planned_flag,'N') = 'N'
14415 AND ue.object_type = 'MR'
14416 AND ue.defer_from_ue_id IS NULL
14417 AND (ue.status_code IS NULL OR ue.status_code = 'INIT-DUE')
14418 AND mr.effective_to < sysdate
14419 GROUP BY UE.csi_item_instance_id, mr.Title
14420 ) exp_mr;
14421
14422 l_inst_id_tbl nbr_tbl_type;
14423 l_mr_id_tbl nbr_tbl_type;
14424
14425 l_return_status VARCHAR2(1);
14426 l_msg_count NUMBER;
14427 l_msg_data VARCHAR2(2000);
14428
14429 l_appl_mrs_tbl AHL_FMP_PVT.applicable_mr_tbl_type;
14430
14431 BEGIN
14432
14433 IF G_config_node_tbl.COUNT > 0 THEN
14434 FOR i IN G_config_node_tbl.FIRST..G_config_node_tbl.LAST LOOP
14435 IF G_DEBUG = 'Y' THEN
14436 AHL_DEBUG_PUB.debug('Processing for..:' || G_config_node_tbl(i).csi_item_instance_id );
14437 END IF;
14438
14439 OPEN get_mr_csr (G_config_node_tbl(i).csi_item_instance_id);
14440
14441 LOOP
14442 FETCH get_mr_csr BULK COLLECT INTO l_inst_id_tbl, l_mr_id_tbl LIMIT 1000;
14443 EXIT WHEN l_inst_id_tbl.count = 0;
14444
14445 FOR j IN l_mr_id_tbl.FIRST..l_mr_id_tbl.LAST LOOP
14446 -- call FMP API to get MR effectivities
14447 AHL_FMP_PVT.GET_MR_APPLICABILITY(p_api_version => 1.0,
14448 p_init_msg_list => FND_API.G_FALSE,
14449 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
14450 x_return_status => l_return_status,
14451 x_msg_count => l_msg_count,
14452 x_msg_data => l_msg_data,
14453 p_item_instance_id => G_config_node_tbl(i).csi_item_instance_id,
14454 p_mr_header_id => l_mr_id_tbl(j),
14455 p_components_flag => 'N',
14456 p_include_doNotImplmt => 'Y',
14457 x_applicable_mr_tbl => l_appl_mrs_tbl);
14458
14459
14460 -- Raise errors if exceptions occur
14461 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
14462 RAISE FND_API.G_EXC_ERROR;
14463 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
14464 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
14465 END IF;
14466
14467 -- Populate temporary table ahl_applicable_mrs.
14468 IF (l_appl_mrs_tbl.COUNT > 0) THEN
14469 FOR i IN l_appl_mrs_tbl.FIRST..l_appl_mrs_tbl.LAST LOOP
14470 INSERT INTO AHL_APPLICABLE_MRS (
14471 CSI_ITEM_INSTANCE_ID,
14472 MR_HEADER_ID,
14473 MR_EFFECTIVITY_ID,
14474 REPETITIVE_FLAG ,
14475 SHOW_REPETITIVE_CODE,
14476 COPY_ACCOMPLISHMENT_CODE,
14477 PRECEDING_MR_HEADER_ID,
14478 IMPLEMENT_STATUS_CODE,
14479 DESCENDENT_COUNT,
14480 PROCESS_STATUS_FLAG,
14481 PROCESSING_ORDER
14482 )
14483 VALUES (
14484 l_appl_mrs_tbl(i).item_instance_id,
14485 l_appl_mrs_tbl(i).mr_header_id,
14486 l_appl_mrs_tbl(i).mr_effectivity_id,
14487 l_appl_mrs_tbl(i).repetitive_flag,
14488 l_appl_mrs_tbl(i).show_repetitive_code,
14489 l_appl_mrs_tbl(i).copy_accomplishment_flag,
14490 l_appl_mrs_tbl(i).preceding_mr_header_id,
14491 l_appl_mrs_tbl(i).implement_status_code,
14492 l_appl_mrs_tbl(i).descendent_count,
14493 'N',
14494 1
14495 );
14496 END LOOP;
14497 END IF;
14498 END LOOP; -- l_mr_id_tbl
14499 END LOOP; -- FETCH
14500 CLOSE get_mr_csr;
14501
14502 END LOOP; -- G_Config_Node
14503 END IF; -- IF G_Config_Node
14504
14505 END Process_Appl_Expired_MRs;
14506
14507 -------------------------------------------------------------
14508 -- JKJain
14509 -- Added this procedure for R12.2 Supplier Warranty Enhancements
14510 -- Procedure to calculate Expiration Date of Contract based on Counter details.
14511 PROCEDURE Get_Cont_Ctr_Expiration_Date (p_item_instance_id IN NUMBER,
14512 p_x_warranty_counter_tbl IN OUT NOCOPY warranty_counter_tbl_type,
14513 x_expiration_date OUT NOCOPY DATE,
14514 x_return_status OUT NOCOPY VARCHAR2,
14515 x_msg_data OUT NOCOPY VARCHAR2,
14516 x_msg_count OUT NOCOPY NUMBER)
14517 IS
14518
14519 -- Get Item Detailsdetails.
14520
14521 CURSOR ahl_item_instance_csr (p_item_instance_id IN NUMBER) IS
14522 SELECT cii.inventory_item_id,
14523 cii.inv_master_organization_id
14524 FROM csi_item_instances cii
14525 WHERE cii.instance_id = p_item_instance_id;
14526
14527
14528 -- get the configuration structure.(G_config_node_tbl).
14529 CURSOR csi_reln_csr ( p_csi_item_instance_id IN NUMBER) IS
14530 SELECT position_reference
14531 FROM csi_ii_relationships
14532 WHERE subject_id = p_csi_item_instance_id
14533 AND relationship_type_code = 'COMPONENT-OF'
14534 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
14535 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1));
14536
14537 -- get the counter usage
14538 CURSOR cs_ctr_counter_csr (--p_csi_item_instance_id IN NUMBER,
14539 p_counter_id IN NUMBER) IS
14540
14541 select nvl(ccr.net_reading,0) net_reading
14542 FROM csi_counters_b cc, csi_counter_readings ccr
14543 WHERE cc.counter_id = p_counter_id
14544 and ccr.counter_value_id = cc.CTR_VAL_MAX_SEQ_NO;
14545
14546 i NUMBER;
14547 l_root_csi_instance_id NUMBER;
14548 l_uc_header_id NUMBER;
14549 l_calc_due_date DATE;
14550 l_due_date DATE;
14551 l_inv_master_organization_id number;
14552 l_inventory_item_id number;
14553 l_position_reference VARCHAR2(30);
14554 l_counter_rules_tbl counter_rules_tbl_type;
14555 l_counter_value number;
14556 l_counter_remain number;
14557 l_user_id NUMBER;
14558 l_login_id NUMBER;
14559
14560
14561 BEGIN
14562
14563 -- Set return status.
14564 x_return_status := FND_API.G_RET_STS_SUCCESS;
14565
14566 -- Enable Debug.
14567 IF G_DEBUG = 'Y' THEN
14568 AHL_DEBUG_PUB.enable_debug;
14569 END IF;
14570
14571 -- Add debug mesg.
14572 IF G_DEBUG = 'Y' THEN
14573 AHL_DEBUG_PUB.debug('Begin private API:' || G_PKG_NAME || '.' || 'Get_Cont_Ctr_Expiration_Date');
14574 AHL_DEBUG_PUB.debug('Dump of input parameters:');
14575 AHL_DEBUG_PUB.debug('Item Instance ID:' || p_item_instance_id);
14576 AHL_DEBUG_PUB.debug('Count on p_x_warranty_counter_tbl:' || p_x_warranty_counter_tbl.COUNT);
14577 END IF;
14578
14579 -- Validate input parameters.
14580 IF (p_item_instance_id IS NULL OR p_item_instance_id = FND_API.G_MISS_NUM) THEN
14581 FND_MESSAGE.Set_Name('AHL','AHL_UMP_CONT_ITEM_ID_NULL');
14582 FND_MSG_PUB.ADD;
14583 RAISE FND_API.G_EXC_ERROR;
14584 ELSE
14585 OPEN ahl_item_instance_csr (p_item_instance_id);
14586 FETCH ahl_item_instance_csr INTO l_inventory_item_id, l_inv_master_organization_id;
14587 IF (ahl_item_instance_csr%NOTFOUND) THEN
14588 FND_MESSAGE.Set_Name('AHL','AHL_UMP_CONT_ITEM_ID_INVALID');
14589 FND_MESSAGE.Set_Token('Item_Instance_ID', p_item_instance_id);
14590 FND_MSG_PUB.ADD;
14591 CLOSE ahl_item_instance_csr;
14592 RAISE FND_API.G_EXC_ERROR;
14593 END IF;
14594 CLOSE ahl_item_instance_csr;
14595 END IF;
14596
14597
14598 IF G_DEBUG = 'Y' THEN
14599 AHL_DEBUG_PUB.debug('Step 1');
14600 AHL_DEBUG_PUB.debug('Inventory Item ID:' || l_inventory_item_id);
14601 AHL_DEBUG_PUB.debug('INV master Org ID:' || l_inv_master_organization_id);
14602 END IF;
14603
14604 -- Get Unit and Master Config IDs if available.
14605 -- Find the root item instance.
14606 l_root_csi_instance_id := Get_RootInstanceID(p_item_instance_id);
14607
14608 -- Get master and unit configuration for the root item instance.
14609 Get_Unit_Master_ConfigIDs (l_root_csi_instance_id,
14610 l_uc_header_id, G_master_config_id);
14611
14612
14613 -- Check for errors.
14614 IF FND_MSG_PUB.Count_msg > 0 THEN
14615 RAISE FND_API.G_EXC_ERROR;
14616 END IF;
14617
14618 -- Get utilization forecast for the unit/part.
14619 Get_Utilization_Forecast (l_root_csi_instance_id,
14620 l_uc_header_id,
14621 l_inventory_item_id,
14622 l_inv_master_organization_id,
14623 G_forecast_details_tbl);
14624
14625 IF G_DEBUG = 'Y' THEN
14626 AHL_DEBUG_PUB.debug('Count on util forecast tbl:' || G_forecast_details_tbl.count);
14627 END IF;
14628
14629 -- Get the position installed in.
14630 OPEN csi_reln_csr(p_item_instance_id);
14631 FETCH csi_reln_csr INTO l_position_reference;
14632 IF (csi_reln_csr%NOTFOUND) THEN
14633 l_position_reference := G_master_config_id;
14634 END IF;
14635 CLOSE csi_reln_csr;
14636
14637 -- Build counter rules ratio if node is not root node.
14638 IF (G_master_config_id IS NOT NULL AND l_position_reference IS NOT NULL) THEN
14639 build_Counter_Ratio(l_position_reference,
14640 p_item_instance_id,
14641 G_master_config_id,
14642 l_counter_rules_tbl);
14643 END IF;
14644
14645 -- Calculate counter_remain and call get_date_from_uf.
14646 IF (p_x_warranty_counter_tbl.COUNT > 0) THEN
14647
14648 l_user_id := to_number(fnd_global.USER_ID);
14649 l_login_id := to_number(fnd_global.LOGIN_ID);
14650 l_calc_due_date := null ;
14651 l_due_date := null;
14652
14653 FOR i IN p_x_warranty_counter_tbl.FIRST..p_x_warranty_counter_tbl.LAST LOOP
14654 -- get current usage
14655 --OPEN cs_ctr_counter_csr(l_csi_item_instance_id, p_x_warranty_counter_tbl(i).counter_id);
14656 OPEN cs_ctr_counter_csr(p_x_warranty_counter_tbl(i).counter_id);
14657 FETCH cs_ctr_counter_csr INTO l_counter_value;
14658 IF (cs_ctr_counter_csr%NOTFOUND) THEN
14659 IF G_DEBUG = 'Y' THEN
14660 AHL_DEBUG_PUB.debug('Step 7');
14661 END IF;
14662 l_counter_value := 0;
14663 END IF;
14664
14665 CLOSE cs_ctr_counter_csr;
14666
14667 IF G_DEBUG = 'Y' THEN
14668 AHL_DEBUG_PUB.debug('l_counter_value:' || l_counter_value);
14669 END IF;
14670
14671 -- Get due date for counter remain.
14672 l_counter_remain := p_x_warranty_counter_tbl(i).max_counter_value - l_counter_value;
14673
14674 IF G_DEBUG = 'Y' THEN
14675 AHL_DEBUG_PUB.debug('l_counter_remain:' || l_counter_remain);
14676 END IF;
14677
14678 -- get date from forecast.
14679 get_date_from_uf(l_counter_remain,
14680 p_x_warranty_counter_tbl(i).uom_code,
14681 l_counter_rules_tbl,
14682 sysdate,
14683 l_due_date);
14684
14685 IF (l_due_date IS NOT NULL) THEN
14686 IF(l_calc_due_date IS NULL) THEN
14687 l_calc_due_date := l_due_date;
14688 ELSIF(l_calc_due_date > l_due_date) THEN
14689 l_calc_due_date := l_due_date;
14690 END IF;
14691 END IF;
14692
14693 IF G_DEBUG = 'Y' THEN
14694 AHL_DEBUG_PUB.debug('Table AHL_WARRANTY_CONT_CTR_B will be updated by Expiration Date ' || l_due_date || ' where WARRANTY_CNTRT_COUNTER_ID = '||p_x_warranty_counter_tbl(i).warranty_cntrt_counter_id);
14695 END IF;
14696 p_x_warranty_counter_tbl(i).counter_expiration_date := l_due_date;
14697 END LOOP;
14698 END IF;
14699 x_expiration_date := l_calc_due_date;
14700
14701 -- Standard call to get message count and if count is 1, get message info
14702 FND_MSG_PUB.Count_And_Get
14703 ( p_count => x_msg_count,
14704 p_data => x_msg_data,
14705 p_encoded => fnd_api.g_false
14706 );
14707
14708 --
14709 EXCEPTION
14710 WHEN FND_API.G_EXC_ERROR THEN
14711 x_return_status := FND_API.G_RET_STS_ERROR;
14712 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
14713 p_data => x_msg_data,
14714 p_encoded => fnd_api.g_false);
14715
14716 -- Disable debug
14717 AHL_DEBUG_PUB.disable_debug;
14718
14719 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
14720 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
14721 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
14722 p_data => x_msg_data,
14723 p_encoded => fnd_api.g_false);
14724
14725 -- Disable debug
14726 AHL_DEBUG_PUB.disable_debug;
14727
14728 WHEN OTHERS THEN
14729
14730 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
14731 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
14732 fnd_msg_pub.add_exc_msg(p_pkg_name => G_PKG_NAME,
14733 p_procedure_name => 'Get_Cont_Ctr_Expiration_Date',
14734 p_error_text => SUBSTR(SQLERRM,1,240));
14735 END IF;
14736 FND_MSG_PUB.count_and_get( p_count => x_msg_count,
14737 p_data => x_msg_data,
14738 p_encoded => fnd_api.g_false);
14739
14740
14741 -- Disable debug
14742 AHL_DEBUG_PUB.disable_debug;
14743
14744 END Get_Cont_Ctr_Expiration_Date;
14745 -------------------------------------------------------
14746
14747 -- If MR has a accomplishment trigger of 'terminated_by' then check if parent MRs are processed
14748 -- and if not, process them.
14749 -- added for SB Enh.
14750 PROCEDURE Process_Terminating_Parent_MRs(p_applicable_mrs_rec IN applicable_mrs_rec_type,
14751 p_current_usage_tbl IN counter_values_tbl_type,
14752 p_counter_rules_tbl IN counter_rules_tbl_type,
14753 x_mr_termination_date OUT NOCOPY DATE)
14754
14755 IS
14756
14757 CURSOR get_parent_csr (p_mr_header_id IN NUMBER,
14758 p_item_instance_id IN NUMBER) IS
14759 SELECT amr.mr_header_id,
14760 mr.version_number,
14761 apmr.csi_item_instance_id,
14762 apmr.Implement_status_code,
14763 apmr.copy_accomplishment_code,
14764 apmr.show_repetitive_code,
14765 apmr.descendent_count,
14766 mr.whichever_first_code,
14767 apmr.repetitive_flag,
14768 mr.title,
14769 mr.effective_from,
14770 mr.effective_to,
14771 apmr.process_status_flag,
14772 apmr.accomplished_ue_id,
14773 apmr.terminate_trigger_check
14774 FROM ahl_mr_relationships amr, ahl_applicable_mrs apmr, ahl_mr_headers_b mr
14775 WHERE amr.related_mr_header_id = p_mr_header_id
14776 AND amr.mr_header_id = apmr.mr_header_id
14777 AND amr.relationship_code = 'TERMINATES'
14778 AND amr.mr_header_id = mr.mr_header_id
14779 AND apmr.csi_item_instance_id = p_item_instance_id;
14780 -- select only those MRs that are unprocessed
14781 -- AND apmr.process_status_flag = 'N';
14782
14783 l_unprocessed_parent_rec applicable_mrs_rec_type;
14784
14785 CURSOR get_earliest_date_csr(p_mr_header_id IN NUMBER,
14786 p_instance_id IN NUMBER) IS
14787 SELECT * FROM (
14788 SELECT due_date, visit_end_date
14789 FROM ahl_temp_unit_effectivities
14790 WHERE csi_item_instance_id = p_instance_id AND
14791 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1
14792 where mr1.title = (select mr2.title from ahl_mr_headers_b mr2 where mr2.mr_header_id = p_mr_header_id)
14793 ) AND
14794 preceding_check_flag = 'N'
14795
14796 UNION
14797 SELECT due_date, visit_end_date
14798 FROM ahl_temp_unit_SR_deferrals
14799 WHERE csi_item_instance_id = p_instance_id AND
14800 mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1
14801 where mr1.title = (select mr2.title from ahl_mr_headers_b mr2 where mr2.mr_header_id = p_mr_header_id)
14802 )
14803 ORDER by due_date
14804 )
14805 WHERE ROWNUM < 2;
14806
14807 l_termination_date DATE;
14808 l_terminating_mr_header_id NUMBER;
14809 l_due_date DATE;
14810 l_visit_end_date DATE;
14811
14812 l_acc_unit_effectivity_id NUMBER;
14813 l_acc_deferral_flag BOOLEAN;
14814 l_acc_status_code VARCHAR2(30);
14815 l_return_val BOOLEAN;
14816
14817 BEGIN
14818 IF G_DEBUG = 'Y' THEN
14819 AHL_DEBUG_PUB.Debug('Start Process_Terminating_Parent_MRs');
14820 AHL_DEBUG_PUB.Debug('For applicable MR:CSI:' || p_applicable_mrs_rec.MR_header_id || ':' || p_applicable_mrs_rec.csi_item_instance_id);
14821 END IF;
14822 --dbms_output.put_line('Start Process_Terminating_Parent_MRs:' || p_applicable_mrs_rec.MR_header_id || ':' || p_applicable_mrs_rec.csi_item_instance_id);
14823
14824 -- process parent MRs
14825 FOR l_appl_rec IN get_parent_csr(p_applicable_mrs_rec.mr_header_id,
14826 p_applicable_mrs_rec.csi_item_instance_id)
14827 LOOP
14828
14829 IF G_DEBUG = 'Y' THEN
14830 AHL_DEBUG_PUB.Debug('Found applicable Terminating parent MR:CSI:' || l_appl_rec.MR_header_id || ':' || l_appl_rec.csi_item_instance_id);
14831 END IF;
14832 --dbms_output.put_line('Found applicable Terminating parent MR:CSI:' || l_appl_rec.MR_header_id || ':' || l_appl_rec.csi_item_instance_id || ':' || l_appl_rec.process_status_flag);
14833
14834 l_due_date := null;
14835
14836 IF (l_appl_rec.process_status_flag = 'N' OR l_appl_rec.accomplished_ue_id IS NOT NULL) THEN
14837 -- in the case of unprocessed parent, check if parent MR is already accomplished. If yes, we do not need to process
14838 -- parent and instead we use the first accomplishment date.
14839 -- in case parent is already processed and has at least one accomplishment, we get the first one.
14840 -- get first accomplishment.
14841 AHL_UMP_UTIL_PKG.get_first_accomplishment(l_appl_rec.csi_item_instance_id,
14842 l_appl_rec.mr_header_id,
14843 l_due_date,
14844 l_acc_unit_effectivity_id,
14845 l_acc_deferral_flag,
14846 l_acc_status_code,
14847 l_return_val);
14848 IF G_DEBUG = 'Y' THEN
14849 AHL_DEBUG_PUB.Debug('first accomplishment:due date:UEID:' || l_due_date || ':' || l_acc_unit_effectivity_id);
14850 --dbms_output.put_line('first accomplishment:due date:UEID:' || l_due_date || ':' || l_acc_unit_effectivity_id);
14851 END IF;
14852 END IF;
14853
14854 IF (l_appl_rec.process_status_flag = 'N' AND l_acc_unit_effectivity_id IS NULL) THEN
14855
14856 -- Build applicable_mrs_rec.
14857 l_unprocessed_parent_rec.csi_item_instance_id := l_appl_rec.csi_item_instance_id;
14858 l_unprocessed_parent_rec.MR_header_id := l_appl_rec.MR_header_id;
14859 l_unprocessed_parent_rec.Implement_status_code := l_appl_rec.Implement_status_code;
14860 l_unprocessed_parent_rec.copy_accomplishment_code := l_appl_rec.copy_accomplishment_code;
14861 l_unprocessed_parent_rec.show_repetitive_code := l_appl_rec.show_repetitive_code;
14862 l_unprocessed_parent_rec.preceding_mr_header_id := null;
14863 l_unprocessed_parent_rec.descendent_count := l_appl_rec.descendent_count;
14864 l_unprocessed_parent_rec.whichever_first_code := l_appl_rec.whichever_first_code;
14865 l_unprocessed_parent_rec.repetitive_flag := l_appl_rec.repetitive_flag;
14866 l_unprocessed_parent_rec.title := l_appl_rec.title;
14867 l_unprocessed_parent_rec.version_number := l_appl_rec.version_number;
14868 l_unprocessed_parent_rec.effective_to := l_appl_rec.effective_to;
14869 l_unprocessed_parent_rec.effective_from := l_appl_rec.effective_from;
14870
14871 -- added for bug# 9263774
14872 IF (l_appl_rec.effective_to < sysdate) THEN
14873 l_unprocessed_parent_rec.expired_mr_flag := 'Y';
14874 ELSE
14875 l_unprocessed_parent_rec.expired_mr_flag := 'N';
14876 END IF;
14877
14878 l_unprocessed_parent_rec.terminate_trigger_check := l_appl_rec.terminate_trigger_check;
14879
14880 --dbms_output.put_line('Calling Build Unit Effe for terminationg parent MR and CSI:exp flag:' || l_unprocessed_parent_rec.expired_mr_flag);
14881
14882 Build_Effectivity (p_applicable_mrs_rec => l_unprocessed_parent_rec,
14883 p_current_usage_tbl => p_current_usage_tbl,
14884 p_counter_rules_tbl => p_counter_rules_tbl);
14885
14886
14887 -- get earliest date.
14888 OPEN get_earliest_date_csr(l_appl_rec.MR_header_id, l_appl_rec.csi_item_instance_id);
14889 FETCH get_earliest_date_csr INTO l_due_date, l_visit_end_date;
14890 IF (get_earliest_date_csr%NOTFOUND) THEN
14891 CLOSE get_earliest_date_csr;
14892 l_termination_date := NULL;
14893 l_terminating_mr_header_id := l_appl_rec.MR_header_id;
14894 EXIT;
14895 END IF;
14896 CLOSE get_earliest_date_csr;
14897 -- if UE is assigned to visit, then consider l_visit_end_date
14898 IF (l_visit_end_date IS NOT NULL) THEN
14899 l_due_date := l_visit_end_date;
14900 END IF;
14901 ELSIF (l_acc_unit_effectivity_id IS NULL) THEN
14902 -- processed case.
14903 -- get date from temp tables
14904 OPEN get_earliest_date_csr(l_appl_rec.MR_header_id, l_appl_rec.csi_item_instance_id);
14905 FETCH get_earliest_date_csr INTO l_due_date, l_visit_end_date;
14906 IF (get_earliest_date_csr%NOTFOUND) THEN
14907 CLOSE get_earliest_date_csr;
14908 l_termination_date := NULL;
14909 l_terminating_mr_header_id := l_appl_rec.MR_header_id;
14910 EXIT;
14911 END IF;
14912 CLOSE get_earliest_date_csr;
14913 -- if UE is assigned to visit, then consider l_visit_end_date
14914 IF (l_visit_end_date IS NOT NULL) THEN
14915 l_due_date := l_visit_end_date;
14916 END IF;
14917 END IF;
14918
14919 -- dbms_output.put_line('dates:term:due date:' || l_termination_date || ':' || l_due_date);
14920 -- evaluate later of termination date or due date
14921 IF (l_terminating_mr_header_id IS NULL) THEN
14922 l_terminating_mr_header_id := l_appl_rec.MR_header_id;
14923 l_termination_date := l_due_date;
14924 ELSIF (trunc(l_termination_date) < trunc(l_due_date)) THEN
14925 l_terminating_mr_header_id := l_appl_rec.MR_header_id;
14926 l_termination_date := l_due_date;
14927 END IF; -- l_terminating_mr_header_id
14928 END LOOP;
14929
14930 l_termination_date := trunc(l_termination_date);
14931
14932 IF (l_termination_date IS NOT NULL) THEN
14933 UPDATE AHL_APPLICABLE_MRS
14934 set TERMINATION_DATE = l_termination_date,
14935 TERMINATING_MR_HEADER_ID = l_terminating_mr_header_id
14936 where mr_header_id = p_applicable_mrs_rec.mr_header_id
14937 and csi_item_instance_id = p_applicable_mrs_rec.csi_item_instance_id;
14938 END IF;
14939 x_mr_termination_date := l_termination_date;
14940
14941 -- dbms_output.put_line('term date:' || l_termination_date );
14942
14943 IF G_DEBUG = 'Y' THEN
14944 AHL_DEBUG_PUB.Debug('End Process_Terminating_Parent_MRs');
14945 END IF;
14946
14947 END Process_Terminating_Parent_MRs;
14948 --------------------------------------------------------------------
14949
14950 -- initialization procedure for loops
14951 PROCEDURE Process_Loop_Init(p_applicable_mrs_rec IN applicable_mrs_rec_type,
14952 p_current_usage_tbl IN counter_values_tbl_type,
14953 p_counter_rules_tbl IN counter_rules_tbl_type,
14954 x_loop_chain_MR_tbl OUT NOCOPY loop_chain_MR_tbl_type,
14955 x_next_due_skip_flag OUT NOCOPY VARCHAR2,
14956 x_loop_last_due_date OUT NOCOPY DATE,
14957 x_loop_last_counter_val_tbl OUT NOCOPY counter_values_tbl_type)
14958 IS
14959
14960 -- get child loop or chain MRs
14961 CURSOR get_lp_chain_mrs(p_start_mr_header_id IN NUMBER,
14962 p_csi_item_instance_id IN NUMBER) IS
14963 SELECT apmr.mr_header_id, apmr.loop_chain_seq_num, mr.title
14964 FROM ahl_applicable_MRs apmr, ahl_mr_headers_b mr
14965 WHERE apmr.mr_header_id = mr.mr_header_id
14966 AND apmr.csi_item_instance_id = p_csi_item_instance_id
14967 AND apmr.start_mr_header_id = p_start_mr_header_id
14968 ORDER BY loop_chain_seq_num ASC;
14969
14970 -- get deferrals for all loop MRs.
14971 -- only 1 deferral to exist
14972 CURSOR ahl_defer_csr (p_csi_instance_id IN NUMBER,
14973 p_mr_header_id IN NUMBER) IS
14974 SELECT * FROM
14975 (SELECT
14976 decode (def.affect_due_calc_flag, 'N', def.deferral_effective_on, nvl(def.visit_end_date, def.due_date)) accomplishment_date,
14977 unit_effectivity_id
14978 FROM ahl_temp_unit_SR_deferrals def, ahl_mr_headers_b mr1,
14979 (select title from ahl_mr_headers_b
14980 where mr_header_id IN (select mr_header_id from ahl_applicable_MRs
14981 where csi_item_instance_id = p_csi_instance_id
14982 and start_mr_header_id = p_mr_header_id)
14983 ) mr2
14984 WHERE def.csi_item_instance_id = p_csi_instance_id
14985 AND def.mr_header_id = mr1.mr_header_id
14986 AND mr1.title = mr2.title
14987 AND def.object_type = 'MR'
14988 AND def.deferral_effective_on IS NOT NULL
14989 ORDER BY def.deferral_effective_on DESC
14990 ) WHERE ROWNUM < 2;
14991 -- get the latest deferral.
14992 -- pick only deferrals and not SR related MRs.
14993
14994 CURSOR ahl_ue_csr (p_unit_effectivity_id IN NUMBER) IS
14995 SELECT loop_chain_seq_num, start_lc_ue_id
14996 FROM ahl_unit_effectivities_b
14997 WHERE unit_effectivity_id = p_unit_effectivity_id;
14998
14999
15000 l_mr_tbl nbr_tbl_type;
15001 l_mr_seq_num nbr_tbl_type;
15002 l_mr_title_tbl vchar_tbl_type;
15003
15004 l_loop_chain_MR_tbl loop_chain_MR_tbl_type;
15005 --l_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
15006
15007 l_lc_mr_accomplishment_date DATE;
15008 l_lc_acc_ue_id NUMBER;
15009 l_lc_acc_deferral_flag BOOLEAN;
15010 l_lc_acc_status_code ahl_unit_effectivities_app_v.status_code%TYPE;
15011 l_lc_return_val BOOLEAN;
15012
15013 l_max_acc_date DATE;
15014 l_last_acc_ue_id NUMBER;
15015 l_loop_chain_seq_num NUMBER;
15016 l_start_lc_ue_id NUMBER;
15017 l_found_deferral VARCHAR2(1);
15018
15019 l_no_forecast_flag BOOLEAN;
15020 l_last_acc_counter_val_tbl counter_values_tbl_type;
15021 l_new_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
15022
15023 l_loop_due_date DATE;
15024 l_loop_last_due_date DATE;
15025 l_loop_last_counter_val_tbl counter_values_tbl_type;
15026
15027 BEGIN
15028 IF G_DEBUG = 'Y' THEN
15029 AHL_DEBUG_PUB.Debug('Start Process_Loop_Init:CSI:MR:' || p_applicable_mrs_rec.csi_item_instance_id || ':' || p_applicable_mrs_rec.mr_header_id);
15030 END IF;
15031
15032 -- get loop or chain MRs.
15033 OPEN get_lp_chain_mrs(p_applicable_mrs_rec.mr_header_id,
15034 p_applicable_mrs_rec.csi_item_instance_id);
15035 FETCH get_lp_chain_mrs BULK COLLECT INTO l_mr_tbl, l_mr_seq_num, l_mr_title_tbl;
15036 CLOSE get_lp_chain_mrs;
15037
15038
15039 IF (l_mr_tbl.count > 0) THEN
15040 FOR i IN l_mr_tbl.FIRST..l_mr_tbl.LAST LOOP
15041 l_loop_chain_MR_tbl(i).mr_header_id := l_mr_tbl(i);
15042 l_loop_chain_MR_tbl(i).loop_chain_seq_num := l_mr_seq_num(i);
15043 l_loop_chain_MR_tbl(i).accomplishment_exists := 'N';
15044 l_loop_chain_MR_tbl(i).mr_title := l_mr_title_tbl(i);
15045
15046 -- check if MR is accomplished at least once.
15047 AHL_UMP_UTIL_PKG.get_last_accomplishment(p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
15048 p_mr_header_id => l_mr_tbl(i),
15049 x_accomplishment_date => l_lc_mr_accomplishment_date,
15050 x_unit_effectivity_id => l_lc_acc_ue_id,
15051 x_deferral_flag => l_lc_acc_deferral_flag,
15052 x_status_code => l_lc_acc_status_code,
15053 x_return_val => l_lc_return_val);
15054 IF (NOT(l_lc_return_val)) THEN
15055 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
15056 ELSE
15057 IF (l_lc_acc_ue_id IS NOT NULL) THEN
15058 l_loop_chain_MR_tbl(i).accomplishment_exists := 'Y';
15059 l_loop_chain_MR_tbl(i).accomplished_ue_id := l_lc_acc_ue_id;
15060 IF (l_max_acc_date IS NULL) THEN
15061 l_max_acc_date := l_lc_mr_accomplishment_date;
15062 l_last_acc_ue_id := l_lc_acc_ue_id;
15063 -- consider = as well to pick the later loop seq.
15064 ELSIF (l_max_acc_date <= l_lc_mr_accomplishment_date) THEN
15065 l_max_acc_date := l_lc_mr_accomplishment_date;
15066 l_last_acc_ue_id := l_lc_acc_ue_id;
15067 END IF;
15068 END IF;
15069 END IF; -- l_acc_unit_effectivity_id
15070 END LOOP;
15071
15072 x_loop_chain_MR_tbl := l_loop_chain_MR_tbl;
15073
15074 l_found_deferral := 'N';
15075 -- check if there are any deferrals. If yes, start loop from there.
15076 OPEN ahl_defer_csr (p_applicable_mrs_rec.csi_item_instance_id,
15077 p_applicable_mrs_rec.mr_header_id);
15078 FETCH ahl_defer_csr INTO l_max_acc_date, l_last_acc_ue_id;
15079 IF (ahl_defer_csr%FOUND) THEN
15080 l_found_deferral := 'Y';
15081 END IF;
15082 CLOSE ahl_defer_csr;
15083
15084 IF (l_last_acc_ue_id IS NOT NULL) THEN
15085 -- get ue details
15086 OPEN ahl_ue_csr(l_last_acc_ue_id);
15087 FETCH ahl_ue_csr INTO l_loop_chain_seq_num, l_start_lc_ue_id;
15088 IF (ahl_ue_csr%NOTFOUND) THEN
15089 FND_MESSAGE.Set_Name('AHL','AHL_UMP_UE_INVALID');
15090 FND_MESSAGE.Set_Token('UE_ID',l_last_acc_ue_id );
15091 FND_MSG_PUB.ADD;
15092 CLOSE ahl_ue_csr;
15093 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
15094 END IF;
15095 CLOSE ahl_ue_csr;
15096 END IF;
15097
15098 -- check if loop seq is last seq.
15099 IF (l_last_acc_ue_id IS NULL) OR (l_loop_chain_seq_num IS NOT NULL AND l_loop_chain_seq_num = l_mr_seq_num.count) THEN
15100 x_next_due_skip_flag := 'N';
15101 RETURN; -- start at the beginning of the loop
15102 END IF;
15103
15104 -- start calculation from l_loop_chain_seq_num
15105 -- get counter values for date.
15106 get_instance_ctr_for_date (p_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
15107 p_last_accomplishment_date => l_max_acc_date,
15108 p_deferral_flag => l_found_deferral,
15109 p_unit_effectivity_id => l_last_acc_ue_id,
15110 p_current_usage_tbl => p_current_usage_tbl,
15111 p_counter_rules_tbl => p_counter_rules_tbl,
15112 x_no_forecast_flag => l_no_forecast_flag,
15113 x_last_acc_counter_val_tbl => l_last_acc_counter_val_tbl);
15114
15115 -- ignore l_no_forecast_flag check as we need to create null rows for due date.
15116 -- initialize l_new_unit_effectivity_rec
15117 l_new_unit_effectivity_rec.due_date := l_max_acc_date;
15118 l_new_unit_effectivity_rec.unit_effectivity_id := l_last_acc_ue_id;
15119 l_new_unit_effectivity_rec.loop_chain_seq_num := l_loop_chain_seq_num;
15120 l_new_unit_effectivity_rec.start_lc_ue_id := l_start_lc_ue_id;
15121 l_new_unit_effectivity_rec.start_mr_header_id := p_applicable_mrs_rec.mr_header_id;
15122 l_new_unit_effectivity_rec.accomplish_trigger_type := p_applicable_mrs_rec.accomplish_trigger_type;
15123 l_new_unit_effectivity_rec.visit_end_date := null;
15124 l_new_unit_effectivity_rec.repetitive_mr_flag := 'N';
15125 l_new_unit_effectivity_rec.forecast_sequence := 1;
15126
15127 Process_Loop_Chain_MRs (p_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
15128 p_repetivity_flag => 'N',
15129 p_new_unit_effectivity_rec => l_new_unit_effectivity_rec,
15130 p_current_usage_tbl => p_current_usage_tbl,
15131 p_counter_rules_tbl => p_counter_rules_tbl,
15132 p_last_due_date => l_max_acc_date,
15133 p_last_due_counter_val_tbl => l_last_acc_counter_val_tbl,
15134 p_loop_chain_MR_tbl => l_loop_chain_MR_tbl,
15135 x_loop_due_date => l_loop_due_date,
15136 x_loop_last_due_date => l_loop_last_due_date,
15137 x_loop_last_counter_val_tbl => l_loop_last_counter_val_tbl);
15138
15139
15140 END IF; -- l_mr_tbl.count
15141
15142 IF (p_applicable_mrs_rec.accomplish_trigger_type = 'LOOP') THEN
15143 --x_loop_due_date := l_loop_due_date;
15144 x_next_due_skip_flag := 'Y';
15145 x_loop_last_due_date := l_loop_last_due_date;
15146 x_loop_last_counter_val_tbl := l_loop_last_counter_val_tbl;
15147 IF G_DEBUG = 'Y' THEN
15148 AHL_DEBUG_PUB.Debug('Start MR due date:' || x_loop_last_due_date);
15149 IF (x_loop_last_counter_val_tbl.count > 0) THEN
15150 FOR i in x_loop_last_counter_val_tbl.FIRST..x_loop_last_counter_val_tbl.LAST LOOP
15151 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || x_loop_last_counter_val_tbl(i).counter_value || 'ID: ' || x_loop_last_counter_val_tbl(i).counter_id);
15152 END LOOP;
15153 END IF;
15154 END IF;
15155 END IF;
15156
15157
15158 IF G_DEBUG = 'Y' THEN
15159 AHL_DEBUG_PUB.Debug('End Process_Loop_Init');
15160 END IF;
15161
15162
15163 END Process_Loop_Init;
15164 ------------------------------------------------------------
15165
15166 -- initialization procedure for chains
15167 PROCEDURE Process_Chain_Init(p_applicable_mrs_rec IN applicable_mrs_rec_type,
15168 p_current_usage_tbl IN counter_values_tbl_type,
15169 p_counter_rules_tbl IN counter_rules_tbl_type,
15170 x_loop_chain_MR_tbl OUT NOCOPY loop_chain_MR_tbl_type)
15171
15172 IS
15173
15174 -- get child loop or chain MRs
15175 CURSOR get_lp_chain_mrs(p_start_mr_header_id IN NUMBER,
15176 p_csi_item_instance_id IN NUMBER) IS
15177 SELECT apmr.mr_header_id, apmr.loop_chain_seq_num, mr.title
15178 FROM ahl_applicable_MRs apmr, ahl_mr_headers_b mr
15179 WHERE apmr.mr_header_id = mr.mr_header_id
15180 AND apmr.csi_item_instance_id = p_csi_item_instance_id
15181 AND apmr.start_mr_header_id = p_start_mr_header_id
15182 ORDER BY loop_chain_seq_num ASC;
15183
15184 /*
15185 -- get inprogress chain MRs
15186 CURSOR ahl_inprogress_chain_MRs(p_csi_item_instance_id IN NUMBER,
15187 p_mr_header_id IN NUMBER) IS
15188 SELECT ue.start_lc_ue_id,
15189 min(loop_chain_seq_num)
15190 FROM ahl_unit_effectivities_b ue1, ahl_unit_effectivities_b ue2
15191 WHERE ue1.unit_effectivity_id = ue2.start_lc_ue_id
15192 AND ue.csi_item_instance_id = p_csi_item_instance_id
15193 AND ue.status_code IS NOT NULL AND ue.status_code <> 'INIT-DUE'
15194 AND EXISTS (select 'x'
15195 from ahl_mr_headers_b mr_title
15196 (select mr_header_id from ahl_unit_effectivities_b ue1
15197 where unit_effectivity_id = ue.start_lc_ue_id) start_mr
15198 where
15199 and appl_mr.start_mr_header_id = p_mr_header_id
15200 and appl_mr.mr_header_id = mr1.mr_header_id)
15201 AND ue.object_type = 'MR'
15202 AND ue.defer_from_ue_id IS NULL
15203 AND ue.accomplish_trigger_type = 'CHAIN'
15204 AND (ue.status_code IS NULL)
15205 -- parent is accomplished
15206 AND NOT EXISTS (select 'x' from ahl_unit_effectivities_b
15207 where unit_effectivity_id = ue.start_lc_ue_id
15208 AND (status_code is NULL or status_code = 'INIT-DUE')
15209 )
15210 GROUP BY ue.start_lc_ue_id;
15211 */
15212
15213 -- get inprogress chain MRs
15214 CURSOR get_inprogress_chain_MRs(p_start_mr_header_id IN NUMBER,
15215 p_csi_item_instance_id IN NUMBER) IS
15216 SELECT ue.start_lc_ue_id, max(ue.loop_chain_seq_num)
15217 from ahl_unit_effectivities_b ue, ahl_mr_headers_b mr
15218 where ue.csi_item_instance_id = p_csi_item_instance_id
15219 and ue.mr_header_id = mr.mr_header_id
15220 and ue.status_code IN ('ACCOMPLISHED','TERMINATED','INIT-ACCOMPLISHED')
15221 and mr.title in (select title from ahl_applicable_mrs appl, ahl_mr_headers_b mr1
15222 where appl.start_mr_header_id = p_start_mr_header_id
15223 and appl.csi_item_instance_id = p_csi_item_instance_id
15224 and appl.mr_header_id = mr1.mr_header_id
15225 )
15226 and exists (select 'x' from ahl_unit_effectivities_b ue1
15227 where ue1.csi_item_instance_id = p_csi_item_instance_id
15228 and ue1.start_lc_ue_id = ue.start_lc_ue_id
15229 and (ue.STATUS_CODE IS NULL or ue.STATUS_CODE = 'INIT-DUE')
15230 )
15231 group by ue.start_lc_ue_id;
15232
15233 -- get unplanned MRs (where start mr is unplanned and is not accomplished)
15234 CURSOR get_unplanned_start_MRs(p_start_mr_title IN VARCHAR2,
15235 p_csi_item_instance_id IN NUMBER) IS
15236 SELECT ue.unit_effectivity_id,
15237 ue.due_date,
15238 ue.mr_header_id,
15239 to_date(null) visit_end_date
15240 FROM ahl_unit_effectivities_b ue
15241 WHERE ue.mr_header_id IN (select amh.mr_header_id from ahl_mr_headers_b amh where amh.title = p_start_mr_title)
15242 AND ue.csi_item_instance_id = p_csi_item_instance_id
15243 AND ue.status_code IS NULL
15244 AND ue.manually_planned_flag = 'Y'
15245 AND ue.defer_from_ue_id IS NULL
15246 -- Do not pick MRs associated to a SR.
15247 AND NOT EXISTS (SELECT 'x'
15248 FROM ahl_ue_relationships uer, ahl_unit_effectivities_b ue1
15249 WHERE uer.related_ue_id = ue.unit_effectivity_id
15250 AND uer.originator_ue_id = ue1.unit_effectivity_id
15251 AND ue1.object_type = 'SR');
15252
15253 -- get deferrals and MRs associated to a SR
15254 CURSOR get_start_def_SR(p_start_mr_title IN VARCHAR2,
15255 p_csi_item_instance_id IN NUMBER) IS
15256 SELECT unit_effectivity_id,
15257 due_date,
15258 mr_header_id,
15259 visit_end_date
15260 FROM ahl_temp_unit_SR_deferrals
15261 WHERE csi_item_instance_id = p_csi_item_instance_id
15262 AND mr_header_id IN (select mr1.mr_header_id from ahl_mr_headers_b mr1 where mr1.title = p_start_mr_title);
15263
15264 -- get chain UE id
15265 CURSOR get_chain_ue_csr(p_start_lc_ue_id in number,
15266 p_chain_seq_num in number) is
15267 SELECT ue.unit_effectivity_id, AHL_UMP_UTIL_PKG.get_Visit_Status (ue.unit_effectivity_id) l_visit_status,
15268 ue.defer_from_ue_id, ue.mr_header_id, mr.title
15269 FROM ahl_unit_effectivities_b ue, ahl_mr_headers_b mr
15270 where ue.mr_header_id = mr.mr_header_id
15271 and ue.start_lc_ue_id = p_start_lc_ue_id
15272 and ue.loop_chain_seq_num = p_chain_seq_num
15273 and ue.accomplish_trigger_type = 'CHAIN';
15274
15275 -- get chain accomplishment
15276 CURSOR get_acc_chain_seq(p_start_lc_ue_id in number,
15277 p_chain_seq_num in number) is
15278 SELECT ue.accomplished_date, ue.unit_effectivity_id, ue.loop_chain_seq_num, ue.mr_header_id,
15279 decode(ue.status_code, 'TERMINATED', ter.affect_due_calc_flag, def.affect_due_calc_flag),
15280 decode(ue.status_code, 'TERMINATED', ter.deferral_effective_on, def.deferral_effective_on)
15281 FROM ahl_unit_effectivities_b ue, ahl_unit_deferrals_b def, ahl_unit_deferrals_b ter
15282 WHERE ue.defer_from_ue_id = def.unit_effectivity_id (+)
15283 AND ue.unit_effectivity_id = ter.unit_effectivity_id(+)
15284 AND ue.status_code IN ('ACCOMPLISHED','INIT-ACCOMPLISHED','TERMINATED')
15285 AND def.unit_deferral_type(+) = 'DEFERRAL'
15286 AND ter.unit_deferral_type(+) = 'DEFERRAL'
15287 AND ue.start_lc_ue_id = p_start_lc_ue_id
15288 AND ue.loop_chain_seq_num = p_chain_seq_num
15289 ORDER BY decode (ue.status_code, 'TERMINATED', ter.deferral_effective_on, ue.accomplished_date) DESC;
15290
15291 -- get deferred or unplanned chain MRs.
15292 CURSOR get_defer_chain_MRs(p_chain_ue_id IN NUMBER) IS
15293 SELECT * FROM
15294 ( SELECT
15295 decode (def.affect_due_calc_flag, 'N', def.deferral_effective_on, nvl(def.visit_end_date, def.due_date)) due_date
15296 FROM ahl_temp_unit_SR_deferrals def
15297 WHERE def.unit_effectivity_id = p_chain_ue_id
15298 AND def.object_type = 'MR'
15299 AND EXISTS (select 'x' from ahl_applicable_mrs
15300 where csi_item_instance_id = def.csi_item_instance_id
15301 and mr_header_id = def.mr_header_id
15302 and accomplish_trigger_type = 'CHAIN')
15303 AND def.deferral_effective_on IS NOT NULL
15304 )
15305 WHERE ROWNUM < 2;
15306
15307 -- get visit end date
15308 CURSOR get_vst_date(p_ue_id IN NUMBER) IS
15309 SELECT vst.close_date_time
15310 from ahl_visits_b vst, ahl_visit_tasks_b tsk
15311 where tsk.unit_effectivity_id = p_ue_id
15312 and tsk.visit_id = vst.visit_id
15313 and tsk.task_type_code = 'SUMMARY';
15314
15315 l_mr_tbl nbr_tbl_type;
15316 l_mr_seq_num nbr_tbl_type;
15317 l_mr_title_tbl vchar_tbl_type;
15318
15319 l_loop_chain_MR_tbl loop_chain_MR_tbl_type;
15320 --l_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
15321
15322 l_lc_mr_accomplishment_date DATE;
15323 l_lc_acc_ue_id NUMBER;
15324 l_lc_acc_deferral_flag BOOLEAN;
15325 l_lc_acc_status_code ahl_unit_effectivities_app_v.status_code%TYPE;
15326 l_lc_return_val BOOLEAN;
15327
15328 l_max_acc_date DATE;
15329 --l_last_acc_ue_id NUMBER;
15330 --l_loop_chain_seq_num NUMBER;
15331 --l_start_lc_ue_id NUMBER;
15332 l_found_deferral VARCHAR2(1);
15333
15334 l_no_forecast_flag BOOLEAN;
15335 l_last_acc_counter_val_tbl counter_values_tbl_type;
15336 l_new_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
15337
15338 l_loop_due_date DATE;
15339 l_loop_last_due_date DATE;
15340 l_loop_last_counter_val_tbl counter_values_tbl_type;
15341
15342 -- chain
15343 l_chain_start_lc_ue_tbl nbr_tbl_type;
15344 l_chain_seq_num_tbl nbr_tbl_type;
15345 l_c_accomplishment_date date;
15346 l_c_unit_effectivity_id number;
15347 l_c_loop_chain_seq_num number;
15348 l_c_mr_header_id number;
15349 l_c_affect_due_calc_flag varchar2(2);
15350 l_c_deferral_effective_on date;
15351
15352 l_chain_ue_id number;
15353 l_visit_status varchar2(30);
15354 l_defer_from_ue_id number;
15355 l_mr_header_id number;
15356 l_mr_title ahl_mr_headers_b.title%TYPE;
15357
15358 l_start_ue_id_tbl nbr_tbl_type;
15359 l_start_due_date_tbl date_tbl_type;
15360 l_start_mr_id_tbl nbr_tbl_type;
15361 l_start_vst_end_tbl date_tbl_type;
15362
15363 l_unplan_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
15364 l_new_unit_effectivity_initrec ahl_temp_unit_effectivities%ROWTYPE;
15365 l_iteration_seq number;
15366
15367 l_visit_start_date DATE;
15368 l_visit_end_date DATE;
15369 l_visit_assign_code fnd_lookups.lookup_code%TYPE;
15370
15371 BEGIN
15372
15373 IF G_DEBUG = 'Y' THEN
15374 AHL_DEBUG_PUB.Debug('Start Process_Chain_Init for MR:CSI:' || p_applicable_mrs_rec.mr_header_id || ':' || p_applicable_mrs_rec.csi_item_instance_id);
15375 END IF;
15376
15377 -- get loop or chain MRs.
15378 OPEN get_lp_chain_mrs(p_applicable_mrs_rec.mr_header_id,
15379 p_applicable_mrs_rec.csi_item_instance_id);
15380 FETCH get_lp_chain_mrs BULK COLLECT INTO l_mr_tbl, l_mr_seq_num, l_mr_title_tbl;
15381 CLOSE get_lp_chain_mrs;
15382
15383
15384 IF (l_mr_tbl.count > 0) THEN
15385 FOR i IN l_mr_tbl.FIRST..l_mr_tbl.LAST LOOP
15386 l_loop_chain_MR_tbl(i).mr_header_id := l_mr_tbl(i);
15387 l_loop_chain_MR_tbl(i).loop_chain_seq_num := l_mr_seq_num(i);
15388 l_loop_chain_MR_tbl(i).accomplishment_exists := 'N';
15389 l_loop_chain_MR_tbl(i).mr_title := l_mr_title_tbl(i);
15390
15391 -- check if MR is accomplished at least once.
15392 AHL_UMP_UTIL_PKG.get_last_accomplishment(p_csi_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
15393 p_mr_header_id => l_mr_tbl(i),
15394 x_accomplishment_date => l_lc_mr_accomplishment_date,
15395 x_unit_effectivity_id => l_lc_acc_ue_id,
15396 x_deferral_flag => l_lc_acc_deferral_flag,
15397 x_status_code => l_lc_acc_status_code,
15398 x_return_val => l_lc_return_val);
15399 IF (NOT(l_lc_return_val)) THEN
15400 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
15401 ELSE
15402 IF (l_lc_acc_ue_id IS NOT NULL) THEN
15403 l_loop_chain_MR_tbl(i).accomplishment_exists := 'Y';
15404 l_loop_chain_MR_tbl(i).accomplished_ue_id := l_lc_acc_ue_id;
15405 END IF;
15406 END IF; -- l_acc_unit_effectivity_id
15407 END LOOP;
15408
15409 x_loop_chain_MR_tbl := l_loop_chain_MR_tbl;
15410 END IF;
15411
15412 -- process chains that are partially accomplished
15413 OPEN get_inprogress_chain_MRs(p_applicable_mrs_rec.mr_header_id,
15414 p_applicable_mrs_rec.csi_item_instance_id);
15415 FETCH get_inprogress_chain_MRs BULK COLLECT INTO l_chain_start_lc_ue_tbl, l_chain_seq_num_tbl;
15416 CLOSE get_inprogress_chain_MRs;
15417
15418 IF G_DEBUG = 'Y' THEN
15419 AHL_DEBUG_PUB.Debug('In progress MRs:count:' || l_chain_start_lc_ue_tbl.count);
15420 END IF;
15421
15422 IF (l_chain_start_lc_ue_tbl.count > 0) THEN
15423 FOR h IN l_chain_start_lc_ue_tbl.FIRST..l_chain_start_lc_ue_tbl.LAST LOOP
15424 -- initialize
15425 l_found_deferral := 'N';
15426
15427 -- get next chain UE details.
15428 OPEN get_chain_ue_csr(l_chain_start_lc_ue_tbl(h), l_chain_seq_num_tbl(h)+1);
15429 FETCH get_chain_ue_csr INTO l_chain_ue_id, l_visit_status, l_defer_from_ue_id, l_mr_header_id, l_mr_title;
15430 IF (get_chain_ue_csr%NOTFOUND) THEN
15431 -- error
15432 FND_MESSAGE.Set_Name('AHL','AHL_UMP_UE_INVALID');
15433 FND_MESSAGE.Set_Token('START_LC_UE_ID',l_chain_start_lc_ue_tbl(h));
15434 FND_MESSAGE.Set_Token('CHAIN_SEQ', l_chain_seq_num_tbl(h)+1);
15435 FND_MSG_PUB.ADD;
15436 CLOSE get_chain_ue_csr;
15437 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
15438 END IF;
15439 CLOSE get_chain_ue_csr;
15440
15441 IF G_DEBUG = 'Y' THEN
15442 AHL_DEBUG_PUB.Debug('Chain UE:' || l_chain_ue_id || ':' || l_defer_from_ue_id || ':' || l_mr_header_id || ':' || l_mr_title);
15443 END IF;
15444
15445 IF (l_loop_chain_MR_tbl.count <= l_chain_seq_num_tbl(h)) OR (l_loop_chain_MR_tbl(l_chain_seq_num_tbl(h)+1).mr_title <> l_mr_title) THEN
15446 IF (l_visit_status IN ('RELEASED','CLOSED')) THEN
15447 -- ue is on shop floor.
15448 IF (l_defer_from_ue_id IS NULL) THEN
15449 -- *****calculate due date only for this instance - rest will not be in a visit and will be deleted.
15450 -- if ue is deferred, due date is already calculated
15451
15452 CONTINUE;
15453 END IF;
15454 END IF;
15455 END IF;
15456
15457 -- if control reaches here, mr title matches
15458 -- start with accomplishment or deferral date.
15459 IF (l_defer_from_ue_id IS NOT NULL) THEN
15460 -- get deferral ue.
15461 OPEN get_defer_chain_MRs(l_chain_ue_id);
15462 FETCH get_defer_chain_MRs INTO l_c_accomplishment_date;
15463 IF (get_defer_chain_MRs%FOUND) THEN
15464 l_found_deferral := 'Y';
15465 END IF;
15466 ELSE
15467 -- get accomplishment dates.
15468 OPEN get_acc_chain_seq(l_chain_start_lc_ue_tbl(h), l_chain_seq_num_tbl(h));
15469 FETCH get_acc_chain_seq INTO l_c_accomplishment_date,
15470 l_c_unit_effectivity_id,
15471 l_c_loop_chain_seq_num,
15472 l_c_mr_header_id,
15473 l_c_affect_due_calc_flag,
15474 l_c_deferral_effective_on;
15475
15476 IF (get_acc_chain_seq%FOUND) THEN
15477 -- dbms_output.put_line ('ue id' || l_unit_effectivity_id);
15478 -- Added for deferral enhancements.
15479 -- Use deferral_effective_on date instead of accomplishment date.
15480 IF (l_c_affect_due_calc_flag = 'N') THEN
15481 l_c_accomplishment_date := l_c_deferral_effective_on;
15482 END IF;
15483 ELSE
15484 -- error
15485 FND_MESSAGE.Set_Name('AHL','AHL_UMP_UE_INVALID');
15486 FND_MESSAGE.Set_Token('START_LC_UE_ID',l_chain_start_lc_ue_tbl(h));
15487 FND_MESSAGE.Set_Token('CHAIN_SEQ', l_chain_seq_num_tbl(h));
15488 FND_MSG_PUB.ADD;
15489 CLOSE get_acc_chain_seq;
15490 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
15491 END IF;
15492 END IF;
15493 CLOSE get_acc_chain_seq;
15494
15495 -- start calculation from l_loop_chain_seq_num
15496 -- get counter values for date.
15497 get_instance_ctr_for_date (p_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
15498 p_last_accomplishment_date => l_c_accomplishment_date,
15499 p_deferral_flag => l_found_deferral,
15500 p_unit_effectivity_id => l_c_unit_effectivity_id,
15501 p_current_usage_tbl => p_current_usage_tbl,
15502 p_counter_rules_tbl => p_counter_rules_tbl,
15503 x_no_forecast_flag => l_no_forecast_flag,
15504 x_last_acc_counter_val_tbl => l_last_acc_counter_val_tbl);
15505
15506 -- ignore l_no_forecast_flag check as we need to create null rows for due date.
15507 -- initialize l_new_unit_effectivity_rec
15508 l_new_unit_effectivity_rec := l_new_unit_effectivity_initrec;
15509 l_new_unit_effectivity_rec.due_date := l_c_accomplishment_date;
15510 l_new_unit_effectivity_rec.unit_effectivity_id := l_c_unit_effectivity_id;
15511 l_new_unit_effectivity_rec.loop_chain_seq_num := l_chain_seq_num_tbl(h);
15512 l_new_unit_effectivity_rec.start_lc_ue_id := l_chain_start_lc_ue_tbl(h);
15513 l_new_unit_effectivity_rec.start_mr_header_id := p_applicable_mrs_rec.mr_header_id;
15514 l_new_unit_effectivity_rec.accomplish_trigger_type := p_applicable_mrs_rec.accomplish_trigger_type;
15515 l_new_unit_effectivity_rec.visit_end_date := null;
15516 l_new_unit_effectivity_rec.repetitive_mr_flag := 'Y';
15517 l_new_unit_effectivity_rec.forecast_sequence := null;
15518
15519 Process_Loop_Chain_MRs (p_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
15520 p_repetivity_flag => 'Y',
15521 p_new_unit_effectivity_rec => l_new_unit_effectivity_rec,
15522 p_current_usage_tbl => p_current_usage_tbl,
15523 p_counter_rules_tbl => p_counter_rules_tbl,
15524 p_last_due_date => l_max_acc_date,
15525 p_last_due_counter_val_tbl => l_last_acc_counter_val_tbl,
15526 p_loop_chain_MR_tbl => l_loop_chain_MR_tbl,
15527 x_loop_due_date => l_loop_due_date,
15528 x_loop_last_due_date => l_loop_last_due_date,
15529 x_loop_last_counter_val_tbl => l_loop_last_counter_val_tbl);
15530
15531 END LOOP; -- l_chain_start_lc_ue_tbl
15532
15533 END IF; -- l_chain_start_lc_ue_tbl.count
15534
15535
15536 -- process chain MRs following any open deferred or unplanned MRs that could be
15537 -- start MR
15538 -- Loop MR unlike chain MRs cannot be added as Unplanned so there will not be
15539 -- multiple instances of a loop for an item instance. The deferred loop MR(if exists)
15540 -- will be processed in build effectivity procedure.
15541
15542 l_iteration_seq := 1;
15543
15544 LOOP
15545 IF (l_iteration_seq = 1) THEN
15546 OPEN get_unplanned_start_MRs (p_applicable_mrs_rec.title,
15547 p_applicable_mrs_rec.csi_item_instance_id);
15548 FETCH get_unplanned_start_MRs BULK COLLECT INTO l_start_ue_id_tbl, l_start_due_date_tbl,
15549 l_start_mr_id_tbl, l_start_vst_end_tbl;
15550 CLOSE get_unplanned_start_MRs;
15551
15552
15553 ELSE
15554 OPEN get_start_def_SR (p_applicable_mrs_rec.title,
15555 p_applicable_mrs_rec.csi_item_instance_id);
15556 FETCH get_start_def_SR BULK COLLECT INTO l_start_ue_id_tbl, l_start_due_date_tbl,
15557 l_start_mr_id_tbl, l_start_vst_end_tbl;
15558 CLOSE get_start_def_SR;
15559
15560 END IF;
15561
15562 IF (l_start_ue_id_tbl.count > 0) THEN
15563 FOR i IN l_start_ue_id_tbl.FIRST..l_start_ue_id_tbl.LAST LOOP
15564
15565 IF (l_iteration_seq = 1) THEN
15566 -- Call visit work package to get visit end date if unit effectivity has been assigned to a visit.
15567 AHL_UMP_UTIL_PKG.get_visit_details (l_start_ue_id_tbl(i),
15568 l_visit_start_date,
15569 l_visit_end_date,
15570 l_visit_assign_code);
15571
15572 IF (l_visit_end_date IS NOT NULL AND trunc(l_visit_end_date) < trunc(sysdate)) THEN
15573 l_visit_end_date := sysdate;
15574 /*
15575 ELSE
15576 -- get visit end date
15577 open get_vst_date(l_start_ue_id_tbl(i));
15578 fetch get_vst_date into l_visit_end_date;
15579 close get_vst_date;
15580 */
15581 END IF;
15582 l_start_due_date_tbl(i) := l_visit_end_date;
15583
15584 END IF;
15585
15586 IF G_DEBUG = 'Y' THEN
15587 AHL_DEBUG_PUB.Debug('Process_Chain_Init:UE:DueDate:End Date:' || l_start_ue_id_tbl(i) || ':' || l_start_due_date_tbl(i) || ':' || l_start_vst_end_tbl(i));
15588 END IF;
15589
15590 -- calculate due date for following chain MRs.
15591 -- form input for Process_Loop_Chain_MRs
15592 l_unplan_unit_effectivity_rec := l_new_unit_effectivity_initrec;
15593 l_unplan_unit_effectivity_rec.due_date := l_start_due_date_tbl(i);
15594 l_unplan_unit_effectivity_rec.unit_effectivity_id := l_start_ue_id_tbl(i);
15595 l_unplan_unit_effectivity_rec.loop_chain_seq_num := p_applicable_mrs_rec.loop_chain_seq_num;
15596 l_unplan_unit_effectivity_rec.start_lc_ue_id := l_start_ue_id_tbl(i);
15597 l_unplan_unit_effectivity_rec.start_mr_header_id := l_start_mr_id_tbl(i);
15598 l_unplan_unit_effectivity_rec.accomplish_trigger_type := p_applicable_mrs_rec.accomplish_trigger_type;
15599 l_unplan_unit_effectivity_rec.visit_end_date := l_start_vst_end_tbl(i);
15600 l_unplan_unit_effectivity_rec.repetitive_mr_flag := 'Y';
15601 l_unplan_unit_effectivity_rec.forecast_sequence := null;
15602
15603 -- update ahl_unit_effectivities_b for chain trigger
15604 UPDATE ahl_unit_effectivities_b
15605 SET accomplish_trigger_type = p_applicable_mrs_rec.accomplish_trigger_type,
15606 start_lc_ue_id = l_start_ue_id_tbl(i),
15607 loop_chain_seq_num = p_applicable_mrs_rec.loop_chain_seq_num
15608 WHERE unit_effectivity_id = l_start_ue_id_tbl(i);
15609
15610 Process_Loop_Chain_MRs (p_item_instance_id => p_applicable_mrs_rec.csi_item_instance_id,
15611 p_repetivity_flag => 'Y',
15612 p_new_unit_effectivity_rec => l_unplan_unit_effectivity_rec,
15613 p_current_usage_tbl => p_current_usage_tbl,
15614 p_counter_rules_tbl => p_counter_rules_tbl,
15615 p_last_due_date => sysdate,
15616 p_last_due_counter_val_tbl => p_current_usage_tbl,
15617 p_loop_chain_MR_tbl => l_loop_chain_MR_tbl,
15618 x_loop_due_date => l_loop_due_date,
15619 x_loop_last_due_date => l_loop_last_due_date,
15620 x_loop_last_counter_val_tbl => l_loop_last_counter_val_tbl
15621 --x_return_status => l_return_status
15622 );
15623
15624
15625 END LOOP;
15626 END IF;
15627
15628 IF (l_iteration_seq = 1) THEN
15629 l_iteration_seq := 2;
15630 l_start_ue_id_tbl.delete;
15631 l_start_due_date_tbl.delete;
15632 l_start_mr_id_tbl.delete;
15633 l_start_vst_end_tbl.delete;
15634 ELSE
15635 EXIT;
15636 END IF;
15637 END LOOP;
15638
15639
15640 IF G_DEBUG = 'Y' THEN
15641 AHL_DEBUG_PUB.Debug('End Process_Chain_Init');
15642 END IF;
15643
15644 END Process_Chain_Init;
15645 -----------------------------------------------------------
15646
15647 PROCEDURE Process_Loop_Chain_MRs (p_item_instance_id IN NUMBER,
15648 p_new_unit_effectivity_rec IN ahl_temp_unit_effectivities%ROWTYPE,
15649 p_repetivity_flag IN VARCHAR2 := 'Y',
15650 p_current_usage_tbl IN counter_values_tbl_type,
15651 p_counter_rules_tbl IN counter_rules_tbl_type,
15652 p_last_due_date IN DATE,
15653 p_last_due_counter_val_tbl IN counter_values_tbl_type,
15654 p_loop_chain_MR_tbl IN loop_chain_MR_tbl_type,
15655 x_loop_due_date OUT NOCOPY DATE,
15656 x_loop_last_due_date OUT NOCOPY DATE,
15657 x_loop_last_counter_val_tbl OUT NOCOPY counter_values_tbl_type)
15658
15659 IS
15660
15661
15662 CURSOR get_appl_mr_dtls_csr(p_mr_header_id IN NUMBER,
15663 p_csi_item_instance_id IN NUMBER) IS
15664 SELECT DISTINCT appl.csi_item_instance_id,
15665 appl.MR_header_id,
15666 mr.Title,
15667 mr.version_number,
15668 appl.Implement_status_code,
15669 appl.copy_accomplishment_code,
15670 appl.repetitive_flag,
15671 appl.show_repetitive_code,
15672 appl.descendent_count,
15673 mr.whichever_first_code,
15674 mr.effective_to,
15675 mr.effective_from,
15676 appl.loop_chain_seq_num
15677 FROM ahl_applicable_MRs appl, ahl_mr_headers_b mr
15678 WHERE appl.csi_item_instance_id = p_csi_item_instance_id
15679 AND appl.mr_header_id = p_mr_header_id
15680 AND (appl.implement_status_code <> 'OPTIONAL_DO_NOT_IMPLEMENT')
15681 AND appl.mr_header_id = mr.mr_header_id
15682 AND trunc(nvl(mr.effective_from,sysdate)) <= trunc(sysdate);
15683
15684 CURSOR ahl_ue_csr (p_start_lc_ue_id IN NUMBER,
15685 p_loop_chain_seq_num IN NUMBER) IS
15686 SELECT unit_effectivity_id, mr.title
15687 FROM ahl_unit_effectivities_b ue, ahl_mr_headers_b mr
15688 WHERE ue.mr_header_id = mr.mr_header_id
15689 AND ue.start_lc_ue_id = p_start_lc_ue_id
15690 AND ue.loop_chain_seq_num = p_loop_chain_seq_num
15691 AND (ue.STATUS_CODE IS NULL or ue.STATUS_CODE = 'INIT-DUE');
15692
15693 l_loop_chain_seq_num NUMBER;
15694 l_appl_rec get_appl_mr_dtls_csr%ROWTYPE;
15695 l_appl_mr_dtls_rec applicable_mrs_rec_type;
15696
15697 l_due_date DATE;
15698 l_last_due_date DATE;
15699
15700 l_last_due_counter_val_tbl counter_values_tbl_type;
15701 l_due_at_counter_val_tbl counter_values_tbl_type;
15702 l_return_value BOOLEAN;
15703 l_no_forecast_available VARCHAR2(1) := 'N';
15704
15705 l_next_due_date_rec next_due_date_rec_type;
15706 l_mr_accomplish_exists BOOLEAN;
15707 l_new_unit_effectivity_rec ahl_temp_unit_effectivities%ROWTYPE;
15708 l_new_unit_effectivity_initrec ahl_temp_unit_effectivities%ROWTYPE;
15709
15710 l_first_time_calc VARCHAR2(1);
15711 l_repetivity_flag VARCHAR2(1);
15712
15713 l_visit_start_date DATE;
15714 l_visit_end_date DATE;
15715 l_visit_assign_code VARCHAR2(30);
15716
15717 l_ue_id NUMBER;
15718 l_ue_mr_title ahl_mr_headers_b.title%TYPE;
15719
15720 BEGIN
15721
15722 IF G_DEBUG = 'Y' THEN
15723 AHL_DEBUG_PUB.Debug('Start Process_Loop_Chain_MRs');
15724 END IF;
15725
15726 -- find the start point to process.
15727 l_loop_chain_seq_num := p_new_unit_effectivity_rec.loop_chain_seq_num;
15728 IF (p_loop_chain_MR_tbl.EXISTS(l_loop_chain_seq_num+1)) THEN
15729 l_loop_chain_seq_num := l_loop_chain_seq_num + 1;
15730 ELSE
15731 RETURN; -- nothing to process.
15732 END IF;
15733
15734 -- Set values for next MR calculation.
15735 IF (p_new_unit_effectivity_rec.visit_end_date IS NOT NULL) THEN
15736 l_due_date := p_new_unit_effectivity_rec.visit_end_date;
15737 ELSE
15738 l_due_date := p_new_unit_effectivity_rec.due_date;
15739 END IF;
15740
15741 l_last_due_date := p_last_due_date;
15742 l_last_due_counter_val_tbl := p_last_due_counter_val_tbl;
15743
15744 l_first_time_calc := 'Y';
15745
15746 IF (p_repetivity_flag = 'Y' AND l_due_date IS NOT NULL) THEN
15747 -- get due counter values on due date.
15748 Get_Due_at_Counter_Values (p_last_due_date => p_last_due_date,
15749 p_last_due_counter_val_tbl => p_last_due_counter_val_tbl,
15750 p_due_date => l_due_date,
15751 p_counter_rules_tbl => p_counter_rules_tbl,
15752 x_due_at_counter_val_tbl => l_due_at_counter_val_tbl,
15753 x_return_value => l_return_value);
15754 IF NOT(l_return_value) THEN
15755 l_no_forecast_available := 'Y';
15756 ELSE
15757 l_no_forecast_available := 'N';
15758 END IF;
15759 -- dbms_output.put_line ('step1.45:l_due_at_counter_val_tbl.count:' || l_due_at_counter_val_tbl.count);
15760
15761
15762 l_last_due_date := l_due_date;
15763 l_last_due_counter_val_tbl := l_due_at_counter_val_tbl;
15764 END IF;
15765
15766 IF G_DEBUG = 'Y' THEN
15767 AHL_DEBUG_PUB.Debug('Start MR due date:' || l_last_due_date);
15768 IF (l_last_due_counter_val_tbl.COUNT) > 0 THEN
15769 FOR i in l_last_due_counter_val_tbl.FIRST..l_last_due_counter_val_tbl.LAST LOOP
15770 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_last_due_counter_val_tbl(i).counter_value || 'ID: ' || l_last_due_counter_val_tbl(i).counter_id);
15771 END LOOP;
15772 END IF;
15773 END IF;
15774 --
15775 IF (l_no_forecast_available = 'Y') THEN
15776 RETURN;
15777 END IF;
15778 --
15779 -- calc due date only if due date is not null and forecast available.
15780 IF (l_due_date is NOT NULL) AND (l_no_forecast_available = 'N') THEN
15781 LOOP
15782
15783 -- get MR details.
15784 OPEN get_appl_mr_dtls_csr(p_loop_chain_MR_tbl(l_loop_chain_seq_num).mr_header_id,
15785 p_item_instance_id);
15786 FETCH get_appl_mr_dtls_csr INTO l_appl_rec;
15787 CLOSE get_appl_mr_dtls_csr;
15788
15789 -- set applicable MR record.
15790 l_appl_mr_dtls_rec.csi_item_instance_id := l_appl_rec.csi_item_instance_id;
15791 l_appl_mr_dtls_rec.MR_header_id := l_appl_rec.MR_header_id;
15792 l_appl_mr_dtls_rec.title := l_appl_rec.title;
15793 l_appl_mr_dtls_rec.version_number := l_appl_rec.version_number;
15794 l_appl_mr_dtls_rec.Implement_status_code := l_appl_rec.Implement_status_code;
15795 l_appl_mr_dtls_rec.copy_accomplishment_code := l_appl_rec.copy_accomplishment_code;
15796 l_appl_mr_dtls_rec.repetitive_flag := l_appl_rec.repetitive_flag;
15797 l_appl_mr_dtls_rec.show_repetitive_code := 'NEXT';
15798 l_appl_mr_dtls_rec.preceding_mr_header_id := null;
15799 l_appl_mr_dtls_rec.descendent_count := l_appl_rec.descendent_count;
15800 l_appl_mr_dtls_rec.whichever_first_code := l_appl_rec.whichever_first_code;
15801 l_appl_mr_dtls_rec.effective_to := l_appl_rec.effective_to;
15802 l_appl_mr_dtls_rec.effective_from := l_appl_rec.effective_from;
15803
15804 -- added for bug# 9263774
15805 IF (l_appl_mr_dtls_rec.effective_to < sysdate) THEN
15806 l_appl_mr_dtls_rec.expired_mr_flag := 'Y';
15807 ELSE
15808 l_appl_mr_dtls_rec.expired_mr_flag := 'N';
15809 END IF;
15810
15811 IF (l_first_time_calc = 'Y') THEN
15812 l_repetivity_flag := p_repetivity_flag;
15813 -- check if UE exists and if associated to a visit.
15814 open ahl_ue_csr(p_new_unit_effectivity_rec.unit_effectivity_id,
15815 p_loop_chain_MR_tbl(l_loop_chain_seq_num).loop_chain_seq_num);
15816 fetch ahl_ue_csr INTO l_ue_id, l_ue_mr_title;
15817 if (ahl_ue_csr%found) THEN
15818 -- check if associcated to a visit.
15819 AHL_UMP_UTIL_PKG.get_visit_details (l_ue_id,
15820 l_visit_start_date,
15821 l_visit_end_date,
15822 l_visit_assign_code);
15823 IF (nvl(l_visit_assign_code,'x') NOT IN ('RELEASED','CLOSED')) THEN
15824 if (l_ue_mr_title <> l_appl_rec.title) THEN
15825 l_visit_end_date := null;
15826 end if;
15827 end if;
15828 end if;
15829 close ahl_ue_csr;
15830 l_first_time_calc := 'N';
15831
15832 ELSE
15833 l_repetivity_flag := 'Y';
15834 l_visit_end_date := null;
15835 END IF;
15836
15837 -- Calculate next due date.
15838 Calculate_Due_Date (p_repetivity_flag => p_repetivity_flag,
15839 p_applicable_mrs_rec => l_appl_mr_dtls_rec,
15840 p_current_usage_tbl => p_current_usage_tbl,
15841 p_counter_rules_tbl => p_counter_rules_tbl,
15842 p_last_due_date => l_last_due_date,
15843 p_last_due_counter_val_tbl => l_last_due_counter_val_tbl,
15844 p_dependent_mr_flag => FALSE,
15845 --p_mr_accomplish_exists => l_mr_accomplish_exists,
15846 p_mr_accomplish_exists => FALSE,
15847 x_next_due_date_rec => l_next_due_date_rec);
15848
15849 IF G_DEBUG = 'Y' THEN
15850 AHL_DEBUG_PUB.Debug('Aft loop/chain calculate_due_date nextdue');
15851 AHL_DEBUG_PUB.Debug('loop/chain due date is ' || l_next_due_date_rec.DUE_DATE);
15852 AHL_DEBUG_PUB.Debug('loop/chain earliest due date is ' || l_next_due_date_rec.EARLIEST_DUE_DATE);
15853 AHL_DEBUG_PUB.Debug('loop/chain latest due date is ' || l_next_due_date_rec.latest_due_date);
15854 END IF;
15855
15856 IF (l_next_due_date_rec.DUE_DATE IS NOT NULL) OR (p_new_unit_effectivity_rec.repetitive_mr_flag = 'N') THEN
15857 -- Insert into temp table
15858 -- construct ahl_unit_effectivity record and write into temporary table.
15859 l_new_unit_effectivity_rec := l_new_unit_effectivity_initrec; -- initialise.
15860
15861 l_new_unit_effectivity_rec.csi_item_instance_id := p_item_instance_id;
15862 l_new_unit_effectivity_rec.mr_header_id := l_appl_mr_dtls_rec.mr_header_id;
15863
15864 l_new_unit_effectivity_rec.due_date := l_next_due_date_rec.due_date;
15865 l_new_unit_effectivity_rec.mr_interval_id := l_next_due_date_rec.mr_interval_id;
15866 l_new_unit_effectivity_rec.mr_effectivity_id := l_next_due_date_rec.mr_effectivity_id;
15867 l_new_unit_effectivity_rec.due_counter_value := l_next_due_date_rec.due_at_counter_value;
15868
15869 l_new_unit_effectivity_rec.tolerance_flag := l_next_due_date_rec.tolerance_flag;
15870
15871 l_new_unit_effectivity_rec.tolerance_before := l_next_due_date_rec.tolerance_before;
15872 l_new_unit_effectivity_rec.tolerance_after := l_next_due_date_rec.tolerance_after;
15873 l_new_unit_effectivity_rec.message_code := l_next_due_date_rec.message_code;
15874 l_new_unit_effectivity_rec.preceding_check_flag:= 'N';
15875
15876 l_new_unit_effectivity_rec.earliest_due_date := l_next_due_date_rec.earliest_due_date;
15877 l_new_unit_effectivity_rec.latest_due_date := l_next_due_date_rec.latest_due_date;
15878
15879 l_new_unit_effectivity_rec.counter_id := l_next_due_date_rec.counter_id;
15880 l_new_unit_effectivity_rec.forecast_sequence := p_new_unit_effectivity_rec.forecast_sequence;
15881
15882 -- set repetivity based on next_due_flag.
15883 l_new_unit_effectivity_rec.repetitive_mr_flag := p_new_unit_effectivity_rec.repetitive_mr_flag;
15884
15885 -- update loop / chain details
15886 l_new_unit_effectivity_rec.start_mr_header_id := p_new_unit_effectivity_rec.start_mr_header_id;
15887 l_new_unit_effectivity_rec.accomplish_trigger_type := p_new_unit_effectivity_rec.accomplish_trigger_type;
15888 l_new_unit_effectivity_rec.start_lc_ue_id := p_new_unit_effectivity_rec.unit_effectivity_id;
15889 l_new_unit_effectivity_rec.loop_chain_seq_num := p_loop_chain_MR_tbl(l_loop_chain_seq_num).loop_chain_seq_num;
15890
15891 Create_Temp_Unit_Effectivity (l_new_unit_effectivity_rec);
15892
15893 END IF;
15894
15895 l_due_date := l_next_due_date_rec.due_date;
15896
15897 IF (l_visit_end_date IS NOT NULL) THEN
15898 l_due_date := l_visit_end_date;
15899 END IF;
15900
15901 -- get all counter values as on l_due_date.
15902 Get_Due_at_Counter_Values (p_last_due_date => l_last_due_date,
15903 p_last_due_counter_val_tbl => l_last_due_counter_val_tbl,
15904 p_due_date => l_due_date,
15905 p_counter_rules_tbl => p_counter_rules_tbl,
15906 x_due_at_counter_val_tbl => l_due_at_counter_val_tbl,
15907 x_return_value => l_return_value);
15908 l_last_due_date := l_due_date;
15909 l_last_due_counter_val_tbl := l_due_at_counter_val_tbl;
15910
15911 IF G_DEBUG = 'Y' THEN
15912 AHL_DEBUG_PUB.Debug('AFter get_due_at_counter_values');
15913 AHL_DEBUG_PUB.Debug('l_last_due_date: '|| l_last_due_date);
15914 AHL_DEBUG_PUB.Debug('l_due_date: '|| l_due_date);
15915 IF (l_due_at_counter_val_tbl.COUNT) > 0 THEN
15916 for i in l_due_at_counter_val_tbl.FIRST..l_due_at_counter_val_tbl.LAST LOOP
15917 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_due_at_counter_val_tbl(i).counter_value || 'ID: ' || l_due_at_counter_val_tbl(i).counter_id);
15918 end loop;
15919 END IF;
15920 END IF;
15921
15922 -- next MR.
15923 IF (p_loop_chain_MR_tbl.EXISTS(l_loop_chain_seq_num + 1)) THEN
15924 l_loop_chain_seq_num := l_loop_chain_seq_num + 1;
15925 ELSE
15926 EXIT;
15927 END IF;
15928
15929 END LOOP;
15930
15931 -- set return values only for loop.
15932 IF (p_new_unit_effectivity_rec.accomplish_trigger_type = 'LOOP') THEN
15933 x_loop_last_counter_val_tbl := l_last_due_counter_val_tbl;
15934 x_loop_last_due_date := l_last_due_date;
15935 x_loop_due_date := l_next_due_date_rec.due_date;
15936 END IF;
15937
15938 END IF;
15939
15940 IF G_DEBUG = 'Y' THEN
15941 AHL_DEBUG_PUB.Debug('End Process_Loop_Chain_MRs');
15942 END IF;
15943
15944 END Process_Loop_Chain_MRs;
15945 --------------------------------------
15946 PROCEDURE get_instance_ctr_for_date (p_item_instance_id IN NUMBER,
15947 p_last_accomplishment_date IN DATE,
15948 p_deferral_flag IN VARCHAR2,
15949 p_unit_effectivity_id IN NUMBER,
15950 p_current_usage_tbl IN counter_values_tbl_type,
15951 p_counter_rules_tbl IN counter_rules_tbl_type,
15952 x_no_forecast_flag OUT NOCOPY BOOLEAN,
15953 x_last_acc_counter_val_tbl OUT NOCOPY counter_values_tbl_type)
15954 IS
15955
15956 -- Get last accomplishment counter values.
15957 CURSOR ahl_unit_accomplish_csr (p_unit_effectivity_id IN NUMBER) IS
15958 SELECT
15959 UA.COUNTER_ID,
15960 UA.COUNTER_VALUE,
15961 CS.UOM_CODE,
15962 CS.COUNTER_TEMPLATE_NAME COUNTER_NAME
15963 FROM
15964 AHL_UNIT_ACCOMPLISHMNTS UA,
15965 CSI_COUNTERS_VL CS
15966 WHERE
15967 UA.COUNTER_ID = CS.COUNTER_ID AND
15968 UA.UNIT_EFFECTIVITY_ID = P_UNIT_EFFECTIVITY_ID
15969 ORDER BY
15970 CS.UOM_CODE ;
15971
15972 -- Get instance counter details.
15973 CURSOR csi_cp_counters_csr (p_csi_instance_id IN NUMBER) IS
15974 SELECT cc.counter_id, cc.uom_code,
15975 cc.counter_template_name counter_name
15976 from csi_counter_associations cca, csi_counters_vl cc
15977 where cca.counter_id = cc.counter_id
15978 AND source_object_code = 'CP'
15979 AND source_object_id = p_csi_instance_id;
15980
15981
15982 l_net_reading NUMBER;
15983 l_last_acc_counter_val_tbl counter_values_tbl_type;
15984
15985 l_due_counter_val_tbl counter_values_tbl_type;
15986 l_due_date DATE;
15987
15988 l_return_val BOOLEAN;
15989 i NUMBER;
15990
15991 BEGIN
15992
15993 -- initialize out parameters
15994 x_no_forecast_flag := FALSE;
15995
15996
15997 IF (p_deferral_flag = 'Y') THEN
15998 IF (p_last_accomplishment_date IS NULL) OR (p_item_instance_id IS NULL) THEN
15999 RETURN;
16000 ELSIF (p_last_accomplishment_date <= sysdate) THEN
16001 -- get counter values from counter values tables.
16002 i := 1;
16003 FOR instance_counter_rec IN csi_cp_counters_csr(p_item_instance_id) LOOP
16004 l_net_reading := 0;
16005 get_ctr_reading_for_datetime (p_csi_item_instance_id => p_item_instance_id,
16006 p_counter_id => instance_counter_rec.counter_id,
16007 p_reading_date => p_last_accomplishment_date,
16008 x_net_reading => l_net_reading);
16009
16010 l_last_acc_counter_val_tbl(i).uom_code := instance_counter_rec.uom_code;
16011 l_last_acc_counter_val_tbl(i).counter_id := instance_counter_rec.counter_id;
16012 l_last_acc_counter_val_tbl(i).counter_name := instance_counter_rec.counter_name;
16013 l_last_acc_counter_val_tbl(i).counter_value := l_net_reading;
16014 i := i + 1;
16015
16016 END LOOP;
16017 ELSE -- deferral due date is a future date.
16018 -- get all counter values as on l_preceding_next_due_date.
16019 Get_Due_at_Counter_Values (p_last_due_date => sysdate,
16020 p_last_due_counter_val_tbl => p_current_usage_tbl,
16021 p_due_date => p_last_accomplishment_date,
16022 p_counter_rules_tbl => p_counter_rules_tbl,
16023 x_due_at_counter_val_tbl => l_last_acc_counter_val_tbl,
16024 x_return_value => l_return_val);
16025
16026 IF G_DEBUG = 'Y' THEN
16027 AHL_DEBUG_PUB.Debug('l_deferral_due_date: ' || p_last_accomplishment_date);
16028 IF (l_last_acc_counter_val_tbl.COUNT) > 0 THEN
16029 for i in l_last_acc_counter_val_tbl.FIRST..l_last_acc_counter_val_tbl.LAST LOOP
16030 AHL_DEBUG_PUB.Debug('i:'|| i|| ' value:' || l_last_acc_counter_val_tbl(i).counter_value || 'ID: ' || l_last_acc_counter_val_tbl(i).counter_id);
16031 end loop;
16032 END IF;
16033 END IF;
16034
16035 -- check return value.
16036 IF NOT(l_return_val) THEN -- no forecast case.
16037 x_no_forecast_flag := TRUE;
16038 END IF;
16039
16040 END IF; -- Last accomplishment date.
16041 ELSE -- not based on deferral_effective_date.
16042 IF (p_unit_effectivity_id IS NOT NULL) THEN
16043 i := 1;
16044 -- Build last accomplishment counter values.
16045 FOR l_acc_counter_rec IN ahl_unit_accomplish_csr(p_unit_effectivity_id) LOOP
16046 l_last_acc_counter_val_tbl(i).uom_code := l_acc_counter_rec.uom_code;
16047 l_last_acc_counter_val_tbl(i).counter_id := l_acc_counter_rec.counter_id;
16048 l_last_acc_counter_val_tbl(i).counter_name := l_acc_counter_rec.counter_name;
16049 l_last_acc_counter_val_tbl(i).counter_value := l_acc_counter_rec.counter_value;
16050 i := i + 1;
16051 END LOOP;
16052
16053 END IF;
16054 END IF; -- p_deferral_flag.
16055
16056 x_last_acc_counter_val_tbl := l_last_acc_counter_val_tbl;
16057
16058 END get_instance_ctr_for_date;
16059 -----------------------------------
16060
16061 -- JKJain, NR Analysis and Forecasting
16062 FUNCTION get_primary_plan_id RETURN NUMBER
16063 IS
16064
16065 -- get fleet for the unit on the date given.
16066 CURSOR get_primary_plan IS
16067 SELECT simulation_plan_id
16068 FROM AHL_SIMULATION_PLANS_B
16069 WHERE primary_plan_flag = 'Y'
16070 AND status_code = 'ACTIVE'
16071 -- AND nvl(simulation_type,'UMP') = 'UMP'; Removed NVL condition as primary plan is seeded with UMP.
16072 AND simulation_type = 'UMP';
16073
16074 l_primary_plan_id NUMBER := NULL;
16075
16076 BEGIN
16077
16078 OPEN get_primary_plan;
16079 FETCH get_primary_plan INTO l_primary_plan_id;
16080 CLOSE get_primary_plan;
16081
16082 RETURN l_primary_plan_id;
16083
16084 END get_primary_plan_id;
16085
16086 FUNCTION get_fleet_from_unit_asso(p_uc_header_id IN NUMBER,
16087 p_date IN DATE,
16088 p_plan_id IN NUMBER) RETURN NUMBER
16089 IS
16090
16091 -- get fleet for the unit on the date given.
16092 CURSOR date_withing_flt_asso(c_unit_config_header_id NUMBER,
16093 c_due_date DATE,
16094 c_plan_id NUMBER) IS
16095 SELECT FUA.fleet_header_id
16096 FROM ahl_fleet_unit_assocs FUA, ahl_fleet_headers_b FLT
16097 WHERE unit_config_header_id = c_unit_config_header_id
16098 AND c_due_date between ASSOCIATION_START and nvl(ASSOCIATION_END,c_due_date)
16099 AND FLT.fleet_header_id = FUA.fleet_header_id
16100 AND FLT.status_code = 'COMPLETE'
16101 AND FUA.simulation_plan_id = nvl(c_plan_id, get_primary_plan_id);
16102
16103 l_fleet_header_id NUMBER := NULL;
16104
16105 BEGIN
16106
16107 OPEN date_withing_flt_asso(p_uc_header_id,p_date,p_plan_id);
16108 FETCH date_withing_flt_asso INTO l_fleet_header_id;
16109 CLOSE date_withing_flt_asso;
16110
16111 RETURN l_fleet_header_id;
16112
16113 END get_fleet_from_unit_asso;
16114 -----------------------------
16115
16116 -- Added for Complex Assembly enhancements.
16117 -- Procedure to calculate NR due date for init-due definition.
16118 -- due date details will be updated in ahl_unit_effectivities_b table.
16119 PROCEDURE Calculate_Init_DueDate (
16120 x_return_status OUT NOCOPY VARCHAR2,
16121 x_msg_data OUT NOCOPY VARCHAR2,
16122 x_msg_count OUT NOCOPY NUMBER,
16123 x_due_date OUT NOCOPY DATE,
16124 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
16125 p_unit_effectivity_id IN NUMBER)
16126 IS
16127
16128 l_due_date DATE;
16129 l_due_counter_value NUMBER;
16130 l_counter_id NUMBER;
16131
16132 BEGIN
16133 x_return_status := FND_API.G_RET_STS_SUCCESS;
16134
16135 -- Enable Debug.
16136 IF G_DEBUG = 'Y' THEN
16137 AHL_DEBUG_PUB.enable_debug;
16138 END IF;
16139
16140 -- Add debug mesg.
16141 IF G_DEBUG = 'Y' THEN
16142 AHL_DEBUG_PUB.debug('At start of procedure:' || G_PKG_NAME || '.' || 'Calculate_Init_DueDate');
16143 AHL_DEBUG_PUB.debug('Dump of input parameters:');
16144 AHL_DEBUG_PUB.debug('Unit Effectivity ID:' || p_unit_effectivity_id);
16145 END IF;
16146
16147 -- Validate input parameters.
16148 IF (p_unit_effectivity_id IS NULL OR p_unit_effectivity_id = FND_API.G_MISS_NUM) THEN
16149 FND_MESSAGE.Set_Name('AHL','AHL_UMP_DEF_UE_NULL');
16150 FND_MSG_PUB.ADD;
16151 RAISE FND_API.G_EXC_ERROR;
16152 END IF;
16153
16154 IF G_DEBUG = 'Y' THEN
16155 AHL_DEBUG_PUB.debug('Before call to Calculate_NR_due_date');
16156 END IF;
16157
16158 Calculate_NR_due_date(p_unit_effectivity_id, l_due_date, l_due_counter_value, l_counter_id);
16159 x_due_date := l_due_date;
16160
16161 IF G_DEBUG = 'Y' THEN
16162 AHL_DEBUG_PUB.debug('After call to Calculate_NR_due_date');
16163 END IF;
16164
16165
16166 IF (l_due_counter_value IS NOT NULL OR l_due_date IS NOT NULL) THEN
16167
16168 IF G_DEBUG = 'Y' THEN
16169 AHL_DEBUG_PUB.debug('Before updating UE table:UE:DDT:DCV:CTR_ID:' || p_unit_effectivity_id || ':' || l_due_date || ':' || l_due_counter_value || ':' || l_counter_id);
16170 END IF;
16171
16172 -- Update table.
16173 UPDATE ahl_unit_effectivities_b
16174 SET due_date = l_due_date,
16175 due_counter_value = l_due_counter_value,
16176 counter_id = l_counter_id,
16177 last_update_date = sysdate,
16178 last_updated_by = fnd_global.user_id,
16179 object_version_number = object_version_number + 1
16180 WHERE unit_effectivity_id = p_unit_effectivity_id;
16181
16182 -- update child UEs.
16183 UPDATE ahl_unit_effectivities_b
16184 SET due_date = l_due_date,
16185 due_counter_value = l_due_counter_value,
16186 counter_id = l_counter_id,
16187 last_update_date = sysdate,
16188 last_updated_by = fnd_global.user_id,
16189 object_version_number = object_version_number + 1
16190 WHERE unit_effectivity_id IN (select related_ue_id
16191 from ahl_ue_relationships
16192 where originator_ue_id = p_unit_effectivity_id);
16193
16194 END IF;
16195
16196
16197 EXCEPTION
16198
16199 WHEN OTHERS THEN
16200 IF (SQLCODE = -54) THEN
16201 FND_MESSAGE.Set_Name('AHL','AHL_UMP_PUE_ALREADY_RUNNING');
16202 FND_MSG_PUB.ADD;
16203 RAISE FND_API.G_EXC_ERROR;
16204 ELSE
16205 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
16206 fnd_msg_pub.add_exc_msg(p_pkg_name => G_PKG_NAME,
16207 p_procedure_name => 'Calculate_Init_DueDate',
16208 p_error_text => SUBSTR(SQLERRM,1,240));
16209 END IF;
16210 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
16211 END IF;
16212
16213 END Calculate_Init_DueDate;
16214 ---------------------------
16215
16216 -- added for Complex Assembly Enh: To calculate due date for nonroutine when UE status is init-due.
16217 PROCEDURE Calculate_NR_due_date(p_unit_effectivity_id IN NUMBER,
16218 x_due_date OUT NOCOPY DATE,
16219 x_due_counter_value OUT NOCOPY NUMBER,
16220 x_counter_id OUT NOCOPY NUMBER)
16221
16222 IS
16223
16224 -- Get Unit Effectivity details.
16225 -- added inventory_item_id, inv_master_organization_id to fix bug# 9284692
16226 CURSOR ahl_unit_effectivity_csr (p_unit_effectivity_id IN NUMBER) IS
16227 SELECT ue.csi_item_instance_id, ue.mr_header_id, cii.inventory_item_id,
16228 cii.inv_master_organization_id
16229 FROM ahl_unit_effectivities_app_v ue, csi_item_instances cii
16230 WHERE ue.unit_effectivity_id = p_unit_effectivity_id
16231 AND ue.csi_item_instance_id = cii.instance_id;
16232
16233 -- Get MR details.
16234 CURSOR ahl_mr_headers_csr (p_mr_header_id IN NUMBER) IS
16235 SELECT whichever_first_code
16236 FROM ahl_mr_headers_app_v
16237 WHERE mr_header_id = p_mr_header_id;
16238
16239 -- get the configuration structure.(G_config_node_tbl).
16240 CURSOR csi_reln_csr ( p_csi_item_instance_id IN NUMBER) IS
16241 SELECT position_reference
16242 FROM csi_ii_relationships
16243 WHERE subject_id = p_csi_item_instance_id
16244 AND relationship_type_code = 'COMPONENT-OF'
16245 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
16246 AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1));
16247
16248
16249 -- get the counter usage
16250 CURSOR cs_ctr_counter_csr (p_counter_id IN NUMBER) IS
16251 select nvl(ccr.net_reading,0) net_reading
16252 FROM csi_counters_b cc, csi_counter_readings ccr
16253 WHERE cc.counter_id = p_counter_id
16254 and ccr.counter_value_id = cc.CTR_VAL_MAX_SEQ_NO;
16255
16256
16257 -- added for USAF: Assembly Maint. Enh.: Support for initializing a NR.
16258 -- Get threshold details.
16259 CURSOR ahl_unit_threshold_csr (p_ue_id IN NUMBER) IS
16260 SELECT aut.counter_id, aut.counter_value, (select uom_code from csi_counters_b where counter_id = aut.counter_id) uom_code
16261 FROM ahl_unit_thresholds aut, ahl_unit_deferrals_b udf
16262 WHERE udf.unit_effectivity_id = p_ue_id
16263 AND udf.unit_deferral_id = aut.unit_deferral_id
16264 AND udf.unit_deferral_type = 'INIT-DUE';
16265
16266 i NUMBER;
16267 l_csi_item_instance_id NUMBER;
16268 l_root_csi_instance_id NUMBER;
16269 l_mr_header_id NUMBER;
16270 l_uc_header_id NUMBER;
16271
16272
16273
16274 l_inv_master_organization_id number;
16275 l_inventory_item_id number;
16276 l_position_reference VARCHAR2(30);
16277 l_counter_rules_tbl counter_rules_tbl_type;
16278 l_current_usage_tbl counter_values_tbl_type;
16279 --l_counter_value number;
16280 l_uom_code VARCHAR2(3);
16281 l_counter_read_date DATE;
16282
16283 l_expected_resolution_date DATE;
16284 l_calc_due_date DATE;
16285 l_calc_counter_id NUMBER;
16286 l_calc_due_counter_value NUMBER;
16287
16288 l_due_date DATE;
16289 l_due_at_counter_value NUMBER;
16290 k NUMBER;
16291 l_counter_remain NUMBER;
16292 l_current_ctr_value NUMBER;
16293 l_return_val BOOLEAN;
16294
16295 BEGIN
16296
16297
16298 OPEN ahl_unit_effectivity_csr (p_unit_effectivity_id);
16299 FETCH ahl_unit_effectivity_csr INTO l_csi_item_instance_id, l_mr_header_id,
16300 l_inventory_item_id, l_inv_master_organization_id;
16301 IF (ahl_unit_effectivity_csr%NOTFOUND) THEN
16302 FND_MESSAGE.Set_Name('AHL','AHL_UMP_DEF_UE_INVALID');
16303 FND_MESSAGE.Set_Token('UE_ID', p_unit_effectivity_id);
16304 FND_MSG_PUB.ADD;
16305 RAISE FND_API.G_EXC_ERROR;
16306 END IF;
16307
16308 IF G_DEBUG = 'Y' THEN
16309 AHL_DEBUG_PUB.debug('Step 1');
16310 AHL_DEBUG_PUB.debug('CSI Item Instance ID:' || l_csi_item_instance_id);
16311 AHL_DEBUG_PUB.debug('Inventory Item ID:' || l_inventory_item_id);
16312 AHL_DEBUG_PUB.debug('INV master Org ID:' || l_inv_master_organization_id);
16313 END IF;
16314
16315 -- Get Unit and Master Config IDs if available.
16316 -- Find the root item instance.
16317 l_root_csi_instance_id := Get_RootInstanceID(l_csi_item_instance_id);
16318
16319 -- Get master and unit configuration for the root item instance.
16320 Get_Unit_Master_ConfigIDs (l_root_csi_instance_id,
16321 l_uc_header_id, G_master_config_id);
16322
16323 IF G_DEBUG = 'Y' THEN
16324 AHL_DEBUG_PUB.debug('Step 2: ROOT CSI: UCH: MCH:' || l_root_csi_instance_id || ':' || l_uc_header_id || ':' || G_master_config_id);
16325 END IF;
16326
16327 -- Check for errors.
16328 IF FND_MSG_PUB.Count_msg > 0 THEN
16329 RAISE FND_API.G_EXC_ERROR;
16330 END IF;
16331
16332 IF G_DEBUG = 'Y' THEN
16333 AHL_DEBUG_PUB.debug('Step 3');
16334 END IF;
16335
16336 -- Get utilization forecast for the unit/part.
16337 Get_Utilization_Forecast (l_root_csi_instance_id,
16338 l_uc_header_id,
16339 l_inventory_item_id,
16340 l_inv_master_organization_id,
16341 G_forecast_details_tbl);
16342
16343 IF G_DEBUG = 'Y' THEN
16344 AHL_DEBUG_PUB.debug('Step 4');
16345 AHL_DEBUG_PUB.debug('Count on util forecast tbl:' || G_forecast_details_tbl.count);
16346 END IF;
16347
16348 -- Get the position installed in.
16349 OPEN csi_reln_csr(l_csi_item_instance_id);
16350 FETCH csi_reln_csr INTO l_position_reference;
16351 IF (csi_reln_csr%NOTFOUND) THEN
16352 l_position_reference := G_master_config_id;
16353 END IF;
16354 CLOSE csi_reln_csr;
16355
16356 IF G_DEBUG = 'Y' THEN
16357 AHL_DEBUG_PUB.debug('Step 5');
16358 END IF;
16359
16360 -- Build counter rules ratio if node is not root node.
16361 IF (G_master_config_id IS NOT NULL AND l_position_reference IS NOT NULL) THEN
16362 build_Counter_Ratio(l_position_reference,
16363 l_csi_item_instance_id,
16364 G_master_config_id,
16365 l_counter_rules_tbl);
16366 END IF;
16367
16368 IF G_DEBUG = 'Y' THEN
16369 AHL_DEBUG_PUB.debug('Step 6');
16370 END IF;
16371
16372
16373 -- read thresholds table.
16374 FOR unit_threshold_rec IN ahl_unit_threshold_csr(p_unit_effectivity_id) LOOP
16375
16376 l_counter_remain := 0;
16377 l_due_at_counter_value := 0;
16378 l_current_ctr_value := 0;
16379
16380 -- get counter usage.
16381 OPEN cs_ctr_counter_csr(unit_threshold_rec.counter_id);
16382 FETCH cs_ctr_counter_csr INTO l_current_ctr_value;
16383 IF (cs_ctr_counter_csr%NOTFOUND) THEN
16384 IF G_DEBUG = 'Y' THEN
16385 AHL_DEBUG_PUB.debug('Step 7');
16386 END IF;
16387 l_current_ctr_value := 0;
16388 END IF;
16389
16390 CLOSE cs_ctr_counter_csr;
16391
16392 IF G_DEBUG = 'Y' THEN
16393 AHL_DEBUG_PUB.debug('l_current_ctr_value:' || l_current_ctr_value);
16394 END IF;
16395
16396 l_due_at_counter_value := unit_threshold_rec.counter_value;
16397 l_counter_remain := l_due_at_counter_value - l_current_ctr_value;
16398
16399 -- calculate due date from forecast.
16400 IF (l_counter_remain > 0) THEN
16401 -- get date from forecast.
16402 get_date_from_uf(l_counter_remain,
16403 unit_threshold_rec.uom_code,
16404 l_counter_rules_tbl,
16405 null, -- start date = sysdate
16406 l_due_date);
16407 ELSIF (l_counter_remain < 0) THEN
16408 -- Due date = counter reading date.
16409 get_ctr_date_for_reading (p_csi_item_instance_id => l_csi_item_instance_id,
16410 p_counter_id => unit_threshold_rec.counter_id,
16411 p_counter_value => l_due_at_counter_value,
16412 x_ctr_record_date => l_counter_read_date,
16413 x_return_val => l_return_val);
16414
16415 IF NOT(l_return_val) THEN
16416 l_due_date := sysdate;
16417 ELSE
16418 l_due_date := l_counter_read_date;
16419 END IF;
16420
16421 ELSIF (l_counter_remain = 0) THEN -- due_date = sysdate
16422 --dbms_output.put_line ('counter remain less than zero');
16423 l_due_date := sysdate;
16424 END IF;
16425
16426 IF (l_due_date IS NULL) THEN
16427 l_calc_due_date := NULL;
16428 l_calc_counter_id := unit_threshold_rec.counter_id;
16429 l_calc_due_counter_value := l_due_at_counter_value;
16430 EXIT;
16431 ELSIF (l_calc_due_date IS NULL) THEN
16432 l_calc_due_date := l_due_date;
16433 l_calc_counter_id := unit_threshold_rec.counter_id;
16434 l_calc_due_counter_value := l_due_at_counter_value;
16435 ELSE
16436 IF (trunc(l_due_date) < trunc(l_calc_due_date)) THEN
16437 l_calc_due_date := l_due_date;
16438 l_calc_counter_id := unit_threshold_rec.counter_id;
16439 l_calc_due_counter_value := l_due_at_counter_value;
16440 END IF;
16441 END IF;
16442
16443 END LOOP;
16444 -- match due date with resolution date and pick earliest.
16445 -- get resolution date.
16446 BEGIN
16447 SELECT cs.expected_resolution_date
16448 INTO l_expected_resolution_date
16449 FROM ahl_unit_effectivities_b ue, cs_incidents_all_b cs
16450 WHERE ue.unit_effectivity_id = p_unit_effectivity_id
16451 AND cs.incident_id = ue.cs_incident_id;
16452 EXCEPTION
16453 WHEN OTHERS THEN
16454 null;
16455 END;
16456
16457 IF (l_expected_resolution_date IS NOT NULL) AND (l_calc_due_date IS NOT NULL) THEN
16458 IF (trunc(l_expected_resolution_date) < trunc(l_calc_due_date)) THEN
16459 l_calc_due_date := l_expected_resolution_date;
16460 l_calc_counter_id := null;
16461 l_calc_due_counter_value := null;
16462 END IF;
16463 END IF;
16464
16465 x_due_date := l_calc_due_date;
16466 x_due_counter_value := l_calc_due_counter_value;
16467 x_counter_id := l_calc_counter_id;
16468
16469 END Calculate_NR_due_date;
16470 --------------------------
16471
16472 END AHL_UMP_ProcessUnit_PVT;