DBA Data[Home] [Help]

PACKAGE BODY: APPS.AHL_COMPLETIONS_PVT

Source


1 PACKAGE BODY AHL_COMPLETIONS_PVT AS
2 /* $Header: AHLVPRCB.pls 120.45.12010000.4 2009/01/09 22:28:16 sikumar ship $ */
3 
4 G_PKG_NAME VARCHAR2(30) := 'AHL_COMPLETIONS_PVT';
5 G_DEBUG    VARCHAR2(1)  := AHL_DEBUG_PUB.is_log_enabled;
6 
7 -- Operation Statuses
8 G_OP_STATUS_UNCOMPLETE VARCHAR2(2) := '2'; --Uncomplete
9 G_OP_STATUS_COMPLETE VARCHAR2(2) := '1'; --Complete
10 
11 -- Job Statuses
12 G_JOB_STATUS_UNRELEASED VARCHAR2(2) := '1'; --Unreleased
13 G_JOB_STATUS_RELEASED VARCHAR2(2) := '3'; --Released
14 G_JOB_STATUS_COMPLETE VARCHAR2(2) := '4'; --Complete
15 G_JOB_STATUS_COMPLETE_NC VARCHAR2(2) := '5'; --Complete No Charges
16 G_JOB_STATUS_ON_HOLD VARCHAR2(2) := '6'; --On Hold
17 G_JOB_STATUS_CANCELLED VARCHAR2(2) := '7'; --Cancelled
18 G_JOB_STATUS_CLOSED VARCHAR2(2) := '12'; --Closed
19 G_JOB_STATUS_PARTS_HOLD VARCHAR2(2) := '19'; --Parts Hold
20 G_JOB_STATUS_QA_PENDING VARCHAR2(2) := '20'; --Pending QA Approval
21 G_JOB_STATUS_DEFERRAL_PENDING VARCHAR2(2) := '21'; --Pending Deferr
22 G_JOB_STATUS_DELETED VARCHAR2(2) := '22'; --Deleted
23 
24 -- MR Statuses
25 G_MR_STATUS_SIGNED_OFF VARCHAR2(30) := 'ACCOMPLISHED'; --Signed Off
26 G_MR_STATUS_DEFERRED VARCHAR2(30) := 'DEFERRED'; --Deferred
27 G_MR_STATUS_JOBS_COMPLETE VARCHAR2(30) := 'ALL_JOBS_COMPLETE'; --All Jobs Complete
28 G_MR_STATUS_JOBS_CANCELLED VARCHAR2(30) := 'ALL_JOBS_CANCELLED'; --All Jobs Cancelled
29 G_MR_STATUS_INSP_NEEDED VARCHAR2(30) := 'INSPECTION_NEEDED'; --Inspection Needed
30 G_MR_STATUS_UNRELEASED VARCHAR2(30) := 'UNRELEASED'; --Unreleased
31 G_MR_STATUS_RELEASED VARCHAR2(30) := 'RELEASED'; --Released
32 G_MR_STATUS_DEFERRAL_PENDING VARCHAR2(30) := 'DEFERRAL_PENDING'; --Deferral Pending
33 G_MR_STATUS_JOBS_ON_HOLD VARCHAR2(30) := 'JOBS_ON_HOLD'; --On Hold
34 G_MR_STATUS_TERMINATED VARCHAR2(30) := 'TERMINATED'; --Terminated
35 G_MR_STATUS_CANCELLED VARCHAR2(30) := 'CANCELLED'; --Cancelled
36 
37 -- Visit Statuses
38 G_VISIT_STATUS_RELEASED VARCHAR2(30) := 'RELEASED'; --Released
39 
40 -- Counter Reading Plan
41 G_CTR_READING_PLAN_ID NUMBER := FND_PROFILE.value ( 'AHL_WO_CTR_READING_PLAN' );
42 
43 -- Common Functions / Procedures
44 
45 --added following procedure for fix of bug number 6467963
46 PROCEDURE get_mr_details_rec
47 (
48   p_unit_effectivity_id     IN         NUMBER,
49   p_object_version_number   IN         NUMBER,
50   x_mr_rec                  OUT NOCOPY mr_rec_type
51 );
52 
53 -- Function to validate the Inputs of the complete_workorder and defer_workorder APIs
54 FUNCTION validate_wo_inputs
55 (
56   p_workorder_id           IN   NUMBER,
57   p_object_version_no      IN   NUMBER
58 ) RETURN VARCHAR2
59 IS
60 BEGIN
61 
62   IF ( p_workorder_id IS NULL OR
63        p_workorder_id = FND_API.G_MISS_NUM OR
64        p_object_version_no IS NULL OR
65        p_object_version_no = FND_API.G_MISS_NUM ) THEN
66     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_WO_INPUTS' );
67     FND_MSG_PUB.add;
68     RETURN FND_API.G_RET_STS_ERROR;
69   END IF;
70 
71   RETURN FND_API.G_RET_STS_SUCCESS;
72 END validate_wo_inputs;
73 
74 -- Function to get the Operation Record
75 FUNCTION get_operation_rec
76 (
77   p_workorder_operation_id   IN          NUMBER,
78   p_object_version_no        IN          NUMBER := NULL,
79   x_operation_rec            OUT NOCOPY  operation_rec_type
80 ) RETURN VARCHAR2
81 IS
82 -- fix for bug number 7295717 (Sunil)
83 CURSOR get_op_details(p_workorder_operation_id IN NUMBER) IS
84 SELECT OP.workorder_operation_id,
85          OP.object_version_number,
86          OP.workorder_id,
87          WO.wip_entity_id,
88          OP.operation_sequence_num,
89          OP.organization_id,
90          OP.description,
91          OP.plan_id,
92          OP.collection_id,
93          OP.actual_start_date,
94          OP.actual_end_date,
95          OP.status_code,
96          OP.status
97 FROM   AHL_WORKORDERS WO, AHL_WORKORDER_OPERATIONS_V OP
98   WHERE  WO.workorder_id = OP.workorder_id
99   AND    OP.workorder_operation_id = p_workorder_operation_id;
100 
101 BEGIN
102 
103   /*SELECT OP.workorder_operation_id,
104          OP.object_version_number,
105          OP.workorder_id,
106          WO.wip_entity_id,
107          OP.operation_sequence_num,
108          OP.organization_id,
109          OP.description,
110          OP.plan_id,
111          OP.collection_id,
112          OP.actual_start_date,
113          OP.actual_end_date,
114          OP.status_code,
115          OP.status
116   INTO   x_operation_rec.workorder_operation_id,
117          x_operation_rec.object_version_number,
118          x_operation_rec.workorder_id,
119          x_operation_rec.wip_entity_id,
120          x_operation_rec.operation_sequence_num,
121          x_operation_rec.organization_id,
122          x_operation_rec.description,
123          x_operation_rec.plan_id,
124          x_operation_rec.collection_id,
125          x_operation_rec.actual_start_date,
126          x_operation_rec.actual_end_date,
127          x_operation_rec.status_code,
128          x_operation_rec.status
129   FROM   AHL_WORKORDERS WO, AHL_WORKORDER_OPERATIONS_V OP
130   WHERE  WO.workorder_id = OP.workorder_id
131   AND    OP.workorder_operation_id = p_workorder_operation_id;*/
132   -- fix for bug number 7295717 (Sunil)
133   OPEN get_op_details(p_workorder_operation_id);
134   FETCH get_op_details INTO x_operation_rec.workorder_operation_id,
135          x_operation_rec.object_version_number,
136          x_operation_rec.workorder_id,
137          x_operation_rec.wip_entity_id,
138          x_operation_rec.operation_sequence_num,
139          x_operation_rec.organization_id,
140          x_operation_rec.description,
141          x_operation_rec.plan_id,
142          x_operation_rec.collection_id,
143          x_operation_rec.actual_start_date,
144          x_operation_rec.actual_end_date,
145          x_operation_rec.status_code,
146          x_operation_rec.status;
147   IF(get_op_details%NOTFOUND)THEN
148          FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_OP_NOT_FOUND' );
149          FND_MSG_PUB.add;
150          CLOSE get_op_details;
151          RETURN FND_API.G_RET_STS_ERROR;
152   END IF;
153   CLOSE get_op_details;
154 
155 
156   IF ( p_object_version_no IS NOT NULL AND
157        p_object_version_no <> FND_API.G_MISS_NUM ) THEN
158     IF ( x_operation_rec.object_version_number <> p_object_version_no ) THEN
159       FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
160       FND_MSG_PUB.add;
161       RETURN FND_API.G_RET_STS_ERROR;
162     END IF;
163   END IF;
164 
165   RETURN FND_API.G_RET_STS_SUCCESS;
166 END get_operation_rec;
167 
168 -- Function to get the status for
169 -- use in the error messages
170 FUNCTIOn get_status
171 (
172   p_status_code 	IN   VARCHAR2,
173 		p_lookup_type  IN   VARCHAR2
174 ) RETURN VARCHAR2
175 IS
176 		CURSOR get_status_csr(c_status_code IN VARCHAR2,
177 																								c_lookup_type IN VARCHAR2) IS
178 		SELECT meaning
179 				FROM fnd_lookup_values_vl
180         WHERE lookup_type = c_lookup_type
181           AND LOOKUP_CODE = c_status_code;
182 
183 
184 		l_status_mean VARCHAR2(80);
185 BEGIN
186 		OPEN get_status_csr(p_status_code, p_lookup_type);
187 		FETCH get_status_csr INTO l_status_mean;
188 		IF get_status_csr%NOTFOUND THEN
189 				l_status_mean := p_status_code;
190 		END IF;
191 		CLOSE get_status_csr;
192 
193 		RETURN l_status_mean;
194 EXCEPTION
195   WHEN OTHERS THEN
196 		  -- no exception thrown
197 				-- just return the status code as the status mean
198     RETURN p_status_code;
199 END get_status;
200 
201 
202 
203 
204 
205 
206 
207 -- Function to get the Workorder Record
208 FUNCTION get_workorder_rec
209 (
210   p_workorder_id        IN          NUMBER,
211   p_object_version_no   IN          NUMBER := NULL,
212   x_workorder_rec       OUT NOCOPY  workorder_rec_type
213 ) RETURN VARCHAR2
214 
215 IS
216 
217 --for fix of bug number 6467963/7295717
218 CURSOR get_wo_dtls_csr(c_workorder_id IN NUMBER) IS
219 SELECT    WO.workorder_id,
220             WO.object_version_number,
221             WO.wip_entity_id,
222             WDJ.organization_id,
223             WO.plan_id,
224             WO.collection_id,
225             WO.actual_start_date,
226             WO.actual_end_date,
227             WO.STATUS_CODE,
228             MLU.MEANING,
229             WO.route_id,
230             WDJ.COMPLETION_SUBINVENTORY,
231             WDJ.COMPLETION_LOCATOR_ID,
232             WO.visit_id,
233             WO.visit_task_id
234   FROM AHL_WORKORDERS WO, FND_LOOKUP_VALUES_VL MLU,WIP_DISCRETE_JOBS WDJ,
235  (SELECT ORGANIZATION_ID FROM INV_ORGANIZATION_INFO_V WHERE
236   NVL (operating_unit, mo_global.get_current_org_id()) = mo_global.get_current_org_id()) ORG
237   WHERE  WDJ.WIP_ENTITY_ID=WO.WIP_ENTITY_ID
238   AND MLU.LOOKUP_TYPE(+)='AHL_JOB_STATUS' AND WO.STATUS_CODE=MLU.LOOKUP_CODE(+)
239   AND WDJ.ORGANIZATION_ID = ORG.ORGANIZATION_ID
240   AND WO.workorder_id = c_workorder_id;
241 
242   l_visit_task_id NUMBER;
243   l_visit_id NUMBER;
244 
245   CURSOR get_inst_ue_dtls_task(c_visit_task_id IN NUMBER) IS
246   SELECT
247             UE.unit_effectivity_id,
248             UE.object_version_number,
249             NVL(VTS.instance_id, VST.item_instance_id),
250             CSI.lot_number,
251             CSI.serial_number,
252             CSI.quantity
253   FROM AHL_VISITS_B VST, AHL_VISIT_TASKS_B VTS, CSI_ITEM_INSTANCES CSI,
254    AHL_UNIT_EFFECTIVITIES_B UE
255   WHERE  VTS.unit_effectivity_id =  UE.unit_effectivity_id
256   AND NVL(VTS.instance_id, VST.item_instance_id) = CSI.instance_id
257   AND VST.visit_id = VTS.visit_id
258   AND VTS.visit_task_id = c_visit_task_id;
259 
260   CURSOR get_inst_dtls_visit(c_visit_id IN NUMBER) IS
261   SELECT nvl (VST.ITEM_INSTANCE_ID, VTSINST.instance_id ),
262        CSI.lot_number,
263        CSI.serial_number,
264        CSI.quantity
265   FROM AHL_VISITS_B VST,CSI_ITEM_INSTANCES CSI,
266        (select instance_id from ahl_visit_tasks_b where visit_id = c_visit_id and instance_id IS NOT NULL AND rownum = 1) VTSINST
267   WHERE nvl (VST.ITEM_INSTANCE_ID, VTSINST.instance_id )= CSI.INSTANCE_ID
268   AND VST.visit_id = c_visit_id;
269 
270 -- Cursor for getting auto_signoff_flag from mr header. Added for bug # 4078536
271 /*CURSOR get_signoff_flag_csr(c_workorder_id IN NUMBER) IS
272 SELECT
273 	MR.auto_signoff_flag
274 FROM
275 	AHL_MR_HEADERS_APP_V MR,
276 	AHL_VISIT_TASKS_B VT,
277 	AHL_WORKORDERS WO
278 WHERE 	MR.MR_HEADER_ID = VT.MR_ID AND
279 	WO.VISIT_TASK_ID = VT.visit_task_id AND
280 	WO.workorder_id = c_workorder_id;*/
281 
282 --for fix of bug number 6467963
283 CURSOR get_signoff_flag_csr(c_visit_task_id IN NUMBER) IS
284 SELECT
285 	MR.auto_signoff_flag
286 FROM
287 	AHL_MR_HEADERS_APP_V MR,
288 	AHL_VISIT_TASKS_B VT
289 	--AHL_WORKORDERS WO
290 WHERE 	MR.MR_HEADER_ID = VT.MR_ID AND
291 	VT.visit_task_id = c_visit_task_id;
292 
293 BEGIN
294 
295    /*SELECT    workorder_id,
296 												job_number,
297             object_version_number,
298             wip_entity_id,
299             organization_id,
300             plan_id,
301             collection_id,
302             actual_start_date,
303             actual_end_date,
304             job_status_code,
305             job_status_meaning,
306             route_id,
307             unit_effectivity_id,
308             ue_object_version_number,
309             --auto_signoff_flag,
310             --'Y',
311             item_instance_id,
312             completion_subinventory,
313             completion_locator_id,
314             lot_number,
315             serial_number,
316             quantity
317   INTO      x_workorder_rec.workorder_id,
318 												x_workorder_rec.workorder_name,
319             x_workorder_rec.object_version_number,
320             x_workorder_rec.wip_entity_id,
321             x_workorder_rec.organization_id,
322             x_workorder_rec.plan_id,
323             x_workorder_rec.collection_id,
324             x_workorder_rec.actual_start_date,
325             x_workorder_rec.actual_end_date,
326             x_workorder_rec.status_code,
327             x_workorder_rec.status,
328             x_workorder_rec.route_id,
329             x_workorder_rec.unit_effectivity_id,
330             x_workorder_rec.ue_object_version_number,
331             --x_workorder_rec.automatic_signoff_flag,
332             x_workorder_rec.item_instance_id,
333             x_workorder_rec.completion_subinventory,
334             x_workorder_rec.completion_locator_id,
335             x_workorder_rec.lot_number,
336             x_workorder_rec.serial_number,
337             x_workorder_rec.txn_quantity
338   FROM      AHL_ALL_WORKORDERS_V
339   WHERE     workorder_id = p_workorder_id;*/
340 
341   --for fix of bug number 6467963
342   OPEN get_wo_dtls_csr(p_workorder_id);
343   FETCH get_wo_dtls_csr INTO x_workorder_rec.workorder_id,
344             x_workorder_rec.object_version_number,
345             x_workorder_rec.wip_entity_id,
346             x_workorder_rec.organization_id,
347             x_workorder_rec.plan_id,
348             x_workorder_rec.collection_id,
349             x_workorder_rec.actual_start_date,
350             x_workorder_rec.actual_end_date,
351             x_workorder_rec.status_code,
352             x_workorder_rec.status,
353             x_workorder_rec.route_id,
354             x_workorder_rec.completion_subinventory,
355             x_workorder_rec.completion_locator_id,
356             l_visit_id,
357             l_visit_task_id;
358   IF(get_wo_dtls_csr%NOTFOUND)THEN
359     FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
360     FND_MSG_PUB.add;
361     CLOSE get_wo_dtls_csr;
362     RETURN FND_API.G_RET_STS_ERROR;
363   END IF;
364   CLOSE get_wo_dtls_csr;
365 
366   IF ( p_object_version_no IS NOT NULL AND
367        p_object_version_no <> FND_API.G_MISS_NUM ) THEN
368     IF ( x_workorder_rec.object_version_number <> p_object_version_no ) THEN
369       FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
370       FND_MSG_PUB.add;
371       RETURN FND_API.G_RET_STS_ERROR;
372     END IF;
373   END IF;
374 
375   -- Code for getting auto_signoff_flag from the child workorder if parent workorder doesnt have the information.
376   -- Balaji added following code to get auto_signoff_flag from mr header intead of hardcoding it to 'Y'
377   -- for bug # 4078536
378   /*OPEN get_signoff_flag_csr(x_workorder_rec.workorder_id);
379   FETCH get_signoff_flag_csr INTO x_workorder_rec.automatic_signoff_flag;
380   x_workorder_rec.automatic_signoff_flag := nvl(x_workorder_rec.automatic_signoff_flag, 'N');
381   CLOSE get_signoff_flag_csr;*/
382 
383   --for fix of bug number 6467963
384     IF(l_visit_task_id IS NOT NULL)THEN
385        OPEN get_inst_ue_dtls_task(l_visit_task_id);
386        FETCH get_inst_ue_dtls_task INTO
387               x_workorder_rec.unit_effectivity_id,
388               x_workorder_rec.ue_object_version_number,
389               x_workorder_rec.item_instance_id,
390               x_workorder_rec.lot_number,
391               x_workorder_rec.serial_number,
392               x_workorder_rec.txn_quantity;
393        CLOSE get_inst_ue_dtls_task;
394 
395        OPEN get_signoff_flag_csr(l_visit_task_id);
396        FETCH get_signoff_flag_csr INTO x_workorder_rec.automatic_signoff_flag;
397        x_workorder_rec.automatic_signoff_flag := nvl(x_workorder_rec.automatic_signoff_flag, 'N');
398        CLOSE get_signoff_flag_csr;
399 
400     ELSE --visit master work order
401        OPEN get_inst_dtls_visit(l_visit_id);
402        FETCH get_inst_dtls_visit INTO
403               x_workorder_rec.item_instance_id,
404               x_workorder_rec.lot_number,
405               x_workorder_rec.serial_number,
406               x_workorder_rec.txn_quantity;
407        CLOSE get_inst_dtls_visit;
408        x_workorder_rec.automatic_signoff_flag := 'N';
409   END IF;
410 
411   RETURN FND_API.G_RET_STS_SUCCESS;
412 EXCEPTION
413   WHEN OTHERS THEN
414     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_NOT_FOUND' );
415     FND_MSG_PUB.add;
416     RETURN FND_API.G_RET_STS_ERROR;
417 
418 END get_workorder_rec;
419 
420 -- Function to validate the given Actual Start and End Dates
421 FUNCTION validate_actual_dates
422 (
423   p_actual_start_date        IN DATE,
424   p_actual_end_date          IN DATE
425 ) RETURN VARCHAR2
426 IS
427 BEGIN
428 
429   IF ( p_actual_start_date IS NULL OR
430        p_actual_end_date IS NULL ) THEN
431     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_ACTUAL_DTS_MISSING' );
432     FND_MSG_PUB.add;
433     RETURN FND_API.G_RET_STS_ERROR;
434   END IF;
435 
436   IF ( p_actual_start_date > p_actual_end_date ) THEN
437     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_ST_DT_END_DT' );
438     FND_MSG_PUB.add;
439     RETURN FND_API.G_RET_STS_ERROR;
440   END IF;
441 
442   IF ( p_actual_end_date > SYSDATE ) THEN
443     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_END_DT_SYSDATE' );
444     FND_MSG_PUB.add;
445     RETURN FND_API.G_RET_STS_ERROR;
446   END IF;
447 
448   RETURN FND_API.G_RET_STS_SUCCESS;
449 END validate_actual_dates;
450 
451 -- Function to validate the given Actual Start and End Dates do not overlap with any of the Open Accounting Period Start Date and Scheduled Close Date.
452 FUNCTION validate_acct_period
453 (
454   p_organization_id          IN NUMBER,
455   p_actual_start_date        IN DATE,
456   p_actual_end_date          IN DATE
457 ) RETURN VARCHAR2
458 IS
459   l_period_start_date DATE;
460   l_schedule_close_date DATE;
461 
462   CURSOR   get_min_period( c_organization_id NUMBER )
463   IS
464   SELECT   period_start_date
465   FROM     ORG_ACCT_PERIODS
466   WHERE    open_flag = 'Y'
467   AND      organization_id = c_organization_id
468   ORDER BY period_start_date;
469 
470   CURSOR   get_max_period( c_organization_id NUMBER )
471   IS
472   SELECT   schedule_close_date
473   FROM     ORG_ACCT_PERIODS
474   WHERE    open_flag = 'Y'
475   AND      organization_id = c_organization_id
476   ORDER BY schedule_close_date DESC;
477 
478 BEGIN
479 
480   OPEN  get_min_period( p_organization_id );
481   FETCH get_min_period
482   INTO  l_period_start_date;
483 
484   IF ( get_min_period%NOTFOUND ) THEN
485     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_NO_OPEN_ACCT_PERIOD' );
486     FND_MSG_PUB.add;
487     CLOSE get_min_period;
488     RETURN FND_API.G_RET_STS_ERROR;
489   END IF;
490 
491   IF ( l_period_start_date > p_actual_start_date ) THEN
492     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_ST_DT_LESS_ACCT_PERIOD' );
493     FND_MSG_PUB.add;
494     CLOSE get_min_period;
495     RETURN FND_API.G_RET_STS_ERROR;
496   END IF;
497 
498   CLOSE get_min_period;
499 
500   OPEN  get_max_period( p_organization_id );
501   FETCH get_max_period
502   INTO  l_schedule_close_date;
503 
504   IF ( get_max_period%NOTFOUND ) THEN
505     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_NO_OPEN_ACT_PERIOD' );
506     FND_MSG_PUB.add;
507     CLOSE get_max_period;
508     RETURN FND_API.G_RET_STS_ERROR;
509   END IF;
510 
511   IF ( l_schedule_close_date < p_actual_end_date ) THEN
512     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_END_DT_LESS_ACT_PERIOD' );
513     FND_MSG_PUB.add;
514     CLOSE get_max_period;
515     RETURN FND_API.G_RET_STS_ERROR;
516   END IF;
517 
518   CLOSE get_max_period;
519 
520   RETURN FND_API.G_RET_STS_SUCCESS;
521 END validate_acct_period;
522 
523 -- Function to get the user-enter value 'Operation Status' or 'Workorder Status' QA Plan Element and to check if this value is 'Complete'.
524 FUNCTION validate_qa_status
525 (
526   p_plan_id                 IN   NUMBER,
527   p_char_id                 IN   NUMBER,
528   p_collection_id           IN   NUMBER
529 ) RETURN VARCHAR2
530 IS
531 
532   l_result_column_name  VARCHAR2(30) := NULL;
533   l_enabled_flag        NUMBER := NULL;
534   l_displayed_flag      NUMBER := NULL;
535   l_result_sql_stmt     VARCHAR2(200);
536   l_result_column_value VARCHAR2(30) := NULL;
537 
538 BEGIN
539 
540   BEGIN
541     SELECT     result_column_name,
542                enabled_flag,
543                displayed_flag
544     INTO       l_result_column_name,
545                l_enabled_flag,
546                l_displayed_flag
547     FROM       QA_PLAN_CHARS
548     WHERE      plan_id = p_plan_id
549     AND        char_id = p_char_id;
550 
551   EXCEPTION
552     WHEN NO_DATA_FOUND THEN
553       RETURN FND_API.G_RET_STS_SUCCESS;
554     WHEN OTHERS THEN
555       RETURN FND_API.G_RET_STS_UNEXP_ERROR;
556   END;
557 
558   IF ( l_result_column_name IS NOT NULL AND
559        l_enabled_flag = 1 AND
560        l_displayed_flag = 1 ) THEN
561 
562     -- Get the user-entered value for the status element
563     l_result_sql_stmt := 'SELECT ' || l_result_column_name || ' FROM QA_RESULTS_V WHERE collection_id = :c_collection_id AND occurrence = ( SELECT MAX( occurrence ) FROM QA_RESULTS WHERE collection_id = :c_collection_id )';
564 
565     BEGIN
566       EXECUTE IMMEDIATE l_result_sql_stmt INTO l_result_column_value USING p_collection_id, p_collection_id;
567     EXCEPTION
568       WHEN OTHERS THEN
569         RETURN FND_API.G_RET_STS_UNEXP_ERROR;
570     END;
571 
572     -- Operation status
573     IF ( p_char_id = 125 AND
574          ( l_result_column_value IS NULL OR
575            l_result_column_value <> G_OP_STATUS_COMPLETE ) ) THEN
576       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_QA_STAT_NOT_COMPL' );
577       FND_MSG_PUB.add;
578       RETURN FND_API.G_RET_STS_ERROR;
579 
580     -- Workorder status
581     ELSIF ( p_char_id = 98 AND
582             ( l_result_column_value IS NULL OR
583               l_result_column_value <> G_JOB_STATUS_COMPLETE ) ) THEN
584       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_QA_STAT_NOT_COMPL' );
585       FND_MSG_PUB.add;
586       RETURN FND_API.G_RET_STS_ERROR;
587     END IF;
588   END IF;
589 
590   RETURN FND_API.G_RET_STS_SUCCESS;
591 END validate_qa_status;
592 
593 -- Function to validate whether the actual end date is later than the
594 -- last workorder transaction date.
595 FUNCTION validate_ahl_wo_txn_date
596 (
597   p_workorder_id            IN   NUMBER,
598   p_actual_end_date         IN   DATE
599 ) RETURN VARCHAR2
600 IS
601   l_transaction_date DATE;
602 
603   CURSOR get_ahl_txn_rec( c_workorder_id NUMBER )
604   IS
605   SELECT MAX ( TXN.creation_date )
606   FROM   AHL_WORKORDER_MTL_TXNS TXN, AHL_WORKORDER_OPERATIONS OP
607   WHERE  TXN.workorder_operation_id = OP.workorder_operation_id
608   AND    OP.workorder_id = c_workorder_id;
609 BEGIN
610 
611   OPEN   get_ahl_txn_rec( p_workorder_id );
612 
613   FETCH  get_ahl_txn_rec
614   INTO   l_transaction_date;
615 
616   IF ( get_ahl_txn_rec%FOUND ) THEN
617     -- Ensure that the Actual End date is greater than the last Transaction Date
618     IF ( l_transaction_date > p_actual_end_date ) THEN
619       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ENDDT_TXNDT' );
620       FND_MSG_PUB.add;
621       CLOSE get_ahl_txn_rec;
622       RETURN FND_API.G_RET_STS_ERROR;
623     END IF;
624   END IF;
625 
626   CLOSE get_ahl_txn_rec;
627 
628   RETURN FND_API.G_RET_STS_SUCCESS;
629 END validate_ahl_wo_txn_date;
630 
631 -- Function to check whether the last EAM Workorder Transaction is Completion
632 -- and to ensure that the actual end date is greater than the
633 -- last transaction date in EAM.
634 FUNCTION validate_eam_wo_compl_txn
635 (
636   p_wip_entity_id           IN   NUMBER,
637   p_actual_end_date         IN   DATE,
638   p_validate_date           IN   VARCHAR2 DEFAULT FND_API.G_TRUE
639 ) RETURN VARCHAR2
640 IS
641 
642   l_transaction_type NUMBER;
643   l_transaction_date DATE;
644 
645   CURSOR       get_eam_txn_rec( c_wip_entity_id NUMBER )
646   IS
647   SELECT       transaction_type,
648                transaction_date
649   FROM         EAM_JOB_COMPLETION_TXNS
650   WHERE        wip_entity_id = p_wip_entity_id
651   ORDER BY     transaction_date DESC;
652 
653 BEGIN
654 
655   OPEN   get_eam_txn_rec( p_wip_entity_id );
656 
657   FETCH  get_eam_txn_rec
658   INTO   l_transaction_type,
659          l_transaction_date;
660 
661   IF ( get_eam_txn_rec%FOUND ) THEN
662 
663     -- Ensure that the Transaction Type is not COMPLETE.
664     IF ( l_transaction_type = 1 ) THEN
665       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_COMP_IN_EAM' );
666       FND_MSG_PUB.add;
667       CLOSE get_eam_txn_rec;
668       RETURN FND_API.G_RET_STS_ERROR;
669     END IF;
670 
671   IF (NVL(p_validate_date, FND_API.G_TRUE) = FND_API.G_TRUE) THEN
672     IF ( l_transaction_date > p_actual_end_date ) THEN
673       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ENDDT_EAM_TXNDT' );
674       FND_MSG_PUB.add;
675       CLOSE get_eam_txn_rec;
676       RETURN FND_API.G_RET_STS_ERROR;
677     END IF;
678   END IF;
679   END IF;
680 
681   CLOSE get_eam_txn_rec;
682 
683   RETURN FND_API.G_RET_STS_SUCCESS;
684 END validate_eam_wo_compl_txn;
685 
686 -- Function to record the Readings of all the Counters associated to the Item Instance associated to the Workorder.
687 FUNCTION record_wo_ctr_readings
688 (
689   x_msg_data           OUT NOCOPY VARCHAR2,
690   x_msg_count          OUT NOCOPY NUMBER,
691   p_wip_entity_id      IN  NUMBER,
692   p_counter_tbl        IN  counter_tbl_type
693 ) RETURN VARCHAR2
694 IS
695 
696   l_return_status           VARCHAR2(1);
697   l_msg_data                VARCHAR2(2000);
698   l_msg_count               NUMBER;
699   l_results_tbl             AHL_QA_RESULTS_PVT.qa_results_tbl_type;
700   l_hidden_results_tbl      AHL_QA_RESULTS_PVT.qa_results_tbl_type;
701   l_context_tbl             AHL_QA_RESULTS_PVT.qa_context_tbl_type;
702   l_organization_id         NUMBER := NULL;
703   l_collection_id           NUMBER := NULL;
704   l_result_count            NUMBER := 1;
705   l_occurrence_count        NUMBER := 1;
706   l_occurrence_tbl          AHL_QA_RESULTS_PVT.occurrence_tbl_type;
707 
708 BEGIN
709 
710   FOR i IN p_counter_tbl.FIRST..p_counter_tbl.LAST LOOP
711     IF ( p_counter_tbl(i).counter_value_id IS NOT NULL ) THEN
712       l_occurrence_tbl( l_occurrence_count ).element_count := 3;
713       l_occurrence_count := l_occurrence_count + 1;
714 
715       -- Workorder
716       l_results_tbl( l_result_count ).char_id := 165;
717       l_results_tbl( l_result_count ).result_id := p_wip_entity_id;
718       l_result_count := l_result_count + 1;
719 
720       -- Counter
721       l_results_tbl( l_result_count ).char_id := 54;
722       l_results_tbl( l_result_count ).result_id := p_counter_tbl(i).counter_id;
723       l_result_count := l_result_count + 1;
724 
725       -- Counter Reading
726       l_results_tbl( l_result_count ).char_id := 55;
727       l_results_tbl( l_result_count ).result_id := p_counter_tbl(i).counter_value_id;
728       l_result_count := l_result_count + 1;
729     END IF;
730 
731   END LOOP;
732 
733   IF ( l_occurrence_count = 1 ) THEN
734     RETURN FND_API.G_RET_STS_SUCCESS;
735   END IF;
736 
737   -- Get the Organization ID of the Counter Reading Plan
738   SELECT organization_id
739   INTO   l_organization_id
740   FROM   QA_PLANS
741   WHERE  plan_id = G_CTR_READING_PLAN_ID;
742 
743   -- Post the Results for the Counter Reading Plan in Oracle Quality
744   -- Note :- The p_commit flag is TRUE because, actions have to fired for
745   -- the Counter Reading Plan
746   AHL_QA_RESULTS_PVT.submit_qa_results
747   (
748     p_api_version        => 1.0,
749     p_init_msg_list      => FND_API.G_TRUE,
750     p_commit             => FND_API.G_TRUE,
751     p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
752     p_default            => FND_API.G_FALSE,
753     p_module_type        => NULL,
754     x_return_status      => l_return_status,
755     x_msg_count          => l_msg_count,
756     x_msg_data           => l_msg_data,
757     p_plan_id            => G_CTR_READING_PLAN_ID,
758     p_organization_id    => l_organization_id,
759     p_transaction_no     => NULL,
760     p_specification_id   => NULL,
761     p_results_tbl        => l_results_tbl,
762     p_hidden_results_tbl => l_hidden_results_tbl,
763     p_context_tbl        => l_context_tbl,
764     p_result_commit_flag => 1,
765     p_id_or_value        => 'ID',
766     p_x_collection_id    => l_collection_id,
767     p_x_occurrence_tbl   => l_occurrence_tbl
768   );
769 
770   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
771     x_msg_data := l_msg_data;
772     x_msg_count := l_msg_count;
773     RETURN FND_API.G_RET_STS_ERROR;
774   END IF;
775 
776   RETURN FND_API.G_RET_STS_SUCCESS;
777 
778 END record_wo_ctr_readings;
779 
780 -- Function to complete the given Workorder in WIP using EAM API
781 FUNCTION complete_eam_workorder
782 (
783   p_workorder_rec          IN   workorder_rec_type
784 ) RETURN VARCHAR2
785 IS
786 
787 l_inventory_item_info EAM_WorkOrderTransactions_PUB.Inventory_Item_Tbl_Type;
788 l_attribute_rec       EAM_WorkOrderTransactions_PUB.Attributes_Rec_Type;
789 
790 l_msg_count           NUMBER;
791 l_return_status       VARCHAR2(1);
792 l_msg_data            VARCHAR2(2000);
793 l_app_name            VARCHAR2(30);
794 l_msg_name            VARCHAR2(30);
795 
796 BEGIN
797 
798   -- Completion Sub-inventory
799   -- Note :- We may want to add more validations here to ensure that
800   -- the installed base transaction does not fail.
801   IF ( p_workorder_rec.completion_subinventory IS NOT NULL ) THEN
802     l_inventory_item_info(1).subinventory := p_workorder_rec.completion_subinventory;
803     l_inventory_item_info(1).locator := p_workorder_rec.completion_locator_id;
804     l_inventory_item_info(1).lot_number := p_workorder_rec.lot_number;
805     l_inventory_item_info(1).serial_number := p_workorder_rec.serial_number;
806     l_inventory_item_info(1).quantity := p_workorder_rec.txn_quantity;
807   END IF;
808 
809   -- Invoke the EAM API. Do not Commit.
810   EAM_WORKORDERTRANSACTIONS_PUB.complete_work_order
811   (
812     p_api_version             => 1.0,
813     p_init_msg_list           => FND_API.G_TRUE,
814     p_commit                  => FND_API.G_FALSE,
815     x_return_status           => l_return_status,
816     x_msg_count               => l_msg_count,
817     x_msg_data                => l_msg_data,
818     p_wip_entity_id           => p_workorder_rec.wip_entity_id,
819     p_transaction_type        => 1,
820     p_transaction_date        => SYSDATE,
821     p_instance_id             => p_workorder_rec.item_instance_id,
822     p_user_id                 => FND_GLOBAL.user_id,
823     p_request_id              => NULL,
824     p_application_id          => NULL,
825     p_program_id              => NULL,
826     p_reconciliation_code     => NULL,
827     p_actual_start_date       => p_workorder_rec.actual_start_date,
828     p_actual_end_date         => p_workorder_rec.actual_end_date,
829     p_actual_duration         => NULL,
830     p_shutdown_start_date     => NULL,
831     p_shutdown_end_date       => NULL,
832     p_shutdown_duration       => NULL,
833     p_inventory_item_info     => l_inventory_item_info,
834     p_reference               => NULL,
835     p_reason                  => NULL,
836     p_attributes_rec          => l_attribute_rec
837   );
838 
839   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
840 
841     IF ( l_msg_data IS NULL ) THEN
842       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EAM_WO_CMPL_ERROR' );
843       FND_MSG_PUB.add;
844     ELSE
845       -- Parse the Encoded message returned by the EAM API
846       FND_MESSAGE.parse_encoded( l_msg_data, l_app_name, l_msg_name );
847       FND_MESSAGE.set_name( l_app_name, l_msg_name );
848       FND_MSG_PUB.add;
849     END IF;
850 
851     RETURN FND_API.G_RET_STS_ERROR;
852 
853   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
854     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EAM_WO_CMPL_ERROR' );
855     FND_MSG_PUB.add;
856     RETURN FND_API.G_RET_STS_ERROR;
857   END IF;
858 
859   RETURN FND_API.G_RET_STS_SUCCESS;
860 
861 END complete_eam_workorder;
862 
863 -- Function to record a Workorder Transaction ASO Entities
864 FUNCTION record_ahl_workorder_txn
865 (
866   p_workorder_rec          IN   workorder_rec_type,
867   p_transaction_type_code  IN   NUMBER
868 ) RETURN VARCHAR2
869 IS
870   l_workorder_txn_id  NUMBER;
871 BEGIN
872 
873   SELECT AHL_WORKORDER_TXNS_S.NEXTVAL
874   INTO   l_workorder_txn_id
875   FROM   DUAL;
876 
877   INSERT INTO AHL_WORKORDER_TXNS
878   (
879    WORKORDER_TXN_ID,
880    OBJECT_VERSION_NUMBER,
881    LAST_UPDATE_DATE,
882    LAST_UPDATED_BY,
883    CREATION_DATE,
884    CREATED_BY,
885    LAST_UPDATE_LOGIN,
886    WORKORDER_ID,
887    TRANSACTION_TYPE_CODE,
888    STATUS_CODE,
889    SCHEDULED_START_DATE,
890    SCHEDULED_END_DATE,
891    ACTUAL_START_DATE,
892    ACTUAL_END_DATE,
893    LOT_NUMBER,
894    COMPLETION_SUBINVENTORY,
895    COMPLETION_LOCATOR_ID
896   ) VALUES (
897    l_workorder_txn_id,
898    1,
899    SYSDATE,
900    FND_GLOBAL.user_id,
901    SYSDATE,
902    FND_GLOBAL.user_id,
903    FND_GLOBAL.login_id,
904    p_workorder_rec.workorder_id,
905    p_transaction_type_code,
906    p_workorder_rec.status_code,
907    p_workorder_rec.actual_start_date,
908    p_workorder_rec.actual_end_date,
909    p_workorder_rec.actual_start_date,
910    p_workorder_rec.actual_end_date,
911    p_workorder_rec.lot_number,
912    p_workorder_rec.completion_subinventory,
913    p_workorder_rec.completion_locator_id
914   );
915 
916   RETURN FND_API.G_RET_STS_SUCCESS;
917 
918 END record_ahl_workorder_txn;
919 
920 -- Function to complete / defer the given Workorder in ASO Entities
921 FUNCTION update_ahl_workorder
922 (
923   p_workorder_rec          IN   workorder_rec_type,
924   p_status_code            IN   VARCHAR2
925 ) RETURN VARCHAR2
926 IS
927   l_transaction_type_code  NUMBER := 1;
928   l_return_status          VARCHAR2(1);
929 BEGIN
930 
931   UPDATE   AHL_WORKORDERS
932   SET      status_code = p_status_code,
933            object_version_number = object_version_number + 1,
934            last_update_date = SYSDATE,
935            last_updated_by = FND_GLOBAL.user_id,
936            last_update_login = FND_GLOBAL.login_id
937   WHERE    workorder_id = p_workorder_rec.workorder_id
938   AND      object_version_number = p_workorder_rec.object_version_number;
939 
940   IF ( SQL%ROWCOUNT = 0 ) THEN
941     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_NOT_FOUND' );
942     FND_MSG_PUB.add;
943     RETURN FND_API.G_RET_STS_ERROR;
944   END IF;
945 
946   -- Set the Transaction Type
947   -- CHECK THIS
948   l_transaction_type_code := TO_NUMBER( p_status_code );
949 
950 /*
951   IF ( p_status_code = '4' ) THEN
952     l_transaction_type_code := TO_NUMBER( p_status_code );
953   ELSE
954     l_transaction_type_code := 2;
955   END IF;
956 */
957 
958   -- Insert a record in AHL_WORKORDER_TXNS for the Completion / Deferral Transaction.
959   l_return_status :=
960   record_ahl_workorder_txn
961   (
962     p_workorder_rec         => p_workorder_rec,
963     p_transaction_type_code => l_transaction_type_code
964   );
965 
966   RETURN FND_API.G_RET_STS_SUCCESS;
967 
968 END update_ahl_workorder;
969 
970 -- Function for Validating Complete Operation Inputs
971 FUNCTION validate_cop_inputs
972 (
973   p_workorder_operation_id   IN   NUMBER,
974   p_object_version_no        IN   NUMBER
975 ) RETURN VARCHAR2
976 IS
977 BEGIN
978 
979   IF ( p_workorder_operation_id IS NULL OR
980        p_workorder_operation_id = FND_API.G_MISS_NUM OR
981        p_object_version_no IS NULL OR
982        p_object_version_no = FND_API.G_MISS_NUM ) THEN
983     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_COP_INPUTS' );
984     FND_MSG_PUB.add;
985     RETURN FND_API.G_RET_STS_ERROR;
986   END IF;
987 
988   RETURN FND_API.G_RET_STS_SUCCESS;
989 END validate_cop_inputs;
990 
991 -- Function to validate whether the Actual End Date is later than the last Transaction date for the Workorder Operation.
992 FUNCTION validate_ahl_op_txn_date
993 (
994   p_workorder_operation_id  IN   NUMBER,
995   p_actual_end_date         IN   DATE
996 ) RETURN VARCHAR2
997 IS
998   l_transaction_date DATE;
999 
1000   CURSOR get_ahl_txn_rec( c_workorder_operation_id NUMBER )
1001   IS
1002   SELECT MAX ( creation_date )
1003   FROM   AHL_WORKORDER_MTL_TXNS
1004   WHERE  workorder_operation_id = c_workorder_operation_id;
1005 BEGIN
1006 
1007   OPEN   get_ahl_txn_rec( p_workorder_operation_id );
1008 
1009   FETCH  get_ahl_txn_rec
1010   INTO   l_transaction_date;
1011 
1012   IF ( get_ahl_txn_rec%FOUND ) THEN
1013 
1014     -- Ensure that the Actual End date is greater than the last Transaction Date
1015     IF ( l_transaction_date > p_actual_end_date ) THEN
1016       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ENDDT_TXNDT' );
1017       FND_MSG_PUB.add;
1018       CLOSE get_ahl_txn_rec;
1019       RETURN FND_API.G_RET_STS_ERROR;
1020     END IF;
1021   END IF;
1022 
1023   CLOSE get_ahl_txn_rec;
1024 
1025   RETURN FND_API.G_RET_STS_SUCCESS;
1026 END validate_ahl_op_txn_date;
1027 
1028 -- Function to check whether the last EAM Workorder Transaction is Completion
1029 -- and to ensure that the actual end date is greater than the
1030 -- last transaction date in EAM.
1031 FUNCTION validate_eam_op_compl_txn
1032 (
1033   p_wip_entity_id                 IN   NUMBER,
1034   p_operation_sequence_num        IN   NUMBER,
1035   p_actual_end_date               IN   DATE,
1036   p_validate_date                 IN   VARCHAR2 DEFAULT FND_API.G_TRUE
1037 ) RETURN VARCHAR2
1038 IS
1039 
1040   l_transaction_type NUMBER;
1041   l_transaction_date DATE;
1042 
1043   CURSOR       get_eam_txn_rec( c_wip_entity_id NUMBER, c_op_seq_num NUMBER )
1044   IS
1045   SELECT       transaction_type,
1046                transaction_date
1047   FROM         EAM_OP_COMPLETION_TXNS
1048   WHERE        wip_entity_id = p_wip_entity_id
1049   AND          operation_seq_num = p_operation_sequence_num
1050   ORDER BY     transaction_date DESC;
1051 
1052 BEGIN
1053 
1054   OPEN   get_eam_txn_rec( p_wip_entity_id, p_operation_sequence_num );
1055 
1056   FETCH  get_eam_txn_rec
1057   INTO   l_transaction_type,
1058          l_transaction_date;
1059 
1060   IF ( get_eam_txn_rec%FOUND ) THEN
1061 
1062     -- Ensure that the Transaction Type is not COMPLETE.
1063     IF ( l_transaction_type = 1 ) THEN
1064       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_OP_COMP_IN_EAM' );
1065       FND_MSG_PUB.add;
1066       CLOSE get_eam_txn_rec;
1067       RETURN FND_API.G_RET_STS_ERROR;
1068     END IF;
1069 
1070     IF (NVL(p_validate_date, FND_API.G_TRUE) = FND_API.G_TRUE) THEN
1071     IF ( l_transaction_date > p_actual_end_date ) THEN
1072       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ENDDT_EAM_TXNDT' );
1073       FND_MSG_PUB.add;
1074       CLOSE get_eam_txn_rec;
1075       RETURN FND_API.G_RET_STS_ERROR;
1076     END IF;
1077     END IF;
1078   END IF;
1079 
1080   RETURN FND_API.G_RET_STS_SUCCESS;
1081 END validate_eam_op_compl_txn;
1082 
1083 -- Function to validate the given Operation.
1084 FUNCTION validate_cop_rec
1085 (
1086   p_operation_rec             IN   operation_rec_type,
1087   p_workorder_rec             IN   workorder_rec_type,
1088   p_validate_date             IN   VARCHAR2 DEFAULT FND_API.G_TRUE,
1089   p_check_unit                IN   VARCHAR2 DEFAULT FND_API.G_TRUE
1090 ) RETURN VARCHAR2
1091 IS
1092   l_return_status VARCHAR2(1);
1093   l_wip_status    BOOLEAN;
1094   l_op_status_meaning  VARCHAR2(80);
1095   l_job_status_meaning  VARCHAR2(80);
1096 
1097 BEGIN
1098 
1099   IF ( p_operation_rec.description IS NULL ) THEN
1100     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_DESC_NULL' );
1101     FND_MSG_PUB.add;
1102     RETURN FND_API.G_RET_STS_ERROR;
1103   END IF;
1104 
1105 		-- rroy
1106 		-- ACL Changes
1107 		IF p_check_unit = FND_API.G_TRUE THEN
1108 		l_return_status := AHL_PRD_UTIL_PKG.Is_Unit_Locked(p_operation_rec.workorder_id, NULL, NULL, NULL);
1109 		IF l_return_status = FND_API.G_TRUE THEN
1110 				FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_OP_COMP_UNTLCKD');
1111 				--FND_MESSAGE.Set_Token('WO_NAME', p_workorder_rec.workorder_name);
1112 				FND_MSG_PUB.ADD;
1113 				RETURN FND_API.G_RET_STS_ERROR;
1114 		END IF;
1115 		END IF;
1116 		-- rroy
1117 		-- ACL Changes
1118 
1119   IF ( G_DEBUG = 'Y' ) THEN
1120 	AHL_DEBUG_PUB.debug( 'before validating actual dates for wo_op_id->'||p_operation_rec.workorder_operation_id);
1121 	AHL_DEBUG_PUB.debug( 'p_operation_rec.actual_start_date->'||TO_CHAR(p_operation_rec.actual_start_date,'DD-MON-YYYY HH24:MI:SS'));
1122 	AHL_DEBUG_PUB.debug( 'p_operation_rec.actual_end_date->'||TO_CHAR(p_operation_rec.actual_end_date,'DD-MON-YYYY HH24:MI:SS'));
1123   END IF;
1124 
1125   IF (NVL(p_validate_date, FND_API.G_TRUE) = FND_API.G_TRUE) THEN
1126     l_return_status :=
1127     validate_actual_dates
1128     (
1129       p_actual_start_date          => p_operation_rec.actual_start_date,
1130       p_actual_end_date            => p_operation_rec.actual_end_date
1131     );
1132   END IF;
1133 
1134   IF ( p_operation_rec.status_code <> G_OP_STATUS_UNCOMPLETE ) THEN
1135     -- Modified by srini to show status meaning
1136 				-- replacing with call to get_status function
1137 				-- so no exceptions are thrown if the
1138 				-- lookup does not exist
1139 				l_op_status_meaning := get_status(p_operation_rec.status_code,
1140    							          'AHL_OPERATION_STATUS');
1141 
1142 
1143 	  /*SELECT MEANING INTO l_op_status_meaning
1144       FROM fnd_lookup_values_vl
1145      WHERE lookup_type = 'AHL_OPERATION_STATUS'
1146 	   AND lookup_code = p_operation_rec.status_code;
1147 				*/
1148     --
1149     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_OP_STATUS' );
1150     FND_MESSAGE.set_token( 'STATUS', l_op_status_meaning );
1151     FND_MSG_PUB.add;
1152     RETURN FND_API.G_RET_STS_ERROR;
1153   END IF;
1154 
1155 		IF (NVL(p_validate_date, FND_API.G_TRUE) = FND_API.G_TRUE) THEN
1156   IF ( p_operation_rec.actual_start_date < p_workorder_rec.actual_start_date ) THEN
1157     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_WO_ST_DT' );
1158     FND_MSG_PUB.add;
1159     RETURN FND_API.G_RET_STS_ERROR;
1160   END IF;
1161 
1162   IF ( p_operation_rec.actual_end_date > p_workorder_rec.actual_end_date ) THEN
1163     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_WO_END_DT' );
1164     FND_MSG_PUB.add;
1165     RETURN FND_API.G_RET_STS_ERROR;
1166   END IF;
1167 		END IF;
1168 
1169   IF ( p_workorder_rec.status_code = G_JOB_STATUS_UNRELEASED OR -- fix for bug# 7555681
1170        p_workorder_rec.status_code = G_JOB_STATUS_COMPLETE OR
1171        p_workorder_rec.status_code = G_JOB_STATUS_COMPLETE_NC OR
1172        p_workorder_rec.status_code = G_JOB_STATUS_CANCELLED OR
1173        p_workorder_rec.status_code = G_JOB_STATUS_CLOSED ) THEN
1174     -- Modified by srini to show status meaning
1175 				-- replacing with call to get_status function
1176 				-- so no exceptions are thrown if the
1177 				-- lookup does not exist
1178 				l_job_status_meaning := get_status(p_workorder_rec.status_code,
1179 								'AHL_JOB_STATUS');
1180 
1181 	/*SELECT MEANING INTO l_job_status_meaning
1182       FROM fnd_lookup_values_vl
1183      WHERE lookup_type = 'AHL_JOB_STATUS'
1184 	   AND lookup_code = p_workorder_rec.status_code;
1185 				*/
1186 
1187     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_OP_WO_STATUS' );
1188     FND_MESSAGE.set_token( 'STATUS', l_job_status_meaning );
1189     FND_MSG_PUB.add;
1190     RETURN FND_API.G_RET_STS_ERROR;
1191   END IF;
1192 
1193   /*
1194   -- Adithya removed below validation for bug # 6326071.
1195   -- Accounting periods are validated against transaction date
1196   -- in EAM. To be inline with EAM validations the check of accouting
1197   -- period against actual start date and end date is removed.
1198   IF (NVL(p_validate_date, FND_API.G_TRUE) = FND_API.G_TRUE) THEN
1199   l_return_status :=
1200   validate_acct_period
1201   (
1202     p_organization_id            => p_operation_rec.organization_id,
1203     p_actual_start_date          => p_operation_rec.actual_start_date,
1204     p_actual_end_date            => p_operation_rec.actual_end_date
1205   );
1206   END IF;
1207   */
1208 
1209   IF ( p_operation_rec.plan_id IS NOT NULL AND
1210        p_operation_rec.collection_id IS NULL ) THEN
1211     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_NO_QA_RESULTS' );
1212     FND_MSG_PUB.add;
1213     RETURN FND_API.G_RET_STS_ERROR;
1214   END IF;
1215 
1216   IF ( p_operation_rec.plan_id IS NOT NULL ) THEN
1217 
1218     l_return_status :=
1219     validate_qa_status
1220     (
1221       p_plan_id                 => p_operation_rec.plan_id,
1222       p_char_id                 => 125, -- Operation Status Plan Element
1223       p_collection_id           => p_operation_rec.collection_id
1224     );
1225   END IF;
1226 
1227 /*
1228   l_return_status :=
1229   validate_ahl_op_txn_date
1230   (
1231     p_workorder_operation_id    => p_operation_rec.workorder_operation_id,
1232     p_actual_end_date           => p_operation_rec.actual_end_date
1233   );
1234 */
1235 
1236   l_return_status :=
1237   validate_eam_op_compl_txn
1238   (
1239     p_wip_entity_id             => p_operation_rec.wip_entity_id,
1240     p_operation_sequence_num    => p_operation_rec.operation_sequence_num,
1241     p_actual_end_date           => p_operation_rec.actual_end_date,
1242     p_validate_date             => p_validate_date
1243   );
1244 
1245   RETURN FND_API.G_RET_STS_SUCCESS;
1246 
1247 END validate_cop_rec;
1248 
1249 FUNCTION complete_eam_wo_operation
1250 (
1251   p_operation_rec          IN   operation_rec_type
1252 ) RETURN VARCHAR2
1253 IS
1254 
1255 l_attribute_rec       EAM_WorkOrderTransactions_PUB.Attributes_Rec_Type;
1256 
1257 l_msg_count           NUMBER;
1258 l_return_status       VARCHAR2(1);
1259 l_msg_data            VARCHAR2(2000);
1260 l_app_name            VARCHAR2(30);
1261 l_msg_name            VARCHAR2(30);
1262 
1263 BEGIN
1264   EAM_WorkOrderTransactions_PUB.complete_operation
1265   (
1266     p_api_version                  => 1.0,
1267     p_init_msg_list                => FND_API.G_TRUE,
1268     p_commit                       => FND_API.G_FALSE,
1269     x_return_status                => l_return_status,
1270     x_msg_count                    => l_msg_count,
1271     x_msg_data                     => l_msg_data,
1272     p_wip_entity_id                => p_operation_rec.wip_entity_id,
1273     p_operation_seq_num            => p_operation_rec.operation_sequence_num,
1274     p_transaction_date             => SYSDATE,
1275     p_transaction_type             => 1,
1276     p_actual_start_date            => p_operation_rec.actual_start_date,
1277     p_actual_end_date              => p_operation_rec.actual_end_date,
1278     p_actual_duration              => NULL,
1279     p_shutdown_start_date          => NULL,
1280     p_shutdown_end_date            => NULL,
1281     p_shutdown_duration            => NULL,
1282     p_reconciliation_code          => NULL,
1283     p_attribute_rec                => l_attribute_rec
1284   );
1285 
1286   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
1287     IF ( l_msg_data IS NOT NULL ) THEN
1288       FND_MESSAGE.parse_encoded( l_msg_data, l_app_name, l_msg_name );
1289       FND_MESSAGE.set_name( l_app_name, l_msg_name );
1290       FND_MSG_PUB.add;
1291     END IF;
1292     RETURN FND_API.G_RET_STS_ERROR;
1293   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
1294     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EAM_WO_OP_CMPL_ERROR' );
1295     FND_MSG_PUB.add;
1296     RETURN FND_API.G_RET_STS_ERROR;
1297   END IF;
1298 
1299   RETURN FND_API.G_RET_STS_SUCCESS;
1300 END complete_eam_wo_operation;
1301 
1302 -- Function to record a Workorder Operation Completion Transaction ASO Entities
1303 FUNCTION record_ahl_wo_operation_txn
1304 (
1305   p_operation_rec                IN   operation_rec_type
1306 ) RETURN VARCHAR2
1307 IS
1308   l_wo_operation_txn_id      NUMBER;
1309   l_transaction_type_code    NUMBER := 1;
1310   l_load_type_code           NUMBER := 1;
1311 BEGIN
1312 
1313   SELECT AHL_WO_OPERATIONS_TXNS_S.NEXTVAL
1314   INTO   l_wo_operation_txn_id
1315   FROM   DUAL;
1316 
1317   INSERT INTO AHL_WO_OPERATIONS_TXNS
1318   (
1319    WO_OPERATION_TXN_ID,
1320    OBJECT_VERSION_NUMBER,
1321    LAST_UPDATE_DATE,
1322    LAST_UPDATED_BY,
1323    CREATION_DATE,
1324    CREATED_BY,
1325    LAST_UPDATE_LOGIN,
1326    TRANSACTION_TYPE_CODE,
1327    LOAD_TYPE_CODE,
1328    WORKORDER_OPERATION_ID,
1329    OP_ACTUAL_START_DATE,
1330    OP_ACTUAL_END_DATE
1331   ) VALUES (
1332    l_wo_operation_txn_id,
1333    1,
1334    SYSDATE,
1335    FND_GLOBAL.user_id,
1336    SYSDATE,
1337    FND_GLOBAL.user_id,
1338    FND_GLOBAL.login_id,
1339    p_operation_rec.workorder_operation_id,
1340    l_transaction_type_code,
1341    l_load_type_code,
1342    p_operation_rec.actual_start_date,
1343    p_operation_rec.actual_end_date
1344   );
1345 
1346   RETURN FND_API.G_RET_STS_SUCCESS;
1347 END record_ahl_wo_operation_txn;
1348 
1349 --Function to complete the given Operation in ASO Entities
1350 FUNCTION complete_ahl_wo_operation
1351 (
1352   p_operation_rec                IN   operation_rec_type
1353 ) RETURN VARCHAR2
1354 IS
1355   l_return_status  VARCHAR2(1);
1356 BEGIN
1357 
1358   UPDATE   AHL_WORKORDER_OPERATIONS
1359   SET      status_code = G_OP_STATUS_COMPLETE,
1360            object_version_number = object_version_number + 1,
1361            last_update_date = SYSDATE,
1362            last_updated_by = FND_GLOBAL.user_id,
1363            last_update_login = FND_GLOBAL.login_id
1364   WHERE    workorder_operation_id = p_operation_rec.workorder_operation_id
1365   AND      object_version_number = p_operation_rec.object_version_number;
1366 
1367   IF ( SQL%ROWCOUNT = 0 ) THEN
1368     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_OP_NOT_FOUND' );
1369     FND_MSG_PUB.add;
1370     RETURN FND_API.G_RET_STS_ERROR;
1371   END IF;
1372 
1373   -- Insert a record in AHL_WO_OPERATION_TXNS for the Completion Transaction.
1374   l_return_status :=
1375   record_ahl_wo_operation_txn
1376   (
1377     p_operation_rec         => p_operation_rec
1378   );
1379 
1380   RETURN FND_API.G_RET_STS_SUCCESS;
1381 
1382 END complete_ahl_wo_operation;
1383 
1384 -- Function to get all the operations for the given Workorder.
1385 FUNCTION get_workorder_operations
1386 (
1387   p_workorder_id           IN          NUMBER,
1388   p_object_version_no      IN          NUMBER := NULL,
1389   x_operation_tbl          OUT NOCOPY operation_tbl_type
1390 ) RETURN VARCHAR2
1391 IS
1392   l_count NUMBER := 1;
1393 
1394   CURSOR get_operations ( c_workorder_id NUMBER )
1395   IS
1396   SELECT workorder_operation_id,
1397          actual_start_date,
1398          actual_end_date,
1399          status_code,
1400          status
1401   FROM   AHL_WORKORDER_OPERATIONS_V
1402   WHERE  workorder_id = c_workorder_id;
1403 
1404 BEGIN
1405 
1406   FOR op_cursor IN get_operations( p_workorder_id ) LOOP
1407     x_operation_tbl( l_count ).workorder_operation_id := op_cursor.workorder_operation_id;
1408     x_operation_tbl( l_count ).actual_start_date := op_cursor.actual_start_date;
1409     x_operation_tbl( l_count ).actual_end_date := op_cursor.actual_end_date;
1410     x_operation_tbl( l_count ).status_code := op_cursor.status_code;
1411     x_operation_tbl( l_count ).status := op_cursor.status;
1412 
1413     l_count := l_count + 1;
1414   END LOOP;
1415 
1416 /*
1417   IF ( x_operation_tbl.COUNT = 0 ) THEN
1418     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_NO_WO_OPERATIONS' );
1419     FND_MSG_PUB.add;
1420     RETURN FND_API.G_RET_STS_ERROR;
1421   END IF;
1422 */
1423 
1424   RETURN FND_API.G_RET_STS_SUCCESS;
1425 END get_workorder_operations;
1426 
1427 -- Function for common record validations for Completion and Deferral.
1428 FUNCTION validate_cwo_dwo_rec
1429 (
1430   p_workorder_rec    IN  workorder_rec_type,
1431   p_validate_date    IN  VARCHAR2 DEFAULT FND_API.G_TRUE
1432 ) RETURN VARCHAR2
1433 IS
1434   l_return_status VARCHAR2(1);
1435   l_wip_status BOOLEAN;
1436 BEGIN
1437 
1438 IF (NVL(p_validate_date, FND_API.G_TRUE) = FND_API.G_TRUE) THEN
1439   l_return_status :=
1440   validate_actual_dates
1441   (
1442     p_actual_start_date          => p_workorder_rec.actual_start_date,
1443     p_actual_end_date            => p_workorder_rec.actual_end_date
1444   );
1445 
1446   /*
1447   -- Adithya  removed below validation for bug # 6326071.
1448   -- Accounting periods are validated against transaction date
1449   -- in EAM. To be inline with EAM validations the check of accouting
1450   -- period against actual start date and end date is removed.
1451   l_return_status :=
1452   validate_acct_period
1453   (
1454     p_organization_id            => p_workorder_rec.organization_id,
1455     p_actual_start_date          => p_workorder_rec.actual_start_date,
1456     p_actual_end_date            => p_workorder_rec.actual_end_date
1457   );
1458   */
1459 END IF;
1460 
1461 		-- moved the below check from this function
1462 		-- since this is not required for deferral
1463 		-- the validation is now being done in
1464 		-- validate_cwo_rec for completion only
1465 		-- bug no 3942950
1466 
1467   /*IF ( p_workorder_rec.plan_id IS NOT NULL AND
1468        p_workorder_rec.collection_id IS NULL ) THEN
1469     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_NO_QA_RESULTS' );
1470     FND_MSG_PUB.add;
1471     RETURN FND_API.G_RET_STS_ERROR;
1472   END IF;
1473 */
1474 /*
1475   l_return_status :=
1476   validate_ahl_wo_txn_date
1477   (
1478     p_workorder_id              => p_workorder_rec.workorder_id,
1479     p_actual_end_date           => p_workorder_rec.actual_end_date
1480   );
1481 */
1482 
1483   l_return_status :=
1484   validate_eam_wo_compl_txn
1485   (
1486     p_wip_entity_id             => p_workorder_rec.wip_entity_id,
1487     p_actual_end_date           => p_workorder_rec.actual_end_date,
1488     p_validate_date             => p_validate_date
1489   );
1490 
1491   RETURN FND_API.G_RET_STS_SUCCESS;
1492 END validate_cwo_dwo_rec;
1493 
1494 FUNCTION validate_cwo_rec
1495 (
1496   p_workorder_rec    IN  workorder_rec_type,
1497   p_operation_tbl    IN  operation_tbl_type,
1498   p_validate_date    IN  VARCHAR2 DEFAULT FND_API.G_TRUE,
1499   p_check_unit       IN  VARCHAR2 DEFAULT FND_API.G_TRUE
1500 ) RETURN VARCHAR2
1501 IS
1502 
1503 l_return_status VARCHAR2(1);
1504 l_wip_status BOOLEAN;
1505 
1506 CURSOR  get_completion_dependencies( c_child_wip_entity_id NUMBER )
1507 IS
1508 SELECT  WO.workorder_name,
1509         WO.status_code
1510 FROM    AHL_WORKORDERS WO,
1511         WIP_SCHED_RELATIONSHIPS WOR
1512 WHERE   WO.wip_entity_id = WOR.parent_object_id
1513 AND     WO.master_workorder_flag = 'N'
1514 AND     WO.status_code <> G_JOB_STATUS_DELETED
1515 AND     WOR.parent_object_type_id = 1
1516 AND     WOR.relationship_type = 2
1517 AND     WOR.child_object_type_id = 1
1518 AND     WOR.child_object_id = c_child_wip_entity_id;
1519 
1520 l_job_status_meaning VARCHAR2(80);
1521 
1522 BEGIN
1523 
1524 		-- rroy
1525 		-- ACL Changes
1526 		IF p_check_unit = FND_API.G_TRUE THEN
1527 		l_return_status := AHL_PRD_UTIL_PKG.Is_Unit_Locked(p_workorder_rec.workorder_id, NULL, NULL, NULL);
1528 		IF l_return_status = FND_API.G_TRUE THEN
1529 				FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_WO_COMP_UNTLCKD');
1530 				FND_MESSAGE.Set_Token('WO_NAME', p_workorder_rec.workorder_name);
1531 				FND_MSG_PUB.ADD;
1532 				RETURN FND_API.G_RET_STS_ERROR;
1533 		END IF;
1534 		END IF;
1535 		-- rroy
1536 		-- ACL Changes
1537 
1538   l_return_status :=
1539   validate_cwo_dwo_rec
1540   (
1541     p_workorder_rec    => p_workorder_rec,
1542     p_validate_date    => p_validate_date
1543   );
1544   -- Moved the below validation from
1545 		-- validate_cwo_dwo_rec to this function because
1546 		-- this validation is not required for deferral
1547 		-- bug no 3942950
1548 		IF ( p_workorder_rec.plan_id IS NOT NULL AND
1549        p_workorder_rec.collection_id IS NULL ) THEN
1550     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_NO_QA_RESULTS' );
1551     FND_MSG_PUB.add;
1552     RETURN FND_API.G_RET_STS_ERROR;
1553   END IF;
1554 
1555 
1556   IF ( p_workorder_rec.status_code <> G_JOB_STATUS_RELEASED AND
1557        p_workorder_rec.status_code <> G_JOB_STATUS_QA_PENDING ) THEN
1558     -- Modified by srini to show status meaning
1559 				-- replacing with call to get_status function
1560 				-- so no exceptions are thrown if the
1561 				-- lookup does not exist
1562 				l_job_status_meaning := get_status(p_workorder_rec.status_code,
1563 															'AHL_JOB_STATUS');
1564 
1565 	/*SELECT MEANING INTO l_job_status_meaning
1566       FROM fnd_lookup_values_vl
1567      WHERE lookup_type = 'AHL_JOB_STATUS'
1568 	   AND lookup_code = p_workorder_rec.status_code;
1569 */
1570     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_WO_STATUS' );
1571     FND_MESSAGE.set_token( 'STATUS', l_job_status_meaning );
1572     FND_MSG_PUB.add;
1573     RETURN FND_API.G_RET_STS_ERROR;
1574   END IF;
1575 
1576   IF ( p_operation_tbl.COUNT > 0 ) THEN
1577     FOR i IN 1..p_operation_tbl.COUNT LOOP
1578     IF (NVL(p_validate_date, FND_API.G_TRUE) = FND_API.G_TRUE) THEN
1579       IF ( p_workorder_rec.actual_start_date > p_operation_tbl(i).actual_start_date ) THEN
1580         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_OP_ST_DT' );
1581         FND_MSG_PUB.add;
1582         RETURN FND_API.G_RET_STS_ERROR;
1583       END IF;
1584 
1585       IF ( p_workorder_rec.actual_end_date < p_operation_tbl(i).actual_end_date ) THEN
1586         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_OP_END_DT' );
1587         FND_MSG_PUB.add;
1588         RETURN FND_API.G_RET_STS_ERROR;
1589       END IF;
1590     END IF;
1591 
1592       IF ( p_operation_tbl(i).status_code <> G_OP_STATUS_COMPLETE ) THEN
1593         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_WO_OP_STATUS' );
1594         FND_MSG_PUB.add;
1595         RETURN FND_API.G_RET_STS_ERROR;
1596       END IF;
1597 
1598     END LOOP;
1599   END IF;
1600 
1601   IF ( p_workorder_rec.plan_id IS NOT NULL ) THEN
1602 
1603     l_return_status :=
1604     validate_qa_status
1605     (
1606       p_plan_id                 => p_workorder_rec.plan_id,
1607       p_char_id                 => 98, -- Workorder Status Plan Element
1608       p_collection_id           => p_workorder_rec.collection_id
1609     );
1610   END IF;
1611 
1612   FOR parent_csr IN get_completion_dependencies( p_workorder_rec.wip_entity_id ) LOOP
1613     IF ( parent_csr.status_code <> G_JOB_STATUS_COMPLETE AND
1614          parent_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
1615          parent_csr.status_code <> G_JOB_STATUS_CLOSED AND
1616          parent_csr.status_code <> G_JOB_STATUS_CANCELLED ) THEN
1617       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_PRIOR_WO_NOT_COMPLETE' );
1618       FND_MESSAGE.set_token( 'WO_NAME', parent_csr.workorder_name );
1619       FND_MSG_PUB.add;
1620       RETURN FND_API.G_RET_STS_ERROR;
1621     END IF;
1622   END LOOP;
1623 
1624   RETURN FND_API.G_RET_STS_SUCCESS;
1625 END validate_cwo_rec;
1626 
1627 FUNCTION validate_dwo_rec
1628 (
1629   p_workorder_rec    IN  workorder_rec_type
1630 ) RETURN VARCHAR2
1631 IS
1632   l_return_status VARCHAR2(1);
1633   l_wip_status BOOLEAN;
1634   l_job_status_meaning VARCHAR2(80);
1635 BEGIN
1636 
1637 
1638 		--rroy
1639 		-- ACL Changes
1640 		l_return_status := AHL_PRD_UTIL_PKG.Is_Unit_Locked(p_workorder_rec.workorder_id, NULL, NULL, NULL);
1641 		IF l_return_status = FND_API.G_TRUE THEN
1642 				FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_WO_DEFF_UNTLCKD');
1643 				FND_MSG_PUB.ADD;
1644 				RETURN FND_API.G_RET_STS_ERROR;
1645 		END IF;
1646 		--rroy
1647 		-- ACL Changes
1648 
1649   l_return_status :=
1650   validate_cwo_dwo_rec
1651   (
1652     p_workorder_rec    => p_workorder_rec
1653   );
1654 
1655   IF ( p_workorder_rec.status_code <> G_JOB_STATUS_RELEASED AND
1656        p_workorder_rec.status_code <> G_JOB_STATUS_ON_HOLD AND
1657        p_workorder_rec.status_code <> G_JOB_STATUS_PARTS_HOLD AND
1658        p_workorder_rec.status_code <> G_JOB_STATUS_QA_PENDING AND
1659        p_workorder_rec.status_code <> G_JOB_STATUS_DEFERRAL_PENDING ) THEN
1660     --Modified by srini to show the status meaning
1661 				-- replacing with call to get_status function
1662 				-- so no exceptions are thrown if the
1663 				-- lookup does not exist
1664 				l_job_status_meaning := get_status(p_workorder_rec.status_code,
1665 															'AHL_JOB_STATUS');
1666 
1667 	/*SELECT MEANING INTO l_job_status_meaning
1668       FROM fnd_lookup_values_vl
1669      WHERE lookup_type = 'AHL_JOB_STATUS'
1670 	   AND lookup_code = p_workorder_rec.status_code;
1671 */
1672     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_WO_STATUS' );
1673     FND_MESSAGE.set_token( 'STATUS', l_job_status_meaning );
1674     FND_MSG_PUB.add;
1675     RETURN FND_API.G_RET_STS_ERROR;
1676   END IF;
1677 
1678   RETURN FND_API.G_RET_STS_SUCCESS;
1679 
1680 END validate_dwo_rec;
1681 
1682 -- Function to validate the Inputs of the complete_mr_instance API
1683 FUNCTION validate_cmri_inputs
1684 (
1685   p_mr_rec               IN   mr_rec_type
1686 ) RETURN VARCHAR2
1687 IS
1688 
1689 l_return_status             VARCHAR2(1);
1690 l_msg_data                  VARCHAR2(2000);
1691 
1692 BEGIN
1693 
1694   -- Balaji - changed the code for 11.5.10
1695   -- API is changed to accept only mr_rec.
1696   IF (
1697          p_mr_rec.unit_effectivity_id = FND_API.G_MISS_NUM OR
1698          p_mr_rec.unit_effectivity_id IS NULL OR
1699          p_mr_rec.ue_object_version_no = FND_API.G_MISS_NUM OR
1700          p_mr_rec.ue_object_version_no IS NULL
1701       ) THEN
1702     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_CMRI_INPUTS' );
1703     FND_MSG_PUB.add;
1704     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
1705   END IF;
1706   RETURN FND_API.G_RET_STS_SUCCESS;
1707 END validate_cmri_inputs;
1708 
1709 -- Function to default missing attributes of the input MR instance record
1710 -- Added in 11.5.10
1711 
1712 FUNCTION default_mr_rec
1713 (
1714   p_x_mr_rec      IN OUT NOCOPY mr_rec_type
1715 )RETURN VARCHAR2
1716 IS
1717 
1718 l_mr_rec  mr_rec_type;
1719 
1720     /*CURSOR get_old_mr_rec(c_unit_effectivity_id NUMBER ,c_ue_object_version_no NUMBER)
1721     IS
1722     SELECT csi_item_instance_id,
1723            mr_header_id,
1724            cs_incident_id,
1725            mr_title,
1726            status_code,
1727            status,
1728            qa_inspection_type,
1729            actual_end_date,
1730            plan_id,
1731            collection_id
1732     FROM   AHL_MR_INSTANCES_V
1733     WHERE  unit_effectivity_id = c_unit_effectivity_id
1734     AND    object_version_number = c_ue_object_version_no;*/
1735 
1736 BEGIN
1737 
1738    /*OPEN get_old_mr_rec(p_x_mr_rec.unit_effectivity_id,p_x_mr_rec.ue_object_version_no);
1739 
1740    FETCH get_old_mr_rec INTO
1741      l_mr_rec.item_instance_id,
1742      l_mr_rec.mr_header_id,
1743      l_mr_rec.incident_id,
1744      l_mr_rec.mr_title,
1745      l_mr_rec.ue_status_code,
1746      l_mr_rec.ue_status,
1747      l_mr_rec.qa_inspection_type,
1748      l_mr_rec.actual_end_date,
1749      l_mr_rec.qa_plan_id,
1750      l_mr_rec.qa_collection_id;
1751 
1752    CLOSE get_old_mr_rec;*/
1753    --for fix of bug number 6467963
1754    get_mr_details_rec
1755       (
1756          p_unit_effectivity_id => p_x_mr_rec.unit_effectivity_id,
1757          p_object_version_number   => p_x_mr_rec.ue_object_version_no,
1758          x_mr_rec => l_mr_rec
1759    );
1760 
1761    -- Convert G_MISS values to NULL and NULL values to Old values
1762    IF ( p_x_mr_rec.item_instance_id = FND_API.G_MISS_NUM ) THEN
1763       p_x_mr_rec.item_instance_id := null;
1764    ELSIF ( p_x_mr_rec.item_instance_id IS NULL ) THEN
1765       p_x_mr_rec.item_instance_id := l_mr_rec.item_instance_id;
1766    END IF;
1767 
1768    IF ( p_x_mr_rec.mr_header_id = FND_API.G_MISS_NUM ) THEN
1769       p_x_mr_rec.mr_header_id := null;
1770    ELSIF ( p_x_mr_rec.mr_header_id IS NULL ) THEN
1771       p_x_mr_rec.mr_header_id := l_mr_rec.mr_header_id;
1772    END IF;
1773 
1774    IF ( p_x_mr_rec.incident_id = FND_API.G_MISS_NUM ) THEN
1775       p_x_mr_rec.incident_id := null;
1776    ELSIF ( p_x_mr_rec.incident_id IS NULL ) THEN
1777       p_x_mr_rec.incident_id := l_mr_rec.incident_id;
1778    END IF;
1779 
1780    IF ( p_x_mr_rec.mr_title = FND_API.G_MISS_CHAR ) THEN
1781       p_x_mr_rec.mr_title := null;
1782    ELSIF ( p_x_mr_rec.mr_title IS NULL ) THEN
1783       p_x_mr_rec.mr_title := l_mr_rec.mr_title;
1784    END IF;
1785 
1786    IF ( p_x_mr_rec.ue_status_code = FND_API.G_MISS_CHAR ) THEN
1787       p_x_mr_rec.ue_status_code := null;
1788    ELSIF ( p_x_mr_rec.ue_status_code IS NULL ) THEN
1789       p_x_mr_rec.ue_status_code := l_mr_rec.ue_status_code;
1790    END IF;
1791 
1792    IF ( p_x_mr_rec.ue_status = FND_API.G_MISS_CHAR ) THEN
1793       p_x_mr_rec.ue_status := null;
1794    ELSIF ( p_x_mr_rec.ue_status IS NULL ) THEN
1795       p_x_mr_rec.ue_status := l_mr_rec.ue_status;
1796    END IF;
1797 
1798    IF ( p_x_mr_rec.qa_inspection_type = FND_API.G_MISS_CHAR ) THEN
1799       p_x_mr_rec.qa_inspection_type := null;
1800    ELSIF ( p_x_mr_rec.qa_inspection_type IS NULL ) THEN
1801       p_x_mr_rec.qa_inspection_type := l_mr_rec.qa_inspection_type;
1802    END IF;
1803 
1804    IF ( p_x_mr_rec.actual_end_date = FND_API.G_MISS_DATE ) THEN
1805       p_x_mr_rec.actual_end_date := null;
1806    ELSIF ( p_x_mr_rec.actual_end_date IS NULL ) THEN
1807       p_x_mr_rec.actual_end_date := l_mr_rec.actual_end_date;
1808    END IF;
1809 
1810    IF ( p_x_mr_rec.qa_plan_id = FND_API.G_MISS_NUM ) THEN
1811       p_x_mr_rec.qa_plan_id := null;
1812    ELSIF ( p_x_mr_rec.qa_plan_id IS NULL ) THEN
1813       p_x_mr_rec.qa_plan_id := l_mr_rec.qa_plan_id;
1814    END IF;
1815 
1816    IF ( p_x_mr_rec.qa_collection_id = FND_API.G_MISS_NUM ) THEN
1817       p_x_mr_rec.qa_collection_id := null;
1818    ELSIF ( p_x_mr_rec.qa_collection_id IS NULL ) THEN
1819       p_x_mr_rec.qa_collection_id := l_mr_rec.qa_collection_id;
1820    END IF;
1821 
1822    RETURN FND_API.G_RET_STS_SUCCESS;
1823 
1824 END default_mr_rec;
1825 
1826 -- Function to check whether the MR/SR is in a status that it can be signed off.
1827 -- Added in 11.5.10
1828 FUNCTION validate_mr_status
1829 (
1830   p_mr_status_code  IN  VARCHAR2,
1831   p_mr_status       IN  VARCHAR2,
1832   p_mr_title        IN  VARCHAR2
1833 )RETURN VARCHAR2
1834 IS
1835 
1836 BEGIN
1837 
1838    IF (p_mr_status_code <> G_MR_STATUS_JOBS_COMPLETE) THEN
1839      FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INV_SIGNOFF_STATUS');
1840      FND_MESSAGE.set_token( 'MAINT_REQ', p_mr_title);
1841      FND_MESSAGE.set_token( 'STATUS', p_mr_status);
1842      FND_MSG_PUB.add;
1843      RETURN FND_API.G_RET_STS_ERROR;
1844    END IF;
1845 
1846    RETURN FND_API.G_RET_STS_SUCCESS;
1847 
1848 END validate_mr_status;
1849 
1850 -- Function to check whether a MR Instance is Complete
1851 FUNCTION is_mr_complete
1852 (
1853   p_mr_title             IN   VARCHAR2,
1854   p_status_code          IN   VARCHAR2,
1855   p_status               IN   VARCHAR2,
1856   p_qa_inspection_type   IN   VARCHAR2,
1857   p_qa_plan_id           IN   NUMBER,
1858   p_qa_collection_id     IN   NUMBER
1859 ) RETURN VARCHAR2
1860 IS
1861 
1862 l_return_status       VARCHAR2(1);
1863 
1864 BEGIN
1865 
1866   -- Validate Status
1867   IF  p_status_code = G_MR_STATUS_DEFERRAL_PENDING  THEN
1868     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INV_SIGNOFF_STATUS');
1869     FND_MESSAGE.set_token( 'MAINT_REQ', p_mr_title );
1870     FND_MESSAGE.set_token( 'STATUS', NVL( p_status, p_status_code ) );
1871     FND_MSG_PUB.add;
1872   END IF;
1873 
1874   -- Check if inspection type is not null then plan id is also not null
1875   -- Bug # 6436307 - start
1876   IF (
1877      p_qa_inspection_type IS NOT NULL
1878      AND p_status_code <> G_MR_STATUS_SIGNED_OFF
1879      AND p_status_code <> G_MR_STATUS_DEFERRED
1880      AND p_status_code <> G_MR_STATUS_DEFERRAL_PENDING
1881      AND p_status_code <> G_MR_STATUS_TERMINATED
1882      AND p_status_code <> G_MR_STATUS_CANCELLED
1883      ) THEN
1884     IF (p_qa_plan_id IS NULL) THEN
1885       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MR_QA_PLAN_ID_NULL' );
1886       FND_MESSAGE.set_token( 'MAINT_REQ', p_mr_title);
1887       FND_MESSAGE.set_token( 'INSP_TYPE', p_qa_inspection_type );
1888       FND_MSG_PUB.add;
1889       RETURN FND_API.G_RET_STS_ERROR;
1890     END IF;
1891   END IF;
1892 
1893   -- Check if inspection type is not null then collection id is also not null
1894   IF (p_qa_inspection_type IS NOT NULL
1895       AND p_status_code <> G_MR_STATUS_SIGNED_OFF
1896       AND p_status_code <> G_MR_STATUS_DEFERRED
1897       AND p_status_code <> G_MR_STATUS_DEFERRAL_PENDING
1898       AND p_status_code <> G_MR_STATUS_TERMINATED
1899       AND p_status_code <> G_MR_STATUS_CANCELLED
1900      ) THEN
1901      IF (p_qa_collection_id IS NULL) THEN
1902       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MR_QA_COL_ID_NULL' );
1903       FND_MESSAGE.set_token( 'MAINT_REQ', p_mr_title);
1904       FND_MSG_PUB.add;
1905       RETURN FND_API.G_RET_STS_ERROR;
1906     END IF;
1907   END IF;
1908   -- Bug # 6436307 - end
1909   RETURN FND_API.G_RET_STS_SUCCESS;
1910 END is_mr_complete;
1911 
1912 -- Function to Check whether all Child MR Instances for a MR Instance
1913 -- are Complete
1914 FUNCTION are_child_mrs_complete
1915 (
1916   p_mr_rec               IN   mr_rec_type
1917 ) RETURN VARCHAR2
1918 IS
1919 
1920 l_return_status      VARCHAR2(1);
1921 l_msg_count          NUMBER;
1922 l_msg_data           VARCHAR2(2000);
1923 
1924 /*CURSOR     get_child_mr_instances( c_unit_effectivity_id NUMBER )
1925 IS
1926 SELECT     mr_header_id,
1927            unit_effectivity_id,
1928            status_code
1929 FROM       AHL_UNIT_EFFECTIVITIES_B
1930 WHERE      unit_effectivity_id IN
1931 (
1932 SELECT     related_ue_id
1933 FROM       AHL_UE_RELATIONSHIPS
1934 WHERE      unit_effectivity_id = related_ue_id
1935 START WITH ue_id = c_unit_effectivity_id
1936        AND relationship_code = 'PARENT'
1937 CONNECT BY ue_id = PRIOR related_ue_id
1938        AND relationship_code = 'PARENT'
1939 );*/
1940 
1941 --for fix of bug number 6467963
1942 CURSOR     get_child_mr_instances( c_unit_effectivity_id NUMBER )
1943 IS
1944 SELECT     mr_header_id,
1945            unit_effectivity_id,
1946            status_code
1947 FROM       AHL_UNIT_EFFECTIVITIES_B UE, (
1948 SELECT     related_ue_id
1949 FROM       AHL_UE_RELATIONSHIPS
1950 START WITH ue_id = c_unit_effectivity_id
1951        AND relationship_code = 'PARENT'
1952 CONNECT BY ue_id = PRIOR related_ue_id
1953        AND relationship_code = 'PARENT'
1954 )CH
1955 WHERE      UE.unit_effectivity_id = CH.related_ue_id;
1956 
1957 BEGIN
1958 
1959   FOR mr_cursor IN get_child_mr_instances( p_mr_rec.unit_effectivity_id ) LOOP
1960     --Balaji added additional status checks for BAE Bug.
1961     IF ( mr_cursor.status_code <> G_MR_STATUS_SIGNED_OFF AND
1962          mr_cursor.status_code <> G_MR_STATUS_DEFERRED AND
1963          mr_cursor.status_code <> G_MR_STATUS_TERMINATED AND
1964          mr_cursor.status_code <> G_MR_STATUS_CANCELLED
1965     ) THEN
1966       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CHILD_MRS_NOT_COMPL' );
1967       FND_MESSAGE.set_token( 'MAINT_REQ', p_mr_rec.mr_title);
1968       FND_MSG_PUB.add;
1969       RETURN FND_API.G_RET_STS_ERROR;
1970     END IF;
1971 
1972   END LOOP;
1973 
1974   RETURN FND_API.G_RET_STS_SUCCESS;
1975 END are_child_mrs_complete;
1976 
1977 -- Function to get the Counter Readings for an Item Instance
1978 -- Balaji added the parameter p_acccomplish_date for Bug # 6784053 (FP for Bug # 6750836).
1979 -- cursor for retrieving latest counter reading before or equal
1980 -- to the actual workorder date.
1981 FUNCTION get_cp_counters
1982 (
1983   p_item_instance_id     IN          NUMBER,
1984   p_wip_entity_id        IN          NUMBER,
1985   p_actual_date          IN          DATE,
1986   x_counter_tbl          OUT NOCOPY  counter_tbl_type
1987 ) RETURN VARCHAR2
1988 IS
1989 
1990 l_ctr_count  NUMBER := 1;
1991 
1992 -- Get the Counter Readings
1993 -- R12 changes for CSI_CP_COUNTERS_V. Bug# 6080133.
1994 CURSOR get_counters( c_item_instance_id NUMBER )
1995 IS
1996 SELECT   DISTINCT
1997          CTR.counter_id counter_id,
1998          --CTR.counter_group_id counter_group_id,
1999          CTR.DEFAULTED_GROUP_ID COUNTER_GROUP_ID,
2000          --CTR.counter_value_id counter_value_id,
2001          --NVL(CTR.net_reading, 0) net_reading,
2002          --CTR.type type
2003          CTR.COUNTER_TYPE type
2004 --FROM     CSI_CP_COUNTERS_V CTR
2005 --WHERE    CTR.customer_product_id = c_item_instance_id
2006 FROM     csi_counter_associations CCA, csi_counters_vl CTR
2007 WHERE    CCA.counter_id = CTR.counter_id
2008 AND      CCA.source_object_id = c_item_instance_id
2009 AND      CCA.source_object_code = 'CP'
2010 ORDER BY CTR.counter_id;
2011 
2012 -- Added for R12 bug# 6080133.
2013 -- get readings.
2014 -- Bug # 6750836 -- start
2015 -- cursor replaced to take care of accomplished date in the past.
2016 /*
2017 CURSOR get_readings(c_counter_id NUMBER)
2018 IS
2019 SELECT NVL(CV.net_reading, 0) net_reading, cv.counter_value_id
2020 FROM csi_counter_values_v cv
2021 WHERE cv.counter_id = c_counter_id
2022 ORDER by value_timestamp DESC;
2023 */
2024 CURSOR c_wo_actual_date(p_wip_entity_id NUMBER)
2025 IS
2026 SELECT
2027  awo.actual_end_date
2028 FROM
2029  ahl_workorders awo
2030 WHERE
2031  awo.wip_entity_id = p_wip_entity_id;
2032 
2033 l_wo_actual_date  DATE;
2034 -- cursor for retrieving latest counter reading before or equal
2035 -- to the actual workorder date.
2036 CURSOR get_readings(c_counter_id NUMBER, p_actual_date DATE)
2037 IS
2038 /*
2039 SELECT
2040       nvl(CCR.NET_READING,0) net_reading,
2041       ccr.counter_value_id
2042 FROM
2043       CSI_COUNTERS_VL CC,
2044       CSI_COUNTER_READINGS CCR
2045 WHERE
2046           CCR.COUNTER_ID = CC.COUNTER_ID
2047       AND CC.COUNTER_ID = c_counter_id
2048       AND CCR.VALUE_TIMESTAMP <= NVL(p_actual_date,CCR.VALUE_TIMESTAMP)
2049 ORDER BY
2050       CCR.VALUE_TIMESTAMP DESC;
2051 */
2052 
2053 SELECT * FROM (
2054       SELECT
2055             nvl(CCR.NET_READING,0) net_reading,
2056             ccr.counter_value_id
2057       FROM
2058             CSI_COUNTER_READINGS CCR
2059       WHERE
2060             CCR.COUNTER_ID = c_counter_id
2061             AND nvl(CCR.disabled_flag,'N') = 'N'
2062             AND CCR.VALUE_TIMESTAMP <= NVL(p_actual_date,CCR.VALUE_TIMESTAMP)
2063       ORDER BY
2064             CCR.VALUE_TIMESTAMP DESC
2065              )
2066 WHERE ROWNUM < 2;
2067 
2068 -- Bug # 6750836 -- end
2069 BEGIN
2070 
2071   l_wo_actual_date := p_actual_date;
2072 
2073   IF p_actual_date IS NULL
2074   THEN
2075 
2076     OPEN c_wo_actual_date(p_wip_entity_id);
2077     FETCH c_wo_actual_date INTO l_wo_actual_date;
2078     CLOSE c_wo_actual_date;
2079 
2080   END IF;
2081 
2082   IF ( FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL)
2083   THEN
2084     fnd_log.string(
2085                    FND_LOG.LEVEL_STATEMENT,
2086                    'ahl.plsql.AHL_COMPLETIONS_PVT.get_cp_counters',
2087                    'l_wo_actual_date in get_cp_counters -> ' || TO_CHAR(l_wo_actual_date, 'DD-MON-YYYY HH24:MI:SS')
2088                   );
2089   END IF;
2090   FOR ctr_cursor IN get_counters( p_item_instance_id )
2091   LOOP
2092     x_counter_tbl( l_ctr_count ).item_instance_id := p_item_instance_id;
2093     x_counter_tbl( l_ctr_count ).counter_id := ctr_cursor.counter_id;
2094     x_counter_tbl( l_ctr_count ).counter_group_id := ctr_cursor.counter_group_id;
2095     -- get reading.
2096     OPEN get_readings(ctr_cursor.counter_id, l_wo_actual_date);
2097     FETCH get_readings INTO x_counter_tbl( l_ctr_count ).counter_reading,
2098                             x_counter_tbl( l_ctr_count ).counter_value_id;
2099     IF (get_readings%NOTFOUND) THEN
2100       x_counter_tbl( l_ctr_count ).counter_reading := 0;
2101       x_counter_tbl( l_ctr_count ).counter_value_id := NULL;
2102     END IF;
2103     CLOSE get_readings;
2104 
2105     --x_counter_tbl( l_ctr_count ).counter_value_id := ctr_cursor.counter_value_id;
2106     --x_counter_tbl( l_ctr_count ).counter_reading := ctr_cursor.net_reading;
2107     x_counter_tbl( l_ctr_count ).counter_type := ctr_cursor.type;
2108 
2109     l_ctr_count := l_ctr_count + 1;
2110 
2111   END LOOP;
2112 
2113 /* Removed for Bug 3310304
2114   IF ( x_counter_tbl.COUNT < 1 ) THEN
2115     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_NO_CTRS_FOR_MR' );
2116     FND_MSG_PUB.add;
2117     RETURN FND_API.G_RET_STS_ERROR;
2118   END IF;
2119 */
2120 
2121   RETURN FND_API.G_RET_STS_SUCCESS;
2122 END get_cp_counters;
2123 
2124 -- Function to get the Reset Counter Readings for an Item Instance for a MR
2125 -- Function to get the Reset Counter Readings for an Item Instance for a MR
2126 FUNCTION get_reset_counters
2127 (
2128   p_mr_header_id         IN          NUMBER,
2129   p_item_instance_id     IN          NUMBER,
2130   p_actual_date          IN          DATE,
2131   x_counter_tbl          OUT NOCOPY  counter_tbl_type
2132 ) RETURN VARCHAR2
2133 IS
2134 
2135 l_ctr_count  NUMBER := 1;
2136 l_prev_counter_id NUMBER := -1;
2137 
2138 l_appl_mrs_tbl    AHL_FMP_PVT.applicable_mr_tbl_type;
2139 l_return_status   VARCHAR2(1);
2140 l_msg_count       NUMBER;
2141 l_msg_data        VARCHAR2(2000);
2142 
2143 -- Get the Counter Readings and Reset Values
2144 -- R12 counter changes for CSI_CP_COUNTERS_V. Bug# 6080133
2145 CURSOR get_counters( c_item_instance_id NUMBER, c_mr_header_id NUMBER, c_mr_eff_id NUMBER )
2146 IS
2147 SELECT   DISTINCT
2148          CTR.counter_id counter_id,
2149          --CTR.counter_group_id counter_group_id,
2150          CTR.DEFAULTED_GROUP_ID COUNTER_GROUP_ID,
2151          --NVL(CTR.net_reading, 0) net_reading,
2152          CTR.COUNTER_TYPE type,
2153          MRI.reset_value reset_value
2154 --FROM     CSI_CP_COUNTERS_V CTR, AHL_MR_INTERVALS_V MRI, AHL_MR_EFFECTIVITIES MRE
2155 FROM     csi_counter_associations CCA, csi_counters_vl CTR, AHL_MR_INTERVALS_V MRI, AHL_MR_EFFECTIVITIES MRE
2156 WHERE    CCA.counter_id = CTR.counter_id
2157 AND      CCA.source_object_id = c_item_instance_id
2158 AND      CCA.source_object_code = 'CP'
2159 --AND      CTR.counter_name = MRI.counter_name
2160 AND      CTR.counter_template_name = MRI.counter_name
2161 AND      MRI.reset_value IS NOT NULL
2162 AND      MRI.mr_effectivity_id = MRE.mr_effectivity_id
2163 AND      MRE.mr_effectivity_id = c_mr_eff_id
2164 AND      MRE.mr_header_id = c_mr_header_id
2165 ORDER BY CTR.counter_id, MRI.reset_value DESC;
2166 
2167 -- get readings. Added for R12 bug# 6080133.
2168 -- Bug # 6750836 -- start
2169 CURSOR get_readings(c_counter_id NUMBER, p_actual_date DATE)
2170 IS
2171 /*
2172 SELECT
2173       nvl(CCR.NET_READING,0) net_reading
2174 FROM
2175       CSI_COUNTERS_VL CC,
2176       CSI_COUNTER_READINGS CCR
2177 WHERE
2178           CCR.COUNTER_ID = CC.COUNTER_ID
2179       AND CC.COUNTER_ID = c_counter_id
2180       AND CCR.VALUE_TIMESTAMP <= p_actual_date
2181 ORDER by
2182       CCR.value_timestamp DESC;
2183 */
2184 
2185 SELECT * FROM (
2186       SELECT
2187             nvl(CCR.NET_READING,0) net_reading
2188       FROM
2189             CSI_COUNTER_READINGS CCR
2190       WHERE
2191             CCR.COUNTER_ID = c_counter_id
2192             AND nvl(CCR.disabled_flag,'N') = 'N'
2193             AND CCR.VALUE_TIMESTAMP <= p_actual_date
2194       ORDER by
2195             CCR.value_timestamp DESC
2196              )
2197 WHERE ROWNUM < 2;
2198 
2199 
2200 -- modified logic to uptake IB changes made in bug# 7374316.
2201 CURSOR get_current_readings(c_counter_id NUMBER)
2202 IS
2203 /*
2204 SELECT
2205       nvl(CCR.NET_READING,0) net_reading
2206 FROM
2207       CSI_COUNTERS_VL CC,
2208       CSI_COUNTER_READINGS CCR
2209 WHERE
2210           CCR.COUNTER_ID = CC.COUNTER_ID
2211       AND CC.COUNTER_ID = c_counter_id
2212 ORDER BY
2213       CCR.VALUE_TIMESTAMP DESC;
2214 */
2215 SELECT
2216       nvl(CCR.NET_READING,0) net_reading
2217 FROM
2218       CSI_COUNTERS_B CC,
2219       CSI_COUNTER_READINGS CCR
2220 WHERE
2221       CCR.COUNTER_VALUE_ID = CC.CTR_VAL_MAX_SEQ_NO
2222       AND nvl(CCR.disabled_flag,'N') = 'N'
2223       AND CC.COUNTER_ID = c_counter_id;
2224 
2225 l_actual_ct_reading NUMBER;
2226 l_cur_ct_reading    NUMBER;
2227 -- Bug # 6750836 -- end
2228 
2229 BEGIN
2230 
2231   IF ( FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL)
2232   THEN
2233     fnd_log.string(
2234                    FND_LOG.LEVEL_STATEMENT,
2235                    'ahl.plsql.AHL_COMPLETIONS_PVT.get_reset_counters',
2236                    'p_actual_date in get_reset_counters -> ' || TO_CHAR(p_actual_date, 'DD-MON-YYYY HH24:MI:SS')
2237                   );
2238   END IF;
2239 
2240   -- get applicable effectivities.
2241   AHL_FMP_PVT.Get_Applicable_MRs(p_api_version => 1.0,
2242                                  x_return_status          => l_return_status,
2243                                  x_msg_count              => l_msg_count,
2244                                  x_msg_data               => l_msg_data,
2245                                  p_item_instance_id       => p_item_instance_id,
2246                                  p_mr_header_id           => p_mr_header_id,
2247                                  p_components_flag        => 'N',
2248                                  x_applicable_mr_tbl      => l_appl_mrs_tbl) ;
2249 
2250   -- Raise errors if exceptions occur
2251   IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
2252     RAISE FND_API.G_EXC_ERROR;
2253   ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2254     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2255   END IF;
2256 
2257   -- Get counters for effectivity.
2258   IF (l_appl_mrs_tbl.COUNT > 0) THEN
2259      FOR i IN l_appl_mrs_tbl.FIRST..l_appl_mrs_tbl.LAST LOOP
2260 
2261        FOR ctr_cursor IN get_counters( p_item_instance_id, p_mr_header_id,
2262                                        l_appl_mrs_tbl(i).mr_effectivity_id )
2263        LOOP
2264          IF ( ctr_cursor.counter_id <> l_prev_counter_id ) THEN
2265 
2266             OPEN get_readings(ctr_cursor.counter_id, p_actual_date);
2267             FETCH get_readings INTO l_actual_ct_reading;
2268             CLOSE get_readings;
2269 
2270             OPEN get_current_readings(ctr_cursor.counter_id);
2271             FETCH get_current_readings INTO l_cur_ct_reading;
2272             CLOSE get_current_readings;
2273 
2274 	    IF ( FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL)
2275 	    THEN
2276 
2277 		fnd_log.string(
2278 			FND_LOG.LEVEL_STATEMENT,
2279 			'ahl.plsql.AHL_COMPLETIONS_PVT.get_reset_counters',
2280 			'counter with id.. -> ' || ctr_cursor.counter_id
2281 			||', l_actual_ct_reading ->' ||l_actual_ct_reading
2282 			||', l_cur_ct_reading ->' ||l_cur_ct_reading
2283 		       );
2284 
2285 	    END IF;
2286 
2287             IF l_actual_ct_reading = l_cur_ct_reading THEN
2288 
2289 		     IF ( FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL)
2290 		     THEN
2291 		         fnd_log.string(
2292 				        FND_LOG.LEVEL_STATEMENT,
2293 				        'ahl.plsql.AHL_COMPLETIONS_PVT.get_reset_counters',
2294 				        'Resetting counter with id.. -> ' || ctr_cursor.counter_id
2295 				       );
2296 		         fnd_log.string(
2297 				        FND_LOG.LEVEL_STATEMENT,
2298 				        'ahl.plsql.AHL_COMPLETIONS_PVT.get_reset_counters',
2299 				        'counter with id.. -> ' || ctr_cursor.counter_id ||', l_actual_ct_reading ->' ||l_actual_ct_reading
2300 				       );
2301 		     END IF;
2302 
2303 		     x_counter_tbl( l_ctr_count ).counter_reading := l_actual_ct_reading;
2304 		     x_counter_tbl( l_ctr_count ).item_instance_id := p_item_instance_id;
2305 		     x_counter_tbl( l_ctr_count ).counter_id := ctr_cursor.counter_id;
2306 		     x_counter_tbl( l_ctr_count ).counter_group_id := ctr_cursor.counter_group_id;
2307 		     -- get readings.
2308 		     /*
2309 		     IF (get_readings%NOTFOUND) THEN
2310 
2311 			-- Bug # 6750836 -- start
2312 			--x_counter_tbl( l_ctr_count ).counter_reading := 0;
2313 			FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CN_RESET_ERROR' );
2314 			FND_MSG_PUB.add;
2315 			RETURN FND_API.G_RET_STS_ERROR;
2316 			-- Bug # 6750836 -- end
2317 
2318 		     END IF;
2319 		     */
2320 		     x_counter_tbl( l_ctr_count ).counter_type := ctr_cursor.type;
2321 		     x_counter_tbl( l_ctr_count ).reset_value := ctr_cursor.reset_value;
2322 
2323 		     l_ctr_count := l_ctr_count + 1;
2324 
2325             END IF;-- l_actual_ct_reading = l_cur_ct_reading
2326 
2327             l_prev_counter_id := ctr_cursor.counter_id;
2328 
2329          END IF; -- ( ctr_cursor.counter_id <> l_prev_counter_id )
2330 
2331        END LOOP;
2332      END LOOP;
2333   END IF;
2334 
2335   RETURN FND_API.G_RET_STS_SUCCESS;
2336 END get_reset_counters;
2337 
2338 -- Function to Reset the Counter Readings
2339 FUNCTION reset_counters
2340 (
2341   p_mr_rec            IN              mr_rec_type,
2342   p_x_counter_tbl     IN OUT NOCOPY   counter_tbl_type,
2343   p_actual_end_date   IN              DATE,
2344   x_msg_count         OUT NOCOPY      VARCHAR2,
2345   x_msg_data          OUT NOCOPY      VARCHAR2
2346 ) RETURN VARCHAR2
2347 IS
2348 
2349 l_ctr_grp_log_rec CS_CTR_CAPTURE_READING_PUB.ctr_grp_log_rec_type;
2350 l_ctr_rdg_tbl     CS_CTR_CAPTURE_READING_PUB.ctr_rdg_tbl_type;
2351 l_prop_rdg_tbl    CS_CTR_CAPTURE_READING_PUB.prop_rdg_tbl_type;
2352 l_return_status   VARCHAR2(2000);
2353 l_msg_count       NUMBER;
2354 l_msg_data        VARCHAR2(2000);
2355 l_ctr_count       NUMBER := 1;
2356 l_app_name        VARCHAR2(30);
2357 l_msg_name        VARCHAR2(30);
2358 BEGIN
2359 
2360   l_ctr_grp_log_rec.counter_group_id := p_x_counter_tbl(1).counter_group_id;
2361   l_ctr_grp_log_rec.value_timestamp := p_actual_end_date;
2362   l_ctr_grp_log_rec.source_transaction_id := p_x_counter_tbl(1).item_instance_id;
2363   l_ctr_grp_log_rec.source_transaction_code := 'CP';
2364   FOR i IN 1..p_x_counter_tbl.COUNT
2365   LOOP
2366 
2367     IF ( p_x_counter_tbl(i).reset_value IS NOT NULL AND
2368          p_x_counter_tbl(i).counter_type = 'REGULAR' ) THEN
2369       l_ctr_rdg_tbl(l_ctr_count).counter_id := p_x_counter_tbl(i).counter_id;
2370       l_ctr_rdg_tbl(l_ctr_count).value_timestamp := p_actual_end_date;
2371       /* -- IB(Anju) suggested as part of fix for bug#6267502
2372       --l_ctr_rdg_tbl(l_ctr_count).counter_reading := p_x_counter_tbl(i).reset_value;
2373       */
2374       l_ctr_rdg_tbl(l_ctr_count).counter_reading := p_x_counter_tbl(i).reset_value; -- IB(Anju) suggested as part of fix for bug#6267502
2375       l_ctr_rdg_tbl(l_ctr_count).valid_flag := 'Y';
2376       l_ctr_rdg_tbl(l_ctr_count).override_valid_flag := 'N';
2377 
2378       IF ( G_DEBUG = 'Y' ) THEN
2379         AHL_DEBUG_PUB.debug( 'Ctr ID:' || TO_CHAR( l_ctr_rdg_tbl(l_ctr_count).counter_id ) || ' Reset Value :' || TO_CHAR( l_ctr_rdg_tbl(l_ctr_count).counter_reading ) );
2380       END IF;
2381 
2382       IF ( p_x_counter_tbl(i).counter_reading <> 0 ) THEN
2383         l_ctr_rdg_tbl(l_ctr_count).reset_flag := 'Y';
2384         l_ctr_rdg_tbl(l_ctr_count).reset_reason := 'ASO Maintenance Requirement Accomplishment. MR-' || TO_CHAR( p_mr_rec.mr_header_id ) || ' UE-' || TO_CHAR( p_mr_rec.unit_effectivity_id );
2385         /* -- fix for bug number 6267502
2386         --l_ctr_rdg_tbl(l_ctr_count).pre_reset_last_rdg := p_x_counter_tbl(i).counter_reading;
2387         --l_ctr_rdg_tbl(l_ctr_count).post_reset_first_rdg := 0;
2388         --l_ctr_rdg_tbl(l_ctr_count).misc_reading_type := 'ASO_HARD_RESET';
2389         --l_ctr_rdg_tbl(l_ctr_count).misc_reading := p_x_counter_tbl(i).counter_reading;
2390         */
2391         /* start of fix -- IB(Anju) suggested as part of fix for bug#6267502 */
2392         l_ctr_rdg_tbl(l_ctr_count).pre_reset_last_rdg := p_x_counter_tbl(i).reset_value;
2393         l_ctr_rdg_tbl(l_ctr_count).post_reset_first_rdg := p_x_counter_tbl(i).reset_value;
2394         /* end of fix -- IB(Anju) suggested as part of fix for bug#6267502 */
2395         IF ( G_DEBUG = 'Y' ) THEN
2396           AHL_DEBUG_PUB.debug( 'Reset Ctr ID:' || TO_CHAR( l_ctr_rdg_tbl(l_ctr_count).counter_id ) || ' Pre-Reset:' || TO_CHAR( l_ctr_rdg_tbl(l_ctr_count).pre_reset_last_rdg ) || ' Adj:' || TO_CHAR( l_ctr_rdg_tbl(l_ctr_count).misc_reading ) );
2397         END IF;
2398       END IF;
2399 
2400       -- Store the Reset Value as the Current Reading ( for UMP )
2401       p_x_counter_tbl(i).counter_reading := p_x_counter_tbl(i).reset_value;
2402       l_ctr_count := l_ctr_count + 1;
2403 
2404     END IF;
2405 
2406   END LOOP;
2407 
2408   IF ( l_ctr_rdg_tbl.COUNT > 0 ) THEN
2409     BEGIN
2410       CS_CTR_CAPTURE_READING_PUB.capture_counter_reading
2411       (
2412           p_api_version_number => 1.0,
2413           p_init_msg_list      => FND_API.G_TRUE,
2414           p_commit             => FND_API.G_FALSE,
2415           p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
2416           p_ctr_grp_log_rec    => l_ctr_grp_log_rec,
2417           p_ctr_rdg_tbl        => l_ctr_rdg_tbl,
2418           p_prop_rdg_tbl       => l_prop_rdg_tbl,
2419           x_return_status      => l_return_status,
2420           x_msg_count          => l_msg_count,
2421           x_msg_data           => l_msg_data
2422       );
2423     EXCEPTION
2424       WHEN OTHERS THEN
2425         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CTR_RESET_API_ERROR' );
2426         FND_MSG_PUB.add;
2427         RETURN FND_API.G_RET_STS_ERROR;
2428     END;
2429 
2430     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2431       IF ( l_msg_data IS NULL ) THEN
2432         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CTR_RESET_API_ERROR' );
2433         FND_MSG_PUB.add;
2434       ELSE
2435         FND_MESSAGE.parse_encoded( l_msg_data, l_app_name, l_msg_name );
2436         FND_MESSAGE.set_name( l_app_name, l_msg_name );
2437         FND_MSG_PUB.add;
2438       END IF;
2439       RETURN FND_API.G_RET_STS_ERROR;
2440     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2441       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CTR_RESET_API_ERROR' );
2442       FND_MSG_PUB.add;
2443       RETURN FND_API.G_RET_STS_ERROR;
2444     END IF;
2445 
2446   END IF;
2447 
2448   RETURN FND_API.G_RET_STS_SUCCESS;
2449 END reset_counters;
2450 
2451 -- Function to Record Accomplishments in UMP
2452 FUNCTION update_ump
2453 (
2454   p_unit_effectivity_id  IN   NUMBER,
2455   p_ue_object_version    IN   NUMBER,
2456   p_actual_end_date      IN   DATE,
2457   p_counter_tbl          IN   counter_tbl_type,
2458   x_msg_count            OUT NOCOPY  VARCHAR2,
2459   x_msg_data             OUT NOCOPY  VARCHAR2
2460 ) RETURN VARCHAR2
2461 IS
2462 l_return_status   VARCHAR2(2000);
2463 l_msg_count       NUMBER;
2464 l_msg_data        VARCHAR2(2000);
2465 l_ctr_count       NUMBER := 1;
2466 
2467 l_unit_effectivity_tbl   AHL_UMP_UNITMAINT_PVT.unit_effectivity_tbl_type;
2468 l_unit_accomplish_tbl    AHL_UMP_UNITMAINT_PVT.unit_accomplish_tbl_type;
2469 l_unit_threshold_tbl     AHL_UMP_UNITMAINT_PVT.unit_threshold_tbl_type;
2470 BEGIN
2471 
2472   l_unit_effectivity_tbl(1).unit_effectivity_id := p_unit_effectivity_id;
2473   l_unit_effectivity_tbl(1).object_version_number := p_ue_object_version;
2474   l_unit_effectivity_tbl(1).status_code := G_MR_STATUS_SIGNED_OFF;
2475   l_unit_effectivity_tbl(1).accomplished_date := p_actual_end_date;
2476 
2477   IF ( p_counter_tbl.COUNT > 0 ) THEN
2478     FOR i IN 1..p_counter_tbl.COUNT
2479     LOOP
2480       IF ( p_counter_tbl(i).counter_reading IS NOT NULL ) THEN
2481         l_unit_accomplish_tbl(l_ctr_count).unit_effectivity_id := p_unit_effectivity_id;
2482         l_unit_accomplish_tbl(l_ctr_count).counter_id := p_counter_tbl(i).counter_id;
2483         l_unit_accomplish_tbl(l_ctr_count).counter_value := p_counter_tbl(i).counter_reading;
2484         l_unit_accomplish_tbl(l_ctr_count).operation_flag := 'C';
2485         l_ctr_count := l_ctr_count + 1;
2486       END IF;
2487     END LOOP;
2488   END IF;
2489 
2490   AHL_UMP_UNITMAINT_PVT.capture_mr_updates
2491   (
2492     p_api_version           => 1.0,
2493     p_init_msg_list         => FND_API.G_TRUE,
2494     p_commit                => FND_API.G_FALSE,
2495     p_validation_level      => FND_API.G_VALID_LEVEL_FULL,
2496     p_default               => FND_API.G_TRUE,
2497     p_module_type           => NULL,
2498     p_unit_effectivity_tbl  => l_unit_effectivity_tbl,
2499     p_x_unit_threshold_tbl  => l_unit_threshold_tbl,
2500     p_x_unit_accomplish_tbl => l_unit_accomplish_tbl,
2501     x_return_status         => l_return_status,
2502     x_msg_count             => l_msg_count,
2503     x_msg_data              => l_msg_data
2504   );
2505 
2506   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2507     IF ( l_msg_data IS NULL ) THEN
2508       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_UMP_API_ERROR' );
2509       FND_MSG_PUB.add;
2510     ELSE
2511       x_msg_count := l_msg_count;
2512       x_msg_data := l_msg_data;
2513     END IF;
2514     RETURN FND_API.G_RET_STS_ERROR;
2515   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2516     IF ( l_msg_data IS NULL ) THEN
2517       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_UMP_API_ERROR' );
2518       FND_MSG_PUB.add;
2519     ELSE
2520       x_msg_count := l_msg_count;
2521       x_msg_data := l_msg_data;
2522     END IF;
2523     RETURN FND_API.G_RET_STS_ERROR;
2524   END IF;
2525 
2526   RETURN FND_API.G_RET_STS_SUCCESS;
2527 END update_ump;
2528 
2529 -- Added for R12-Serial Reservation enhancements.
2530 -- We need to delete any reserved serial numbers when a workorder is completed.
2531 PROCEDURE Delete_Serial_Reservations (p_workorder_id  IN NUMBER,
2532                                       x_return_status OUT NOCOPY VARCHAR2)
2533 IS
2534 
2535   CURSOR get_scheduled_mater_csr (p_workorder_id IN NUMBER) IS
2536     SELECT scheduled_material_id
2537     FROM  ahl_job_oper_materials_v
2538     WHERE workorder_id = p_workorder_id
2539       AND reserved_quantity > 0;
2540 
2541   l_msg_count  NUMBER;
2542   l_msg_data   VARCHAR2(2000);
2543 
2544   l_DEBUG_LEVEL       NUMBER := FND_LOG.G_CURRENT_RUNTIME_LEVEL;
2545   l_DEBUG_PROC        NUMBER := FND_LOG.LEVEL_PROCEDURE;
2546   l_DEBUG_STMT        NUMBER := FND_LOG.LEVEL_STATEMENT;
2547 
2548 BEGIN
2549 
2550 
2551   IF ( l_DEBUG_PROC >= l_DEBUG_LEVEL) THEN
2552     fnd_log.string(l_DEBUG_PROC, 'ahl.plsql.AHL_PRD_WORKORDER_PVT.delete_serial_reservations.begin',
2553                    'At the start of procedure for workorder_id:' || p_workorder_id);
2554   END IF;
2555 
2556   -- Initialize return status.
2557   x_return_status := FND_API.G_RET_STS_SUCCESS;
2558 
2559   FOR get_scheduled_mater_rec IN get_scheduled_mater_csr(p_workorder_id)
2560   LOOP
2561        -- Call delete reservation API.
2562        AHL_RSV_RESERVATIONS_PVT.Delete_Reservation (
2563                           p_api_version => 1.0,
2564                           p_init_msg_list          => FND_API.G_TRUE             ,
2565                           p_commit                 => FND_API.G_FALSE            ,
2566                           p_validation_level       => FND_API.G_VALID_LEVEL_FULL ,
2567                           p_module_type            => NULL,
2568                           x_return_status          => x_return_status            ,
2569                           x_msg_count              => l_msg_count                ,
2570                           x_msg_data               => l_msg_data                 ,
2571                           p_scheduled_material_id   => get_scheduled_mater_rec.scheduled_material_id );
2572 
2573        IF ( x_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
2574           IF (l_DEBUG_STMT >= l_DEBUG_LEVEL) THEN
2575              fnd_log.string(l_DEBUG_STMT, 'ahl.plsql.AHL_PRD_WORKORDER_PVT.delete_serial_reservations',
2576                          'AHL_RSV_RESERVATIONS_PVT.Delete_Reservation failed for schedule material ID: '
2577                          || get_scheduled_mater_rec.scheduled_material_id);
2578           END IF; -- x_return_status
2579 
2580           EXIT;
2581 
2582        END IF; -- x_return_status
2583 
2584     END LOOP; -- get_scheduled_mater_rec
2585 
2586 END Delete_Serial_Reservations;
2587 
2588 --------------------------------------------------------------
2589 -- Procedure adde by Balaji for bug # 4757222, FP Bug # 4955278.
2590 --
2591 -- This procedure derives operation actual start and end dates
2592 -- from resource transactions dates.
2593 --------------------------------------------------------------
2594 /* Bug # 4955278 - start */
2595 PROCEDURE Get_Op_Act_from_Res_Txn
2596 (
2597  p_wip_entity_id     IN NUMBER,
2598  p_operation_seq_num IN NUMBER,
2599  x_actual_start_date OUT NOCOPY DATE,
2600  x_actual_end_date   OUT NOCOPY DATE
2601 )
2602 IS
2603 
2604 CURSOR c_get_wop_details(p_wip_entity_id IN NUMBER,
2605 			 p_operation_seq_num IN NUMBER)
2606 IS
2607 SELECT
2608    WIOP.organization_id
2609 FROM
2610    WIP_OPERATIONS WIOP
2611 WHERE
2612    WIOP.wip_entity_id = p_wip_entity_id
2613    AND WIOP.operation_seq_num = p_operation_seq_num;
2614 
2615 -- query to retrieve total hrs transacted for a operation.
2616 CURSOR c_get_txn_dates(p_wip_entity_id     IN NUMBER,
2617                        p_operation_seq_num IN NUMBER,
2618                        p_organization_id IN NUMBER)
2619 IS
2620 SELECT
2621   MIN(WIPT.TRANSACTION_DATE),
2622   MAX(WIPT.TRANSACTION_DATE + (WIPT.TRANSACTION_QUANTITY/24))
2623 FROM
2624   WIP_TRANSACTIONS WIPT
2625 WHERE
2626   WIPT.wip_entity_id = p_wip_entity_id
2627   AND  WIPT.operation_seq_num = p_operation_seq_num
2628   AND WIPT.organization_id = p_organization_id;
2629 
2630 
2631 CURSOR c_get_pending_txn_dates(p_wip_entity_id     IN NUMBER,
2632                        	       p_operation_seq_num IN NUMBER,
2633                        	       p_organization_id IN NUMBER)
2634 IS
2635 SELECT MIN(WIPT.TRANSACTION_DATE),
2636        MAX(WIPT.TRANSACTION_DATE + (WIPT.TRANSACTION_QUANTITY/24))
2637 FROM
2638     WIP_COST_TXN_INTERFACE WIPT
2639 WHERE
2640     WIPT.wip_entity_id = p_wip_entity_id
2641     AND  WIPT.operation_seq_num = p_operation_seq_num
2642     AND WIPT.organization_id = p_organization_id;
2643 
2644 l_min_txn_date DATE;
2645 l_max_txn_date DATE;
2646 l_min_pending_txn_date DATE;
2647 l_max_pending_txn_date DATE;
2648 l_org_id NUMBER;
2649 
2650 BEGIN
2651 
2652   OPEN c_get_wop_details(p_wip_entity_id, p_operation_seq_num);
2653   FETCH c_get_wop_details INTO l_org_id;
2654   CLOSE c_get_wop_details;
2655 
2656   -- Get min and max transactions dates from already completed transactions.
2657   OPEN c_get_txn_dates(p_wip_entity_id, p_operation_seq_num,l_org_id);
2658   FETCH c_get_txn_dates INTO l_min_txn_date, l_max_txn_date;
2659   CLOSE c_get_txn_dates;
2660 
2661   -- Get min and max transactions dates from pending resource transactions.
2662   OPEN c_get_pending_txn_dates(p_wip_entity_id, p_operation_seq_num,l_org_id);
2663   FETCH c_get_pending_txn_dates INTO l_min_pending_txn_date, l_max_pending_txn_date;
2664   CLOSE c_get_pending_txn_dates;
2665 
2666   IF l_min_txn_date IS NULL AND l_min_pending_txn_date IS NULL
2667   THEN
2668        x_actual_start_date := NULL;
2669   ELSE
2670        x_actual_start_date := LEAST(NVL(l_min_txn_date, l_min_pending_txn_date), NVL(l_min_pending_txn_date, l_min_txn_date));
2671   END IF;
2672 
2673   IF l_max_txn_date IS NULL AND l_max_pending_txn_date IS NULL
2674   THEN
2675        x_actual_end_date := NULL;
2676   ELSE
2677        x_actual_end_date := GREATEST(NVL(l_max_txn_date, l_max_pending_txn_date), NVL(l_max_pending_txn_date, l_max_txn_date));
2678   END IF;
2679 
2680 END Get_Op_Act_from_Res_Txn;
2681 /* Bug # 4955278 - end */
2682 
2683 -- BEGIN APIs
2684 
2685 -- Procedure to Complete an Operation
2686 PROCEDURE complete_operation
2687 (
2688   p_api_version            IN   NUMBER     := 1.0,
2689   p_init_msg_list          IN   VARCHAR2   := FND_API.G_TRUE,
2690   p_commit                 IN   VARCHAR2   := FND_API.G_FALSE,
2691   p_validation_level       IN   NUMBER     := FND_API.G_VALID_LEVEL_FULL,
2692   p_default                IN   VARCHAR2   := FND_API.G_FALSE,
2693   p_module_type            IN   VARCHAR2   := NULL,
2694   x_return_status          OUT NOCOPY  VARCHAR2,
2695   x_msg_count              OUT NOCOPY  NUMBER,
2696   x_msg_data               OUT NOCOPY  VARCHAR2,
2697   p_workorder_operation_id IN   NUMBER,
2698   p_object_version_no      IN   NUMBER := NULL
2699 )
2700 IS
2701 
2702 l_api_name       VARCHAR2(30) := 'complete_operation';
2703 l_return_status  VARCHAR2(1);
2704 l_msg_count      NUMBER;
2705 l_msg_data       VARCHAR2(2000) := NULL;
2706 
2707 l_operation_rec  operation_rec_type;
2708 l_workorder_rec  workorder_rec_type;
2709 
2710 -- rroy
2711 -- R12 Tech UIs
2712 l_operation_tbl operation_tbl_type;
2713 l_workorder_id NUMBER;
2714 l_operation_seq_num NUMBER;
2715 l_actual_end_date DATE;
2716 l_actual_start_date DATE;
2717 --l_resource_id NUMBER;
2718 l_resource_seq_num NUMBER;
2719 l_employee_id NUMBER;
2720 
2721 -- R12
2722 -- Tech UIs
2723 CURSOR get_op_details(x_wo_op_id NUMBER)
2724 IS
2725 SELECT workorder_id,
2726 Operation_sequence_num,
2727 Actual_start_date,
2728 Actual_end_date
2729 FROM AHL_WORKORDER_OPERATIONS
2730 WHERE workorder_operation_id = x_wo_op_id;
2731 
2732 -- R12
2733 -- Tech UIs
2734 
2735 
2736 -- R12: login/logout feature.
2737 CURSOR c_get_login_recs(p_workorder_id NUMBER,
2738                         p_operation_seq_num NUMBER)
2739 IS
2740 SELECT employee_id,
2741        resource_seq_num
2742 FROM   ahl_work_login_times
2743 WHERE  workorder_id = p_workorder_id
2744 AND OPERATION_SEQ_NUM = p_operation_seq_num
2745 AND login_level IN ('O','R')   -- logout only those employees who are logged in at oper, oper-resrc level.
2746 AND LOGOUT_DATE IS NULL;
2747 
2748 BEGIN
2749   -- Enable Debug (optional)
2750   IF ( G_DEBUG = 'Y' ) THEN
2751     AHL_DEBUG_PUB.enable_debug;
2752   END IF;
2753 
2754   -- Initialize API return status to success
2755   x_return_status := FND_API.G_RET_STS_SUCCESS;
2756 
2757   -- Standard Start of API savepoint
2758   SAVEPOINT complete_operation_PVT;
2759 
2760   -- Initialize message list if p_init_msg_list is set to TRUE.
2761   IF FND_API.to_boolean( p_init_msg_list ) THEN
2762     FND_MSG_PUB.initialize;
2763   END IF;
2764 
2765   -- Validate all the inputs of the API
2766   l_return_status :=
2767   validate_cop_inputs
2768   (
2769     p_workorder_operation_id => p_workorder_operation_id,
2770     p_object_version_no      => p_object_version_no
2771   );
2772 
2773   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2774     RAISE FND_API.G_EXC_ERROR;
2775   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2776     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2777   END IF;
2778 
2779   -- rroy
2780   -- R12 Tech UIs
2781   IF p_default = FND_API.G_TRUE THEN
2782     -- retrieve the workorder id and the operation sequence number
2783     OPEN get_op_details(p_workorder_operation_id);
2784     FETCH get_op_details INTO l_workorder_id, l_operation_seq_num, l_actual_start_date, l_actual_end_date;
2785     IF get_op_details%NOTFOUND THEN
2786       CLOSE get_op_details;
2787       FND_MESSAGE.set_name('AHL', 'AHL_PRD_OP_DEF_ERROR');
2788       FND_MSG_PUB.add;
2789       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2790     END IF;
2791     CLOSE get_op_details;
2792 
2793     l_operation_tbl(1).workorder_id := l_workorder_id;
2794     l_operation_tbl(1).operation_sequence_num := l_operation_seq_num;
2795 
2796     Get_default_op_actual_dates(x_return_status => l_return_status,
2797                                 x_msg_count     => l_msg_count,
2798 				x_msg_data      => l_msg_data,
2799                                 p_x_operation_tbl => l_operation_tbl);
2800     IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
2801       FND_MESSAGE.set_name('AHL', 'AHL_PRD_OP_DEF_ERROR');
2802       FND_MSG_PUB.add;
2803       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2804     END IF;
2805 
2806     -- update the actual dates in the table
2807     IF l_actual_start_date IS NULL THEN
2808       UPDATE AHL_WORKORDER_OPERATIONS
2809       SET ACTUAL_START_DATE = l_operation_tbl(1).actual_start_date,
2810       LAST_UPDATE_DATE = SYSDATE,
2811       LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
2812       LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
2813       WHERE WORKORDER_OPERATION_ID = p_workorder_operation_id;
2814       IF SQL%ROWCOUNT = 0 THEN
2815         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_DEF_ERROR' );
2816         FND_MSG_PUB.add;
2817         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2818       END IF;
2819      END IF; -- IF l_actual_start_date IS NULL THEN
2820     IF l_actual_end_date IS NULL THEN
2821       UPDATE AHL_WORKORDER_OPERATIONS
2822       SET ACTUAL_END_DATE = l_operation_tbl(1).actual_end_date,
2823       LAST_UPDATE_DATE = SYSDATE,
2824       LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
2825       LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
2826       WHERE WORKORDER_OPERATION_ID = p_workorder_operation_id;
2827       IF SQL%ROWCOUNT = 0 THEN
2828         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_DEF_ERROR' );
2829         FND_MSG_PUB.add;
2830         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2831       END IF;
2832      END IF; -- IF l_actual_end_date IS NULL THEN
2833    END IF; -- IF p_default = FND_API.G_TRUE THEN
2834    -- rroy
2835    -- R12 Tech UIs
2836 
2837   --Get the Operation Details
2838   l_return_status :=
2839   get_operation_rec
2840   (
2841     p_workorder_operation_id => p_workorder_operation_id,
2842     p_object_version_no      => p_object_version_no,
2843     x_operation_rec          => l_operation_rec
2844   );
2845 
2846   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2847     RAISE FND_API.G_EXC_ERROR;
2848   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2849     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2850   END IF;
2851 
2852   --Get the Associated Workorder Details
2853   l_return_status :=
2854   get_workorder_rec
2855   (
2856     p_workorder_id              => l_operation_rec.workorder_id,
2857     x_workorder_rec             => l_workorder_rec
2858   );
2859 
2860   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2861     RAISE FND_API.G_EXC_ERROR;
2862   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2863     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2864   END IF;
2865 
2866   --Validate the Operation
2867   l_return_status :=
2868   validate_cop_rec
2869   (
2870     p_operation_rec          => l_operation_rec,
2871     p_workorder_rec          => l_workorder_rec
2872   );
2873 
2874   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2875     RAISE FND_API.G_EXC_ERROR;
2876   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2877     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2878   END IF;
2879 
2880   -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
2881   l_msg_count := FND_MSG_PUB.count_msg;
2882   IF l_msg_count > 0 THEN
2883     x_msg_count := l_msg_count;
2884     RAISE FND_API.G_EXC_ERROR;
2885   END IF;
2886 
2887   -- rroy
2888   -- R12 Tech UIs
2889   -- Log all technicians out of the operation being completed only if logged in at operation or resource levels.
2890   OPEN c_get_login_recs(l_operation_rec.workorder_id, l_operation_rec.operation_sequence_num);
2891   LOOP
2892 
2893      FETCH c_get_login_recs INTO l_employee_id, --l_resource_id,
2894                                  l_resource_seq_num;
2895      EXIT WHEN c_get_login_recs%NOTFOUND;
2896      -- if login at workorder, then logout these users when workorder is completed/cancelled.
2897      -- resource txns will post at the time user logs out of the workorder.
2898      AHL_PRD_WO_LOGIN_PVT.Workorder_Logout(p_api_version       => 1.0,
2899                                            p_init_msg_list     => p_init_msg_list,
2900                                            p_commit            => FND_API.G_FALSE,
2901                                            p_validation_level    => p_validation_level,
2902                                            p_module_type       => p_module_type,
2903                                            x_return_status     => l_return_status,
2904                                            x_msg_count         => l_msg_count,
2905                                            x_msg_data          => l_msg_data,
2906                                            p_employee_id       => l_employee_id,
2907                                            p_workorder_id      => l_operation_rec.workorder_id,
2908                                            p_operation_seq_num => l_operation_rec.operation_sequence_num,
2909                                            --p_resource_id       => l_resource_id,
2910                                            p_resource_seq_num  => l_resource_seq_num
2911                                           );
2912      IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
2913         EXIT;
2914      END IF;
2915 
2916   END LOOP;
2917   CLOSE c_get_login_recs;
2918 
2919   IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
2920       RAISE FND_API.G_EXC_ERROR;
2921   END IF;
2922 
2923   --Complete the EAM Workorder Operation
2924   l_return_status :=
2925   complete_eam_wo_operation
2926   (
2927     p_operation_rec            => l_operation_rec
2928   );
2929 
2930   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2931     RAISE FND_API.G_EXC_ERROR;
2932   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2933     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2934   END IF;
2935 
2936   --Complete the AHL Workorder Operation
2937   l_return_status :=
2938   complete_ahl_wo_operation
2939   (
2940     p_operation_rec            => l_operation_rec
2941   );
2942 
2943   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2944     RAISE FND_API.G_EXC_ERROR;
2945   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2946     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2947   END IF;
2948 
2949   --If collection_id is not null, then, Enable and Fire QA Actions if Commit Flag is true
2950   IF ( l_operation_rec.collection_id IS NOT NULL AND
2951        FND_API.to_boolean( p_commit ) ) THEN
2952 
2953     QA_SS_RESULTS.wrapper_fire_action
2954     (
2955       q_collection_id    => l_operation_rec.collection_id,
2956       q_return_status    => l_return_status,
2957       q_msg_count        => l_msg_count,
2958       q_msg_data         => l_msg_data
2959     );
2960 
2961     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
2962       x_msg_data := l_msg_data;
2963       x_msg_count := l_msg_count;
2964       x_return_status := FND_API.G_RET_STS_ERROR;
2965       RETURN;
2966     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
2967       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2968     END IF;
2969 
2970     -- Re-set the API savepoint because, the wrapper_fire_action commits.
2971     SAVEPOINT complete_operation_PVT;
2972 
2973   END IF;
2974 
2975   -- Perform the Commit (if requested)
2976   IF FND_API.to_boolean( p_commit ) THEN
2977     COMMIT WORK;
2978   END IF;
2979 
2980   -- Disable debug (if enabled)
2981   IF ( G_DEBUG = 'Y' ) THEN
2982     AHL_DEBUG_PUB.disable_debug;
2983   END IF;
2984 
2985 EXCEPTION
2986 
2987   WHEN FND_API.G_EXC_ERROR THEN
2988     ROLLBACK TO complete_operation_PVT;
2989     x_return_status := FND_API.G_RET_STS_ERROR;
2990     FND_MSG_PUB.count_and_get
2991     (
2992       p_encoded  => FND_API.G_FALSE,
2993       p_count    => x_msg_count,
2994       p_data     => x_msg_data
2995     );
2996 
2997     IF ( G_DEBUG = 'Y' ) THEN
2998       AHL_DEBUG_PUB.disable_debug;
2999     END IF;
3000 
3001   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
3002     ROLLBACK TO complete_operation_PVT;
3003     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
3004     FND_MSG_PUB.count_and_get
3005     (
3006       p_encoded  => FND_API.G_FALSE,
3007       p_count    => x_msg_count,
3008       p_data     => x_msg_data
3009     );
3010 
3011     IF ( G_DEBUG = 'Y' ) THEN
3012       AHL_DEBUG_PUB.disable_debug;
3013     END IF;
3014 
3015   WHEN OTHERS THEN
3016     ROLLBACK TO complete_operation_PVT;
3017     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
3018     IF FND_MSG_PUB.check_msg_level( FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR )
3019     THEN
3020       FND_MSG_PUB.add_exc_msg
3021       (
3022         p_pkg_name         => G_PKG_NAME,
3023         p_procedure_name   => l_api_name,
3024         p_error_text       => SUBSTRB(SQLERRM,1,240)
3025       );
3026     END IF;
3027     FND_MSG_PUB.count_and_get
3028     (
3029       p_encoded  => FND_API.G_FALSE,
3030       p_count    => x_msg_count,
3031       p_data     => x_msg_data
3032     );
3033 
3034     IF ( G_DEBUG = 'Y' ) THEN
3035       AHL_DEBUG_PUB.disable_debug;
3036     END IF;
3037 END complete_operation;
3038 
3039 PROCEDURE complete_workorder
3040 (
3041   p_api_version       IN    NUMBER     := 1.0,
3042   p_init_msg_list     IN    VARCHAR2   := FND_API.G_TRUE,
3043   p_commit            IN    VARCHAR2   := FND_API.G_FALSE,
3044   p_validation_level  IN    NUMBER     := FND_API.G_VALID_LEVEL_FULL,
3045   p_default           IN    VARCHAR2   := FND_API.G_FALSE,
3046   p_module_type       IN    VARCHAR2   := NULL,
3047   x_return_status     OUT NOCOPY   VARCHAR2,
3048   x_msg_count         OUT NOCOPY   NUMBER,
3049   x_msg_data          OUT NOCOPY   VARCHAR2,
3050   p_workorder_id      IN    NUMBER,
3051   p_object_version_no IN    NUMBER     := NULL
3052 )
3053 IS
3054 
3055 l_api_name               VARCHAR2(30) := 'complete_workorder';
3056 l_return_status          VARCHAR2(1);
3057 l_msg_count              NUMBER;
3058 l_msg_index_out          NUMBER;
3059 l_msg_data               VARCHAR2(2000) := NULL;
3060 
3061 l_operation_tbl          operation_tbl_type;
3062 l_workorder_rec          workorder_rec_type;
3063 l_mr_rec                 mr_rec_type;
3064 l_counter_tbl            counter_tbl_type;
3065 
3066 l_child_wos_complete     BOOLEAN := TRUE;
3067 l_prd_workorder_rec      AHL_PRD_WORKORDER_PVT.prd_workorder_rec;
3068 l_prd_workoper_tbl       AHL_PRD_WORKORDER_PVT.prd_workoper_tbl;
3069 
3070 l_mr_status              VARCHAR2(30);
3071 
3072 CURSOR  get_parent_master_wos( c_child_wip_entity_id NUMBER )
3073 IS
3074 SELECT  WO.workorder_id workorder_id,
3075         WO.object_version_number object_version_number,
3076         WO.wip_entity_id wip_entity_id,
3077         WO.status_code status_code
3078 FROM    AHL_WORKORDERS WO,
3079         WIP_SCHED_RELATIONSHIPS WOR
3080 WHERE   WO.wip_entity_id = WOR.parent_object_id
3081 AND     WO.master_workorder_flag = 'Y'
3082 AND     WO.status_code <> G_JOB_STATUS_DELETED
3083 AND     WOR.parent_object_type_id = 1
3084 AND     WOR.relationship_type = 1
3085 AND     WOR.child_object_type_id = 1
3086 AND     WOR.child_object_id = c_child_wip_entity_id;
3087 
3088 CURSOR  get_child_wo_status( c_master_wip_entity_id NUMBER )
3089 IS
3090 SELECT  DISTINCT WO.status_code status_code
3091 FROM    AHL_WORKORDERS WO,
3092         WIP_SCHED_RELATIONSHIPS WOR
3093 WHERE   WO.wip_entity_id = WOR.child_object_id
3094 AND     WO.status_code <> G_JOB_STATUS_DELETED
3095 AND     WOR.parent_object_type_id = 1
3096 AND     WOR.relationship_type = 1
3097 AND     WOR.child_object_type_id = 1
3098 AND     WOR.parent_object_id = c_master_wip_entity_id;
3099 
3100 
3101 /*CURSOR Check_child_exists (c_unit_effectivity_id IN NUMBER)
3102 IS
3103 SELECT  1
3104 FROM       AHL_UE_DEFERRAL_DETAILS_V
3105 WHERE      unit_effectivity_id IN
3106            (
3107              SELECT     related_ue_id
3108              FROM       AHL_UE_RELATIONSHIPS
3109              WHERE      unit_effectivity_id = related_ue_id
3110              START WITH ue_id = c_unit_effectivity_id
3111                     AND relationship_code = 'PARENT'
3112              CONNECT BY ue_id = PRIOR related_ue_id
3113                     AND relationship_code = 'PARENT'
3114            );*/
3115 CURSOR Check_child_exists (c_unit_effectivity_id IN NUMBER)
3116 IS
3117 SELECT  1
3118 FROM       AHL_UNIT_EFFECTIVITIES_B UE,(
3119 SELECT     related_ue_id
3120 FROM       AHL_UE_RELATIONSHIPS
3121 START WITH ue_id = c_unit_effectivity_id
3122        AND relationship_code = 'PARENT'
3123 CONNECT BY ue_id = PRIOR related_ue_id
3124        AND relationship_code = 'PARENT'
3125 )CH
3126 WHERE      UE.unit_effectivity_id = CH.related_ue_id;
3127 -- Balaji commented out the order by clause for the issue # 3 in bug #4613940(CMRO)
3128 -- and this fix has reference to bug #3085871(ST) where it is described that order by level
3129 -- should not be used without a reference to "start with.. connect by clause" starting 10g
3130 --ORDER BY   level DESC;
3131 
3132 -- rroy
3133 -- R12 Tech UIs
3134 -- cursor to retrieve the workorder actual dates
3135 CURSOR get_wo_dates(x_wo_id NUMBER)
3136 IS
3137 SELECT Actual_start_date,
3138 Actual_end_date,
3139 Workorder_name
3140 FROM AHL_WORKORDERS
3141 WHERE workorder_id = x_wo_id;
3142 
3143 -- R12: Login/logout feature.
3144 -- here we pick up all employees logged in at all levels.
3145 CURSOR c_get_login_recs(p_workorder_id NUMBER)
3146 IS
3147 SELECT employee_id, operation_seq_num, resource_seq_num
3148 FROM   ahl_work_login_times
3149 WHERE  workorder_id = p_workorder_id
3150 AND LOGOUT_DATE IS NULL;
3151 
3152 
3153 l_dummy  NUMBER;
3154 l_actual_end_date DATE;
3155 l_actual_start_date DATE;
3156 l_def_actual_end_date DATE;
3157 l_def_actual_start_date DATE;
3158 l_wo_name  ahl_workorders.workorder_name%TYPE;
3159 
3160 l_employee_id  NUMBER;
3161 l_operation_seq_num NUMBER;
3162 l_resource_seq_num  NUMBER;
3163 l_up_workorder_rec  AHL_PRD_WORKORDER_PVT.prd_workorder_rec;
3164 l_up_workoper_tbl   AHL_PRD_WORKORDER_PVT.prd_workoper_tbl;
3165 l_object_version_number NUMBER     := NULL;
3166 
3167 
3168 BEGIN
3169   -- Enable Debug (optional)
3170   IF ( G_DEBUG = 'Y' ) THEN
3171     AHL_DEBUG_PUB.enable_debug;
3172   END IF;
3173 
3174   -- Initialize API return status to success
3175   x_return_status := FND_API.G_RET_STS_SUCCESS;
3176 
3177   -- Standard Start of API savepoint
3178   SAVEPOINT complete_workorder_PVT;
3179 
3180   -- Initialize message list if p_init_msg_list is set to TRUE.
3181   IF FND_API.to_boolean( p_init_msg_list ) THEN
3182     FND_MSG_PUB.initialize;
3183   END IF;
3184 
3185   l_object_version_number := p_object_version_no;
3186 
3187   -- Validate all the inputs of the API
3188   l_return_status :=
3189   validate_wo_inputs
3190   (
3191     p_workorder_id           => p_workorder_id,
3192     p_object_version_no      => l_object_version_number
3193   );
3194 
3195   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3196     RAISE FND_API.G_EXC_ERROR;
3197   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3198     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3199   END IF;
3200 
3201   -- R12
3202   -- Tech UIs
3203   -- default the workorder actual dates
3204   IF p_default = FND_API.G_TRUE THEN
3205     -- retrieve the workorder actual dates
3206     OPEN get_wo_dates(p_workorder_id);
3207     FETCH get_wo_dates INTO l_actual_start_date, l_actual_end_date, l_wo_name;
3208     IF get_wo_dates%NOTFOUND THEN
3209       CLOSE get_wo_dates;
3210       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_DEF_ERROR' );
3211       -- Error defaulting the actual dates for workorder WO_NAME before completion.
3212       -- Do we raise an error for this or just ignore the error since this is defaulting code?
3213       -- Check during UTs
3214       FND_MSG_PUB.add;
3215       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3216     END IF; -- IF get_wo_dates%NOTFOUND THEN
3217     CLOSE get_wo_dates;
3218 
3219     Get_default_wo_actual_dates(p_workorder_id => p_workorder_id,
3220                                 x_return_status => l_return_status,
3221 				x_actual_start_date => l_def_actual_start_date,
3222 				x_actual_end_date => l_def_actual_end_date);
3223     IF l_return_status <> FND_API. G_RET_STS_SUCCESS THEN
3224       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_DEF_ERROR' );
3225       FND_MSG_PUB.add;
3226       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3227     END IF;
3228     /* Start ER # 4757222 */
3229     l_up_workorder_rec.WORKORDER_ID := p_workorder_id;
3230     l_up_workorder_rec.ACTUAL_START_DATE := nvl(l_actual_start_date, l_def_actual_start_date);
3231     l_up_workorder_rec.ACTUAL_END_DATE := nvl(l_actual_end_date, l_def_actual_end_date);
3232 
3233     IF l_up_workorder_rec.ACTUAL_START_DATE IS NOT NULL THEN
3234     	l_up_workorder_rec.ACTUAL_START_HR := TO_NUMBER(TO_CHAR(l_up_workorder_rec.ACTUAL_START_DATE, 'HH24'));
3235     	l_up_workorder_rec.ACTUAL_START_MI := TO_NUMBER(TO_CHAR(l_up_workorder_rec.ACTUAL_START_DATE, 'MI'));
3236     END IF;
3237 
3238     IF l_up_workorder_rec.ACTUAL_END_DATE IS NOT NULL THEN
3239        l_up_workorder_rec.ACTUAL_END_HR := TO_NUMBER(TO_CHAR(l_up_workorder_rec.ACTUAL_END_DATE, 'HH24'));
3240        l_up_workorder_rec.ACTUAL_END_MI := TO_NUMBER(TO_CHAR(l_up_workorder_rec.ACTUAL_END_DATE, 'MI'));
3241     END IF;
3242 
3243     AHL_PRD_WORKORDER_PVT.update_job
3244       (
3245         p_api_version            => 1.0                        ,
3246         p_init_msg_list          => FND_API.G_TRUE             ,
3247         p_commit                 => FND_API.G_FALSE            ,
3248         p_validation_level       => FND_API.G_VALID_LEVEL_FULL ,
3249         p_default                => FND_API.G_TRUE             ,
3250         p_module_type            => NULL                       ,
3251         x_return_status          => l_return_status            ,
3252         x_msg_count              => l_msg_count                ,
3253         x_msg_data               => l_msg_data                 ,
3254         p_wip_load_flag          => 'Y'		               ,
3255         p_x_prd_workorder_rec    => l_up_workorder_rec     ,
3256         p_x_prd_workoper_tbl     => l_up_workoper_tbl
3257       );
3258 
3259     IF ( l_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
3260        RAISE FND_API.G_EXC_ERROR;
3261     END IF;
3262 
3263     l_object_version_number := l_up_workorder_rec.object_version_number;
3264 
3265     /*
3266     -- update the actual dates in the table
3267     IF l_actual_start_date IS NULL THEN
3268       UPDATE AHL_WORKORDERS
3269       SET ACTUAL_START_DATE = l_def_actual_start_date,
3270       LAST_UPDATE_DATE = SYSDATE,
3271       LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
3272       LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
3273       WHERE WORKORDER_ID = p_workorder_id;
3274       IF SQL%ROWCOUNT = 0 THEN
3275         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_DEF_ERROR' );
3276    	FND_MSG_PUB.add;
3277         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3278       END IF;
3279     END IF;-- IF l_actual_start_date IS NULL THEN
3280 
3281     -- update the actual dates in the table
3282     IF l_actual_end_date IS NULL THEN
3283       UPDATE AHL_WORKORDERS
3284       SET ACTUAL_END_DATE = l_def_actual_end_date,
3285       LAST_UPDATE_DATE = SYSDATE,
3286       LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
3287       LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
3288       WHERE WORKORDER_ID = p_workorder_id;
3289       IF SQL%ROWCOUNT = 0 THEN
3290         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_DEF_ERROR' );
3291    	FND_MSG_PUB.add;
3292         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3293       END IF;
3294     END IF; -- IF l_actual_end_date IS NULL THEN
3295     */
3296     /* End ER # 4757222 */
3297   END IF; -- IF p_default = FND_API.G_TRUE THEN
3298 
3299 
3300   --Get the Workorder Details
3301   l_return_status :=
3302   get_workorder_rec
3303   (
3304     p_workorder_id           => p_workorder_id,
3305     p_object_version_no      => l_object_version_number,
3306     x_workorder_rec          => l_workorder_rec
3307   );
3308 
3309   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3310     RAISE FND_API.G_EXC_ERROR;
3311   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3312     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3313   END IF;
3314 
3315   --Get the Associated Operations
3316   l_return_status :=
3317   get_workorder_operations
3318   (
3319     p_workorder_id              => p_workorder_id,
3320     p_object_version_no         => l_object_version_number,
3321     x_operation_tbl             => l_operation_tbl
3322   );
3323 
3324   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3325     RAISE FND_API.G_EXC_ERROR;
3326   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3327     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3328   END IF;
3329 
3330   --Validate the Workorder
3331   l_return_status :=
3332   validate_cwo_rec
3333   (
3334     p_workorder_rec          => l_workorder_rec,
3335     p_operation_tbl          => l_operation_tbl
3336   );
3337 
3338   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3339     RAISE FND_API.G_EXC_ERROR;
3340   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3341     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3342   END IF;
3343 
3344   -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
3345   l_msg_count := FND_MSG_PUB.count_msg;
3346   IF l_msg_count > 0 THEN
3347     x_msg_count := l_msg_count;
3348     RAISE FND_API.G_EXC_ERROR;
3349   END IF;
3350 
3351   -- R12: Tech UIs
3352   -- Log all technicians out of the workorder being completed
3353   OPEN c_get_login_recs(l_workorder_rec.workorder_id);
3354   LOOP
3355   FETCH c_get_login_recs INTO l_employee_id, l_operation_seq_num, l_resource_seq_num;
3356   EXIT WHEN c_get_login_recs%NOTFOUND;
3357       AHL_PRD_WO_LOGIN_PVT.Workorder_Logout(p_api_version       => 1.0,
3358                                       p_init_msg_list     => p_init_msg_list,
3359                                       p_commit            => FND_API.G_FALSE,
3360                                       p_validation_level    => p_validation_level,
3361                                       x_return_status     => l_return_status,
3362                                       x_msg_count         => l_msg_count,
3363                                       x_msg_data          => l_msg_data,
3364                                       p_employee_id       => l_employee_id,
3365                                       p_workorder_id      => l_workorder_rec.workorder_id,
3366                                       p_operation_seq_num => l_operation_seq_num,
3367                                       p_resource_seq_num  => l_resource_seq_num
3368                                      );
3369       IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
3370         EXIT;
3371       END IF;
3372   END LOOP;
3373   CLOSE c_get_login_recs;
3374 
3375   IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
3376         RAISE FND_API.G_EXC_ERROR;
3377   END IF;
3378 
3379   --Complete the EAM Workorder
3380   l_return_status :=
3381   complete_eam_workorder
3382   (
3383     p_workorder_rec          => l_workorder_rec
3384   );
3385 
3386   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3387     RAISE FND_API.G_EXC_ERROR;
3388   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3389     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3390   END IF;
3391 
3392   --Complete the AHL Workorder
3393   l_return_status :=
3394   update_ahl_workorder
3395   (
3396     p_workorder_rec            => l_workorder_rec,
3397     p_status_code              => G_JOB_STATUS_COMPLETE
3398   );
3399 
3400   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3401     RAISE FND_API.G_EXC_ERROR;
3402   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3403     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3404   END IF;
3405 
3406   l_workorder_rec.object_version_number := l_workorder_rec.object_version_number +1;
3407 
3408   --If l_workorder_rec.collection_id is not null, then, Enable and Fire QA Actions if Commit Flag is true
3409   IF ( l_workorder_rec.collection_id IS NOT NULL AND
3410        FND_API.to_boolean( p_commit ) ) THEN
3411     QA_SS_RESULTS.wrapper_fire_action
3412     (
3413       q_collection_id    => l_workorder_rec.collection_id,
3414       q_return_status    => l_return_status,
3415       q_msg_count        => l_msg_count,
3416       q_msg_data         => l_msg_data
3417     );
3418 
3419     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3420       x_msg_data := l_msg_data;
3421       x_msg_count := l_msg_count;
3422       x_return_status := FND_API.G_RET_STS_ERROR;
3423       RETURN;
3424     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3425       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3426     END IF;
3427 
3428     -- Re-set the API savepoint because, the wrapper_fire_action commits.
3429     SAVEPOINT complete_workorder_PVT;
3430 
3431   END IF;
3432 
3433   IF ( G_CTR_READING_PLAN_ID IS NOT NULL AND
3434        l_workorder_rec.item_instance_id IS NOT NULL AND
3435        FND_API.to_boolean( p_commit ) ) THEN
3436 
3437     -- Get the Current Counter Readings for all Counters associted with
3438     -- the Item Instance.
3439     -- Bug # 6784053 (FP for Bug # 6750836) -- start
3440     l_return_status :=
3441     get_cp_counters
3442     (
3443       p_item_instance_id  => l_workorder_rec.item_instance_id,
3444       p_wip_entity_id     => l_workorder_rec.wip_entity_id,
3445       p_actual_date       => l_workorder_rec.actual_end_date,
3446       x_counter_tbl       => l_counter_tbl
3447     );
3448     -- Bug # 6784053 (FP for Bug # 6750836) -- end
3449 
3450     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3451       RAISE FND_API.G_EXC_ERROR;
3452     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3453       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3454     END IF;
3455 
3456     IF ( l_counter_tbl.COUNT > 0 ) THEN
3457       l_return_status :=
3458       record_wo_ctr_readings
3459       (
3460         x_msg_data           => l_msg_data,
3461         x_msg_count          => l_msg_count,
3462         p_wip_entity_id      => l_workorder_rec.wip_entity_id,
3463         p_counter_tbl        => l_counter_tbl
3464       );
3465 
3466       IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3467         RAISE FND_API.G_EXC_ERROR;
3468       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3469         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3470       END IF;
3471 
3472       -- Re-set the API savepoint because, Quality Results submission commits
3473       IF FND_API.to_boolean( p_commit ) THEN
3474         SAVEPOINT complete_workorder_PVT;
3475       END IF;
3476     END IF;
3477 
3478   END IF;
3479 
3480   -- R12: Serial Reservation enhancements.
3481   -- Delete remaining reservations.
3482   Delete_Serial_Reservations (p_workorder_id => p_workorder_id,
3483                               x_return_status => l_return_status);
3484 
3485   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3486      RAISE FND_API.G_EXC_ERROR;
3487   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3488      RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3489   END IF;
3490 
3491 /* Commenting out as part of fix for bug 4626717 Issue 5
3492   FOR parent_csr IN get_parent_master_wos( l_workorder_rec.wip_entity_id ) LOOP
3493     IF ( parent_csr.status_code <> G_JOB_STATUS_COMPLETE AND
3494          parent_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
3495          parent_csr.status_code <> G_JOB_STATUS_CLOSED AND
3496          parent_csr.status_code <> G_JOB_STATUS_CANCELLED ) THEN
3497 
3498       FOR child_csr IN get_child_wo_status( parent_csr.wip_entity_id ) LOOP
3499         IF ( child_csr.status_code <> G_JOB_STATUS_COMPLETE AND
3500              child_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
3501              child_csr.status_code <> G_JOB_STATUS_CLOSED AND
3502              child_csr.status_code <> G_JOB_STATUS_CANCELLED ) THEN
3503           l_child_wos_complete := FALSE;
3504           EXIT;
3505         END IF;
3506       END LOOP;
3507 
3508       IF ( l_child_wos_complete = TRUE ) THEN
3509 
3510         complete_workorder
3511         (
3512           p_api_version        => 1.0,
3513           p_init_msg_list      => FND_API.G_TRUE,
3514           p_commit             => p_commit,
3515           p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
3516           p_default            => FND_API.G_FALSE,
3517           p_module_type        => NULL,
3518           x_return_status      => l_return_status,
3519           x_msg_count          => l_msg_count,
3520           x_msg_data           => l_msg_data,
3521           p_workorder_id       => parent_csr.workorder_id,
3522           p_object_version_no  => parent_csr.object_version_number
3523         );
3524 
3525         IF ( l_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
3526           RAISE FND_API.G_EXC_ERROR;
3527         END IF;
3528 
3529         -- Re-set the API savepoint because, complete_workorder commits
3530         IF FND_API.to_boolean( p_commit ) THEN
3531           SAVEPOINT complete_workorder_PVT;
3532         END IF;
3533 
3534       ELSE
3535         l_child_wos_complete := TRUE;
3536       END IF;
3537 
3538     END IF;
3539 
3540   END LOOP;
3541 */
3542   -- If l_workorder_rec.unit_effectivity_id is not null, then, Attempt to complete the MR Instance ( Ignore Errors )
3543   IF ( l_workorder_rec.unit_effectivity_id IS NOT NULL AND
3544        NVL(l_workorder_rec.automatic_signoff_flag , 'N' ) = 'Y' ) THEN
3545 
3546     l_mr_status := get_mr_status( l_workorder_rec.unit_effectivity_id );
3547 
3548     IF ( l_mr_status = G_MR_STATUS_JOBS_COMPLETE ) THEN
3549 
3550      OPEN Check_child_exists(l_workorder_rec.unit_effectivity_id);
3551      FETCH Check_child_exists INTO l_dummy;
3552      IF Check_child_exists%NOTFOUND THEN
3553 
3554     l_mr_rec.unit_effectivity_id := l_workorder_rec.unit_effectivity_id;
3555     l_mr_rec.ue_object_version_no := l_workorder_rec.ue_object_version_number;
3556 
3557     complete_mr_instance
3558     (
3559       p_api_version         => 1.0,
3560       p_init_msg_list       => FND_API.G_TRUE,
3561       p_commit              => p_commit,
3562       p_validation_level    => FND_API.G_VALID_LEVEL_FULL,
3563       p_default             => FND_API.G_FALSE,
3564       p_module_type         => NULL,
3565       x_return_status       => l_return_status,
3566       x_msg_count           => l_msg_count,
3567       x_msg_data            => l_msg_data,
3568       p_x_mr_rec            => l_mr_rec
3569     );
3570 
3571     -- Abort for Unexpected errors, but, continue for other errors.
3572     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3573       IF ( G_DEBUG = 'Y' ) THEN
3574         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Could Not Complete MR Instance with UE : ' || TO_CHAR( l_workorder_rec.unit_effectivity_id ) || ' associated to Workorder : ' || TO_CHAR( p_workorder_id ) || ' because of...' );
3575         FOR I IN 1..l_msg_count LOOP
3576           FND_MSG_PUB.get
3577           (
3578             p_msg_index      => i,
3579             p_encoded        => FND_API.G_FALSE,
3580             p_data           => l_msg_data,
3581             p_msg_index_out  => l_msg_index_out
3582           );
3583 
3584           AHL_DEBUG_PUB.debug(' Error : ' || I || ': ' || l_msg_data);
3585         END LOOP;
3586       END IF;
3587 
3588       -- Initialize message list since errors are not reported
3589       IF FND_API.to_boolean( p_init_msg_list ) THEN
3590         FND_MSG_PUB.initialize;
3591       END IF;
3592 
3593     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3594       x_return_status := l_return_status;
3595       x_msg_data := l_msg_data;
3596       x_msg_count := l_msg_count;
3597       RETURN;
3598     ELSE
3599       IF ( G_DEBUG = 'Y' ) THEN
3600         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Completed MR  Instance with UE : ' || TO_CHAR( l_workorder_rec.unit_effectivity_id ) || ' associated to Workorder : ' || TO_CHAR( p_workorder_id ) || ' Successfuly...' );
3601       END IF;
3602 
3603       -- Re-set the API savepoint because, complete_mr_instance commits
3604       IF FND_API.to_boolean( p_commit ) THEN
3605         SAVEPOINT complete_workorder_PVT;
3606       END IF;
3607     END IF;
3608     END IF; --Child checks
3609    CLOSE Check_child_exists;
3610    END IF;
3611   END IF;
3612 
3613   -- Perform the Commit (if requested)
3614   IF FND_API.to_boolean( p_commit ) THEN
3615     COMMIT WORK;
3616   END IF;
3617 
3618   -- Disable debug (if enabled)
3619   IF ( G_DEBUG = 'Y' ) THEN
3620     AHL_DEBUG_PUB.disable_debug;
3621   END IF;
3622 
3623 EXCEPTION
3624 
3625   WHEN FND_API.G_EXC_ERROR THEN
3626     ROLLBACK TO complete_workorder_PVT;
3627     x_return_status := FND_API.G_RET_STS_ERROR;
3628     FND_MSG_PUB.count_and_get
3629     (
3630       p_encoded  => FND_API.G_FALSE,
3631       p_count    => x_msg_count,
3632       p_data     => x_msg_data
3633     );
3634 
3635     IF ( G_DEBUG = 'Y' ) THEN
3636       AHL_DEBUG_PUB.disable_debug;
3637     END IF;
3638 
3639   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
3640     ROLLBACK TO complete_workorder_PVT;
3641     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
3642     FND_MSG_PUB.count_and_get
3643     (
3644       p_encoded  => FND_API.G_FALSE,
3645       p_count    => x_msg_count,
3646       p_data     => x_msg_data
3647     );
3648 
3649     IF ( G_DEBUG = 'Y' ) THEN
3650       AHL_DEBUG_PUB.disable_debug;
3651     END IF;
3652 
3653   WHEN OTHERS THEN
3654     ROLLBACK TO complete_workorder_PVT;
3655     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
3656     IF FND_MSG_PUB.check_msg_level( FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR )
3657     THEN
3658       FND_MSG_PUB.add_exc_msg
3659       (
3660         p_pkg_name         => G_PKG_NAME,
3661         p_procedure_name   => l_api_name,
3662         p_error_text       => SUBSTRB(SQLERRM,1,240)
3663       );
3664     END IF;
3665     FND_MSG_PUB.count_and_get
3666     (
3667       p_encoded  => FND_API.G_FALSE,
3668       p_count    => x_msg_count,
3669       p_data     => x_msg_data
3670     );
3671 
3672     IF ( G_DEBUG = 'Y' ) THEN
3673       AHL_DEBUG_PUB.disable_debug;
3674     END IF;
3675 END complete_workorder;
3676 
3677 PROCEDURE defer_workorder
3678 (
3679   p_api_version       IN    NUMBER     := 1.0,
3680   p_init_msg_list     IN    VARCHAR2   := FND_API.G_TRUE,
3681   p_commit            IN    VARCHAR2   := FND_API.G_FALSE,
3682   p_validation_level  IN    NUMBER     := FND_API.G_VALID_LEVEL_FULL,
3683   p_default           IN    VARCHAR2   := FND_API.G_FALSE,
3684   p_module_type       IN    VARCHAR2   := NULL,
3685   x_return_status     OUT NOCOPY   VARCHAR2,
3686   x_msg_count         OUT NOCOPY   NUMBER,
3687   x_msg_data          OUT NOCOPY   VARCHAR2,
3688   p_workorder_id      IN    NUMBER,
3689   p_object_version_no IN    NUMBER := NULL
3690 )
3691 IS
3692 
3693 l_api_name               VARCHAR2(30) := 'defer_workorder';
3694 l_return_status          VARCHAR2(1);
3695 l_msg_count              NUMBER;
3696 l_msg_data               VARCHAR2(2000) := NULL;
3697 
3698 l_workorder_rec          workorder_rec_type;
3699 l_counter_tbl            counter_tbl_type;
3700 
3701 BEGIN
3702   -- Enable Debug (optional)
3703   IF ( G_DEBUG = 'Y' ) THEN
3704     AHL_DEBUG_PUB.enable_debug;
3705   END IF;
3706 
3707   -- Initialize API return status to success
3708   x_return_status := FND_API.G_RET_STS_SUCCESS;
3709 
3710   -- Standard Start of API savepoint
3711   SAVEPOINT defer_workorder_PVT;
3712 
3713   -- Initialize message list if p_init_msg_list is set to TRUE.
3714   IF FND_API.to_boolean( p_init_msg_list ) THEN
3715     FND_MSG_PUB.initialize;
3716   END IF;
3717 
3718   -- Validate all the inputs of the API
3719   l_return_status :=
3720   validate_wo_inputs
3721   (
3722     p_workorder_id           => p_workorder_id,
3723     p_object_version_no      => p_object_version_no
3724   );
3725 
3726   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3727     RAISE FND_API.G_EXC_ERROR;
3728   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3729     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3730   END IF;
3731 
3732   --Get the Workorder Details
3733   l_return_status :=
3734   get_workorder_rec
3735   (
3736     p_workorder_id           => p_workorder_id,
3737     p_object_version_no      => p_object_version_no,
3738     x_workorder_rec          => l_workorder_rec
3739   );
3740 
3741   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3742     RAISE FND_API.G_EXC_ERROR;
3743   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3744     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3745   END IF;
3746 
3747   --Validate the Workorder
3748   l_return_status :=
3749   validate_dwo_rec
3750   (
3751     p_workorder_rec          => l_workorder_rec
3752   );
3753 
3754   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3755     RAISE FND_API.G_EXC_ERROR;
3756   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3757     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3758   END IF;
3759 
3760   -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
3761   l_msg_count := FND_MSG_PUB.count_msg;
3762   IF l_msg_count > 0 THEN
3763     x_msg_count := l_msg_count;
3764     RAISE FND_API.G_EXC_ERROR;
3765   END IF;
3766 
3767   --Complete the EAM Workorder
3768   l_return_status :=
3769   complete_eam_workorder
3770   (
3771     p_workorder_rec          => l_workorder_rec
3772   );
3773 
3774   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3775     RAISE FND_API.G_EXC_ERROR;
3776   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3777     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3778   END IF;
3779 
3780   --Defer the AHL Workorder
3781   l_return_status :=
3782   update_ahl_workorder
3783   (
3784     p_workorder_rec            => l_workorder_rec,
3785     p_status_code              => G_JOB_STATUS_COMPLETE
3786   );
3787 
3788   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3789     RAISE FND_API.G_EXC_ERROR;
3790   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3791     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3792   END IF;
3793 
3794   l_workorder_rec.object_version_number := l_workorder_rec.object_version_number +1;
3795 
3796   --If l_workorder_rec.collection_id is not null, then, Enable and Fire QA Actions
3797   IF ( l_workorder_rec.collection_id IS NOT NULL ) THEN
3798     QA_SS_RESULTS.wrapper_fire_action
3799     (
3800       q_collection_id    => l_workorder_rec.collection_id,
3801       q_return_status    => l_return_status,
3802       q_msg_count        => l_msg_count,
3803       q_msg_data         => l_msg_data
3804     );
3805 
3806     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3807       x_msg_data := l_msg_data;
3808       x_msg_count := l_msg_count;
3809       x_return_status := FND_API.G_RET_STS_ERROR;
3810       RETURN;
3811     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3812       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3813     END IF;
3814 
3815     -- Re-set the API savepoint because, the wrapper_fire_action commits.
3816     SAVEPOINT defer_workorder_PVT;
3817 
3818   END IF;
3819 
3820   IF ( G_CTR_READING_PLAN_ID IS NOT NULL AND
3821        l_workorder_rec.item_instance_id IS NOT NULL ) THEN
3822 
3823     -- Get the Current Counter Readings for all Counters associted with
3824     -- the Item Instance.
3825     -- Bug # 6784053 (FP for Bug # 6750836) -- start
3826     l_return_status :=
3827     get_cp_counters
3828     (
3829       p_item_instance_id  => l_workorder_rec.item_instance_id,
3830       p_wip_entity_id       => l_workorder_rec.wip_entity_id,
3831       p_actual_date       => l_workorder_rec.actual_end_date,
3832       x_counter_tbl       => l_counter_tbl
3833     );
3834     -- Bug # 6784053 (FP for Bug # 6750836) -- end
3835     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3836       RAISE FND_API.G_EXC_ERROR;
3837     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3838       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3839     END IF;
3840 
3841     IF ( l_counter_tbl.COUNT > 0 ) THEN
3842       l_return_status :=
3843       record_wo_ctr_readings
3844       (
3845         x_msg_data           => l_msg_data,
3846         x_msg_count          => l_msg_count,
3847         p_wip_entity_id      => l_workorder_rec.wip_entity_id,
3848         p_counter_tbl        => l_counter_tbl
3849       );
3850 
3851       IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3852         RAISE FND_API.G_EXC_ERROR;
3853       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3854         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3855       END IF;
3856 
3857       -- Re-set the API savepoint because, Quality Results submission commits
3858       SAVEPOINT defer_workorder_PVT;
3859     END IF;
3860   END IF;
3861 
3862   -- Perform the Commit (if requested)
3863   IF FND_API.to_boolean( p_commit ) THEN
3864     COMMIT WORK;
3865   END IF;
3866 
3867   -- Disable debug (if enabled)
3868   IF ( G_DEBUG = 'Y' ) THEN
3869     AHL_DEBUG_PUB.disable_debug;
3870   END IF;
3871 
3872 EXCEPTION
3873 
3874   WHEN FND_API.G_EXC_ERROR THEN
3875     ROLLBACK TO defer_workorder_PVT;
3876     x_return_status := FND_API.G_RET_STS_ERROR;
3877     FND_MSG_PUB.count_and_get
3878     (
3879       p_encoded  => FND_API.G_FALSE,
3880       p_count    => x_msg_count,
3881       p_data     => x_msg_data
3882     );
3883 
3884     IF ( G_DEBUG = 'Y' ) THEN
3885       AHL_DEBUG_PUB.disable_debug;
3886     END IF;
3887 
3888   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
3889     ROLLBACK TO defer_workorder_PVT;
3890     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
3891     FND_MSG_PUB.count_and_get
3892     (
3893       p_encoded  => FND_API.G_FALSE,
3894       p_count    => x_msg_count,
3895       p_data     => x_msg_data
3896     );
3897 
3898     IF ( G_DEBUG = 'Y' ) THEN
3899       AHL_DEBUG_PUB.disable_debug;
3900     END IF;
3901 
3902   WHEN OTHERS THEN
3903     ROLLBACK TO defer_workorder_PVT;
3904     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
3905     IF FND_MSG_PUB.check_msg_level( FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR )
3906     THEN
3907       FND_MSG_PUB.add_exc_msg
3908       (
3909         p_pkg_name         => G_PKG_NAME,
3910         p_procedure_name   => l_api_name,
3911         p_error_text       => SUBSTRB(SQLERRM,1,240)
3912       );
3913     END IF;
3914     FND_MSG_PUB.count_and_get
3915     (
3916       p_encoded  => FND_API.G_FALSE,
3917       p_count    => x_msg_count,
3918       p_data     => x_msg_data
3919     );
3920 
3921     IF ( G_DEBUG = 'Y' ) THEN
3922       AHL_DEBUG_PUB.disable_debug;
3923     END IF;
3924 
3925 END defer_workorder;
3926 
3927 -- Procedure to Complete a FMP / UMP MR Instance
3928 PROCEDURE complete_mr_instance
3929 (
3930   p_api_version          IN   NUMBER      := 1.0,
3931   p_init_msg_list        IN   VARCHAR2    := FND_API.G_TRUE,
3932   p_commit               IN   VARCHAR2    := FND_API.G_FALSE,
3933   p_validation_level     IN   NUMBER      := FND_API.G_VALID_LEVEL_FULL,
3934   p_default              IN   VARCHAR2    := FND_API.G_FALSE,
3935   p_module_type          IN   VARCHAR2    := NULL,
3936   x_return_status        OUT NOCOPY  VARCHAR2,
3937   x_msg_count            OUT NOCOPY  NUMBER,
3938   x_msg_data             OUT NOCOPY  VARCHAR2,
3939   p_x_mr_rec             IN OUT NOCOPY  mr_rec_type
3940 )
3941 IS
3942 
3943 l_api_name               VARCHAR2(30) := 'complete_mr_instance';
3944 l_return_status          VARCHAR2(1);
3945 l_mwo_return_status      VARCHAR2(1);
3946 l_msg_count              NUMBER;
3947 l_msg_index_out          NUMBER;
3948 l_msg_data               VARCHAR2(2000) := NULL;
3949 
3950 l_counter_tbl            counter_tbl_type;
3951 l_reset_counter_tbl      counter_tbl_type;
3952 l_parent_mr_rec          mr_rec_type;
3953 
3954 CURSOR  get_parent_mrs( c_unit_effectivity_id NUMBER )
3955 IS
3956 SELECT  UE.unit_effectivity_id unit_effectivity_id,
3957         UE.object_version_number ue_object_version_number
3958 FROM    AHL_MR_HEADERS_B MR,
3959         AHL_UNIT_EFFECTIVITIES_B UE,
3960         AHL_UE_RELATIONSHIPS REL
3961 WHERE   MR.mr_header_id = UE.mr_header_id
3962 AND     MR.auto_signoff_flag = 'Y'
3963 AND     UE.unit_effectivity_id = REL.ue_id
3964 AND     REL.related_ue_id = c_unit_effectivity_id
3965 AND     REL.relationship_code = 'PARENT';
3966 
3967 BEGIN
3968   -- Enable Debug (optional)
3969   IF ( G_DEBUG = 'Y' ) THEN
3970     AHL_DEBUG_PUB.enable_debug;
3971   END IF;
3972 
3973   -- Initialize API return status to success
3974   x_return_status := FND_API.G_RET_STS_SUCCESS;
3975 
3976   -- Standard Start of API savepoint
3977   SAVEPOINT complete_mr_instance_PVT;
3978 
3979   -- Initialize message list if p_init_msg_list is set to TRUE.
3980   IF FND_API.to_boolean( p_init_msg_list ) THEN
3981     FND_MSG_PUB.initialize;
3982   END IF;
3983 
3984   -- Validate all the inputs of the API
3985   l_return_status :=
3986   validate_cmri_inputs
3987   (
3988     p_mr_rec                 => p_x_mr_rec
3989   );
3990 
3991   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
3992     RAISE FND_API.G_EXC_ERROR;
3993   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
3994     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3995   END IF;
3996 
3997  -- default missing attributes of the input MR Instance Record
3998  l_return_status :=
3999  default_mr_rec
4000  (
4001    p_x_mr_rec => p_x_mr_rec
4002  );
4003 
4004  IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4005     RAISE FND_API.G_EXC_ERROR;
4006  ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4007     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4008  END IF;
4009 
4010  IF ( G_DEBUG = 'Y' ) THEN
4011   AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' Inputs:'  );
4012   AHL_DEBUG_PUB.debug( 'unit_effectivity_id:'  || p_x_mr_rec.unit_effectivity_id );
4013   AHL_DEBUG_PUB.debug( 'ue_object_version_no:'  || p_x_mr_rec.ue_object_version_no );
4014   AHL_DEBUG_PUB.debug( 'item_instance_id:'  || p_x_mr_rec.item_instance_id );
4015   AHL_DEBUG_PUB.debug( 'mr_header_id:'  || p_x_mr_rec.mr_header_id );
4016   AHL_DEBUG_PUB.debug( 'incident_id:'  || p_x_mr_rec.incident_id );
4017   AHL_DEBUG_PUB.debug( 'mr_title:'  || p_x_mr_rec.mr_title );
4018   AHL_DEBUG_PUB.debug( 'ue_status_code:'  || p_x_mr_rec.ue_status_code );
4019   AHL_DEBUG_PUB.debug( 'qa_inspection_type:'  || p_x_mr_rec.qa_inspection_type );
4020   AHL_DEBUG_PUB.debug( 'actual_end_date:'  || p_x_mr_rec.actual_end_date );
4021   AHL_DEBUG_PUB.debug( 'qa_plan_id:'  || p_x_mr_rec.qa_plan_id );
4022   AHL_DEBUG_PUB.debug( 'qa_collection_id:'  || p_x_mr_rec.qa_collection_id );
4023  END IF;
4024 
4025  -- Validate the status to check if the MR/SR status is valid for Sign off
4026  l_return_status :=
4027  validate_mr_status
4028  (
4029    p_mr_status_code  =>  p_x_mr_rec.ue_status_code,
4030    p_mr_status    =>  p_x_mr_rec.ue_status,
4031    p_mr_title    =>  p_x_mr_rec.mr_title
4032  );
4033 
4034  IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4035      RAISE FND_API.G_EXC_ERROR;
4036  ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4037      RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4038  END IF;
4039 
4040   -- Check if the MR/SR Instance is complete
4041   l_return_status:=
4042   is_mr_complete
4043   (
4044     p_mr_title             => p_x_mr_rec.mr_title,
4045     p_status_code          => p_x_mr_rec.ue_status_code,
4046     p_status               => p_x_mr_rec.ue_status,
4047     p_qa_inspection_type   => p_x_mr_rec.qa_inspection_type,
4048     p_qa_plan_id           => p_x_mr_rec.qa_plan_id,
4049     p_qa_collection_id     => p_x_mr_rec.qa_collection_id
4050   );
4051 
4052   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4053     RAISE FND_API.G_EXC_ERROR;
4054   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4055     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4056   END IF;
4057 
4058   -- Check if all Child MR Instances are complete
4059   l_return_status :=
4060   are_child_mrs_complete
4061   (
4062     p_mr_rec    => p_x_mr_rec
4063   );
4064 
4065   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4066     RAISE FND_API.G_EXC_ERROR;
4067   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4068     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4069   END IF;
4070 
4071   IF ( G_DEBUG = 'Y' ) THEN
4072     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || 'Getting Reset Counters'  );
4073   END IF;
4074 
4075   -- Get the Reset Counter Readings for all Counters associted with
4076   -- the MR and the Item Instance.
4077   IF(p_x_mr_rec.mr_header_id IS NOT NULL)THEN
4078   l_return_status :=
4079   get_reset_counters
4080   (
4081     p_mr_header_id      => p_x_mr_rec.mr_header_id,
4082     p_item_instance_id  => p_x_mr_rec.item_instance_id,
4083     p_actual_date       => p_x_mr_rec.actual_end_date,
4084     x_counter_tbl       => l_reset_counter_tbl
4085   );
4086   END IF;
4087 
4088   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4089     RAISE FND_API.G_EXC_ERROR;
4090   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4091     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4092   END IF;
4093 
4094   IF ( l_reset_counter_tbl IS NOT NULL AND l_reset_counter_tbl.COUNT > 0 ) THEN
4095 
4096     IF ( G_DEBUG = 'Y' ) THEN
4097       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || 'Resetting Counters'  );
4098     END IF;
4099 
4100     -- Reset all the Counters with Reset Values specified in FMP
4101     l_return_status :=
4102     reset_counters
4103     (
4104       p_mr_rec              => p_x_mr_rec,
4105       p_x_counter_tbl       => l_reset_counter_tbl,
4106       p_actual_end_date     => p_x_mr_rec.actual_end_date,
4107       x_msg_count           => l_msg_count,
4108       x_msg_data            => l_msg_data
4109     );
4110 
4111     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4112       IF ( l_msg_data IS NOT NULL ) THEN
4113         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4114         x_msg_count := l_msg_count;
4115         x_msg_data := l_msg_data;
4116         RETURN;
4117       END IF;
4118       RAISE FND_API.G_EXC_ERROR;
4119     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4120       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4121     END IF;
4122 
4123   END IF;
4124 
4125   IF ( G_DEBUG = 'Y' ) THEN
4126     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || 'Getting CP Counters'  );
4127   END IF;
4128 
4129   -- Get the Current Counter Readings for all Counters associted with
4130   -- the Item Instance.
4131   -- Bug # 6784053 (FP for Bug # 6750836) -- start
4132   l_return_status :=
4133   get_cp_counters
4134   (
4135     p_item_instance_id  => p_x_mr_rec.item_instance_id,
4136     p_wip_entity_id     => null,
4137     p_actual_date       => p_x_mr_rec.actual_end_date,
4138     x_counter_tbl       => l_counter_tbl
4139   );
4140   -- Bug # 6784053 (FP for Bug # 6750836) -- end
4141   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4142     RAISE FND_API.G_EXC_ERROR;
4143   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4144     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4145   END IF;
4146 
4147 /* Removed for Bug 3310304
4148   IF ( l_counter_tbl.COUNT > 0 ) THEN
4149 */
4150 
4151   IF ( G_DEBUG = 'Y' ) THEN
4152     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || 'Updating UMP'  );
4153   END IF;
4154 
4155   -- Record Accomplishment in UMP for UMP MR Instance
4156   l_return_status :=
4157   update_ump
4158   (
4159       p_unit_effectivity_id  => p_x_mr_rec.unit_effectivity_id,
4160       p_ue_object_version    => p_x_mr_rec.ue_object_version_no,
4161       p_actual_end_date      => p_x_mr_rec.actual_end_date,
4162       p_counter_tbl          => l_counter_tbl,
4163       x_msg_count            => l_msg_count,
4164       x_msg_data             => l_msg_data
4165   );
4166 
4167   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4168     IF ( l_msg_data IS NOT NULL ) THEN
4169       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4170       x_msg_count := l_msg_count;
4171       x_msg_data := l_msg_data;
4172       RETURN;
4173     END IF;
4174     RAISE FND_API.G_EXC_ERROR;
4175   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4176     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4177   END IF;
4178 
4179 /* Removed for Bug 3310304
4180   END IF;
4181 */
4182 
4183   -- At this point the UE is ready for Sign off. which means following conditions are
4184   -- satisfied
4185   -- 1. All workorders associated to the UE MWO are either complete or cancelled or closed.
4186   -- 2. All Child UE are in either Signed off or Cancelled or deferred or terminated.
4187   -- 3. All other workorders in the Hierarchy are either complete or cancelled or closed.
4188   --
4189   -- As per the issue # 2 in bug # 4626717 the master workorder has to be completed once
4190   -- the associated UE is signed off.Putting this code here because this is the logical end
4191   -- of mr signoff and before parent mr check starts.
4192   IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
4193 	fnd_log.string
4194 	(
4195 		fnd_log.level_statement,
4196 		'ahl.plsql.AHL_PRD_COMPLETIONS_PVT.complete_mr_instance',
4197 		'p_x_mr_rec.unit_effectivity_id : ' || p_x_mr_rec.unit_effectivity_id
4198 	);
4199   END IF;
4200 
4201   l_mwo_return_status := complete_master_wo(
4202 	 p_visit_id	=>	null,
4203 	 p_workorder_id	=>	null,
4204 	 p_ue_id	=>	p_x_mr_rec.unit_effectivity_id
4205   );
4206 
4207   IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
4208 	fnd_log.string
4209 	(
4210 		fnd_log.level_statement,
4211 		'ahl.plsql.AHL_PRD_COMPLETIONS_PVT.complete_mr_instance',
4212 		'return status after calling complete_master_wo: ' || l_mwo_return_status
4213 	);
4214   END IF;
4215 
4216   IF l_mwo_return_status = FND_API.G_RET_STS_ERROR THEN
4217   	RAISE FND_API.G_EXC_ERROR;
4218   ELSIF l_mwo_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
4219   	RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4220   END IF;
4221 
4222   -- Additional logic added in 11.5.10 for QA Collection
4223   IF ( p_x_mr_rec.qa_collection_id IS NOT NULL AND
4224        FND_API.to_boolean( p_commit ) ) THEN
4225 
4226     QA_SS_RESULTS.wrapper_fire_action
4227     (
4228       q_collection_id => p_x_mr_rec.qa_collection_id,
4229       q_return_status => l_return_status,
4230       q_msg_count     => l_msg_count,
4231       q_msg_data      => l_msg_data
4232     );
4233 
4234     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4235       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_QA_ACTION_ERROR' );
4236       FND_MESSAGE.set_token( 'MAINT_REQ', p_x_mr_rec.mr_title);
4237       FND_MSG_PUB.add;
4238       RAISE FND_API.G_EXC_ERROR;
4239     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4240       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
4241     END IF;
4242 
4243     -- Re-establish the save point because the QA API Commits
4244     IF FND_API.to_boolean( p_commit ) THEN
4245       SAVEPOINT complete_mr_instance_PVT;
4246     END IF;
4247 
4248   END IF;
4249 
4250   -- Get Parent MRs which require automatic Signoff
4251   FOR parent_csr IN get_parent_mrs( p_x_mr_rec.unit_effectivity_id ) LOOP
4252 
4253     -- Attempt to complete the parent MR Instance ( Ignore Errors )
4254     l_parent_mr_rec.unit_effectivity_id := parent_csr.unit_effectivity_id;
4255     l_parent_mr_rec.ue_object_version_no := parent_csr.ue_object_version_number;
4256 
4257     complete_mr_instance
4258     (
4259       p_api_version         => 1.0,
4260       p_init_msg_list       => FND_API.G_TRUE,
4261       p_commit              => p_commit,
4262       p_validation_level    => FND_API.G_VALID_LEVEL_FULL,
4263       p_default             => FND_API.G_FALSE,
4264       p_module_type         => NULL,
4265       x_return_status       => l_return_status,
4266       x_msg_count           => l_msg_count,
4267       x_msg_data            => l_msg_data,
4268       p_x_mr_rec            => l_parent_mr_rec
4269     );
4270 
4271     -- Abort for Unexpected errors, but, continue for other errors.
4272     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
4273       IF ( G_DEBUG = 'Y' ) THEN
4274         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
4275         ||' : Could Not Complete Parent MR Instance with UE : '
4276         ||TO_CHAR( parent_csr.unit_effectivity_id )
4277         || ' associated to UE : ' || TO_CHAR( p_x_mr_rec.unit_effectivity_id )
4278         || ' because of...' );
4279         FOR I IN 1..l_msg_count LOOP
4280           FND_MSG_PUB.get
4281           (
4282             p_msg_index      => i,
4283             p_encoded        => FND_API.G_FALSE,
4284             p_data           => l_msg_data,
4285             p_msg_index_out  => l_msg_index_out
4286           );
4287 
4288           AHL_DEBUG_PUB.debug(' Error : ' || I || ': ' || l_msg_data);
4289         END LOOP;
4290       END IF;
4291 
4292       -- Initialize message list since errors are not reported
4293       IF FND_API.to_boolean( p_init_msg_list ) THEN
4294         FND_MSG_PUB.initialize;
4295       END IF;
4296 
4297     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
4298       x_return_status := l_return_status;
4299       x_msg_data := l_msg_data;
4300       x_msg_count := l_msg_count;
4301       RETURN;
4302     ELSE
4303       IF ( G_DEBUG = 'Y' ) THEN
4304         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Completed MR  Instance with UE : ' || TO_CHAR( parent_csr.unit_effectivity_id ) || ' associated to UE : ' || TO_CHAR( p_x_mr_rec.unit_effectivity_id ) || ' Successfuly...' );
4305       END IF;
4306 
4307       -- Re-establish the save point because the complete_mr_instance Commits
4308       IF FND_API.to_boolean( p_commit ) THEN
4309         SAVEPOINT complete_mr_instance_PVT;
4310       END IF;
4311 
4312     END IF;
4313   END LOOP;
4314 
4315   -- Perform the Commit (if requested)
4316   IF FND_API.to_boolean( p_commit ) THEN
4317     COMMIT WORK;
4318   END IF;
4319 
4320   -- Disable debug (if enabled)
4321   IF ( G_DEBUG = 'Y' ) THEN
4322     AHL_DEBUG_PUB.disable_debug;
4323   END IF;
4324 
4325 EXCEPTION
4326 
4327   WHEN FND_API.G_EXC_ERROR THEN
4328     ROLLBACK TO complete_mr_instance_PVT;
4329     x_return_status := FND_API.G_RET_STS_ERROR;
4330     FND_MSG_PUB.count_and_get
4331     (
4332       p_encoded  => FND_API.G_FALSE,
4333       p_count    => x_msg_count,
4334       p_data     => x_msg_data
4335     );
4336 
4337     IF ( G_DEBUG = 'Y' ) THEN
4338       AHL_DEBUG_PUB.disable_debug;
4339     END IF;
4340 
4341   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
4342     ROLLBACK TO complete_mr_instance_PVT;
4343     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
4344     FND_MSG_PUB.count_and_get
4345     (
4346       p_encoded  => FND_API.G_FALSE,
4347       p_count    => x_msg_count,
4348       p_data     => x_msg_data
4349     );
4350 
4351     IF ( G_DEBUG = 'Y' ) THEN
4352       AHL_DEBUG_PUB.disable_debug;
4353     END IF;
4354 
4355   WHEN OTHERS THEN
4356     ROLLBACK TO complete_mr_instance_PVT;
4357     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
4358     IF FND_MSG_PUB.check_msg_level( FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR )
4359     THEN
4360       FND_MSG_PUB.add_exc_msg
4361       (
4362         p_pkg_name         => G_PKG_NAME,
4363         p_procedure_name   => l_api_name,
4364         p_error_text       => SUBSTRB(SQLERRM,1,240)
4365       );
4366     END IF;
4367     FND_MSG_PUB.count_and_get
4368     (
4369       p_encoded  => FND_API.G_FALSE,
4370       p_count    => x_msg_count,
4371       p_data     => x_msg_data
4372     );
4373 
4374     IF ( G_DEBUG = 'Y' ) THEN
4375       AHL_DEBUG_PUB.disable_debug;
4376     END IF;
4377 END complete_mr_instance;
4378 
4379 -- Function added in 11.5.10 for getting the status of an MR instance.
4380 FUNCTION get_mr_status
4381 (
4382    p_unit_effectivity_id  IN NUMBER
4383 ) RETURN VARCHAR2
4384 
4385 IS
4386   l_mr_status_code VARCHAR2(30);
4387   --l_mr_status_count NUMBER := 0;
4388   l_job_status_complete BOOLEAN := FALSE;
4389   l_job_status_qa_pending BOOLEAN := FALSE;
4390   l_job_status_on_hold BOOLEAN := FALSE;
4391   l_job_status_released BOOLEAN := FALSE;
4392   l_job_status_cancelled BOOLEAN := FALSE;
4393   l_job_status_unreleased BOOLEAN := FALSE;
4394 
4395 /* CURSOR get_mr_status_ue(c_unit_effectivity_id NUMBER) IS
4396   SELECT UE.ump_status_code
4397   FROM AHL_UE_DEFERRAL_DETAILS_V UE
4398   WHERE UE.unit_effectivity_id = c_unit_effectivity_id;
4399 
4400   CURSOR get_mr_status_wo(c_unit_effectivity_id NUMBER) IS
4401   SELECT DISTINCT DECODE( WO.status_code,
4402                           G_JOB_STATUS_CLOSED, G_JOB_STATUS_COMPLETE,
4403                           G_JOB_STATUS_COMPLETE_NC, G_JOB_STATUS_COMPLETE,
4404                           G_JOB_STATUS_PARTS_HOLD, G_JOB_STATUS_ON_HOLD,
4405                           G_JOB_STATUS_DEFERRAL_PENDING,G_JOB_STATUS_ON_HOLD,
4406                           WO.status_code ) status_code
4407   FROM  AHL_WORKORDERS WO,
4408         AHL_VISIT_TASKS_B VT
4409   WHERE WO.visit_task_id = VT.visit_task_id
4410   AND   WO.status_code <> G_JOB_STATUS_DELETED
4411   AND   WO.master_workorder_flag = 'N'
4412   AND   VT.unit_effectivity_id = c_unit_effectivity_id;
4413 */
4414 
4415   -- Balaji made following change for checking wip completion dates for
4416   -- differentiating workorders which are cancelled and then closed from
4417   -- those workorders which are completed and closed.
4418   -- For MR status derivation cancelled closed should be considered as cacelled
4419   -- and completion followed by closure should be considered as complete.
4420 
4421   -- Changed to consider Child MR Jobs statuses for Bug 3406703
4422   /*  CURSOR get_mr_status_wo(c_unit_effectivity_id NUMBER) IS
4423     SELECT DISTINCT DECODE( CWO.status_code,
4424                             G_JOB_STATUS_CLOSED, decode(WIPJ.date_completed, null, G_JOB_STATUS_CANCELLED, G_JOB_STATUS_COMPLETE),
4425                             G_JOB_STATUS_COMPLETE_NC, G_JOB_STATUS_COMPLETE,
4426                             G_JOB_STATUS_PARTS_HOLD, G_JOB_STATUS_ON_HOLD,
4427                             G_JOB_STATUS_DEFERRAL_PENDING,G_JOB_STATUS_ON_HOLD,
4428                             CWO.status_code ) status_code
4429     FROM   AHL_WORKORDERS CWO, ahl_visit_tasks_b vst, wip_discrete_jobs WIPJ
4430     where CWO.visit_task_id = vst.visit_task_id
4431     AND vst.unit_effectivity_id = c_unit_effectivity_id
4432     AND CWO.master_workorder_flag = 'N'
4433     AND CWO.wip_entity_id in (SELECT REL.child_object_id
4434                               from WIP_SCHED_RELATIONSHIPS REL
4435     START WITH      REL.parent_object_id IN
4436                     (
4437                        SELECT PWO.wip_entity_id
4438                        FROM   AHL_WORKORDERS PWO,
4439                               AHL_VISIT_TASKS_B VT,
4440                               AHL_VISITS_B VS
4441                        WHERE  PWO.master_workorder_flag = 'Y'
4442                        AND    PWO.visit_task_id = VT.visit_task_id
4443                        AND    VS.VISIT_ID = VT.VISIT_ID
4444                        AND    VS.STATUS_CODE NOT IN ('CLOSED','CANCELLED')
4445                        AND    VT.unit_effectivity_id = c_unit_effectivity_id
4446                     )
4447                     AND             REL.parent_object_type_id = 1
4448                     AND             REL.relationship_type = 1
4449     CONNECT BY      REL.parent_object_id = PRIOR REL.child_object_id
4450     AND             REL.parent_object_type_id = PRIOR REL.child_object_type_id
4451     AND             REL.relationship_type = 1
4452   )
4453   AND WIPJ.wip_entity_id = CWO.wip_entity_id;*/
4454 
4455   -- this cursor will be used when
4456 		-- 1. ue status is null
4457 		-- 2. this is an unassociated task created as a result of
4458 		-- SR creation from Production
4459   -- Balaji made following change for checking wip completion dates for
4460   -- differentiating workorders which are cancelled and then closed from
4461   -- those workorders which are completed and closed.
4462   -- For MR status derivation cancelled closed should be considered as cacelled
4463   -- and completion followed by closure should be considered as complete.
4464 
4465   /*CURSOR get_status_unassoc(c_unit_effectivity_id NUMBER) IS
4466 		SELECT  DISTINCT DECODE( CWO.status_code,
4467                             G_JOB_STATUS_CLOSED, decode(WIPJ.date_completed, null, G_JOB_STATUS_CANCELLED, G_JOB_STATUS_COMPLETE),
4468                             G_JOB_STATUS_COMPLETE_NC, G_JOB_STATUS_COMPLETE,
4469                             G_JOB_STATUS_PARTS_HOLD, G_JOB_STATUS_ON_HOLD,
4470                             G_JOB_STATUS_DEFERRAL_PENDING,G_JOB_STATUS_ON_HOLD,
4471                             CWO.status_code ) status_code
4472   FROM   AHL_WORKORDERS CWO, ahl_visit_tasks_b vst, wip_discrete_jobs WIPJ
4473   where CWO.visit_task_id = vst.visit_task_id
4474   AND vst.unit_effectivity_id = c_unit_effectivity_id
4475 		AND vst.task_type_code = 'UNASSOCIATED'
4476   AND WIPJ.wip_entity_id = CWO.wip_entity_id; */
4477 
4478 		-- bug 4087041
4479 		-- this bug takes care of the case of
4480 		-- signing of sr with mrs and group mrs
4481   -- Balaji made following change for checking wip completion dates for
4482   -- differentiating workorders which are cancelled and then closed from
4483   -- those workorders which are completed and closed.
4484   -- For MR status derivation cancelled closed should be considered as cacelled
4485   -- and completion followed by closure should be considered as complete.
4486 
4487   /*CURSOR get_status_top_level_sr(c_unit_effectivity_id NUMBER) IS
4488   SELECT DISTINCT DECODE( CWO.status_code,
4489                             G_JOB_STATUS_CLOSED, decode(WIPJ.date_completed, null, G_JOB_STATUS_CANCELLED, G_JOB_STATUS_COMPLETE),
4490                             G_JOB_STATUS_COMPLETE_NC, G_JOB_STATUS_COMPLETE,
4491                             G_JOB_STATUS_PARTS_HOLD, G_JOB_STATUS_ON_HOLD,
4492                             G_JOB_STATUS_DEFERRAL_PENDING,G_JOB_STATUS_ON_HOLD,
4493                             CWO.status_code ) status_code
4494     FROM   AHL_WORKORDERS CWO, ahl_visit_tasks_b vst, wip_discrete_jobs WIPJ
4495     where CWO.visit_task_id = vst.visit_task_id
4496     --AND vst.unit_effectivity_id = c_unit_effectivity_id
4497     AND CWO.master_workorder_flag = 'N'
4498     AND CWO.wip_entity_id in (SELECT REL.child_object_id
4499                               from WIP_SCHED_RELATIONSHIPS REL
4500     START WITH      REL.parent_object_id IN
4501                     (
4502                        SELECT PWO.wip_entity_id
4503                        FROM   AHL_WORKORDERS PWO,
4504                               AHL_VISIT_TASKS_B VT,
4505                               AHL_VISITS_B VS
4506                        WHERE  PWO.master_workorder_flag = 'Y'
4507                        AND    PWO.visit_task_id = VT.visit_task_id
4508                        AND    VS.VISIT_ID = VT.VISIT_ID
4509                        AND    VS.STATUS_CODE NOT IN ('CLOSED','CANCELLED')
4510                        AND    VT.unit_effectivity_id = c_unit_effectivity_id
4511                     )
4512                     AND             REL.parent_object_type_id = 1
4513                     AND             REL.relationship_type = 1
4514     CONNECT BY      REL.parent_object_id = PRIOR REL.child_object_id
4515     AND             REL.parent_object_type_id = PRIOR REL.child_object_type_id
4516     AND             REL.relationship_type = 1
4517   )
4518   AND WIPJ.wip_entity_id = CWO.wip_entity_id;*/
4519 
4520   --to check released/unpleased/qa-pending
4521   --to check released/unpleased/qa-pending
4522   CURSOR get_mr_status_csr(c_unit_effectivity_id NUMBER,p_status_code VARCHAR2) IS
4523   SELECT
4524     CWO.status_code
4525     FROM   AHL_WORKORDERS CWO, ahl_visit_tasks_b vst
4526     where CWO.visit_task_id = vst.visit_task_id
4527     AND CWO.master_workorder_flag = 'N'
4528     AND CWO.status_code IN (p_status_code)
4529     AND vst.unit_effectivity_id IN (select related_ue_id
4530                                     from ahl_ue_relationships
4531                                     start with ue_id = c_unit_effectivity_id
4532                                     AND relationship_code = 'PARENT'
4533                                     connect by prior related_ue_id = ue_id
4534                                     AND relationship_code = 'PARENT'
4535                                     union all
4536                                     select c_unit_effectivity_id
4537                                     from dual)
4538    AND rownum < 2;
4539 
4540   CURSOR is_mr_on_hold_csr(c_unit_effectivity_id NUMBER) IS
4541   SELECT
4542     CWO.status_code
4543     FROM   AHL_WORKORDERS CWO, ahl_visit_tasks_b vst
4544     where CWO.visit_task_id = vst.visit_task_id
4545     AND CWO.master_workorder_flag = 'N'
4546     AND CWO.status_code IN (G_JOB_STATUS_PARTS_HOLD, G_JOB_STATUS_ON_HOLD,
4547                             G_JOB_STATUS_DEFERRAL_PENDING)
4548     AND vst.unit_effectivity_id IN (select related_ue_id
4549                                     from ahl_ue_relationships
4550                                     start with ue_id = c_unit_effectivity_id
4551                                     AND relationship_code = 'PARENT'
4552                                     connect by prior related_ue_id = ue_id
4553                                     AND relationship_code = 'PARENT'
4554                                     union all
4555                                     select c_unit_effectivity_id
4556                                     from dual)
4557    AND rownum < 2;
4558 
4559   CURSOR is_mr_complete_csr(c_unit_effectivity_id NUMBER) IS
4560   SELECT
4561     CWO.status_code
4562     FROM   AHL_WORKORDERS CWO, ahl_visit_tasks_b vst, wip_discrete_jobs wipj
4563     where CWO.visit_task_id = vst.visit_task_id
4564     AND WIPJ.wip_entity_id = CWO.wip_entity_id
4565     AND CWO.master_workorder_flag = 'N'
4566     AND CWO.status_code IN (G_JOB_STATUS_CLOSED, G_JOB_STATUS_COMPLETE_NC, G_JOB_STATUS_COMPLETE)
4567     AND WIPJ.date_completed IS NOT NULL
4568     AND vst.unit_effectivity_id IN (select related_ue_id
4569                                     from ahl_ue_relationships
4570                                     start with ue_id = c_unit_effectivity_id
4571                                     AND relationship_code = 'PARENT'
4572                                     connect by prior related_ue_id = ue_id
4573                                     AND relationship_code = 'PARENT'
4574                                     union all
4575                                     select c_unit_effectivity_id
4576                                     from dual)
4577    AND rownum < 2;
4578 
4579   CURSOR is_mr_cancelled_csr(c_unit_effectivity_id NUMBER) IS
4580   SELECT
4581     CWO.status_code
4582     FROM   AHL_WORKORDERS CWO, ahl_visit_tasks_b vst, wip_discrete_jobs wipj
4583     where CWO.visit_task_id = vst.visit_task_id
4584     AND WIPJ.wip_entity_id = CWO.wip_entity_id
4585     --AND vst.unit_effectivity_id = c_unit_effectivity_id
4586     AND CWO.master_workorder_flag = 'N'
4587     AND CWO.status_code IN (G_JOB_STATUS_CLOSED, G_JOB_STATUS_CANCELLED)
4588     AND WIPJ.date_completed IS NULL
4589     AND vst.unit_effectivity_id IN (select related_ue_id
4590                                     from ahl_ue_relationships
4591                                     start with ue_id = c_unit_effectivity_id
4592                                     AND relationship_code = 'PARENT'
4593                                     connect by prior related_ue_id = ue_id
4594                                     AND relationship_code = 'PARENT'
4595                                     union all
4596                                     select c_unit_effectivity_id
4597                                     from dual)
4598    AND rownum < 2;
4599 
4600 BEGIN
4601 
4602    IF ( p_unit_effectivity_id IS NULL OR
4603         p_unit_effectivity_id = FND_API.G_MISS_NUM ) THEN
4604      RETURN NULL;
4605    END IF;
4606 
4607    -- check unit effectivity status first
4608    /*OPEN get_mr_status_ue(p_unit_effectivity_id);
4609 
4610    FETCH get_mr_status_ue INTO l_mr_status_code;
4611 
4612    IF (l_mr_status_code = G_MR_STATUS_SIGNED_OFF) THEN
4613      CLOSE get_mr_status_ue;
4614      RETURN G_MR_STATUS_SIGNED_OFF;
4615    ELSIF (l_mr_status_code = G_MR_STATUS_DEFERRED) THEN
4616      CLOSE get_mr_status_ue;
4617      RETURN G_MR_STATUS_DEFERRED;
4618    ELSIF (l_mr_status_code = G_MR_STATUS_TERMINATED) THEN
4619      CLOSE get_mr_status_ue;
4620      RETURN G_MR_STATUS_TERMINATED;
4621    ELSIF (l_mr_status_code = G_MR_STATUS_CANCELLED) THEN
4622      CLOSE get_mr_status_ue;
4623      RETURN G_MR_STATUS_CANCELLED;
4624    ELSIF (l_mr_status_code = G_MR_STATUS_DEFERRAL_PENDING) THEN
4625      CLOSE get_mr_status_ue;
4626      RETURN G_MR_STATUS_DEFERRAL_PENDING;
4627    END IF;
4628 
4629    CLOSE get_mr_status_ue; */
4630 
4631    l_mr_status_code := get_ue_mr_status_code(p_unit_effectivity_id);
4632    IF l_mr_status_code IN (G_MR_STATUS_SIGNED_OFF,G_MR_STATUS_DEFERRED,
4633       G_MR_STATUS_TERMINATED,G_MR_STATUS_CANCELLED,G_MR_STATUS_DEFERRAL_PENDING)THEN
4634       RETURN l_mr_status_code;
4635    END IF;
4636 
4637    OPEN get_mr_status_csr(p_unit_effectivity_id, G_JOB_STATUS_QA_PENDING);
4638    FETCH get_mr_status_csr INTO l_mr_status_code;
4639    IF(get_mr_status_csr%FOUND)THEN
4640      CLOSE get_mr_status_csr;
4641      RETURN G_MR_STATUS_INSP_NEEDED;
4642    END IF;
4643    CLOSE get_mr_status_csr;
4644 
4645    OPEN is_mr_on_hold_csr(p_unit_effectivity_id);
4646    FETCH is_mr_on_hold_csr INTO l_mr_status_code;
4647    IF(is_mr_on_hold_csr%FOUND)THEN
4648      CLOSE is_mr_on_hold_csr;
4649      RETURN G_MR_STATUS_JOBS_ON_HOLD;
4650    END IF;
4651    CLOSE is_mr_on_hold_csr;
4652 
4653    OPEN get_mr_status_csr(p_unit_effectivity_id, G_JOB_STATUS_RELEASED);
4654    FETCH get_mr_status_csr INTO l_mr_status_code;
4655    IF(get_mr_status_csr%FOUND)THEN
4656      CLOSE get_mr_status_csr;
4657      RETURN G_MR_STATUS_RELEASED;
4658    END IF;
4659    CLOSE get_mr_status_csr;
4660 
4661    OPEN get_mr_status_csr(p_unit_effectivity_id, G_JOB_STATUS_UNRELEASED);
4662    FETCH get_mr_status_csr INTO l_mr_status_code;
4663    IF(get_mr_status_csr%FOUND)THEN
4664      l_job_status_unreleased := TRUE;
4665      --CLOSE get_mr_status_csr;
4666      --RETURN G_MR_STATUS_UNRELEASED;
4667    END IF;
4668    CLOSE get_mr_status_csr;
4669 
4670    OPEN is_mr_complete_csr(p_unit_effectivity_id);
4671    FETCH is_mr_complete_csr INTO l_mr_status_code;
4672    IF(is_mr_complete_csr%FOUND)THEN
4673      l_job_status_complete := TRUE;
4674      --CLOSE is_mr_complete_csr;
4675      --RETURN G_MR_STATUS_JOBS_COMPLETE;
4676    END IF;
4677    CLOSE is_mr_complete_csr;
4678 
4679    IF(l_job_status_unreleased AND l_job_status_complete)THEN
4680       RETURN G_MR_STATUS_RELEASED;
4681    END IF;
4682 
4683    OPEN is_mr_cancelled_csr(p_unit_effectivity_id);
4684    FETCH is_mr_cancelled_csr INTO l_mr_status_code;
4685    IF(is_mr_cancelled_csr%FOUND)THEN
4686      l_job_status_cancelled := TRUE;
4687      --CLOSE is_mr_cancelled_csr;
4688      --RETURN G_MR_STATUS_JOBS_CANCELLED;
4689    END IF;
4690    CLOSE is_mr_cancelled_csr;
4691 
4692    IF(l_job_status_unreleased AND l_job_status_cancelled)THEN
4693       RETURN G_MR_STATUS_RELEASED;
4694    END IF;
4695 
4696    IF(NOT l_job_status_unreleased) THEN
4697       IF(l_job_status_complete) THEN
4698         RETURN G_MR_STATUS_JOBS_COMPLETE;
4699       ELSIF(l_job_status_cancelled) THEN
4700         RETURN G_MR_STATUS_JOBS_CANCELLED;
4701       END IF;
4702    ELSE
4703       RETURN G_MR_STATUS_UNRELEASED;
4704    END IF;
4705    RETURN G_MR_STATUS_UNRELEASED;
4706 
4707    /*FOR l_mr_status_rec IN get_mr_status_wo(p_unit_effectivity_id) LOOP
4708      l_mr_status_code := l_mr_status_rec.status_code;
4709 
4710      IF (l_mr_status_code = G_JOB_STATUS_QA_PENDING) THEN
4711        l_job_status_qa_pending := TRUE;
4712      ELSIF (l_mr_status_code = G_JOB_STATUS_ON_HOLD) THEN
4713        l_job_status_on_hold := TRUE;
4714      ELSIF (l_mr_status_code = G_JOB_STATUS_RELEASED) THEN
4715        l_job_status_released := TRUE;
4716      ELSIF (l_mr_status_code = G_JOB_STATUS_CANCELLED) THEN
4717        l_job_status_cancelled := TRUE;
4718      ELSIF (l_mr_status_code = G_JOB_STATUS_COMPLETE) THEN
4719        l_job_status_complete := TRUE;
4720      ELSIF (l_mr_status_code = G_JOB_STATUS_UNRELEASED) THEN
4721        l_job_status_unreleased := TRUE;
4722      END IF;
4723 
4724      l_mr_status_count := l_mr_status_count + 1;
4725   END LOOP;
4726 
4727   IF(l_mr_status_count <> 0) THEN
4728   		IF ( l_mr_status_count = 1 ) THEN
4729     		IF ( l_job_status_qa_pending = TRUE ) THEN
4730       		RETURN G_MR_STATUS_INSP_NEEDED;
4731     		ELSIF (l_job_status_complete = TRUE ) THEN
4732       		RETURN G_MR_STATUS_JOBS_COMPLETE;
4733    		 ELSIF (l_job_status_released = TRUE ) THEN
4734       		RETURN G_MR_STATUS_RELEASED;
4735     		ELSIF (l_job_status_unreleased = TRUE ) THEN
4736       		RETURN G_MR_STATUS_UNRELEASED;
4737    		 ELSIF (l_job_status_cancelled = TRUE ) THEN
4738       		RETURN G_MR_STATUS_JOBS_CANCELLED;
4739     		ELSIF (l_job_status_on_hold = TRUE ) THEN
4740       		RETURN G_MR_STATUS_JOBS_ON_HOLD;
4741     		ELSE
4742       		-- Default return status if no match found.
4743      		 RETURN G_MR_STATUS_RELEASED;
4744     		END IF;
4745  		 END IF;
4746 
4747   		IF ( l_job_status_qa_pending = TRUE ) THEN
4748     		RETURN G_MR_STATUS_INSP_NEEDED;
4749   		ELSIF ( l_job_status_on_hold = TRUE ) THEN
4750     		RETURN G_MR_STATUS_JOBS_ON_HOLD;
4751   		ELSIF ( l_job_status_released = TRUE ) THEN
4752     		RETURN G_MR_STATUS_RELEASED;
4753  		 ELSIF ( l_job_status_unreleased = FALSE AND
4754           l_job_status_complete = TRUE AND
4755           l_job_status_cancelled = TRUE ) THEN
4756     		RETURN G_MR_STATUS_JOBS_COMPLETE;
4757   		ELSE
4758     		-- Default return status if no match found.
4759     		RETURN G_MR_STATUS_RELEASED;
4760  		 END IF;
4761 		ELSE -- l_mr_status_count == 0
4762 		  OPEN get_status_unassoc(p_unit_effectivity_id);
4763 				FETCH get_status_unassoc INTO l_mr_status_code;
4764 				CLOSE get_status_unassoc;
4765 
4766 					IF (l_mr_status_code = G_JOB_STATUS_QA_PENDING) THEN
4767        RETURN G_MR_STATUS_INSP_NEEDED;
4768      ELSIF (l_mr_status_code = G_JOB_STATUS_COMPLETE) THEN
4769        RETURN G_MR_STATUS_JOBS_COMPLETE;
4770      ELSIF (l_mr_status_code = G_JOB_STATUS_RELEASED) THEN
4771        	RETURN G_MR_STATUS_RELEASED;
4772 					ELSIF (l_mr_status_code = G_JOB_STATUS_UNRELEASED) THEN
4773        	RETURN G_MR_STATUS_UNRELEASED;
4774      ELSIF (l_mr_status_code = G_JOB_STATUS_CANCELLED) THEN
4775        	RETURN G_MR_STATUS_JOBS_CANCELLED;
4776      ELSIF (l_mr_status_code = G_JOB_STATUS_ON_HOLD) THEN
4777        RETURN G_MR_STATUS_JOBS_ON_HOLD;
4778 					ELSE
4779 					   OPEN get_status_top_level_sr(p_unit_effectivity_id);
4780         FETCH  get_status_top_level_sr INTO l_mr_status_code;
4781 								CLOSE get_status_top_level_sr;
4782 								IF (l_mr_status_code = G_JOB_STATUS_QA_PENDING) THEN
4783        RETURN G_MR_STATUS_INSP_NEEDED;
4784      ELSIF (l_mr_status_code = G_JOB_STATUS_COMPLETE) THEN
4785        RETURN G_MR_STATUS_JOBS_COMPLETE;
4786      ELSIF (l_mr_status_code = G_JOB_STATUS_RELEASED) THEN
4787        	RETURN G_MR_STATUS_RELEASED;
4788 					ELSIF (l_mr_status_code = G_JOB_STATUS_UNRELEASED) THEN
4789        	RETURN G_MR_STATUS_UNRELEASED;
4790      ELSIF (l_mr_status_code = G_JOB_STATUS_CANCELLED) THEN
4791        	RETURN G_MR_STATUS_JOBS_CANCELLED;
4792      ELSIF (l_mr_status_code = G_JOB_STATUS_ON_HOLD) THEN
4793        RETURN G_MR_STATUS_JOBS_ON_HOLD;
4794 					ELSE
4795 
4796 
4797      			-- Default return status if no match found.
4798      		 RETURN G_MR_STATUS_RELEASED;
4799 					END IF;
4800      END IF;
4801    END IF;*/
4802 
4803 END get_mr_status;
4804 -- Function to validate the Inputs of the signoff_mr_instance API
4805 FUNCTION validate_smri_inputs
4806 (
4807   p_signoff_mr_rec          IN   signoff_mr_rec_type
4808 ) RETURN VARCHAR2
4809 IS
4810 
4811 BEGIN
4812 
4813   IF ( p_signoff_mr_rec.unit_effectivity_id = FND_API.G_MISS_NUM OR
4814        p_signoff_mr_rec.unit_effectivity_id IS NULL OR
4815        p_signoff_mr_rec.object_version_number = FND_API.G_MISS_NUM OR
4816        p_signoff_mr_rec.object_version_number IS NULL ) THEN
4817     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_SMRI_INPUTS' );
4818     FND_MSG_PUB.add;
4819     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4820   END IF;
4821 
4822   IF ( p_signoff_mr_rec.signoff_child_mrs_flag IS NULL OR
4823        p_signoff_mr_rec.signoff_child_mrs_flag = FND_API.G_MISS_CHAR OR
4824        ( p_signoff_mr_rec.signoff_child_mrs_flag <> 'Y' AND
4825          p_signoff_mr_rec.signoff_child_mrs_flag <> 'N' ) ) THEN
4826     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_SIGNOFF_CHILD_MR_FLAG' );
4827     FND_MSG_PUB.add;
4828     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4829   END IF;
4830 
4831   IF ( p_signoff_mr_rec.complete_job_ops_flag IS NULL OR
4832        p_signoff_mr_rec.complete_job_ops_flag = FND_API.G_MISS_CHAR OR
4833        ( p_signoff_mr_rec.complete_job_ops_flag <> 'Y' AND
4834          p_signoff_mr_rec.complete_job_ops_flag <> 'N' ) ) THEN
4835     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CMPL_JOB_OPS_FLAG' );
4836     FND_MSG_PUB.add;
4837     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4838   END IF;
4839 
4840   IF ( p_signoff_mr_rec.transact_resource_flag IS NULL OR
4841        p_signoff_mr_rec.transact_resource_flag = FND_API.G_MISS_CHAR OR
4842        ( p_signoff_mr_rec.transact_resource_flag <> 'Y' AND
4843          p_signoff_mr_rec.transact_resource_flag <> 'N' ) ) THEN
4844     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_TRANSACT_RES_FLAG' );
4845     FND_MSG_PUB.add;
4846     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4847   END IF;
4848 
4849   IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' AND
4850        ( p_signoff_mr_rec.default_actual_dates_flag IS NULL OR
4851          p_signoff_mr_rec.default_actual_dates_flag = FND_API.G_MISS_CHAR OR
4852          ( p_signoff_mr_rec.default_actual_dates_flag <> 'Y' AND
4853            p_signoff_mr_rec.default_actual_dates_flag <> 'N' ) ) ) THEN
4854     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_DEFAULT_ACT_DTS_FLAG' );
4855     FND_MSG_PUB.add;
4856     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4857   END IF;
4858 
4859   IF ( p_signoff_mr_rec.transact_resource_flag = 'Y' AND
4860        ( p_signoff_mr_rec.employee_number IS NULL OR
4861          p_signoff_mr_rec.employee_number = FND_API.G_MISS_CHAR ) AND
4862        ( p_signoff_mr_rec.serial_number IS NULL OR
4863          p_signoff_mr_rec.serial_number = FND_API.G_MISS_CHAR ) ) THEN
4864     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_TRANSACT_RES_INPUTS' );
4865     FND_MSG_PUB.add;
4866     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4867   END IF;
4868 
4869   IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' AND
4870        p_signoff_mr_rec.default_actual_dates_flag = 'N' AND
4871        ( p_signoff_mr_rec.actual_start_date IS NULL OR
4872          p_signoff_mr_rec.actual_start_date = FND_API.G_MISS_DATE OR
4873          p_signoff_mr_rec.actual_end_date IS NULL OR
4874          p_signoff_mr_rec.actual_end_date = FND_API.G_MISS_DATE ) ) THEN
4875     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_ACTUAL_DTS_MISSING' );
4876     FND_MSG_PUB.add;
4877     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4878   END IF;
4879 
4880   IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' AND
4881        p_signoff_mr_rec.default_actual_dates_flag = 'N' AND
4882        p_signoff_mr_rec.actual_end_date < p_signoff_mr_rec.actual_start_date ) THEN
4883     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_ST_DT_END_DT' );
4884     FND_MSG_PUB.add;
4885     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4886   END IF;
4887 
4888   IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' AND
4889        p_signoff_mr_rec.default_actual_dates_flag = 'N' AND
4890        p_signoff_mr_rec.actual_end_date > SYSDATE ) THEN
4891     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_END_DT_SYSDATE' );
4892     FND_MSG_PUB.add;
4893     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4894   END IF;
4895 
4896   RETURN FND_API.G_RET_STS_SUCCESS;
4897 END validate_smri_inputs;
4898 
4899 -- Function to validate the Inputs of the close_visit API
4900 FUNCTION validate_cv_inputs
4901 (
4902   p_close_visit_rec          IN   close_visit_rec_type
4903 ) RETURN VARCHAR2
4904 IS
4905 -- rroy
4906 -- ACL Changes
4907 CURSOR get_Wo_details(c_visit_id NUMBER)
4908 IS
4909 SELECT workorder_id,
4910 workorder_name
4911 FROM AHL_WORKORDERS
4912 WHERE visit_id = c_visit_id
4913 AND MASTER_WORKORDER_FLAG = 'N';
4914 
4915 CURSOR get_ue_title(p_workorder_id NUMBER)
4916 IS
4917 SELECT
4918     UE.title
4919 FROM
4920     ahl_workorders WO,
4921     ahl_visit_tasks_b VTSK,
4922     ahl_unit_effectivities_v UE
4923 WHERE
4924     WO.workorder_id = p_workorder_id
4925 		AND VTSK.visit_task_id = WO.visit_task_id
4926 		AND UE.unit_effectivity_id = VTSK.unit_effectivity_id;
4927 l_return_status VARCHAR2(1);
4928 l_ue_title      VARCHAR2(80);
4929 -- rroy
4930 -- ACL Changes
4931 
4932 BEGIN
4933 
4934   IF ( p_close_visit_rec.visit_id = FND_API.G_MISS_NUM OR
4935        p_close_visit_rec.visit_id IS NULL OR
4936        p_close_visit_rec.object_version_number = FND_API.G_MISS_NUM OR
4937        p_close_visit_rec.object_version_number IS NULL ) THEN
4938     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INVALID_CV_INPUTS' );
4939     FND_MSG_PUB.add;
4940     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4941   END IF;
4942 
4943 		-- rroy
4944 		-- ACL Changes
4945 		FOR wo_details IN get_wo_Details(p_close_visit_rec.visit_id) LOOP
4946 				l_return_status := AHL_PRD_UTIL_PKG.Is_Unit_Locked(wo_details.workorder_id, NULL, NULL, NULL);
4947 				IF l_return_status = FND_API.G_TRUE THEN
4948 						OPEN get_ue_title(wo_details.workorder_id);
4949 						FETCH get_ue_title INTO l_ue_title;
4950 						CLOSE get_ue_title;
4951 						FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_CV_UNTLCKD');
4952 						FND_MESSAGE.Set_Token('MR_TITLE', l_ue_title);
4953 						FND_MSG_PUB.ADD;
4954 						RETURN FND_API.G_RET_STS_ERROR;
4955 				END IF;
4956 		END LOOP;
4957 		-- rroy
4958 		-- ACL Changes
4959 
4960 
4961   IF ( p_close_visit_rec.signoff_mrs_flag IS NULL OR
4962        p_close_visit_rec.signoff_mrs_flag = FND_API.G_MISS_CHAR OR
4963        ( p_close_visit_rec.signoff_mrs_flag <> 'Y' AND
4964          p_close_visit_rec.signoff_mrs_flag <> 'N' ) ) THEN
4965     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_SIGNOFF_CHILD_MR_FLAG' );
4966     FND_MSG_PUB.add;
4967     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4968   END IF;
4969 
4970   IF ( p_close_visit_rec.complete_job_ops_flag IS NULL OR
4971        p_close_visit_rec.complete_job_ops_flag = FND_API.G_MISS_CHAR OR
4972        ( p_close_visit_rec.complete_job_ops_flag <> 'Y' AND
4973          p_close_visit_rec.complete_job_ops_flag <> 'N' ) ) THEN
4974     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CMPL_JOB_OPS_FLAG' );
4975     FND_MSG_PUB.add;
4976     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4977   END IF;
4978 
4979   IF ( p_close_visit_rec.transact_resource_flag IS NULL OR
4980        p_close_visit_rec.transact_resource_flag = FND_API.G_MISS_CHAR OR
4981        ( p_close_visit_rec.transact_resource_flag <> 'Y' AND
4982          p_close_visit_rec.transact_resource_flag <> 'N' ) ) THEN
4983     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_TRANSACT_RES_FLAG' );
4984     FND_MSG_PUB.add;
4985     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4986   END IF;
4987 
4988   IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' AND
4989        ( p_close_visit_rec.default_actual_dates_flag IS NULL OR
4990          p_close_visit_rec.default_actual_dates_flag = FND_API.G_MISS_CHAR OR
4991          ( p_close_visit_rec.default_actual_dates_flag <> 'Y' AND
4992            p_close_visit_rec.default_actual_dates_flag <> 'N' ) ) ) THEN
4993     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_DEFAULT_ACT_DTS_FLAG' );
4994     FND_MSG_PUB.add;
4995     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
4996   END IF;
4997 
4998   IF ( p_close_visit_rec.transact_resource_flag = 'Y' AND
4999        ( p_close_visit_rec.employee_number IS NULL OR
5000          p_close_visit_rec.employee_number = FND_API.G_MISS_CHAR ) AND
5001        ( p_close_visit_rec.serial_number IS NULL OR
5002          p_close_visit_rec.serial_number = FND_API.G_MISS_CHAR ) ) THEN
5003     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_TRANSACT_RES_INPUTS' );
5004     FND_MSG_PUB.add;
5005     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
5006   END IF;
5007 
5008   IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' AND
5009        p_close_visit_rec.default_actual_dates_flag = 'N' AND
5010        ( p_close_visit_rec.actual_start_date IS NULL OR
5011          p_close_visit_rec.actual_start_date = FND_API.G_MISS_DATE OR
5012          p_close_visit_rec.actual_end_date IS NULL OR
5013          p_close_visit_rec.actual_end_date = FND_API.G_MISS_DATE ) ) THEN
5014     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_ACTUAL_DTS_MISSING' );
5015     FND_MSG_PUB.add;
5016     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
5017   END IF;
5018 
5019   IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' AND
5020        p_close_visit_rec.default_actual_dates_flag = 'N' AND
5021        p_close_visit_rec.actual_end_date < p_close_visit_rec.actual_start_date ) THEN
5022     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_ST_DT_END_DT' );
5023     FND_MSG_PUB.add;
5024     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
5025   END IF;
5026 
5027   IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' AND
5028        p_close_visit_rec.default_actual_dates_flag = 'N' AND
5029        p_close_visit_rec.actual_end_date > SYSDATE ) THEN
5030     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_END_DT_SYSDATE' );
5031     FND_MSG_PUB.add;
5032     RETURN FND_API.G_RET_STS_UNEXP_ERROR;
5033   END IF;
5034 
5035   RETURN FND_API.G_RET_STS_SUCCESS;
5036 END validate_cv_inputs;
5037 
5038 FUNCTION update_mwo_actual_dates
5039 (
5040   p_wip_entity_id     IN NUMBER,
5041   p_default_flag      IN VARCHAR2,
5042   p_actual_start_date IN DATE,
5043   p_actual_end_date   IN DATE
5044 ) RETURN VARCHAR2
5045 IS
5046 
5047 -- To get the Child Workorder Details for a Master WO
5048 CURSOR     get_child_wos( c_wip_entity_id NUMBER ) IS
5049 SELECT     CWO.workorder_id workorder_id,
5050            CWO.object_version_number object_version_number,
5051            CWO.workorder_name workorder_name,
5052            CWO.wip_entity_id wip_entity_id,
5053            REL.parent_object_id parent_object_id,
5054            CWO.actual_start_date actual_start_date,
5055            CWO.actual_end_date actual_end_date,
5056            CWO.status_code status_code,
5057            CWO.master_workorder_flag master_workorder_flag
5058 FROM       AHL_WORKORDERS CWO,
5059            WIP_SCHED_RELATIONSHIPS REL
5060 WHERE      CWO.wip_entity_id = REL.child_object_id
5061 AND        CWO.status_code <> G_JOB_STATUS_DELETED
5062 AND        REL.parent_object_type_id = 1
5063 AND        REL.child_object_type_id = 1
5064 START WITH REL.parent_object_id = c_wip_entity_id
5065 AND        REL.relationship_type = 1
5066 CONNECT BY REL.parent_object_id = PRIOR REL.child_object_id
5067 AND        REL.relationship_type = 1
5068 ORDER BY   level DESC;
5069 
5070 
5071 TYPE child_wo_rec_type IS RECORD
5072 (
5073   parent_object_id           NUMBER,
5074   actual_start_date          DATE,
5075   actual_end_date            DATE
5076 
5077 );
5078 
5079 TYPE child_wo_tbl_type IS TABLE OF child_wo_rec_type INDEX BY BINARY_INTEGER;
5080 
5081 l_workorder_tbl     child_wo_tbl_type;
5082 l_ctr               NUMBER := 0;
5083 
5084 l_api_name               VARCHAR2(30) := 'update_mwo_actual_dates';
5085 l_min               DATE;
5086 l_max               DATE;
5087 
5088 BEGIN
5089 
5090   -- Get the Child Workorders for the Visit
5091   FOR wo_csr IN get_child_wos( p_wip_entity_id ) LOOP
5092 
5093     l_ctr := l_ctr + 1;
5094     l_workorder_tbl(l_ctr).parent_object_id := wo_csr.parent_object_id;
5095 
5096     IF ( G_DEBUG = 'Y' ) THEN
5097       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Getting ' || l_ctr || ' th WO of Visit - ' || wo_csr.workorder_name );
5098     END IF;
5099 
5100     -- Check if Incomplete Master Workorder
5101     IF ( wo_csr.master_workorder_flag = 'Y' AND
5102          wo_csr.status_code <> G_JOB_STATUS_COMPLETE AND
5103          wo_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
5104          wo_csr.status_code <> G_JOB_STATUS_CLOSED AND
5105          wo_csr.status_code <> G_JOB_STATUS_CANCELLED ) THEN
5106 
5107       IF ( G_DEBUG = 'Y' ) THEN
5108         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : This is a Master Workorder ' );
5109       END IF;
5110 
5111       -- Since Master Workorders are obtained after the child Workorders
5112       -- It is enough to iterate through these child Workorders obtained
5113       -- in the previous iterations
5114       FOR i IN l_workorder_tbl.FIRST..l_workorder_tbl.LAST LOOP
5115 
5116         -- Check if the Master WO is the parent of the current Wo
5117         IF ( l_workorder_tbl(i).parent_object_id = wo_csr.wip_entity_id ) THEN
5118 
5119           -- Store the Least value of the children in the Actual Start Date
5120           IF l_workorder_tbl(i).actual_start_date IS NOT NULL
5121           THEN
5122             l_workorder_tbl(l_ctr).actual_start_date := LEAST( NVL( l_workorder_tbl(l_ctr).actual_start_date,
5123           		                                            l_workorder_tbl(i).actual_start_date ),
5124           		                                            l_workorder_tbl(i).actual_start_date );
5125           END IF;
5126 
5127 	  -- Store the Greatest value of the children in the Actual End Date
5128 	  IF l_workorder_tbl(i).actual_end_date IS NOT NULL
5129 	  THEN
5130             l_workorder_tbl(l_ctr).actual_end_date := GREATEST( NVL( l_workorder_tbl(l_ctr).actual_end_date,
5131           		                                             l_workorder_tbl(i).actual_end_date ),
5132           			                                     l_workorder_tbl(i).actual_end_date );
5133           END IF;
5134         END IF;
5135       END LOOP;
5136 
5137       -- Ensure that the actual start date entered is less than the Master Wo
5138       /*Start ER # 4757222
5139       IF ( p_actual_start_date IS NOT NULL AND
5140            l_workorder_tbl(l_ctr).actual_start_date < p_actual_start_date ) THEN
5141         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_ST_DATE_LESS' );
5142         FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
5143         FND_MESSAGE.set_token( 'START_DT',
5144         TO_CHAR( l_workorder_tbl(l_ctr).actual_start_date , 'DD-MON-YYYY HH24:MI' ) );
5145         FND_MSG_PUB.add;
5146         RAISE FND_API.G_EXC_ERROR;
5147       END IF;
5148 
5149       -- Ensure the actual end date entered is greater than the Master Wo
5150       IF ( p_actual_end_date IS NOT NULL AND
5151            l_workorder_tbl(l_ctr).actual_end_date > p_actual_end_date ) THEN
5152         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_END_DATE_GT' );
5153         FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
5154         FND_MESSAGE.set_token( 'END_DT',
5155          TO_CHAR( l_workorder_tbl(l_ctr).actual_end_date , 'DD-MON-YYYY HH24:MI' ) );
5156         FND_MSG_PUB.add;
5157         RAISE FND_API.G_EXC_ERROR;
5158       END IF;
5159       */--End ER # 4757222
5160 
5161       IF ( G_DEBUG = 'Y' ) THEN
5162         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
5163         || ' : Calculated ACtual Start Date - '
5164         || to_char( l_workorder_tbl(l_ctr).actual_start_date, 'DD-MON-YYYY HH24:MI' )
5165         || ' Calculated Actual End Date - '
5166         || to_char( l_workorder_tbl(l_ctr).actual_end_date, 'DD-MON-YYYY HH24:MI' ) );
5167       END IF;
5168 
5169 
5170       BEGIN
5171 
5172         UPDATE  AHL_WORKORDERS
5173         SET     object_version_number = object_version_number + 1,
5174                 actual_start_date = l_workorder_tbl(l_ctr).actual_start_date,
5175                 actual_end_date = l_workorder_tbl(l_ctr).actual_end_date
5176         WHERE   workorder_id = wo_csr.workorder_id
5177         AND     object_version_number = wo_csr.object_version_number;
5178 
5179         IF ( SQL%ROWCOUNT = 0 ) THEN
5180           FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
5181           FND_MSG_PUB.add;
5182           RETURN FND_API.G_RET_STS_ERROR;
5183         END IF;
5184       EXCEPTION
5185         WHEN OTHERS THEN
5186           FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
5187           FND_MSG_PUB.add;
5188           RETURN FND_API.G_RET_STS_UNEXP_ERROR;
5189       END;
5190 
5191     ELSE
5192 
5193       IF ( G_DEBUG = 'Y' ) THEN
5194         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Storing ACtual Start Date of Child - ' || to_char( wo_csr.actual_start_date, 'DD-MON-YYYY HH24:MI' ) || ' Actual End Date' || to_char( wo_csr.actual_end_date, 'DD-MON-YYYY HH24:MI' ) );
5195       END IF;
5196 
5197       -- Store the Child Wo or Complete Master Wo Actual Dates as it is
5198       l_workorder_tbl(l_ctr).actual_start_date := wo_csr.actual_start_date;
5199       l_workorder_tbl(l_ctr).actual_end_date := wo_csr.actual_end_date;
5200     END IF;
5201 
5202   END LOOP;
5203 
5204    /*Start ER # 4757222*/
5205    --Update master workorder record.If all
5206    --IF p_default_flag = 'Y' THEN
5207    -- Master workorder dates will no longer be defaulted from user entered dates as per
5208    -- the ER # . Master workorder actual dates will be derived from its child workorders
5209    -- if not present already.
5210    /*End ER # 4757222*/
5211      l_min := null;
5212      l_max := NULL;
5213      --l_max := sysdate;
5214 
5215      FOR wo_csr IN get_child_wos( p_wip_entity_id ) LOOP
5216      	IF wo_csr.actual_start_date IS NOT NULL
5217      	THEN
5218        		l_min := least(nvl(l_min, wo_csr.actual_start_date), wo_csr.actual_start_date);
5219        	END IF;
5220 
5221        	IF wo_csr.actual_end_date IS NOT NULL
5222        	THEN
5223         	l_max := greatest(nvl(l_max, wo_csr.actual_end_date), wo_csr.actual_end_date);
5224         END IF;
5225      END LOOP;
5226 
5227    /*Start ER # 4757222*/
5228    /*ELSE
5229    	l_min := p_actual_start_date;
5230    	l_max := p_actual_end_date;
5231    END IF;*/
5232    /*End ER # 4757222*/
5233 
5234    UPDATE  AHL_WORKORDERS
5235       SET object_version_number = object_version_number + 1,
5236       actual_start_date = l_min,
5237       actual_end_date = l_max
5238    WHERE   wip_entity_id = p_wip_entity_id;
5239 
5240 
5241   RETURN FND_API.G_RET_STS_SUCCESS;
5242 
5243 END update_mwo_actual_dates;
5244 
5245 FUNCTION complete_visit_mr_wos
5246 (
5247   p_wip_entity_id     IN            NUMBER, -- Visit or MR WO
5248   p_x_workorder_tbl   IN OUT NOCOPY workorder_tbl_type
5249 ) RETURN VARCHAR2
5250 IS
5251 
5252 -- To get all the completion dependencies in a Visit
5253 CURSOR  get_visit_dependencies( c_wip_entity_id NUMBER )
5254 IS
5255 SELECT  WO.wip_entity_id parent_we_id,
5256         WO.workorder_name parent_wo_name,
5257         DECODE( WO.status_code,
5258                 G_JOB_STATUS_COMPLETE, G_JOB_STATUS_COMPLETE,
5259                 G_JOB_STATUS_COMPLETE_NC, G_JOB_STATUS_COMPLETE,
5260                 G_JOB_STATUS_CLOSED, G_JOB_STATUS_COMPLETE,
5261                 G_JOB_STATUS_CANCELLED, G_JOB_STATUS_COMPLETE,
5262                 G_JOB_STATUS_DELETED, G_JOB_STATUS_COMPLETE,
5263                 WO.status_code ) parent_status_code,
5264         WOR.child_object_id child_we_id
5265 FROM    AHL_WORKORDERS WO,
5266         WIP_SCHED_RELATIONSHIPS WOR
5267 WHERE   WO.wip_entity_id = WOR.parent_object_id
5268 AND     WOR.top_level_object_id = c_wip_entity_id
5269 AND     WOR.relationship_type = 2
5270 AND     WOR.parent_object_type_id = 1
5271 AND     WOR.child_object_type_id = 1;
5272 
5273 TYPE parent_wo_rec_type IS RECORD
5274 (
5275   parent_we_id               NUMBER,
5276   parent_wo_name             VARCHAR2(80),
5277   parent_status_code         VARCHAR2(30),
5278   child_we_id                NUMBER
5279 );
5280 
5281 TYPE parent_wo_tbl_type IS TABLE OF parent_wo_rec_type INDEX BY BINARY_INTEGER;
5282 
5283 -- To hold the completion parent records.
5284 l_parent_wo_tbl  parent_wo_tbl_type;
5285 l_ctr            NUMBER := 0;
5286 
5287 -- To hold the number of iterations processed for completing WOs
5288 l_iteration_ctr  NUMBER := 0;
5289 
5290 -- To check if a Workorder is within the Visit or MR Hierarchy
5291 l_wo_found       BOOLEAN := FALSE;
5292 
5293 -- To check if all the Workorders in a Visit or MR are complete
5294 l_all_wos_cmpl   BOOLEAN := TRUE;
5295 
5296 -- To check whether a completion parent is complete or non-existant.
5297 l_parent_wo_cmpl BOOLEAN := TRUE;
5298 
5299 l_return_status  VARCHAR2(1);
5300 l_msg_count      NUMBER;
5301 l_msg_data       VARCHAR2(2000);
5302 
5303 l_api_name               VARCHAR2(30) := 'complete_visit_mr_wos';
5304 BEGIN
5305 
5306   IF ( G_DEBUG = 'Y' ) THEN
5307     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Getting Visit Dependencies' );
5308   END IF;
5309 
5310   -- Get all the completion dependencies in a Visit
5311   FOR parent_csr IN get_visit_dependencies( p_wip_entity_id ) LOOP
5312     l_ctr := l_ctr + 1;
5313     l_parent_wo_tbl(l_ctr).parent_we_id := parent_csr.parent_we_id;
5314     l_parent_wo_tbl(l_ctr).parent_wo_name := parent_csr.parent_wo_name;
5315     l_parent_wo_tbl(l_ctr).parent_status_code := parent_csr.parent_status_code;
5316     l_parent_wo_tbl(l_ctr).child_we_id := parent_csr.child_we_id;
5317   END LOOP;
5318 
5319   -- There are no Completion Dependencies.
5320   IF ( l_parent_wo_tbl.COUNT = 0 ) THEN
5321 
5322     IF ( G_DEBUG = 'Y' ) THEN
5323       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Completion Dependencies do not exist' );
5324     END IF;
5325 
5326     -- Complete all Workorders
5327     FOR i IN p_x_workorder_tbl.FIRST..p_x_workorder_tbl.LAST LOOP
5328 
5329       -- Complete only Child Workorders because
5330       -- Master Workorders are completed automatically
5331       IF ( p_x_workorder_tbl(i).master_workorder_flag = 'N' ) THEN
5332 
5333         IF ( G_DEBUG = 'Y' ) THEN
5334           AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Completing Workorder - ' || p_x_workorder_tbl(i).workorder_name || ' ID - ' || p_x_workorder_tbl(i).workorder_id );
5335         END IF;
5336 
5337         complete_workorder
5338         (
5339           p_api_version            => 1.0,
5340           p_init_msg_list          => FND_API.G_FALSE,
5341           p_commit                 => FND_API.G_FALSE,
5342           p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
5343           p_default                => FND_API.G_FALSE,
5344           p_module_type            => NULL,
5345           x_return_status          => l_return_status,
5346           x_msg_count              => l_msg_count,
5347           x_msg_data               => l_msg_data,
5348           p_workorder_id           => p_x_workorder_tbl(i).workorder_id,
5349           p_object_version_no      => p_x_workorder_tbl(i).object_version_number
5350         );
5351 
5352         IF ( l_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
5353           RETURN l_return_status;
5354         END IF;
5355 
5356       END IF;
5357 
5358     END LOOP;
5359 
5360   ELSE
5361 
5362     IF ( G_DEBUG = 'Y' ) THEN
5363       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Completion Dependencies exist' );
5364     END IF;
5365 
5366     -- Since Completion dependencies exist multiple iterations may be
5367     -- required for completing the Visit or MR Workorders
5368     -- Break out when all the Wos of the Visit or MR are complete
5369     WHILE TRUE LOOP
5370 
5371       IF ( G_DEBUG = 'Y' ) THEN
5372         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Begin Iteration - ' || l_iteration_ctr );
5373       END IF;
5374 
5375       -- Increment Iteration counter
5376       l_iteration_ctr := l_iteration_ctr + 1;
5377 
5378       -- Reset for Every Iteration of the Input Wo Table
5379       l_all_wos_cmpl := TRUE;
5380 
5381       -- Process Completion Dependencies
5382       -- Iterate Through all the Child Wos in the input Wo table
5383       FOR i IN p_x_workorder_tbl.FIRST..p_x_workorder_tbl.LAST LOOP
5384 
5385         -- Check if a Wo needs to be completed
5386         -- Ignore Master Workorders since they are completed automatically
5387         IF ( p_x_workorder_tbl(i).master_workorder_flag = 'N' AND
5388              NVL(p_x_workorder_tbl(i).status_code,'X') <> NVL(G_JOB_STATUS_COMPLETE,'Y') ) THEN
5389 
5390           IF ( G_DEBUG = 'Y' ) THEN
5391             AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Need to Complete WO - ' || p_x_workorder_tbl(i).workorder_name );
5392           END IF;
5393 
5394           -- Reset for Every Iteration of a Child Workorder
5395           l_parent_wo_cmpl := TRUE;
5396 
5397           -- Iterate through the Parent Workorders
5398           FOR j IN l_parent_wo_tbl.FIRST..l_parent_wo_tbl.LAST LOOP
5399 
5400             -- Matching Parent
5401             IF ( l_parent_wo_tbl(j).child_we_id = p_x_workorder_tbl(i).wip_entity_id ) THEN
5402               -- Parent not Complete
5403               IF ( l_parent_wo_tbl(j).parent_status_code <> G_JOB_STATUS_COMPLETE ) THEN
5404                 -- Set Parent Wo as not Complete
5405                 l_parent_wo_cmpl := FALSE;
5406 
5407                 -- Since the Parent is not Complete more iterations are reqd
5408                 l_all_wos_cmpl := FALSE;
5409 
5410                 -- Check if Parent exists in the Hierarchy for first iteration
5411                 IF ( l_iteration_ctr = 1 ) THEN
5412 
5413                   -- Iterate through the Visit or MR Workorders
5414                   FOR x IN p_x_workorder_tbl.FIRST..p_x_workorder_tbl.LAST LOOP
5415 
5416                     -- Parent exists in the Visit or MR Hierarchy
5417                     IF ( l_parent_wo_tbl(j).parent_we_id = p_x_workorder_tbl(x).wip_entity_id ) THEN
5418                       l_wo_found := TRUE;
5419                       EXIT;
5420                     END IF;
5421                   END LOOP;
5422 
5423                   IF ( l_wo_found = TRUE ) THEN
5424                     l_wo_found := FALSE;
5425                     EXIT;
5426                   ELSE
5427 
5428                     -- Error out since the Visit or the MR cannot be completed
5429                     -- as the Parent is outside the Hierarchy
5430                     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_PARENT_WO_NOT_CMPL' );
5431                     FND_MESSAGE.set_token( 'WO', p_x_workorder_tbl(i).workorder_name );
5432                     FND_MESSAGE.set_token( 'PARENT_WO', l_parent_wo_tbl(j).parent_wo_name );
5433                     FND_MSG_PUB.add;
5434                     RETURN FND_API.G_RET_STS_ERROR;
5435                   END IF; -- Hierarchy check
5436                 END IF; -- First Iteration
5437               END IF; -- Parent WOs complete check
5438             END IF; -- Match Parent check
5439 
5440             -- If any Parent is not complete then the Wo cannot be completed
5441             -- Break out of the iterate parents loop
5442             IF ( l_parent_wo_cmpl = FALSE ) THEN
5443 
5444               IF ( G_DEBUG = 'Y' ) THEN
5445                 AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Workorder cannot be completed in this iteration because one or more parents are not complete ' );
5446               END IF;
5447 
5448               EXIT;
5449             END IF;
5450 
5451           END LOOP; -- Match Iterate Parents Loop;
5452 
5453           -- All the Parents of a child WO are complete
5454           IF ( l_parent_wo_cmpl = TRUE ) THEN
5455 
5456             IF ( G_DEBUG = 'Y' ) THEN
5457               AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Workorder can be completed in this iteration because all parents are complete ' );
5458             END IF;
5459 
5460             -- Complete the Child Workorder
5461             complete_workorder
5462             (
5463               p_api_version            => 1.0,
5464               p_init_msg_list          => FND_API.G_FALSE,
5465               p_commit                 => FND_API.G_FALSE,
5466               p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
5467               p_default                => FND_API.G_FALSE,
5468               p_module_type            => NULL,
5469               x_return_status          => l_return_status,
5470               x_msg_count              => l_msg_count,
5471               x_msg_data               => l_msg_data,
5472               p_workorder_id           => p_x_workorder_tbl(i).workorder_id,
5473               p_object_version_no      => p_x_workorder_tbl(i).object_version_number
5474             );
5475 
5476             IF ( l_return_status <> FND_API.G_RET_STS_SUCCESS ) THEN
5477               RETURN l_return_status;
5478             END IF;
5479 
5480             -- Set the Workorder status as Complete for next iteration
5481             p_x_workorder_tbl(i).status_code := G_JOB_STATUS_COMPLETE;
5482 
5483             -- Iterate through the Parents for setting Wo Status as Complete
5484             FOR y IN l_parent_wo_tbl.FIRST..l_parent_wo_tbl.LAST LOOP
5485               IF ( l_parent_wo_tbl(y).parent_we_id = p_x_workorder_tbl(i).wip_entity_id ) THEN
5486                 -- Set the Workorder status as Complete wherever it is a Parent
5487                 l_parent_wo_tbl(y).parent_status_code := G_JOB_STATUS_COMPLETE;
5488               END IF;
5489             END LOOP; -- Match Update Parent Status Loop
5490 
5491           END IF; -- Match Parent Complete check
5492 
5493         END IF; -- Match Complete Wos check
5494 
5495       END LOOP; -- Match Child Wos Loop
5496 
5497       -- If all the Wos of the Visit or MR are complete in this iteration
5498       -- Break out of the outermost loop
5499       IF ( l_all_wos_cmpl = TRUE ) THEN
5500         IF ( G_DEBUG = 'Y' ) THEN
5501           AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : All Workorders are completed in this iteration ' );
5502         END IF;
5503 
5504         EXIT;
5505       END IF;
5506 
5507     END LOOP; -- Match While loop of outermost Iteration
5508 
5509   END IF; -- Match Completion dependencies existence check
5510 
5511   RETURN FND_API.G_RET_STS_SUCCESS;
5512 
5513 END complete_visit_mr_wos;
5514 
5515 PROCEDURE signoff_mr_instance
5516 (
5517   p_api_version      IN         NUMBER        := 1.0,
5518   p_init_msg_list    IN         VARCHAR2      := FND_API.G_TRUE,
5519   p_commit           IN         VARCHAR2      := FND_API.G_FALSE,
5520   p_validation_level IN         NUMBER        := FND_API.G_VALID_LEVEL_FULL,
5521   p_default          IN         VARCHAR2      := FND_API.G_FALSE,
5522   p_module_type      IN         VARCHAR2      := NULL,
5523   x_return_status    OUT NOCOPY VARCHAR2,
5524   x_msg_count        OUT NOCOPY NUMBER,
5525   x_msg_data         OUT NOCOPY VARCHAR2,
5526   p_signoff_mr_rec   IN         signoff_mr_rec_type
5527 )
5528 IS
5529 
5530 l_api_name               VARCHAR2(30) := 'signoff_mr_instance';
5531 l_return_status          VARCHAR2(1);
5532 l_msg_count              NUMBER;
5533 l_msg_data               VARCHAR2(2000);
5534 l_status_meaning        VARCHAR2(80);
5535 l_actual_end_date DATE;
5536 l_actual_start_date DATE;
5537 l_wo_name VARCHAR2(80);
5538 
5539 -- rroy
5540 -- R12 Tech UIs
5541 -- cursor to retrieve the workorder actual dates
5542 CURSOR get_wo_dates(x_wo_id NUMBER)
5543 IS
5544 SELECT Actual_start_date,
5545 Actual_end_date,
5546 Workorder_name
5547 FROM AHL_WORKORDERS
5548 WHERE workorder_id = x_wo_id;
5549 
5550 -- To get the Unit Effectivity Details and it's master workorder details
5551 /*CURSOR     get_ue_details( c_unit_effectivity_id NUMBER ) IS
5552 SELECT     UE.unit_effectivity_id unit_effectivity_id,
5553            UE.title ue_title,
5554            UE.object_version_number ue_object_version_number,
5555            UE.ump_status_code ue_status_code,
5556            UE.qa_inspection_type_code ue_qa_inspection_type_code,
5557            UE.qa_plan_id ue_qa_plan_id,
5558            UE.qa_collection_id ue_qa_collection_id,
5559            WO.workorder_id workorder_id,
5560            WIP.organization_id,
5561            WO.object_version_number wo_object_version_number,
5562            WO.workorder_name workorder_name,
5563            WO.wip_entity_id wip_entity_id,
5564            VWO.wip_entity_id visit_wip_entity_id,
5565            VT.instance_id item_instance_id,
5566            WIP.scheduled_start_date scheduled_start_date,
5567            WIP.scheduled_completion_date scheduled_end_date,
5568            WO.actual_start_date actual_start_date,
5569            WO.actual_end_date actual_end_date,
5570            WO.status_code wo_status_code,
5571            WO.plan_id wo_plan_id,
5572            WO.collection_id wo_collection_id,
5573    	   WO.master_workorder_flag
5574 FROM       WIP_DISCRETE_JOBS WIP,
5575            AHL_WORKORDERS WO,
5576            AHL_WORKORDERS VWO,
5577            AHL_VISIT_TASKS_B VT,
5578            AHL_UE_DEFERRAL_DETAILS_V UE
5579 WHERE      WIP.wip_entity_id = WO.wip_entity_id
5580 AND        WO.visit_task_id = VT.visit_task_id
5581 AND        VWO.visit_task_id IS NULL
5582 AND        VWO.visit_id = VT.visit_id
5583 AND        VT.task_type_code IN ( 'SUMMARY' , 'UNASSOCIATED' )
5584 AND        VT.unit_effectivity_id = UE.unit_effectivity_id
5585 AND        UE.unit_effectivity_id = c_unit_effectivity_id;*/
5586 --fix for bug number 7295717 (Sunil)
5587 CURSOR     get_ue_details( c_unit_effectivity_id NUMBER ) IS
5588 SELECT     UE.unit_effectivity_id unit_effectivity_id,
5589            DECODE( UE.Mr_header_id, null,
5590            (select cit.name || '-' || cs.incident_number from cs_incidents_all_vl cs, cs_incident_types_vl cit WHERE cs.incident_type_id = cit.incident_type_id AND cs.incident_id = UE.Cs_Incident_id),
5591            (select title from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id )) ue_title,
5592            UE.object_version_number ue_object_version_number,
5593            UE.status_code ue_status_code,
5594            --UE.qa_inspection_type_code ue_qa_inspection_type_code,
5595            DECODE( UE.Mr_header_id, null,null,(select QA_INSPECTION_TYPE from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id ))  ue_qa_inspection_type_code,
5596            -1 ue_qa_plan_id,
5597            UE.qa_collection_id ue_qa_collection_id,
5598            WO.workorder_id workorder_id,
5599            WIP.organization_id,
5600            WO.object_version_number wo_object_version_number,
5601            WO.workorder_name workorder_name,
5602            WO.wip_entity_id wip_entity_id,
5603            VWO.wip_entity_id visit_wip_entity_id,
5604            VT.instance_id item_instance_id,
5605            WIP.scheduled_start_date scheduled_start_date,
5606            WIP.scheduled_completion_date scheduled_end_date,
5607            WO.actual_start_date actual_start_date,
5608            WO.actual_end_date actual_end_date,
5609            WO.status_code wo_status_code,
5610            WO.plan_id wo_plan_id,
5611            WO.collection_id wo_collection_id,
5612    	       WO.master_workorder_flag,
5613    	       WIP.ORGANIZATION_ID org_id
5614 FROM       WIP_DISCRETE_JOBS WIP,
5615            AHL_WORKORDERS WO,
5616            AHL_WORKORDERS VWO,
5617            AHL_VISIT_TASKS_B VT,
5618            AHL_UNIT_EFFECTIVITIES_APP_V UE
5619 WHERE      WIP.wip_entity_id = WO.wip_entity_id
5620 AND        WO.visit_task_id = VT.visit_task_id
5621 AND        VWO.visit_task_id IS NULL
5622 AND        VWO.visit_id = VT.visit_id
5623 AND        VT.task_type_code IN ( 'SUMMARY' , 'UNASSOCIATED' )
5624 AND        VT.unit_effectivity_id = UE.unit_effectivity_id
5625 AND        UE.unit_effectivity_id = c_unit_effectivity_id;
5626 
5627 CURSOR get_qa_plan_id_csr1(p_collection_id IN NUMBER)IS
5628 SELECT qa.plan_id from qa_results qa
5629 where qa.collection_id = p_collection_id and rownum < 2;
5630 
5631 CURSOR get_qa_plan_id_csr2(p_org_id IN NUMBER, p_qa_inspection_type IN VARCHAR2)IS
5632 SELECT QP.plan_id FROM QA_PLANS_VAL_V QP, QA_PLAN_TRANSACTIONS QPT, QA_PLAN_COLLECTION_TRIGGERS QPCT
5633 WHERE QP.plan_id = QPT.plan_id AND QPT.plan_transaction_id = QPCT.plan_transaction_id
5634 AND QP.organization_id = p_org_id
5635 AND QPT.transaction_number in (9999,2001)
5636 AND QPCT.collection_trigger_id = 87
5637 AND QPCT.low_value = p_qa_inspection_type
5638 group by qp.plan_id, qpt.transaction_number having transaction_number = MAX(transaction_number);
5639 
5640 -- To get the Child Unit Effectivity Details
5641 /*CURSOR     get_child_ue_details( c_unit_effectivity_id NUMBER ) IS
5642 SELECT     unit_effectivity_id,
5643            object_version_number,
5644            title,
5645            ump_status_code,
5646            qa_inspection_type_code,
5647            qa_plan_id,
5648            qa_collection_id
5649 FROM       AHL_UE_DEFERRAL_DETAILS_V
5650 WHERE      unit_effectivity_id IN
5651            (
5652              SELECT     related_ue_id
5653              FROM       AHL_UE_RELATIONSHIPS
5654              WHERE      unit_effectivity_id = related_ue_id
5655              START WITH ue_id = c_unit_effectivity_id
5656                     AND relationship_code = 'PARENT'
5657              CONNECT BY ue_id = PRIOR related_ue_id
5658                     AND relationship_code = 'PARENT'
5659            );*/
5660 
5661 CURSOR     get_child_ue_details( c_unit_effectivity_id NUMBER ) IS
5662 SELECT     unit_effectivity_id,
5663            object_version_number,
5664            DECODE( UE.Mr_header_id, null,
5665            (select cit.name || '-' || cs.incident_number from cs_incidents_all_vl cs, cs_incident_types_vl cit WHERE cs.incident_type_id = cit.incident_type_id AND cs.incident_id = UE.Cs_Incident_id),
5666            (select title from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id )) title,
5667            status_code ump_status_code,
5668            DECODE( UE.Mr_header_id, null,null,(select QA_INSPECTION_TYPE from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id ))  qa_inspection_type_code,
5669            -1 qa_plan_id,
5670            qa_collection_id
5671 FROM       AHL_UNIT_EFFECTIVITIES_B UE,(SELECT     related_ue_id
5672 FROM       AHL_UE_RELATIONSHIPS
5673   START WITH ue_id = c_unit_effectivity_id
5674   AND relationship_code = 'PARENT'
5675   CONNECT BY ue_id = PRIOR related_ue_id
5676   AND relationship_code = 'PARENT') CH
5677 WHERE      UE.unit_effectivity_id = CH.related_ue_id ORDER BY unit_effectivity_id ASC;
5678 
5679 -- rroy
5680 -- Commented out the order by because of
5681 -- error ORA-01788 being thrown on signoff mr page
5682 --ORDER BY   level DESC;
5683 
5684 -- To get the Child Workorder Details for a UE
5685 CURSOR     get_ue_workorders( c_wip_entity_id NUMBER ) IS
5686 SELECT     CWO.workorder_id workorder_id,
5687            CWO.object_version_number object_version_number,
5688            CWO.workorder_name workorder_name,
5689            CWO.wip_entity_id wip_entity_id,
5690            WIP.scheduled_start_date scheduled_start_date,
5691            WIP.scheduled_completion_date scheduled_end_date,
5692            CWO.actual_start_date actual_start_date,
5693            CWO.actual_end_date actual_end_date,
5694            CWO.status_code status_code,
5695            CWO.master_workorder_flag master_workorder_flag,
5696            CWO.plan_id plan_id,
5697            CWO.collection_id collection_id
5698 FROM       WIP_DISCRETE_JOBS WIP,
5699            AHL_WORKORDERS CWO,
5700            WIP_SCHED_RELATIONSHIPS REL
5701 WHERE      WIP.wip_entity_id = CWO.wip_entity_id
5702 AND        CWO.wip_entity_id = REL.child_object_id
5703 AND        CWO.status_code <> G_JOB_STATUS_DELETED
5704 AND        REL.parent_object_type_id = 1
5705 AND        REL.child_object_type_id = 1
5706 START WITH REL.parent_object_id = c_wip_entity_id
5707 AND        REL.relationship_type = 1
5708 CONNECT BY REL.parent_object_id = PRIOR REL.child_object_id
5709 AND        REL.relationship_type = 1
5710 ORDER BY   level DESC;
5711 
5712 -- To get all the Child Operation Details for a UE
5713 CURSOR     get_ue_operations( c_wip_entity_id NUMBER ) IS
5714 SELECT     WOP.workorder_operation_id workorder_operation_id,
5715            WOP.object_version_number object_version_number,
5716            CWO.workorder_name workorder_name,
5717            WIP.wip_entity_id wip_entity_id,
5718            WIP.operation_seq_num operation_seq_num,
5719            WIP.first_unit_start_date scheduled_start_date,
5720            WIP.last_unit_completion_date scheduled_end_date,
5721            WOP.actual_start_date actual_start_date,
5722            WOP.actual_end_date actual_end_date,
5723            WOP.status_code status_code,
5724            WOP.plan_id plan_id,
5725            WOP.collection_id collection_id
5726 FROM       AHL_WORKORDER_OPERATIONS WOP,
5727            WIP_OPERATIONS WIP,
5728            AHL_WORKORDERS CWO
5729 WHERE      WOP.operation_sequence_num = WIP.operation_seq_num
5730 AND        WOP.workorder_id = CWO.workorder_id
5731 AND        WIP.wip_entity_id = CWO.wip_entity_id
5732 --AND        CWO.status_code <> G_JOB_STATUS_DELETED
5733 --Balaji added the check for BAE bug.
5734 AND        CWO.status_code NOT IN
5735            (
5736              G_JOB_STATUS_COMPLETE_NC,
5737              G_JOB_STATUS_COMPLETE,
5738              G_JOB_STATUS_CLOSED,
5739              G_JOB_STATUS_CANCELLED,
5740              G_JOB_STATUS_DELETED
5741            )
5742 AND        WIP.WIP_ENTITY_ID IN (
5743              SELECT     CWO.wip_entity_id
5744 FROM       WIP_DISCRETE_JOBS WIP,
5745            AHL_WORKORDERS CWO,
5746            WIP_SCHED_RELATIONSHIPS REL
5747 WHERE      WIP.wip_entity_id = CWO.wip_entity_id
5748 AND        CWO.wip_entity_id = REL.child_object_id
5749 AND        CWO.status_code <> G_JOB_STATUS_DELETED
5750 AND        REL.parent_object_type_id = 1
5751 AND        REL.child_object_type_id = 1
5752 START WITH REL.parent_object_id = c_wip_entity_id
5753 AND        REL.relationship_type = 1
5754 CONNECT BY REL.parent_object_id = PRIOR REL.child_object_id
5755 AND        REL.relationship_type = 1);
5756 -- rroy
5757 -- Commented out the order by because of
5758 -- error ORA-01788 being thrown on signoff mr page
5759 --ORDER BY   level DESC;
5760 
5761 -- To get operation for UE associated with SR created from Production
5762 CURSOR    get_unassoc_ue_op(c_wip_entity_id NUMBER) IS
5763 SELECT     WOP.workorder_operation_id workorder_operation_id,
5764            WOP.object_version_number object_version_number,
5765            CWO.workorder_name workorder_name,
5766            WIP.wip_entity_id wip_entity_id,
5767            WIP.operation_seq_num operation_seq_num,
5768            WIP.first_unit_start_date scheduled_start_date,
5769            WIP.last_unit_completion_date scheduled_end_date,
5770            WOP.actual_start_date actual_start_date,
5771            WOP.actual_end_date actual_end_date,
5772            WOP.status_code status_code,
5773            WOP.plan_id plan_id,
5774            WOP.collection_id collection_id
5775 FROM       AHL_WORKORDER_OPERATIONS WOP,
5776            WIP_OPERATIONS WIP,
5777            AHL_WORKORDERS CWO
5778 WHERE      WOP.operation_sequence_num = WIP.operation_seq_num
5779 AND        WOP.workorder_id = CWO.workorder_id
5780 AND        WIP.wip_entity_id = CWO.wip_entity_id
5781 AND        WIP.WIP_ENTITY_ID = c_wip_entity_id
5782 AND        CWO.MASTER_WORKORDER_FLAG = 'N'
5783 --Balaji added the status check for BAE Bug
5784 AND        CWO.status_code NOT IN
5785            (
5786              G_JOB_STATUS_COMPLETE_NC,
5787              G_JOB_STATUS_COMPLETE,
5788              G_JOB_STATUS_CLOSED,
5789              G_JOB_STATUS_CANCELLED,
5790              G_JOB_STATUS_DELETED
5791            );
5792 -- Balaji commented out the order by clause for the issue # 3 in bug #4613940(CMRO)
5793 -- and this fix has reference to bug #3085871(ST) where it is described that order by level
5794 -- should not be used without a reference to "start with.. connect by clause" starting 10g
5795 -- ORDER BY   level DESC;
5796 
5797 -- To get all the Resource Requirements for a UE
5798 CURSOR     get_ue_resource_req( c_wip_entity_id NUMBER ) IS
5799 SELECT     WOR.wip_entity_id wip_entity_id,
5800            CWO.workorder_name,
5801            CWO.workorder_id,
5802            WOP.workorder_operation_id,
5803            WOR.operation_seq_num operation_seq_num,
5804            WOR.resource_seq_num resource_seq_num,
5805            WOR.organization_id organization_id,
5806            WOR.department_id department_id,
5807            BOM.resource_code resource_name,
5808            WOR.resource_id resource_id,
5809            BOM.resource_type,
5810            WOR.uom_code uom_code,
5811            WOR.usage_rate_or_amount usage_rate_or_amount
5812 FROM       BOM_RESOURCES BOM,
5813            WIP_OPERATION_RESOURCES WOR,
5814            AHL_WORKORDER_OPERATIONS WOP,
5815            AHL_WORKORDERS CWO,
5816            WIP_SCHED_RELATIONSHIPS REL
5817 WHERE      BOM.resource_type IN ( 1 , 2 )
5818 AND        BOM.resource_id = WOR.resource_id
5819 AND        WOR.operation_seq_num = WOP.operation_sequence_num
5820 AND        WOR.wip_entity_id = CWO.wip_entity_id
5821 AND        WOP.status_code <> G_OP_STATUS_COMPLETE
5822 AND        WOP.workorder_id = CWO.workorder_id
5823 AND        CWO.status_code NOT IN
5824            (
5825              G_JOB_STATUS_COMPLETE_NC,
5826              G_JOB_STATUS_COMPLETE,
5827              G_JOB_STATUS_CLOSED,
5828              G_JOB_STATUS_CANCELLED,
5829              G_JOB_STATUS_DELETED
5830            )
5831 AND        CWO.wip_entity_id = REL.child_object_id
5832 AND        REL.parent_object_type_id = 1
5833 AND        REL.child_object_type_id = 1
5834 START WITH REL.parent_object_id = c_wip_entity_id
5835 AND        REL.relationship_type = 1
5836 CONNECT BY REL.parent_object_id = PRIOR REL.child_object_id
5837 AND        REL.relationship_type = 1;
5838 
5839 -- Balaji added this cursor for bug # 4955278.
5840 -- this cursor retrieves res req for operations associated with
5841 -- workorders created out of NR created in Prod floor or from
5842 -- an unassociated task in VWP.
5843 CURSOR     get_unass_ue_resource_req( c_wip_entity_id NUMBER ) IS
5844 SELECT     WOR.wip_entity_id wip_entity_id,
5845            CWO.workorder_name,
5846            CWO.workorder_id,
5847            WOP.workorder_operation_id,
5848            WOR.operation_seq_num operation_seq_num,
5849            WOR.resource_seq_num resource_seq_num,
5850            WOR.organization_id organization_id,
5851            WOR.department_id department_id,
5852            BOM.resource_code resource_name,
5853            WOR.resource_id resource_id,
5854            BOM.resource_type,
5855            WOR.uom_code uom_code,
5856            WOR.usage_rate_or_amount usage_rate_or_amount
5857 FROM       BOM_RESOURCES BOM,
5858            WIP_OPERATION_RESOURCES WOR,
5859            AHL_WORKORDER_OPERATIONS WOP,
5860            AHL_WORKORDERS CWO
5861 WHERE      BOM.resource_type IN ( 1 , 2 )
5862 AND        BOM.resource_id = WOR.resource_id
5863 AND        WOR.operation_seq_num = WOP.operation_sequence_num
5864 AND        WOR.wip_entity_id = CWO.wip_entity_id
5865 AND        WOP.status_code <> G_OP_STATUS_COMPLETE
5866 AND        WOP.workorder_id = CWO.workorder_id
5867 AND        CWO.status_code NOT IN
5868            (
5869              G_JOB_STATUS_COMPLETE_NC,
5870              G_JOB_STATUS_COMPLETE,
5871              G_JOB_STATUS_CLOSED,
5872              G_JOB_STATUS_CANCELLED,
5873              G_JOB_STATUS_DELETED
5874            )
5875 AND        CWO.wip_entity_id = c_wip_entity_id
5876 AND        CWO.MASTER_WORKORDER_FLAG = 'N';
5877 
5878 -- To get the Resource Transactions performed for a Resource Requirement
5879 CURSOR     get_resource_txns( c_wip_entity_id NUMBER,
5880                               c_operation_seq_num NUMBER,
5881                               c_resource_seq_num NUMBER ) IS
5882 SELECT     NVL( SUM( transaction_quantity ), 0 )
5883 FROM       WIP_TRANSACTIONS
5884 WHERE      wip_entity_id = c_wip_entity_id
5885 AND        operation_seq_num = c_operation_seq_num
5886 AND        resource_seq_num = c_resource_seq_num;
5887 
5888 -- To get the Pending Resource Transactions for a Resource Requirement
5889 -- Confirm
5890 CURSOR     get_pending_resource_txns( c_wip_entity_id NUMBER,
5891                                       c_operation_seq_num NUMBER,
5892                                       c_resource_seq_num NUMBER ) IS
5893 SELECT     NVL( SUM( transaction_quantity ), 0 )
5894 FROM       WIP_COST_TXN_INTERFACE
5895 WHERE      wip_entity_id = c_wip_entity_id
5896 AND        operation_seq_num = c_operation_seq_num
5897 AND        resource_seq_num = c_resource_seq_num
5898 AND        process_status = 1;
5899 
5900 l_ctr                    NUMBER := 0;
5901 l_wo_actual_start_date      DATE;
5902 l_wo_actual_end_date        DATE;
5903 l_def_actual_start_date  DATE;
5904 l_def_actual_end_date    DATE;
5905 l_transaction_qty        NUMBER := 0;
5906 l_txn_qty                NUMBER := 0;
5907 l_pending_txn_qty        NUMBER := 0;
5908 l_employee_id            NUMBER;
5909 l_ue_status_code         VARCHAR2(30);
5910 l_mr_rec                 get_ue_details%ROWTYPE;
5911 l_child_mr_tbl           mr_tbl_type;
5912 l_workorder_tbl          workorder_tbl_type;
5913 l_operation_tbl          operation_tbl_type;
5914 l_resource_req_tbl       resource_req_tbl_type;
5915 l_counter_tbl            counter_tbl_type;
5916 --l_res_txn_tbl            AHL_WIP_JOB_PVT.ahl_res_txn_tbl_type;
5917 l_job_status_meaning     VARCHAR2(80);
5918 l_unassoc_ue_op_rec      get_unassoc_ue_op%ROWTYPE;
5919 l_default                VARCHAR2(1);
5920 TYPE child_ue_tbl_type IS TABLE OF get_child_ue_details%ROWTYPE INDEX BY BINARY_INTEGER;
5921 
5922 l_child_ue_tbl child_ue_tbl_type;
5923 l_ue_ctr NUMBER := 0;
5924 
5925 l_op_actual_start_date DATE;
5926 l_op_actaul_end_date DATE;
5927 
5928 -- parameters to call process_resource_txns.
5929 l_prd_resrc_txn_tbl     AHL_PRD_RESOURCE_TRANX_PVT.PRD_RESOURCE_TXNS_TBL;
5930 
5931 BEGIN
5932 
5933   -- Enable Debug (optional)
5934   IF ( G_DEBUG = 'Y' ) THEN
5935     AHL_DEBUG_PUB.enable_debug;
5936   END IF;
5937 
5938   -- Initialize API return status to success
5939   x_return_status := FND_API.G_RET_STS_SUCCESS;
5940 
5941   -- Standard Start of API savepoint
5942   SAVEPOINT signoff_mr_instance_PVT;
5943 
5944   -- Initialize message list if p_init_msg_list is set to TRUE.
5945   IF FND_API.to_boolean( p_init_msg_list ) THEN
5946     FND_MSG_PUB.initialize;
5947   END IF;
5948 
5949   IF ( G_DEBUG = 'Y' ) THEN
5950     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Validating Inputs' );
5951   END IF;
5952 
5953   -- Validate all the inputs of the API
5954   l_return_status :=
5955   validate_smri_inputs
5956   (
5957     p_signoff_mr_rec      => p_signoff_mr_rec
5958   );
5959 
5960   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
5961     RAISE FND_API.G_EXC_ERROR;
5962   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
5963     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5964   END IF;
5965 
5966   IF ( G_DEBUG = 'Y' ) THEN
5967     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.unit_effectivity_id - ' || p_signoff_mr_rec.unit_effectivity_id );
5968     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.object_version_number - ' || p_signoff_mr_rec.object_version_number );
5969     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.signoff_child_mrs_flag - ' || p_signoff_mr_rec.signoff_child_mrs_flag );
5970     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.complete_job_ops_flag - ' || p_signoff_mr_rec.complete_job_ops_flag );
5971     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.default_actual_dates_flag - ' || p_signoff_mr_rec.default_actual_dates_flag );
5972     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.actual_start_date - ' || p_signoff_mr_rec.actual_start_date );
5973     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.actual_end_date - ' || p_signoff_mr_rec.actual_end_date );
5974     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.transact_resource_flag - ' || p_signoff_mr_rec.transact_resource_flag );
5975     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.employee_number - ' || p_signoff_mr_rec.employee_number );
5976     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Inputs - p_signoff_mr_rec.serial_number - ' || p_signoff_mr_rec.serial_number );
5977   END IF;
5978 
5979   -- Invoke Complete MR Instance API if this is not a top-down signoff
5980   IF ( p_signoff_mr_rec.signoff_child_mrs_flag = 'N' AND
5981        p_signoff_mr_rec.complete_job_ops_flag = 'N' AND
5982        p_signoff_mr_rec.transact_resource_flag = 'N' ) THEN
5983 
5984     IF ( G_DEBUG = 'Y' ) THEN
5985       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Not Top Down Signoff ' );
5986     END IF;
5987 
5988     l_ctr := l_ctr + 1;
5989     l_child_mr_tbl(l_ctr).unit_effectivity_id := p_signoff_mr_rec.unit_effectivity_id;
5990     l_child_mr_tbl(l_ctr).ue_object_version_no := p_signoff_mr_rec.object_version_number;
5991 
5992     complete_mr_instance
5993     (
5994       p_api_version            => 1.0,
5995       p_init_msg_list          => FND_API.G_FALSE,
5996       p_commit                 => FND_API.G_TRUE,
5997       p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
5998       p_default                => FND_API.G_FALSE,
5999       p_module_type            => NULL,
6000       x_return_status          => l_return_status,
6001       x_msg_count              => l_msg_count,
6002       x_msg_data               => l_msg_data,
6003       p_x_mr_rec               => l_child_mr_tbl(l_ctr)
6004     );
6005 
6006     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
6007       RAISE FND_API.G_EXC_ERROR;
6008     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
6009       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6010     END IF;
6011 
6012     RETURN;
6013 
6014   END IF;
6015 
6016   IF ( G_DEBUG = 'Y' ) THEN
6017     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing UE' );
6018   END IF;
6019 
6020   -- Get the UE Details
6021   OPEN  get_ue_details( p_signoff_mr_rec.unit_effectivity_id );
6022   FETCH get_ue_details
6023   INTO  l_mr_rec;
6024 
6025   IF(l_mr_rec.ue_qa_inspection_type_code IS NULL)THEN
6026          l_mr_rec.ue_qa_plan_id := NULL;
6027       ELSIF(l_mr_rec.ue_qa_collection_id IS NOT NULL)THEN
6028          OPEN get_qa_plan_id_csr1(l_mr_rec.ue_qa_collection_id);
6029          FETCH get_qa_plan_id_csr1 INTO l_mr_rec.ue_qa_plan_id;
6030          CLOSE get_qa_plan_id_csr1;
6031       ELSE
6032          OPEN get_qa_plan_id_csr2(l_mr_rec.organization_id,l_mr_rec.ue_qa_inspection_type_code);
6033          FETCH get_qa_plan_id_csr2 INTO l_mr_rec.ue_qa_plan_id;
6034          CLOSE get_qa_plan_id_csr2;
6035   END IF;
6036 
6037   IF ( get_ue_details%NOTFOUND ) THEN
6038     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MR_REC_NOT_FOUND' );
6039     FND_MSG_PUB.add;
6040     CLOSE get_ue_details;
6041     RAISE FND_API.G_EXC_ERROR;
6042   END IF;
6043 
6044   CLOSE get_ue_details;
6045 
6046   -- Validate Object Version Number
6047   IF ( l_mr_rec.ue_object_version_number <> p_signoff_mr_rec.object_version_number ) THEN
6048     FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
6049     FND_MSG_PUB.add;
6050     RAISE FND_API.G_EXC_ERROR;
6051   END IF;
6052 
6053   -- Check if this MR is already signed off
6054   IF ( l_mr_rec.ue_status_code = G_MR_STATUS_SIGNED_OFF ) THEN
6055     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INV_SIGNOFF_STATUS');
6056     FND_MESSAGE.set_token( 'MAINT_REQ', l_mr_rec.ue_title );
6057 				-- replacing with call to get_status function
6058 				-- so no exceptions are thrown if the
6059 				-- lookup does not exist
6060     l_status_meaning := get_status(l_mr_rec.ue_status_code,
6061 				'AHL_PRD_MR_STATUS');
6062 
6063      /*SELECT meaning INTO l_status_meaning
6064 	   FROM fnd_lookup_values_vl
6065         WHERE lookup_type = 'AHL_PRD_MR_STATUS'
6066           AND LOOKUP_CODE = l_mr_rec.ue_status_code;
6067      */
6068 
6069     FND_MESSAGE.set_token( 'STATUS', l_status_meaning );
6070     FND_MSG_PUB.add;
6071   END IF;
6072 
6073   -- Check if the UE is complete
6074   l_return_status:=
6075   is_mr_complete
6076   (
6077     p_mr_title             => l_mr_rec.ue_title,
6078     p_status_code          => l_mr_rec.ue_status_code,
6079     p_status               => NULL,
6080     p_qa_inspection_type   => l_mr_rec.ue_qa_inspection_type_code,
6081     p_qa_plan_id           => l_mr_rec.ue_qa_plan_id,
6082     p_qa_collection_id     => l_mr_rec.ue_qa_collection_id
6083   );
6084 
6085   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
6086     RAISE FND_API.G_EXC_ERROR;
6087   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
6088     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6089   END IF;
6090 
6091   IF ( G_DEBUG = 'Y' ) THEN
6092     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing Child UEs' );
6093   END IF;
6094 
6095   -- Balaji added the following loop for the BAE bug.
6096   -- The cursor get_child_ue_details doesnt UEs at the leaf node first
6097   -- their parent next, etc., instead it returns Mrs in Top down fashion.
6098   -- Hence below loop fetches all the child UEs in top down fashion and in
6099   -- subsequent code the top down will be converted into bottom up to
6100   -- circumvent the "At least one child Maintenance Requirement is unaccomplished"
6101   FOR child_ue_rec IN get_child_ue_details( p_signoff_mr_rec.unit_effectivity_id ) LOOP
6102     l_ue_ctr := l_ue_ctr + 1;
6103     l_child_ue_tbl(l_ue_ctr) := child_ue_rec;
6104     -- fix for bug number 7295717 (Sunil)
6105     IF(l_child_ue_tbl(l_ue_ctr).qa_inspection_type_code IS NULL)THEN
6106          l_child_ue_tbl(l_ue_ctr).qa_plan_id := NULL;
6107     ELSIF(l_child_ue_tbl(l_ue_ctr).qa_collection_id IS NOT NULL)THEN
6108          OPEN get_qa_plan_id_csr1(l_child_ue_tbl(l_ue_ctr).qa_collection_id);
6109          FETCH get_qa_plan_id_csr1 INTO l_child_ue_tbl(l_ue_ctr).qa_plan_id;
6110          CLOSE get_qa_plan_id_csr1;
6111     ELSE
6112          OPEN get_qa_plan_id_csr2(l_mr_rec.organization_id,l_child_ue_tbl(l_ue_ctr).qa_inspection_type_code);
6113          FETCH get_qa_plan_id_csr2 INTO l_child_ue_tbl(l_ue_ctr).qa_plan_id;
6114          CLOSE get_qa_plan_id_csr2;
6115     END IF;
6116   END LOOP;
6117 
6118   IF ( G_DEBUG = 'Y' ) THEN
6119     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Child UE Table Size '||l_child_ue_tbl.COUNT );
6120   END IF;
6121   -- Get the Child UE Details
6122   IF l_child_ue_tbl.COUNT > 0 THEN
6123 
6124         -- Reverse the order of signing off the Ues. First child UE then its parent
6125         -- etc.,Balaji modified the code for BAE bug.
6126 	  FOR l_ue_count IN REVERSE l_child_ue_tbl.FIRST..l_child_ue_tbl.LAST LOOP
6127           IF ( G_DEBUG = 'Y' ) THEN
6128             AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : l_child_ue_tbl(l_ue_count).title '||l_child_ue_tbl(l_ue_count).title );
6129             AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : ump_status_code '||l_child_ue_tbl(l_ue_count).ump_status_code );
6130             AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : l_child_ue_tbl(l_ue_count).qa_collection_id '||l_child_ue_tbl(l_ue_count).qa_collection_id );
6131           END IF;
6132 	    -- If top down signoff is required for the Child UEs
6133 	    IF ( p_signoff_mr_rec.signoff_child_mrs_flag = 'Y' ) THEN
6134 
6135 	      /*-- Check if the Child UE is complete
6136 	      l_return_status:=
6137 	      is_mr_complete
6138 	      (
6139 		p_mr_title             => l_child_ue_tbl(l_ue_count).title,
6140 		p_status_code          => l_child_ue_tbl(l_ue_count).ump_status_code,
6141 		p_status               => NULL,
6142 		p_qa_inspection_type   => l_child_ue_tbl(l_ue_count).qa_inspection_type_code,
6143 		p_qa_plan_id           => l_child_ue_tbl(l_ue_count).qa_plan_id,
6144 		p_qa_collection_id     => l_child_ue_tbl(l_ue_count).qa_collection_id
6145 	      );
6146 
6147 	      IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
6148 		RAISE FND_API.G_EXC_ERROR;
6149 	      ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
6150 		RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6151 	      END IF;*/
6152 
6153 	      -- Store the Child UEs in a table of records for Signing off
6154 	      IF ( NVL(l_child_ue_tbl(l_ue_count).ump_status_code,'X') <> NVL(G_MR_STATUS_SIGNED_OFF,'Y') ) THEN
6155 		-- If the derived status for child UE falls in any of below statuses then block their signoff
6156 		-- B'cos they cannot be signed off really in these status.
6157 		-- Balaji added for a part of Visit Closure BAE Bug.
6158 		l_ue_status_code := get_mr_status( l_child_ue_tbl(l_ue_count).unit_effectivity_id );
6159 
6160 		IF (
6161 		      l_ue_status_code <> G_MR_STATUS_DEFERRED AND
6162 		      l_ue_status_code <> G_MR_STATUS_TERMINATED AND
6163 		      l_ue_status_code <> G_MR_STATUS_CANCELLED
6164 
6165 		) THEN
6166 		   -- Check if the Child UE is complete
6167 	      l_return_status:=
6168 	      is_mr_complete
6169 	      (
6170 		    p_mr_title             => l_child_ue_tbl(l_ue_count).title,
6171 		    p_status_code          => l_child_ue_tbl(l_ue_count).ump_status_code,
6172 		    p_status               => NULL,
6173 		    p_qa_inspection_type   => l_child_ue_tbl(l_ue_count).qa_inspection_type_code,
6174 		    p_qa_plan_id           => l_child_ue_tbl(l_ue_count).qa_plan_id,
6175 		    p_qa_collection_id     => l_child_ue_tbl(l_ue_count).qa_collection_id
6176 	      );
6177 
6178 	      IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
6179 		     RAISE FND_API.G_EXC_ERROR;
6180 	      ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
6181 		     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6182 	      END IF;
6183 
6184 			IF ( G_DEBUG = 'Y' ) THEN
6185 			   AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : l_ue_status_code '||l_ue_status_code );
6186 			END IF;
6187 
6188 			l_ctr := l_ctr + 1;
6189 			l_child_mr_tbl(l_ctr).unit_effectivity_id := l_child_ue_tbl(l_ue_count).unit_effectivity_id;
6190 			l_child_mr_tbl(l_ctr).ue_object_version_no := l_child_ue_tbl(l_ue_count).object_version_number;
6191 			l_child_mr_tbl(l_ctr).mr_title := l_child_ue_tbl(l_ue_count).title;
6192 			l_child_mr_tbl(l_ctr).qa_collection_id := l_child_ue_tbl(l_ue_count).qa_collection_id;
6193 		END IF;
6194 	      END IF;
6195 	    ELSE
6196 
6197 	      -- Child UEs are not required to be signed off
6198 	      -- Validate that the Child UEs are already signed off
6199 	      -- Null check added by balaji for bug # 4078536
6200 	      IF (
6201 	           l_child_ue_tbl(l_ue_count).ump_status_code IS NULL OR
6202 	           (
6203 	            l_child_ue_tbl(l_ue_count).ump_status_code <> G_MR_STATUS_SIGNED_OFF AND
6204 	            l_child_ue_tbl(l_ue_count).ump_status_code <> G_MR_STATUS_DEFERRED AND
6205 	            l_child_ue_tbl(l_ue_count).ump_status_code <> G_MR_STATUS_CANCELLED AND
6206 	            l_child_ue_tbl(l_ue_count).ump_status_code <> G_MR_STATUS_TERMINATED
6207 	           )
6208 	         )  THEN
6209 		FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_CHILD_MRS_NOT_COMPL' );
6210 		FND_MESSAGE.set_token( 'MAINT_REQ', l_mr_rec.ue_title);
6211 		FND_MSG_PUB.add;
6212 		RAISE FND_API.G_EXC_ERROR;
6213 	      END IF;
6214 	    END IF;
6215 	  END LOOP;
6216   END IF;
6217   -- Add the given UE in the Table of UE Records to be signed Off
6218   l_ctr := l_ctr + 1;
6219   l_child_mr_tbl(l_ctr).unit_effectivity_id := l_mr_rec.unit_effectivity_id;
6220   l_child_mr_tbl(l_ctr).ue_object_version_no := l_mr_rec.ue_object_version_number;
6221   l_child_mr_tbl(l_ctr).mr_title := l_mr_rec.ue_title;
6222   l_child_mr_tbl(l_ctr).qa_collection_id := l_mr_rec.ue_qa_collection_id;
6223 
6224   l_ctr := 0;
6225 
6226   IF ( G_DEBUG = 'Y' ) THEN
6227     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing UE Workorders' );
6228   END IF;
6229 
6230   -- Get all the Workorders for the UE
6231   FOR wo_csr IN get_ue_workorders( l_mr_rec.wip_entity_id ) LOOP
6232 
6233     -- Check if Jobs and Operations need to be completed
6234     IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' ) THEN
6235 
6236       -- Check if the Input Actual dates are required
6237       /*-- Start ER # 4757222
6238       IF ( p_signoff_mr_rec.default_actual_dates_flag = 'N' ) THEN
6239 
6240         -- Validate if the actual start dates entered is less than any WO
6241         IF ( wo_csr.actual_start_date IS NOT NULL AND
6242              wo_csr.actual_start_date < p_signoff_mr_rec.actual_start_date ) THEN
6243           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_ST_DATE_LESS' );
6244           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
6245           FND_MESSAGE.set_token( 'START_DT', TO_CHAR( wo_csr.actual_start_date , 'DD-MON-YYYY HH24:MI' ) );
6246           FND_MSG_PUB.add;
6247           RAISE FND_API.G_EXC_ERROR;
6248         END IF;
6249 
6250         -- Validate if the actual end dates entered is greater than any WO
6251         IF ( wo_csr.actual_end_date IS NOT NULL AND
6252              wo_csr.actual_end_date > p_signoff_mr_rec.actual_end_date ) THEN
6253           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_END_DATE_GT' );
6254           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
6255           FND_MESSAGE.set_token( 'END_DT', TO_CHAR( wo_csr.actual_end_date , 'DD-MON-YYYY HH24:MI' ) );
6256           FND_MSG_PUB.add;
6257           RAISE FND_API.G_EXC_ERROR;
6258         END IF;
6259 
6260       END IF; -- Check Input Dates are required
6261       */--End ER # 4757222
6262       -- Do not process Workorders which are already Complete
6263       IF ( wo_csr.status_code <> G_JOB_STATUS_COMPLETE AND
6264            wo_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
6265            wo_csr.status_code <> G_JOB_STATUS_CLOSED AND
6266            wo_csr.status_code <> G_JOB_STATUS_CANCELLED ) THEN
6267 
6268 	-- rroy
6269 	-- ACL Changes
6270 	l_return_status := AHL_PRD_UTIL_PKG.Is_Unit_Locked(wo_csr.workorder_id, NULL, NULL, NULL);
6271 	IF l_return_status = FND_API.G_TRUE THEN
6272   	  FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_SM_UNTLCKD');
6273 	  FND_MESSAGE.Set_Token('MR_TITLE', l_mr_rec.ue_title);
6274 	  FND_MSG_PUB.ADD;
6275 	  RAISE FND_API.G_EXC_ERROR;
6276 	END IF;
6277 	--nsikka
6278 	--Changes made for Bug 5324101 .
6279 	--tokens passed changed to MR_TITLE
6280 	-- rroy
6281 	-- ACL Changes
6282 
6283         -- Validate whether the Workorders can be completed
6284         IF ( wo_csr.status_code = G_JOB_STATUS_UNRELEASED OR
6285              wo_csr.status_code = G_JOB_STATUS_ON_HOLD OR
6286              wo_csr.status_code = G_JOB_STATUS_PARTS_HOLD OR
6287              wo_csr.status_code = G_JOB_STATUS_DEFERRAL_PENDING ) THEN
6288         --Modified by Srini
6289 	-- replacing with call to get_status function
6290 	-- so no exceptions are thrown if the
6291         -- lookup does not exist
6292 	l_job_status_meaning := get_status(wo_csr.status_code,
6293 					'AHL_JOB_STATUS');
6294 
6295      	/*SELECT MEANING INTO l_job_status_meaning
6296           FROM fnd_lookup_values_vl
6297          WHERE lookup_type = 'AHL_JOB_STATUS'
6298 	       AND lookup_code = wo_csr.status_code;
6299 						*/
6300           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_NOT_ALL_WOS_OPEN' );
6301           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
6302           FND_MESSAGE.set_token( 'STATUS', l_job_status_meaning );
6303           FND_MSG_PUB.add;
6304           RAISE FND_API.G_EXC_ERROR;
6305         END IF;
6306 
6307         -- Validate whether Quality Results are Submitted
6308         IF ( wo_csr.plan_id IS NOT NULL AND
6309              wo_csr.collection_id IS NULL ) THEN
6310           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_QA_PENDING' );
6311           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
6312           FND_MSG_PUB.add;
6313           RAISE FND_API.G_EXC_ERROR;
6314         END IF;
6315 
6316         -- Add the Workorder in the Workorder Records for Completion
6317         l_ctr := l_ctr + 1;
6318         l_workorder_tbl(l_ctr).workorder_id := wo_csr.workorder_id;
6319         l_workorder_tbl(l_ctr).object_version_number := wo_csr.object_version_number;
6320         l_workorder_tbl(l_ctr).workorder_name := wo_csr.workorder_name;
6321         l_workorder_tbl(l_ctr).wip_entity_id := wo_csr.wip_entity_id;
6322         l_workorder_tbl(l_ctr).master_workorder_flag := wo_csr.master_workorder_flag;
6323         l_workorder_tbl(l_ctr).collection_id := wo_csr.collection_id;
6324         IF ( wo_csr.master_workorder_flag = 'N' ) THEN
6325 	  l_workorder_tbl(l_ctr).actual_start_date := wo_csr.actual_start_date;
6326 	  l_workorder_tbl(l_ctr).actual_end_date := wo_csr.actual_end_date;
6327 	ELSE
6328           -- Reset Actual Dates of Master WO
6329           l_workorder_tbl(l_ctr).actual_start_date := NULL;
6330           l_workorder_tbl(l_ctr).actual_end_date := NULL;
6331 	END IF;
6332 
6333         -- Store the Actual Dates for Workorders
6334         -- No need to store actual dates for Master Workorders because it can be
6335         -- done only after updating the Actual dates of child Workorders
6336         /*Start ER # 4757222
6337          -- Balaji commented out the code as per the requirement in the BAE ER # 4757222.
6338          -- As per the new requirement, Work Order actual dates will be defaulted based
6339          -- on following logic.
6340          -- 1. Work Order actual start date is minimum of operation actual start dates.
6341          -- 2. Work Order actual end date is maximum of operation actual end dates.
6342         IF ( wo_csr.master_workorder_flag = 'N' ) THEN
6343 
6344           -- Check if Actual Date is already entered
6345           IF ( wo_csr.actual_start_date IS NULL ) THEN
6346 	    -- R12
6347             -- Actual dates are no longer defaulted from scheduled dates
6348 	    -- They are defaulted in the Completions API to the res txn dates
6349 	    -- if p_default flag is passed as FND_API.G_TRUE
6350             /*IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
6351               -- Update Actual Date with Scheduled Date
6352               l_workorder_tbl(l_ctr).actual_start_date := wo_csr.scheduled_start_date;
6353             ELSE
6354               -- Update Actual Date with User Entered Value
6355               l_workorder_tbl(l_ctr).actual_start_date := p_signoff_mr_rec.actual_start_date;
6356             END IF;
6357 	    */
6358             /*IF ( p_signoff_mr_rec.default_actual_dates_flag = 'N' ) THEN
6359               -- Update Actual Date with User Entered Value
6360               l_workorder_tbl(l_ctr).actual_start_date := p_signoff_mr_rec.actual_start_date;
6361             END IF;
6362           ELSE
6363             -- Update Actual Date with DB Value if already entered
6364             l_workorder_tbl(l_ctr).actual_start_date := wo_csr.actual_start_date;
6365           END IF;
6366 
6367           -- Check if Actual Date is already entered
6368           IF ( wo_csr.actual_end_date IS NULL ) THEN
6369 	    -- R12
6370             -- Actual dates are no longer defaulted from scheduled dates
6371 	    -- They are defaulted in the Completions API to the res txn dates
6372 	    -- if p_default flag is passed as FND_API.G_TRUE
6373 
6374             /*IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
6375               -- Update Actual Date with Scheduled Date
6376               l_workorder_tbl(l_ctr).actual_end_date := LEAST( SYSDATE , wo_csr.scheduled_end_date );
6377             ELSE
6378               -- Update Actual Date with User Entered Value
6379               l_workorder_tbl(l_ctr).actual_end_date := p_signoff_mr_rec.actual_end_date;
6380             END IF;
6381 	    */
6382             /*IF ( p_signoff_mr_rec.default_actual_dates_flag = 'N' ) THEN
6383               -- Update Actual Date with User Entered Value
6384               l_workorder_tbl(l_ctr).actual_end_date := p_signoff_mr_rec.actual_end_date;
6385             END IF;
6386           ELSE
6387             -- Update Actual Date with DB Value if already entered
6388             l_workorder_tbl(l_ctr).actual_end_date := wo_csr.actual_end_date;
6389           END IF;
6390 
6391           IF ( G_DEBUG = 'Y' ) THEN
6392             AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6393             || ' : Wo Name - ' || l_workorder_tbl(l_ctr).workorder_name
6394             || ' WO ID - ' || l_workorder_tbl(l_ctr).workorder_id
6395             || ' Actual Start Date - ' || l_workorder_tbl(l_ctr).actual_start_date
6396             || ' Actual End Date - ' || l_workorder_tbl(l_ctr).actual_end_date );
6397           END IF;
6398 
6399         ELSIF ( wo_csr.master_workorder_flag = 'Y' ) THEN
6400 
6401           -- Reset Actual Dates of Master WO
6402           l_workorder_tbl(l_ctr).actual_start_date := NULL;
6403           l_workorder_tbl(l_ctr).actual_end_date := NULL;
6404 
6405         END IF; -- Check Master Workorder
6406 	*/--End ER # 4757222
6407       END IF; -- Check Workorder Complete
6408 
6409     ELSE
6410 
6411       -- Since Workorders need not be completed
6412       -- Validate to ensure that the Workorders are already completed
6413       -- This validation should not be done for master workorders
6414       -- since their status is determined internally. Balaji added this
6415       -- fix for the BAE bug # 4626717.
6416       IF ( wo_csr.status_code <> G_JOB_STATUS_COMPLETE AND
6417            wo_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
6418            wo_csr.status_code <> G_JOB_STATUS_CLOSED AND
6419            wo_csr.status_code <> G_JOB_STATUS_CANCELLED AND
6420            wo_csr.master_workorder_flag = 'N') THEN
6421         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MR_WO_NOT_CMPL' );
6422         FND_MESSAGE.set_token( 'MAINT_REQ', l_mr_rec.ue_title);
6423         FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
6424         FND_MSG_PUB.add;
6425         RAISE FND_API.G_EXC_ERROR;
6426       END IF;
6427     END IF; -- Check Complete Workorder Flag
6428 
6429   END LOOP; -- Iterate all MR Workorders
6430 
6431   -- Add the UE Workorder for Updates
6432   -- Do not process UE Workorders if it is already Complete
6433   IF ( l_mr_rec.wo_status_code <> G_JOB_STATUS_COMPLETE AND
6434        l_mr_rec.wo_status_code <> G_JOB_STATUS_COMPLETE_NC AND
6435        l_mr_rec.wo_status_code <> G_JOB_STATUS_CLOSED AND
6436        l_mr_rec.wo_status_code <> G_JOB_STATUS_CANCELLED ) THEN
6437 
6438     -- Check if Jobs and Operations need to be completed
6439     IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' ) THEN
6440 
6441       -- Validate Whether Quality Results are submitted for WO
6442       IF ( l_mr_rec.wo_plan_id IS NOT NULL AND
6443            l_mr_rec.wo_collection_id IS NULL ) THEN
6444         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_QA_PENDING' );
6445         FND_MESSAGE.set_token( 'WO_NAME', l_mr_rec.workorder_name );
6446         FND_MSG_PUB.add;
6447         RAISE FND_API.G_EXC_ERROR;
6448       END IF;
6449 
6450       -- Add the UE Master WO to the Workorder Table of Records
6451       l_ctr := l_ctr + 1;
6452       l_workorder_tbl(l_ctr).workorder_id := l_mr_rec.workorder_id;
6453       l_workorder_tbl(l_ctr).object_version_number := l_mr_rec.wo_object_version_number;
6454       l_workorder_tbl(l_ctr).workorder_name := l_mr_rec.workorder_name;
6455       l_workorder_tbl(l_ctr).wip_entity_id := l_mr_rec.wip_entity_id;
6456 						-- fix mde for bug 4087041
6457 						-- master_wo_flag cannot be hardcoded to Y in this case because
6458 						-- this may also be an unassociated task created after SR creation from Production
6459       l_workorder_tbl(l_ctr).master_workorder_flag := l_mr_rec.master_workorder_flag; --'Y';
6460       l_workorder_tbl(l_ctr).collection_id := l_mr_rec.wo_collection_id;
6461 						-- fix mde for bug 4087041
6462 						-- now since the master_wo_flag may be 'N', we cannot hardcode actual dates to null
6463 						IF l_workorder_tbl(l_ctr).master_workorder_flag = 'N' THEN
6464 						 -- Check if the Input Actual dates are required
6465        /*Start ER # 4757222
6466        IF ( p_signoff_mr_rec.default_actual_dates_flag = 'N' ) THEN
6467 
6468         -- Validate if the actual start dates entered is less than any WO
6469         IF ( l_mr_rec.actual_start_date IS NOT NULL AND
6470              l_mr_rec.actual_start_date < p_signoff_mr_rec.actual_start_date ) THEN
6471           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_ST_DATE_LESS' );
6472           FND_MESSAGE.set_token( 'WO_NAME', l_mr_rec.workorder_name );
6473           FND_MESSAGE.set_token( 'START_DT', TO_CHAR( l_mr_rec.actual_start_date , 'DD-MON-YYYY HH24:MI' ) );
6474           FND_MSG_PUB.add;
6475           RAISE FND_API.G_EXC_ERROR;
6476         END IF;
6477 
6478         -- Validate if the actual end dates entered is greater than any WO
6479         IF ( l_mr_rec.actual_end_date IS NOT NULL AND
6480              l_mr_rec.actual_end_date > p_signoff_mr_rec.actual_end_date ) THEN
6481           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_END_DATE_GT' );
6482           FND_MESSAGE.set_token( 'WO_NAME', l_mr_rec.workorder_name );
6483           FND_MESSAGE.set_token( 'END_DT', TO_CHAR( l_mr_rec.actual_end_date , 'DD-MON-YYYY HH24:MI' ) );
6484           FND_MSG_PUB.add;
6485           RAISE FND_API.G_EXC_ERROR;
6486         END IF;
6487 
6488       END IF; -- Check Input Dates are required
6489        */--End ER # 4757222
6490        l_workorder_tbl(l_ctr).actual_start_date := l_mr_rec.actual_start_date;
6491        l_workorder_tbl(l_ctr).actual_end_date := l_mr_rec.actual_start_date;
6492 
6493  	/*Start ER # 4757222
6494  									-- Check if Actual Date is already entered
6495           IF ( l_mr_rec.actual_start_date IS NULL ) THEN
6496 	    -- R12
6497             -- Actual dates are no longer defaulted from scheduled dates
6498 	    -- They are defaulted in the Completions API to the res txn dates
6499 	    -- if p_default flag is passed as FND_API.G_TRUE
6500 
6501             /*IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
6502               -- Update Actual Date with Scheduled Date
6503               l_workorder_tbl(l_ctr).actual_start_date := l_mr_rec.scheduled_start_date;
6504             ELSE
6505               -- Update Actual Date with User Entered Value
6506               l_workorder_tbl(l_ctr).actual_start_date := p_signoff_mr_rec.actual_start_date;
6507             END IF;
6508 	    */
6509             /*IF ( p_signoff_mr_rec.default_actual_dates_flag = 'N' ) THEN
6510               -- Update Actual Date with User Entered Value
6511               l_workorder_tbl(l_ctr).actual_start_date := p_signoff_mr_rec.actual_start_date;
6512             END IF;
6513           ELSE
6514             -- Update Actual Date with DB Value if already entered
6515             l_workorder_tbl(l_ctr).actual_start_date := l_mr_rec.actual_start_date;
6516           END IF;
6517 
6518           -- Check if Actual Date is already entered
6519           IF ( l_mr_rec.actual_end_date IS NULL ) THEN
6520             IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
6521               -- Update Actual Date with Scheduled Date
6522               l_workorder_tbl(l_ctr).actual_end_date := LEAST( SYSDATE , l_mr_rec.scheduled_end_date );
6523             ELSE
6524               -- Update Actual Date with User Entered Value
6525               l_workorder_tbl(l_ctr).actual_end_date := p_signoff_mr_rec.actual_end_date;
6526             END IF;
6527           ELSE
6528             -- Update Actual Date with DB Value if already entered
6529             l_workorder_tbl(l_ctr).actual_end_date := l_mr_rec.actual_end_date;
6530           END IF;
6531           */--End ER # 4757222
6532 
6533 						 ELSE
6534       -- Reset Actual Date of UE Master WO
6535       l_workorder_tbl(l_ctr).actual_start_date := NULL;
6536       l_workorder_tbl(l_ctr).actual_end_date := NULL;
6537 						END IF;
6538 						-- end of changes for 4087041
6539 
6540     END IF; -- Check Complet Jobs Flag
6541 
6542   END IF; -- Check Complete UE
6543 
6544   /* Bug # 4955278 - start */
6545   /*
6546    * Interchanged resource transaction logic before processing operations
6547    */
6548   l_ctr := 0;
6549 
6550   IF ( G_DEBUG = 'Y' ) THEN
6551     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6552     || ' : Before Processing Resource Transactions' );
6553   END IF;
6554 
6555   -- Check if Resources need to transacted
6556   IF ( p_signoff_mr_rec.transact_resource_flag = 'Y' ) THEN
6557 
6558     -- Get all the Resource Requirements for the UE Operations
6559     FOR res_csr IN get_ue_resource_req( l_mr_rec.wip_entity_id ) LOOP
6560 
6561       -- Validate if Equipment is entered for Machine Type Resource
6562       IF ( res_csr.resource_type = 1 AND
6563            ( p_signoff_mr_rec.serial_number IS NULL OR
6564              p_signoff_mr_rec.serial_number = FND_API.G_MISS_CHAR ) ) THEN
6565         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MACH_RES_REQD' );
6566         FND_MESSAGE.set_token( 'WO_NAME', res_csr.workorder_name );
6567         FND_MESSAGE.set_token( 'OP_SEQ', res_csr.operation_seq_num );
6568         FND_MESSAGE.set_token( 'RES_SEQ', res_csr.resource_seq_num );
6569         FND_MSG_PUB.add;
6570         RAISE FND_API.G_EXC_ERROR;
6571       END IF;
6572 
6573       -- Validate if Technicain is entered for Person Type Resource
6574       IF ( res_csr.resource_type = 2 AND
6575            ( p_signoff_mr_rec.employee_number IS NULL OR
6576              p_signoff_mr_rec.employee_number = FND_API.G_MISS_CHAR ) ) THEN
6577         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EMP_RES_REQD' );
6578         FND_MESSAGE.set_token( 'WO_NAME', res_csr.workorder_name );
6579         FND_MESSAGE.set_token( 'OP_SEQ', res_csr.operation_seq_num );
6580         FND_MESSAGE.set_token( 'RES_SEQ', res_csr.resource_seq_num );
6581         FND_MSG_PUB.add;
6582         RAISE FND_API.G_EXC_ERROR;
6583       END IF;
6584 
6585       -- Add the Resource Requirement in a Table for processing transactions
6586       l_ctr := l_ctr + 1;
6587       l_resource_req_tbl(l_ctr).wip_entity_id := res_csr.wip_entity_id;
6588       l_resource_req_tbl(l_ctr).workorder_name := res_csr.workorder_name;
6589       l_resource_req_tbl(l_ctr).workorder_id  := res_csr.workorder_id;
6590       l_resource_req_tbl(l_ctr).operation_seq_num := res_csr.operation_seq_num;
6591       l_resource_req_tbl(l_ctr).workorder_operation_id := res_csr.workorder_operation_id;
6592       l_resource_req_tbl(l_ctr).resource_seq_num := res_csr.resource_seq_num;
6593       l_resource_req_tbl(l_ctr).organization_id := res_csr.organization_id;
6594       l_resource_req_tbl(l_ctr).department_id := res_csr.department_id;
6595       l_resource_req_tbl(l_ctr).resource_name := res_csr.resource_name;
6596       l_resource_req_tbl(l_ctr).resource_id := res_csr.resource_id;
6597       l_resource_req_tbl(l_ctr).resource_type := res_csr.resource_type;
6598       l_resource_req_tbl(l_ctr).uom_code := res_csr.uom_code;
6599       l_resource_req_tbl(l_ctr).usage_rate_or_amount := res_csr.usage_rate_or_amount;
6600 
6601     END LOOP; -- Iterate Resource Requirements
6602 
6603 
6604     -- Code added by balaji for bug # 4955278
6605     -- Above loop doesnt fetch res req for operations belonging to
6606     -- a workorder originated out of NR created in production floor or
6607     -- a workorder created out of unassociated task which will not have
6608     -- any related workorders. Hence this need to be processed seperately
6609     -- as below.
6610     -- Get all the Resource Requirements for the UE Operations
6611     IF l_ctr = 0 THEN
6612 	    FOR unass_res_csr IN get_unass_ue_resource_req( l_mr_rec.wip_entity_id ) LOOP
6613 
6614 	      -- Validate if Equipment is entered for Machine Type Resource
6615 	      IF ( unass_res_csr.resource_type = 1 AND
6616 		   ( p_signoff_mr_rec.serial_number IS NULL OR
6617 		     p_signoff_mr_rec.serial_number = FND_API.G_MISS_CHAR ) ) THEN
6618 		FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MACH_RES_REQD' );
6619 		FND_MESSAGE.set_token( 'WO_NAME', unass_res_csr.workorder_name );
6620 		FND_MESSAGE.set_token( 'OP_SEQ', unass_res_csr.operation_seq_num );
6621 		FND_MESSAGE.set_token( 'RES_SEQ', unass_res_csr.resource_seq_num );
6622 		FND_MSG_PUB.add;
6623 		RAISE FND_API.G_EXC_ERROR;
6624 	      END IF;
6625 
6626 	      -- Validate if Technicain is entered for Person Type Resource
6627 	      IF ( unass_res_csr.resource_type = 2 AND
6628 		   ( p_signoff_mr_rec.employee_number IS NULL OR
6629 		     p_signoff_mr_rec.employee_number = FND_API.G_MISS_CHAR ) ) THEN
6630 		FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EMP_RES_REQD' );
6631 		FND_MESSAGE.set_token( 'WO_NAME', unass_res_csr.workorder_name );
6632 		FND_MESSAGE.set_token( 'OP_SEQ', unass_res_csr.operation_seq_num );
6633 		FND_MESSAGE.set_token( 'RES_SEQ', unass_res_csr.resource_seq_num );
6634 		FND_MSG_PUB.add;
6635 		RAISE FND_API.G_EXC_ERROR;
6636 	      END IF;
6637 
6638 	      -- Add the Resource Requirement in a Table for processing transactions
6639 	      l_ctr := l_ctr + 1;
6640 	      l_resource_req_tbl(l_ctr).wip_entity_id := unass_res_csr.wip_entity_id;
6641 	      l_resource_req_tbl(l_ctr).workorder_name := unass_res_csr.workorder_name;
6642 	      l_resource_req_tbl(l_ctr).workorder_id  := unass_res_csr.workorder_id;
6643 	      l_resource_req_tbl(l_ctr).operation_seq_num := unass_res_csr.operation_seq_num;
6644 	      l_resource_req_tbl(l_ctr).workorder_operation_id := unass_res_csr.workorder_operation_id;
6645 	      l_resource_req_tbl(l_ctr).resource_seq_num := unass_res_csr.resource_seq_num;
6646 	      l_resource_req_tbl(l_ctr).organization_id := unass_res_csr.organization_id;
6647 	      l_resource_req_tbl(l_ctr).department_id := unass_res_csr.department_id;
6648 	      l_resource_req_tbl(l_ctr).resource_name := unass_res_csr.resource_name;
6649 	      l_resource_req_tbl(l_ctr).resource_id := unass_res_csr.resource_id;
6650 	      l_resource_req_tbl(l_ctr).resource_type := unass_res_csr.resource_type;
6651 	      l_resource_req_tbl(l_ctr).uom_code := unass_res_csr.uom_code;
6652 	      l_resource_req_tbl(l_ctr).usage_rate_or_amount := unass_res_csr.usage_rate_or_amount;
6653 
6654 	    END LOOP; -- Iterate Resource Requirements
6655     END IF;
6656 
6657     l_ctr := 0;
6658 
6659   END IF; -- Check Transact Resource Flag
6660 
6661   IF ( G_DEBUG = 'Y' ) THEN
6662     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6663     || ' : Before Calling resource request table:' ||l_resource_req_tbl.COUNT);
6664   END IF;
6665 
6666   IF ( l_resource_req_tbl.COUNT > 0 ) THEN
6667 
6668     -- Get the Employee ID of Technician
6669     /* SELECT  person_id
6670     INTO    l_employee_id
6671     FROM    PER_PEOPLE_F
6672     WHERE   employee_number = p_signoff_mr_rec.employee_number
6673       AND   rownum = 1; */
6674 
6675     BEGIN
6676        -- Fix for bug# 4553747.
6677        SELECT employee_id
6678        INTO l_employee_id
6679        FROM  mtl_employees_current_view
6680        WHERE organization_id = l_mr_rec.organization_id
6681          AND employee_num =   p_signoff_mr_rec.employee_number
6682          AND rownum = 1;
6683     EXCEPTION
6684       WHEN no_data_found THEN
6685         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EMPLOYEE_NOT_FOUND' );
6686         FND_MESSAGE.set_token( 'EMP_NUM', p_signoff_mr_rec.employee_number );
6687         FND_MSG_PUB.add;
6688         RAISE FND_API.G_EXC_ERROR;
6689     END;
6690 
6691     /*IF ( SQL%NOTFOUND ) THEN
6692       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EMPLOYEE_NOT_FOUND' );
6693       FND_MESSAGE.set_token( 'EMP_NUM', p_signoff_mr_rec.employee_number );
6694       FND_MSG_PUB.add;
6695       RAISE FND_API.G_EXC_ERROR;
6696     END IF;*/
6697 
6698     -- Process all Resource Requirements
6699     FOR i IN l_resource_req_tbl.FIRST..l_resource_req_tbl.LAST LOOP
6700 
6701       -- Get the Resource Transactions performed against a Requirement
6702       OPEN  get_resource_txns( l_resource_req_tbl(i).wip_entity_id,
6703                                l_resource_req_tbl(i).operation_seq_num,
6704                                l_resource_req_tbl(i).resource_seq_num);
6705       FETCH get_resource_txns
6706       INTO  l_txn_qty;
6707       CLOSE get_resource_txns;
6708 
6709       /*
6710       IF ( l_transaction_qty > 0 ) THEN
6711 
6712         -- Subtract the consumed quantity from the required quantity
6713         l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).usage_rate_or_amount - l_transaction_qty;
6714         l_transaction_qty := 0;
6715       END IF;
6716       */
6717       -- Get the Pending Resource Transactions performed against a Requirement
6718       OPEN  get_pending_resource_txns( l_resource_req_tbl(i).wip_entity_id,
6719                                        l_resource_req_tbl(i).operation_seq_num,
6720                                        l_resource_req_tbl(i).resource_seq_num);
6721       FETCH get_pending_resource_txns
6722       INTO  l_pending_txn_qty;
6723       CLOSE get_pending_resource_txns;
6724 
6725       /*
6726       IF ( l_transaction_qty > 0 ) THEN
6727         IF ( l_resource_req_tbl(i).transaction_quantity <> 0 ) THEN
6728 
6729           -- Subtract the consumed quantity from the required quantity
6730           l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).transaction_quantity - l_transaction_qty;
6731         ELSE
6732 
6733           -- Subtract the consumed quantity from the required quantity
6734           l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).usage_rate_or_amount - l_transaction_qty;
6735         END IF;
6736 
6737         l_transaction_qty := 0;
6738       END IF;
6739       */
6740 
6741       -- Subtract the consumed quantity from the required quantity
6742       l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).usage_rate_or_amount - l_txn_qty - l_pending_txn_qty;
6743 
6744       IF ( G_DEBUG = 'Y' ) THEN
6745 	    AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6746 	    || ' :l_resource_req_tbl(i).usage_rate_or_amount--> :' ||l_resource_req_tbl(i).usage_rate_or_amount);
6747 	     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6748 	    || ' :l_txn_qty--> :' ||l_txn_qty);
6749 	     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6750 	    || ' :l_txn_qty--> :' ||l_pending_txn_qty);
6751       END IF;
6752 
6753       -- If the required qty is greater than zero then txn needs to be performed
6754       IF ( l_resource_req_tbl(i).transaction_quantity > 0 ) THEN
6755 
6756         -- Add a Resource Transaction Record
6757         l_ctr := l_ctr + 1;
6758 
6759         /*
6760         l_res_txn_tbl(l_ctr).wip_entity_id := l_resource_req_tbl(i).wip_entity_id;
6761         --l_res_txn_tbl(l_ctr).organization_id := l_resource_req_tbl(i).organization_id;
6762         l_res_txn_tbl(l_ctr).department_id := l_resource_req_tbl(i).department_id;
6763         l_res_txn_tbl(l_ctr).operation_seq_num := l_resource_req_tbl(i).operation_seq_num;
6764         l_res_txn_tbl(l_ctr).resource_seq_num := l_resource_req_tbl(i).resource_seq_num;
6765         l_res_txn_tbl(l_ctr).resource_id := l_resource_req_tbl(i).resource_id;
6766         l_res_txn_tbl(l_ctr).transaction_quantity := l_resource_req_tbl(i).transaction_quantity;
6767         l_res_txn_tbl(l_ctr).transaction_uom := l_resource_req_tbl(i).uom_code;
6768         */
6769 
6770 
6771         l_prd_resrc_txn_tbl(l_ctr).workorder_id := l_resource_req_tbl(i).workorder_id;
6772         l_prd_resrc_txn_tbl(l_ctr).organization_id := l_resource_req_tbl(i).organization_id;
6773         l_prd_resrc_txn_tbl(l_ctr).dml_operation := 'C';
6774         l_prd_resrc_txn_tbl(l_ctr).operation_sequence_num := l_resource_req_tbl(i).operation_seq_num;
6775         l_prd_resrc_txn_tbl(l_ctr).workorder_operation_id := l_resource_req_tbl(i).workorder_operation_id;
6776         l_prd_resrc_txn_tbl(l_ctr).resource_sequence_num := l_resource_req_tbl(i).resource_seq_num;
6777         l_prd_resrc_txn_tbl(l_ctr).resource_id := l_resource_req_tbl(i).resource_id;
6778         l_prd_resrc_txn_tbl(l_ctr).resource_name := l_resource_req_tbl(i).resource_name;
6779 
6780         l_prd_resrc_txn_tbl(l_ctr).department_id := l_resource_req_tbl(i).department_id;
6781 
6782         l_prd_resrc_txn_tbl(l_ctr).qty := l_resource_req_tbl(i).transaction_quantity;
6783         l_prd_resrc_txn_tbl(l_ctr).uom_code := l_resource_req_tbl(i).uom_code;
6784 
6785         -- Pass the Employee ID or the Serial Number
6786         IF ( l_resource_req_tbl(i).resource_type = 2 ) THEN
6787           --l_res_txn_tbl(l_ctr).employee_id := l_employee_id;
6788           l_prd_resrc_txn_tbl(l_ctr).employee_num := p_signoff_mr_rec.employee_number;
6789         ELSIF ( l_resource_req_tbl(i).resource_type = 1 ) THEN
6790           --l_res_txn_tbl(l_ctr).serial_number := p_signoff_mr_rec.serial_number;
6791           l_prd_resrc_txn_tbl(l_ctr).serial_number := p_signoff_mr_rec.serial_number;
6792         END IF;
6793 
6794       END IF; -- Check Txn Required
6795 
6796     END LOOP; -- Iterate Requirements
6797 
6798     IF ( G_DEBUG = 'Y' ) THEN
6799 	    AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6800 	    || ' : size of l_prd_resrc_txn_tbl is:' ||l_prd_resrc_txn_tbl.COUNT);
6801     END IF;
6802 
6803     --IF ( l_res_txn_tbl.COUNT > 0 ) THEN
6804     IF ( l_prd_resrc_txn_tbl.COUNT > 0 ) THEN
6805 
6806       -- Perform the Resource Txns
6807 
6808       /*
6809       AHL_WIP_JOB_PVT.insert_resource_txn
6810       (
6811         p_api_version        => 1.0,
6812         p_init_msg_list      => FND_API.G_FALSE,
6813         p_commit             => FND_API.G_FALSE,
6814         p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
6815         x_return_status      => l_return_status,
6816         x_msg_count          => l_msg_count,
6817         x_msg_data           => l_msg_data,
6818         p_ahl_res_txn_tbl    => l_res_txn_tbl
6819       );
6820       */
6821 
6822       AHL_PRD_RESOURCE_TRANX_PVT.PROCESS_RESOURCE_TXNS
6823       (
6824         p_api_version        => 1.0,
6825         p_init_msg_list      => FND_API.G_FALSE,
6826         p_commit             => FND_API.G_FALSE,
6827         p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
6828         x_return_status      => l_return_status,
6829         x_msg_count          => l_msg_count,
6830         x_msg_data           => l_msg_data,
6831         p_x_prd_resrc_txn_tbl => l_prd_resrc_txn_tbl
6832       );
6833 
6834       IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
6835         RAISE FND_API.G_EXC_ERROR;
6836       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
6837         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6838       END IF;
6839 
6840     END IF;
6841 
6842   END IF;
6843   /* Bug # 4955278 - end */
6844 
6845   l_ctr := 0;
6846 
6847   IF ( G_DEBUG = 'Y' ) THEN
6848     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing UE Operations' );
6849   END IF;
6850 
6851   -- Get all the Workorder Operations for the UE
6852   FOR op_csr IN get_ue_operations( l_mr_rec.wip_entity_id ) LOOP
6853 
6854     -- Check if Operations need to be completed
6855     IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' ) THEN
6856 
6857       -- Do not process Workorder Operations which are already Complete
6858       IF ( op_csr.status_code <> G_OP_STATUS_COMPLETE ) THEN
6859 
6860         /*Start ER # 4757222*/
6861         /*
6862          * Moved this validation here since there is no need to validate
6863          * the actual dates entered against completed operations. Need to validate dates
6864          * against only those operations which need to be completed.
6865          */
6866       -- Check if the Input Actual dates are required
6867      /* No need for this validation as the default dates entered by the user should not
6868      -- be modified. Balaji commented out the code for the ER # 4757222
6869       IF ( p_signoff_mr_rec.default_actual_dates_flag = 'N' ) THEN
6870 
6871         -- Validate if the actual start dates entered is less than any WO Op
6872         IF ( op_csr.actual_start_date IS NOT NULL AND
6873              op_csr.actual_start_date < p_signoff_mr_rec.actual_start_date ) THEN
6874           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ACT_ST_DATE_LESS' );
6875           FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
6876           FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
6877           FND_MESSAGE.set_token( 'START_DT', TO_CHAR( op_csr.actual_start_date, 'DD-MON-YYYY HH24:MI' ) );
6878           FND_MSG_PUB.add;
6879           RAISE FND_API.G_EXC_ERROR;
6880         END IF;
6881 
6882         -- Validate if the actual end dates entered is greater than any WO Op
6883         IF ( op_csr.actual_end_date IS NOT NULL AND
6884              op_csr.actual_end_date > p_signoff_mr_rec.actual_end_date ) THEN
6885           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ACT_END_DATE_GT' );
6886           FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
6887           FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
6888           FND_MESSAGE.set_token( 'END_DT', TO_CHAR( op_csr.actual_end_date, 'DD-MON-YYYY HH24:MI' ) );
6889           FND_MSG_PUB.add;
6890           RAISE FND_API.G_EXC_ERROR;
6891         END IF;
6892 
6893       END IF;
6894       */
6895       /*End ER # 4757222*/
6896 
6897         -- Validate whether Quality Results are Submitted
6898         IF ( op_csr.plan_id IS NOT NULL AND
6899              op_csr.collection_id IS NULL ) THEN
6900           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_QA_PENDING' );
6901           FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
6902           FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
6903           FND_MSG_PUB.add;
6904           RAISE FND_API.G_EXC_ERROR;
6905         END IF;
6906 
6907         -- Add the Wo Operation record in the table of records for Completion
6908         l_ctr := l_ctr + 1;
6909         l_operation_tbl(l_ctr).workorder_operation_id := op_csr.workorder_operation_id;
6910         l_operation_tbl(l_ctr).object_version_number := op_csr.object_version_number;
6911         l_operation_tbl(l_ctr).workorder_name := op_csr.workorder_name;
6912         l_operation_tbl(l_ctr).collection_id := op_csr.collection_id;
6913 
6914 	/* Bug # 4955278 - start */
6915 	IF (op_csr.actual_end_date IS NULL OR op_csr.actual_start_date IS NULL)
6916 	   AND
6917 	   (p_signoff_mr_rec.default_actual_dates_flag = 'Y')
6918 	THEN
6919 		-- Derive operation actual dates from res txn dates.
6920 		-- Balaji added this code for R12. Also refer ER # 4955278
6921    		Get_Op_Act_from_Res_Txn( p_wip_entity_id	=>	op_csr.wip_entity_id,
6922 					 p_operation_seq_num	=>	op_csr.operation_seq_num,
6923 					 x_actual_start_date	=>	l_def_actual_start_date,
6924 					 x_actual_end_date	=>	l_def_actual_end_date
6925 					);
6926 
6927 		IF (l_def_actual_start_date IS NULL OR
6928 		    l_def_actual_end_date IS NULL )
6929 		THEN
6930 		  FND_MESSAGE.set_name( 'AHL', 'AHL_OP_DEF_NO_RES_TXN' );
6931 		  FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
6932 		  FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
6933 		  FND_MSG_PUB.add;
6934 		  RAISE FND_API.G_EXC_ERROR;
6935 		END IF;
6936 	END IF;
6937 	/* Bug # 4955278 - end */
6938 
6939 	/*Start ER # 4757222*/
6940 	-- Changed the order of defaulting to be first end date and then start date for
6941 	-- the ER.
6942 	/* Bug # 4955278 - start */
6943         -- Update Actual Date only if it is empty
6944         IF ( op_csr.actual_end_date IS NULL ) THEN
6945           IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
6946             -- Update with Scheduled End Date or SYSDATE
6947             l_operation_tbl(l_ctr).actual_end_date := LEAST( SYSDATE , l_def_actual_end_date );
6948           ELSE
6949             -- Update with User Entered Value
6950             l_operation_tbl(l_ctr).actual_end_date := p_signoff_mr_rec.actual_end_date;
6951           END IF;
6952         ELSE
6953 
6954           -- Update with DB Value
6955           l_operation_tbl(l_ctr).actual_end_date := op_csr.actual_end_date;
6956         END IF;
6957 
6958         -- Update Actual Date only if it is empty
6959         IF ( op_csr.actual_start_date IS NULL ) THEN
6960           IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
6961             -- Update with Scheduled Date
6962             IF ( l_def_actual_start_date < SYSDATE ) THEN
6963                l_operation_tbl(l_ctr).actual_start_date := l_def_actual_start_date;
6964             ELSE
6965                l_operation_tbl(l_ctr).actual_start_date := l_operation_tbl(l_ctr).actual_end_date - (l_def_actual_end_date - l_def_actual_start_date);
6966             END IF;
6967           ELSE
6968             -- Update with User Entered Value
6969             l_operation_tbl(l_ctr).actual_start_date := p_signoff_mr_rec.actual_start_date;
6970           END IF;
6971         ELSE
6972 
6973           -- Update with DB Value
6974           l_operation_tbl(l_ctr).actual_start_date := op_csr.actual_start_date;
6975         END IF;
6976         /*End ER # 4757222*/
6977 	/* Bug # 4955278 - end */
6978         IF ( G_DEBUG = 'Y' ) THEN
6979           AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
6980           || ' : Wo Name - ' || l_operation_tbl(l_ctr).workorder_name
6981           || ' OP Seq - ' || op_csr.operation_seq_num || ' WO OP ID - '
6982           || l_operation_tbl(l_ctr).workorder_operation_id || ' Actual Start Date - '
6983           || TO_CHAR(l_operation_tbl(l_ctr).actual_start_date,'DD-MON-YYYY HH24:MI:SS') || ' Actual End Date - '
6984           || TO_CHAR(l_operation_tbl(l_ctr).actual_end_date,'DD-MON-YYYY HH24:MI:SS') );
6985         END IF;
6986 
6987       END IF;
6988     ELSE
6989 
6990       -- Since Operations are not required to be completed
6991       -- Validate to ensure that the Workorder Ops are already completed
6992       IF ( op_csr.status_code <> G_OP_STATUS_COMPLETE ) THEN
6993         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MR_WO_OP_NOT_CMPL' );
6994         FND_MESSAGE.set_token( 'MAINT_REQ', l_mr_rec.ue_title);
6995         FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
6996         FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
6997         FND_MSG_PUB.add;
6998         RAISE FND_API.G_EXC_ERROR;
6999       END IF;
7000     END IF; -- Check Complete Operations
7001 
7002   END LOOP; -- Iterate Operations
7003 
7004   -- for a ue that is assocaited to an Unassocaited Task created as a result of
7005 		-- SR creation from Production
7006 		-- There will not be any child UE operations and we need to
7007 		-- take in the default operation associated with that workorder
7008   -- bug 4087041
7009  /*Start ER # 4757222*/
7010  --An workorder orginating out of unassociated task(either through unassociated task
7011  --created in production or thorugh the backward flow during NR creation in production)
7012  -- can have multiple operations in it. previous logic doesnt fetch all operations
7013  -- Balaji modified the logic for ER #4757222.
7014  IF l_ctr = 0 THEN
7015 		--OPEN get_unassoc_ue_op(l_mr_rec.wip_entity_id);
7016 		--FETCH get_unassoc_ue_op INTO l_unassoc_ue_op_rec;
7017 		--IF get_unassoc_ue_op%FOUND THEN
7018 		  -- populate the operation table
7019  			-- Check if Operations need to be completed
7020     FOR l_unassoc_ue_op_rec IN get_unassoc_ue_op( l_mr_rec.wip_entity_id )
7021     LOOP
7022 
7023     IF ( G_DEBUG = 'Y' ) THEN
7024        AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7025 	|| ' : Wo op id - ' ||l_unassoc_ue_op_rec.workorder_operation_id);
7026     END IF;
7027 
7028 	    IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' ) THEN
7029 
7030 	      -- Do not process Workorder Operations which are already Complete
7031 	      IF ( l_unassoc_ue_op_rec.status_code <> G_OP_STATUS_COMPLETE ) THEN
7032 
7033 		/*Start ER # 4757222*/
7034 		/*
7035 		 * Moved this validation here since there is no need to validate
7036 		 * the actual dates entered against completed operations. Need to validate dates
7037 		 * against only those operations which need to be completed.
7038 		 */
7039 	      -- Check if the Input Actual dates are required
7040 		/* No need for this validation as the default dates entered by the user should not
7041 		-- be modified. Balaji commented out the code for the ER # 4757222
7042 
7043 	      IF ( p_signoff_mr_rec.default_actual_dates_flag = 'N' ) THEN
7044 
7045 		-- Validate if the actual start dates entered is less than any WO Op
7046 		IF ( l_unassoc_ue_op_rec.actual_start_date IS NOT NULL AND
7047 		     l_unassoc_ue_op_rec.actual_start_date < p_signoff_mr_rec.actual_start_date ) THEN
7048 		  FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ACT_ST_DATE_LESS' );
7049 		  FND_MESSAGE.set_token( 'WO_NAME', l_unassoc_ue_op_rec.workorder_name );
7050 		  FND_MESSAGE.set_token( 'OP_SEQ', l_unassoc_ue_op_rec.operation_seq_num );
7051 		  FND_MESSAGE.set_token( 'START_DT', TO_CHAR( l_unassoc_ue_op_rec.actual_start_date, 'DD-MON-YYYY HH24:MI' ) );
7052 		  FND_MSG_PUB.add;
7053 		  RAISE FND_API.G_EXC_ERROR;
7054 		END IF;
7055 
7056 		-- Validate if the actual end dates entered is greater than any WO Op
7057 		IF ( l_unassoc_ue_op_rec.actual_end_date IS NOT NULL AND
7058 		     l_unassoc_ue_op_rec.actual_end_date > p_signoff_mr_rec.actual_end_date ) THEN
7059 		  FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ACT_END_DATE_GT' );
7060 		  FND_MESSAGE.set_token( 'WO_NAME', l_unassoc_ue_op_rec.workorder_name );
7061 		  FND_MESSAGE.set_token( 'OP_SEQ', l_unassoc_ue_op_rec.operation_seq_num );
7062 		  FND_MESSAGE.set_token( 'END_DT', TO_CHAR( l_unassoc_ue_op_rec.actual_end_date, 'DD-MON-YYYY HH24:MI' ) );
7063 		  FND_MSG_PUB.add;
7064 		  RAISE FND_API.G_EXC_ERROR;
7065 		     END IF;
7066 		END IF; */
7067 		/*End ER # 4757222*/
7068 
7069 
7070 		-- Validate whether Quality Results are Submitted
7071 		IF ( l_unassoc_ue_op_rec.plan_id IS NOT NULL AND
7072 		     l_unassoc_ue_op_rec.collection_id IS NULL ) THEN
7073 		  FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_QA_PENDING' );
7074 		  FND_MESSAGE.set_token( 'WO_NAME', l_unassoc_ue_op_rec.workorder_name );
7075 		  FND_MESSAGE.set_token( 'OP_SEQ', l_unassoc_ue_op_rec.operation_seq_num );
7076 		  FND_MSG_PUB.add;
7077 		  RAISE FND_API.G_EXC_ERROR;
7078 		END IF;
7079 
7080 		-- Add the Wo Operation record in the table of records for Completion
7081 		l_ctr := l_ctr + 1;
7082 		l_operation_tbl(l_ctr).workorder_operation_id := l_unassoc_ue_op_rec.workorder_operation_id;
7083 		l_operation_tbl(l_ctr).object_version_number := l_unassoc_ue_op_rec.object_version_number;
7084 		l_operation_tbl(l_ctr).workorder_name := l_unassoc_ue_op_rec.workorder_name;
7085 		l_operation_tbl(l_ctr).collection_id := l_unassoc_ue_op_rec.collection_id;
7086 
7087 		/* Bug # 4955278 - start */
7088 		IF (l_unassoc_ue_op_rec.actual_end_date IS NULL OR l_unassoc_ue_op_rec.actual_start_date IS NULL)
7089 		   AND
7090 		   (p_signoff_mr_rec.default_actual_dates_flag = 'Y')
7091 		THEN
7092 			-- Derive operation actual dates from res txn dates.
7093 			-- Balaji added this code for R12. Also refer ER # 4955278
7094 			Get_Op_Act_from_Res_Txn( p_wip_entity_id	=>	l_unassoc_ue_op_rec.wip_entity_id,
7095 						 p_operation_seq_num	=>	l_unassoc_ue_op_rec.operation_seq_num,
7096 						 x_actual_start_date	=>	l_def_actual_start_date,
7097 						 x_actual_end_date	=>	l_def_actual_end_date
7098 						);
7099 
7100 			IF (l_def_actual_start_date IS NULL OR l_def_actual_end_date IS NULL )
7101 			THEN
7102 			  FND_MESSAGE.set_name( 'AHL', 'AHL_OP_DEF_NO_RES_TXN' );
7103 			  FND_MESSAGE.set_token( 'WO_NAME', l_unassoc_ue_op_rec.workorder_name );
7104 			  FND_MESSAGE.set_token( 'OP_SEQ', l_unassoc_ue_op_rec.operation_seq_num );
7105 			  FND_MSG_PUB.add;
7106 			  RAISE FND_API.G_EXC_ERROR;
7107 			END IF;
7108 		END IF;
7109 		/* Bug # 4955278 - end */
7110 
7111 		-- Update Actual Date only if it is empty
7112 		/* Bug # 4955278 - start */
7113 		IF ( l_unassoc_ue_op_rec.actual_end_date IS NULL ) THEN
7114 		  IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
7115 		    -- Update with Scheduled End Date or SYSDATE
7116 		    l_operation_tbl(l_ctr).actual_end_date := LEAST( SYSDATE , l_def_actual_end_date );
7117 		  ELSE
7118 		    -- Update with User Entered Value
7119 		    l_operation_tbl(l_ctr).actual_end_date := p_signoff_mr_rec.actual_end_date;
7120 		  END IF;
7121 		ELSE
7122 
7123 		  -- Update with DB Value
7124 		  l_operation_tbl(l_ctr).actual_end_date := l_unassoc_ue_op_rec.actual_end_date;
7125 		END IF;
7126 
7127 		-- Update Actual Date only if it is empty
7128 		IF ( l_unassoc_ue_op_rec.actual_start_date IS NULL ) THEN
7129 		  IF ( p_signoff_mr_rec.default_actual_dates_flag = 'Y' ) THEN
7130 
7131 		    -- Update with Scheduled Date
7132 		    IF ( l_def_actual_start_date < SYSDATE ) THEN
7133 		       l_operation_tbl(l_ctr).actual_start_date := l_def_actual_start_date;
7134 		    ELSE
7135 		       l_operation_tbl(l_ctr).actual_start_date := l_operation_tbl(l_ctr).actual_end_date - (l_def_actual_end_date - l_def_actual_start_date);
7136 		    END IF;
7137 		  ELSE
7138 
7139 		    -- Update with User Entered Value
7140 		    l_operation_tbl(l_ctr).actual_start_date := p_signoff_mr_rec.actual_start_date;
7141 		  END IF;
7142 		ELSE
7143 
7144 		  -- Update with DB Value
7145 		  l_operation_tbl(l_ctr).actual_start_date := l_unassoc_ue_op_rec.actual_start_date;
7146 		END IF;
7147 		/* Bug # 4955278 - end */
7148 
7149 		IF ( G_DEBUG = 'Y' ) THEN
7150 		  AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7151 		  || ' : Wo Name - ' || l_operation_tbl(l_ctr).workorder_name
7152 		  || ' OP Seq - ' || l_unassoc_ue_op_rec.operation_seq_num || ' WO OP ID - '
7153 		  || l_operation_tbl(l_ctr).workorder_operation_id || ' Actual Start Date - '
7154 		  || l_operation_tbl(l_ctr).actual_start_date || ' Actual End Date - '
7155 		  || l_operation_tbl(l_ctr).actual_end_date );
7156 		END IF;
7157 
7158 	      END IF;
7159 	    ELSE
7160 
7161 	      -- Since Operations are not required to be completed
7162 	      -- Validate to ensure that the Workorder Ops are already completed
7163 	      IF ( l_unassoc_ue_op_rec.status_code <> G_OP_STATUS_COMPLETE ) THEN
7164 		FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MR_WO_OP_NOT_CMPL' );
7165 		FND_MESSAGE.set_token( 'MAINT_REQ', l_mr_rec.ue_title);
7166 		FND_MESSAGE.set_token( 'WO_NAME', l_unassoc_ue_op_rec.workorder_name );
7167 		FND_MESSAGE.set_token( 'OP_SEQ', l_unassoc_ue_op_rec.operation_seq_num );
7168 		FND_MSG_PUB.add;
7169 		RAISE FND_API.G_EXC_ERROR;
7170 	      END IF;
7171 	    END IF; -- complete_job_ops_flag
7172      END LOOP;
7173    END IF; -- IF l_ctr = 0 THEN
7174  -- end of changes for bug 4087041
7175 
7176   IF ( G_DEBUG = 'Y' ) THEN
7177     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7178     || ' : Before Updating Operations. Total - ' || l_operation_tbl.COUNT );
7179   END IF;
7180 
7181   -- R12
7182   -- If the dates are being defaulted, then Operation updates will be performed in the Completions API
7183   -- otherwise perform the Operation Updates for Actual Dates
7184 
7185   --Balaji remvoed default_actual_dates_flag = 'N' condition for bug # 4955278
7186   IF ( p_signoff_mr_rec.complete_job_ops_flag = 'Y' )
7187 
7188    -- AND p_signoff_mr_rec.default_actual_dates_flag = 'N' )
7189   THEN
7190 
7191   IF ( l_operation_tbl.COUNT > 0 ) THEN
7192     FOR i IN l_operation_tbl.FIRST..l_operation_tbl.LAST LOOP
7193       UPDATE  AHL_WORKORDER_OPERATIONS
7194       SET     object_version_number = object_version_number + 1,
7195               actual_start_date = l_operation_tbl(i).actual_start_date,
7196               actual_end_date = l_operation_tbl(i).actual_end_date,
7197               LAST_UPDATE_DATE = SYSDATE,
7198               LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
7199               LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
7200       WHERE   workorder_operation_id = l_operation_tbl(i).workorder_operation_id
7201       AND     object_version_number = l_operation_tbl(i).object_version_number;
7202 
7203       IF ( SQL%ROWCOUNT = 0 ) THEN
7204         FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
7205         FND_MSG_PUB.add;
7206         RAISE FND_API.G_EXC_ERROR;
7207       END IF;
7208 
7209       --Balaji-debug
7210       IF ( G_DEBUG = 'Y' ) THEN
7211         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7212         || ' : Actual start date - ' || to_char(l_operation_tbl(i).actual_start_date,'DD-MM-YYYY HH24:MI'));
7213         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7214         || ' : Actual end date - ' || to_char(l_operation_tbl(i).actual_end_date,'DD-MM-YYYY HH24:MI'));
7215       END IF;
7216 
7217       l_operation_tbl(i).object_version_number := l_operation_tbl(i).object_version_number + 1;
7218     END LOOP;
7219   END IF;
7220   END IF;
7221 
7222   IF ( G_DEBUG = 'Y' ) THEN
7223     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7224     || ' : Before Updating Workorders. Total - ' || l_workorder_tbl.COUNT );
7225   END IF;
7226 
7227 
7228   IF ( G_DEBUG = 'Y' ) THEN
7229     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Completing Operations' );
7230   END IF;
7231 
7232   -- Invoke Complete Operation API to Complete All Operations
7233   IF ( l_operation_tbl.COUNT > 0 ) THEN
7234     FOR i IN l_operation_tbl.FIRST..l_operation_tbl.LAST LOOP
7235 
7236       IF ( G_DEBUG = 'Y' ) THEN
7237         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7238         || ' : Before Completing Operation - ' || l_operation_tbl(i).workorder_operation_id );
7239       END IF;
7240 
7241       -- R12
7242       -- The actual dates are defaulted from the resource txn dates
7243       -- instead of the scheduled dates
7244       -- This is taken care of in the Completions API if the p_default param
7245       -- is passed as FND_API.G_TRUE
7246       l_default := FND_API.G_FALSE;
7247       IF (p_signoff_mr_rec.complete_job_ops_flag = 'Y' AND p_signoff_mr_rec.default_actual_dates_flag = 'Y') THEN
7248         l_default := FND_API.G_TRUE;
7249       END IF;
7250 
7251       complete_operation
7252       (
7253         p_api_version            => 1.0,
7254         p_init_msg_list          => FND_API.G_FALSE,
7255         p_commit                 => FND_API.G_FALSE,
7256         p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
7257         p_default                => l_default,
7258         p_module_type            => NULL,
7259         x_return_status          => l_return_status,
7260         x_msg_count              => l_msg_count,
7261         x_msg_data               => l_msg_data,
7262         p_workorder_operation_id => l_operation_tbl(i).workorder_operation_id,
7263         p_object_version_no      => l_operation_tbl(i).object_version_number
7264       );
7265 
7266       IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7267         RAISE FND_API.G_EXC_ERROR;
7268       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7269         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7270       END IF;
7271 
7272     END LOOP;
7273   END IF;
7274 
7275   -- perform the Job Updates for Actual Dates after updating operation actuals and completing operations
7276 
7277   IF ( l_workorder_tbl.COUNT > 0 ) THEN
7278     FOR i IN l_workorder_tbl.FIRST..l_workorder_tbl.LAST LOOP
7279      /*Start ER # 4757222*/
7280      -- Do not update Master Wos because they are post processed separately
7281      IF ( l_workorder_tbl(i).master_workorder_flag = 'N' AND
7282           p_signoff_mr_rec.complete_job_ops_flag  = 'Y') THEN
7283     -- Workorder actual dates need to be defaulted from the resource txn dates
7284     -- retrieve the workorder actual dates
7285 
7286 
7287     OPEN get_wo_dates(l_workorder_tbl(i).workorder_id);
7288     FETCH get_wo_dates INTO l_wo_actual_start_date, l_wo_actual_end_date, l_wo_name;
7289     IF get_wo_dates%NOTFOUND THEN
7290       CLOSE get_wo_dates;
7291       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_DEF_ERROR' );
7292       -- Error defaulting the actual dates for workorder WO_NAME before completion.
7293       -- Do we raise an error for this or just ignore the error since this is defaulting code?
7294       -- Check during UTs
7295       FND_MSG_PUB.add;
7296       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7297     END IF; -- IF get_wo_dates %NOTFOUND THEN
7298     CLOSE get_wo_dates;
7299 
7300     Get_default_wo_actual_dates(x_return_status => l_return_status,
7301                                 p_workorder_id => l_workorder_tbl(i).workorder_id,
7302 				x_actual_start_date => l_def_actual_start_date,
7303 				x_actual_end_date => l_def_actual_end_date
7304 				);
7305     IF l_return_status <> FND_API. G_RET_STS_SUCCESS THEN
7306       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_DEF_ERROR' );
7307       FND_MSG_PUB.add;
7308       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7309     END IF;
7310 
7311     -- update the actual dates in the table
7312     IF l_wo_actual_start_date IS NULL THEN
7313       UPDATE AHL_WORKORDERS
7314       SET OBJECT_VERSION_NUMBER = OBJECT_VERSION_NUMBER + 1,
7315       ACTUAL_START_DATE = l_def_actual_start_date,
7316       LAST_UPDATE_DATE = SYSDATE,
7317       LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
7318       LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
7319       WHERE WORKORDER_ID = l_workorder_tbl(i).workorder_id
7320       AND OBJECT_VERSION_NUMBER = l_workorder_tbl(i).object_version_number;
7321       IF SQL%ROWCOUNT = 0 THEN
7322         FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
7323 	FND_MESSAGE.set_token('WO_NAME', l_wo_name);
7324    	FND_MSG_PUB.add;
7325         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7326       END IF;
7327       l_workorder_tbl(i).object_version_number := l_workorder_tbl(i).object_version_number + 1;
7328     END IF;-- IF l_actual_start_date IS NULL THEN
7329 
7330     -- update the actual dates in the table
7331     IF l_wo_actual_end_date IS NULL THEN
7332       UPDATE AHL_WORKORDERS
7333       SET OBJECT_VERSION_NUMBER = OBJECT_VERSION_NUMBER + 1,
7334       ACTUAL_END_DATE = l_def_actual_end_date,
7335       LAST_UPDATE_DATE = SYSDATE,
7336       LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
7337       LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
7338       WHERE WORKORDER_ID = l_workorder_tbl(i).workorder_id
7339       AND OBJECT_VERSION_NUMBER = l_workorder_tbl(i).object_version_number;
7340       IF SQL%ROWCOUNT = 0 THEN
7341         FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
7342 	FND_MESSAGE.set_token('WO_NAME', l_wo_name);
7343    	FND_MSG_PUB.add;
7344         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7345       END IF;
7346       l_workorder_tbl(i).object_version_number := l_workorder_tbl(i).object_version_number + 1;
7347     END IF; -- IF l_actual_end_date IS NULL THEN
7348     /*ELSE
7349 
7350         UPDATE  AHL_WORKORDERS
7351         SET     object_version_number = object_version_number + 1,
7352                 actual_start_date = l_workorder_tbl(i).actual_start_date,
7353                 actual_end_date = l_workorder_tbl(i).actual_end_date,
7354                 LAST_UPDATE_DATE = SYSDATE,
7355                 LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
7356                 LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
7357         WHERE   workorder_id = l_workorder_tbl(i).workorder_id
7358         AND     object_version_number = l_workorder_tbl(i).object_version_number;
7359 
7360         IF ( SQL%ROWCOUNT = 0 ) THEN
7361           FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
7362           FND_MSG_PUB.add;
7363           RAISE FND_API.G_EXC_ERROR;
7364         END IF;
7365 
7366         l_workorder_tbl(i).object_version_number := l_workorder_tbl(i).object_version_number + 1;*/
7367     END IF; --IF (complete_job_ops_flag = 'Y' AND default_actual_dates_flag = 'Y') THEN
7368     --END IF; -- IF ( l_workorder_tbl(i).master_workorder_flag = 'N' ) THEN
7369 
7370     END LOOP;
7371 
7372     -- Check if Workorders need to be completed
7373     IF (p_signoff_mr_rec.complete_job_ops_flag = 'Y' AND p_signoff_mr_rec.default_actual_dates_flag = 'N') THEN
7374 
7375       l_actual_start_date := p_signoff_mr_rec.actual_start_date;
7376       l_actual_end_date := p_signoff_mr_rec.actual_end_date;
7377     END IF;
7378     IF ( G_DEBUG = 'Y' ) THEN
7379       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Updating Master Workorders' );
7380     END IF;
7381 
7382     -- Update the Actual Dates for Master Workorders in the Visit
7383     l_return_status :=
7384     update_mwo_actual_dates
7385     (
7386       p_wip_entity_id     => l_mr_rec.visit_wip_entity_id,
7387       p_default_flag      => p_signoff_mr_rec.default_actual_dates_flag,
7388       p_actual_start_date => l_actual_start_date,
7389       p_actual_end_date   => l_actual_end_date
7390     );
7391 
7392     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7393       RAISE FND_API.G_EXC_ERROR;
7394     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7395       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7396     END IF;
7397 
7398   END IF;
7399 
7400 
7401   IF ( G_DEBUG = 'Y' ) THEN
7402     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Completing WOs' );
7403   END IF;
7404 
7405   -- Complete All MR Workorders in the Order of Completion Dependencies
7406   IF ( l_workorder_tbl.COUNT > 0 ) THEN
7407     l_return_status :=
7408     complete_visit_mr_wos
7409     (
7410       p_wip_entity_id   => l_mr_rec.visit_wip_entity_id,
7411       p_x_workorder_tbl => l_workorder_tbl
7412     );
7413 
7414     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7415       RAISE FND_API.G_EXC_ERROR;
7416     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7417       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7418     END IF;
7419 
7420   END IF;
7421 
7422   IF ( G_DEBUG = 'Y' ) THEN
7423     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Completing UEs' );
7424   END IF;
7425 
7426   -- Invoke Complete MR Instance API to Complete All UEs
7427   IF ( l_child_mr_tbl.COUNT > 0 ) THEN
7428     FOR i IN l_child_mr_tbl.FIRST..l_child_mr_tbl.LAST LOOP
7429 
7430       -- Check Status again because UE could be completed automatically
7431       l_ue_status_code := get_mr_status( l_child_mr_tbl(i).unit_effectivity_id );
7432       IF ( l_ue_status_code <> G_MR_STATUS_SIGNED_OFF ) THEN
7433 
7434         IF ( l_ue_status_code <> G_MR_STATUS_JOBS_COMPLETE ) THEN
7435           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INV_SIGNOFF_STATUS');
7436           FND_MESSAGE.set_token( 'MAINT_REQ', l_child_mr_tbl(i).mr_title);
7437   	  -- replacing with call to get_status function
7438 	  -- so no exceptions are thrown if the
7439 	  -- lookup does not exist
7440 	  l_status_meaning := get_status(l_ue_status_code,
7441 	                                 'AHL_PRD_MR_STATUS');
7442 
7443 
7444 	/*SELECT meaning INTO l_status_meaning
7445 	   FROM fnd_lookup_values_vl
7446         WHERE lookup_type = 'AHL_PRD_MR_STATUS'
7447           AND LOOKUP_CODE = l_ue_status_code;
7448         */
7449           FND_MESSAGE.set_token( 'STATUS', l_status_meaning );
7450           FND_MSG_PUB.add;
7451           RAISE FND_API.G_EXC_ERROR;
7452         END IF;
7453 
7454         IF ( G_DEBUG = 'Y' ) THEN
7455           AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7456           || ' : Before Completing MR - ' || l_child_mr_tbl(i).unit_effectivity_id );
7457         END IF;
7458 
7459         complete_mr_instance
7460         (
7461           p_api_version            => 1.0,
7462           p_init_msg_list          => FND_API.G_FALSE,
7463           p_commit                 => FND_API.G_FALSE,
7464           p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
7465           p_default                => FND_API.G_FALSE,
7466           p_module_type            => NULL,
7467           x_return_status          => l_return_status,
7468           x_msg_count              => l_msg_count,
7469           x_msg_data               => l_msg_data,
7470           p_x_mr_rec               => l_child_mr_tbl(i)
7471         );
7472 
7473         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7474           RAISE FND_API.G_EXC_ERROR;
7475         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7476           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7477         END IF;
7478       END IF;
7479 
7480     END LOOP;
7481   END IF;
7482 
7483   IF ( G_DEBUG = 'Y' ) THEN
7484     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Recording Counter Readings' );
7485   END IF;
7486 
7487   -- Record Counter Readings for all WOs
7488   IF ( l_workorder_tbl.COUNT > 0 AND
7489        G_CTR_READING_PLAN_ID IS NOT NULL AND
7490        l_mr_rec.item_instance_id IS NOT NULL ) THEN
7491 
7492     --IF ( l_counter_tbl.COUNT > 0 ) THEN
7493 
7494       -- Record Counter Readings for all the Workorders.
7495       FOR i IN l_workorder_tbl.FIRST..l_workorder_tbl.LAST LOOP
7496 
7497         -- Get the Current Counter Readings for the Item Instance.
7498         -- Bug # 6750836 -- Start
7499         l_return_status :=
7500         get_cp_counters
7501         (
7502           p_item_instance_id  => l_mr_rec.item_instance_id,
7503           p_wip_entity_id     => l_workorder_tbl(i).wip_entity_id,
7504           p_actual_date       => l_workorder_tbl(i).actual_end_date,
7505           x_counter_tbl       => l_counter_tbl
7506         );
7507 
7508         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7509           RAISE FND_API.G_EXC_ERROR;
7510         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7511           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7512         END IF;
7513 
7514         -- Bug # 6750836 -- end
7515 
7516         IF ( l_counter_tbl.COUNT > 0 ) THEN
7517 
7518 		l_return_status :=
7519 		record_wo_ctr_readings
7520 		(
7521 		  x_msg_data           => l_msg_data,
7522 		  x_msg_count          => l_msg_count,
7523 		  p_wip_entity_id      => l_workorder_tbl(i).wip_entity_id,
7524 		  p_counter_tbl        => l_counter_tbl
7525 		);
7526 
7527 		IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7528 		  RAISE FND_API.G_EXC_ERROR;
7529 		ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7530 		  RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7531 		END IF;
7532 
7533 		-- Re-set the API savepoint because, Quality Results submission commits
7534 		SAVEPOINT signoff_mr_instance_PVT;
7535 
7536         END IF;
7537 
7538       END LOOP;
7539     --END IF;
7540   END IF;
7541 
7542   IF ( G_DEBUG = 'Y' ) THEN
7543     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
7544     || ' : Before Firing QA Actions for UE, WO and OP' );
7545   END IF;
7546 
7547   -- Fire QA Actions for all UEs
7548   IF ( l_child_mr_tbl.COUNT > 0 ) THEN
7549     FOR i IN l_child_mr_tbl.FIRST..l_child_mr_tbl.LAST LOOP
7550 
7551       IF ( l_child_mr_tbl(i).qa_collection_id IS NOT NULL ) THEN
7552 
7553         QA_SS_RESULTS.wrapper_fire_action
7554         (
7555           q_collection_id    => l_child_mr_tbl(i).qa_collection_id,
7556           q_return_status    => l_return_status,
7557           q_msg_count        => l_msg_count,
7558           q_msg_data         => l_msg_data
7559         );
7560 
7561         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7562           x_msg_data := l_msg_data;
7563           x_msg_count := l_msg_count;
7564           RETURN;
7565         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7566           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7567         END IF;
7568 
7569         -- Re-set the API savepoint because, the wrapper_fire_action commits.
7570         SAVEPOINT signoff_mr_instance_PVT;
7571 
7572       END IF;
7573     END LOOP;
7574   END IF;
7575 
7576   -- Fire QA Actions for all Operations
7577   IF ( l_operation_tbl.COUNT > 0 ) THEN
7578     FOR i IN l_operation_tbl.FIRST..l_operation_tbl.LAST LOOP
7579       IF ( l_operation_tbl(i).collection_id IS NOT NULL ) THEN
7580 
7581         QA_SS_RESULTS.wrapper_fire_action
7582         (
7583           q_collection_id    => l_operation_tbl(i).collection_id,
7584           q_return_status    => l_return_status,
7585           q_msg_count        => l_msg_count,
7586           q_msg_data         => l_msg_data
7587         );
7588 
7589         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7590           x_msg_data := l_msg_data;
7591           x_msg_count := l_msg_count;
7592           RETURN;
7593         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7594           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7595         END IF;
7596 
7597         -- Re-set the API savepoint because, the wrapper_fire_action commits.
7598         SAVEPOINT signoff_mr_instance_PVT;
7599 
7600       END IF;
7601     END LOOP;
7602   END IF;
7603 
7604   -- Fire QA Actions for all Workorders
7605   IF ( l_workorder_tbl.COUNT > 0 ) THEN
7606     FOR i IN l_workorder_tbl.FIRST..l_workorder_tbl.LAST LOOP
7607       IF ( l_workorder_tbl(i).collection_id IS NOT NULL ) THEN
7608 
7609         QA_SS_RESULTS.wrapper_fire_action
7610         (
7611           q_collection_id    => l_workorder_tbl(i).collection_id,
7612           q_return_status    => l_return_status,
7613           q_msg_count        => l_msg_count,
7614           q_msg_data         => l_msg_data
7615         );
7616 
7617         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
7618           x_msg_data := l_msg_data;
7619           x_msg_count := l_msg_count;
7620           RETURN;
7621         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
7622           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7623         END IF;
7624 
7625         -- Re-set the API savepoint because, the wrapper_fire_action commits.
7626         SAVEPOINT signoff_mr_instance_PVT;
7627 
7628       END IF;
7629     END LOOP;
7630   END IF;
7631 
7632   -- Perform the Commit (if requested)
7633   IF FND_API.to_boolean( p_commit ) THEN
7634     COMMIT WORK;
7635   END IF;
7636 
7637   -- Disable debug (if enabled)
7638   IF ( G_DEBUG = 'Y' ) THEN
7639     AHL_DEBUG_PUB.disable_debug;
7640   END IF;
7641 
7642 EXCEPTION
7643 
7644   WHEN FND_API.G_EXC_ERROR THEN
7645     ROLLBACK TO signoff_mr_instance_PVT;
7646     x_return_status := FND_API.G_RET_STS_ERROR;
7647     FND_MSG_PUB.count_and_get
7648     (
7649       p_encoded  => FND_API.G_FALSE,
7650       p_count    => x_msg_count,
7651       p_data     => x_msg_data
7652     );
7653 
7654     IF ( G_DEBUG = 'Y' ) THEN
7655       AHL_DEBUG_PUB.disable_debug;
7656     END IF;
7657 
7658   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
7659     ROLLBACK TO signoff_mr_instance_PVT;
7660     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
7661     FND_MSG_PUB.count_and_get
7662     (
7663       p_encoded  => FND_API.G_FALSE,
7664       p_count    => x_msg_count,
7665       p_data     => x_msg_data
7666     );
7667 
7668     IF ( G_DEBUG = 'Y' ) THEN
7669       AHL_DEBUG_PUB.disable_debug;
7670     END IF;
7671 
7672   WHEN OTHERS THEN
7673     ROLLBACK TO signoff_mr_instance_PVT;
7674     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
7675     IF FND_MSG_PUB.check_msg_level( FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR )
7676     THEN
7677       FND_MSG_PUB.add_exc_msg
7678       (
7679         p_pkg_name         => G_PKG_NAME,
7680         p_procedure_name   => l_api_name,
7681         p_error_text       => SUBSTRB(SQLERRM,1,240)
7682       );
7683     END IF;
7684     FND_MSG_PUB.count_and_get
7685     (
7686       p_encoded  => FND_API.G_FALSE,
7687       p_count    => x_msg_count,
7688       p_data     => x_msg_data
7689     );
7690 
7691     IF ( G_DEBUG = 'Y' ) THEN
7692       AHL_DEBUG_PUB.disable_debug;
7693     END IF;
7694 END signoff_mr_instance;
7695 
7696 PROCEDURE close_visit
7697 (
7698   p_api_version      IN         NUMBER        := 1.0,
7699   p_init_msg_list    IN         VARCHAR2      := FND_API.G_TRUE,
7700   p_commit           IN         VARCHAR2      := FND_API.G_FALSE,
7701   p_validation_level IN         NUMBER        := FND_API.G_VALID_LEVEL_FULL,
7702   p_default          IN         VARCHAR2      := FND_API.G_FALSE,
7703   p_module_type      IN         VARCHAR2      := NULL,
7704   x_return_status    OUT NOCOPY VARCHAR2,
7705   x_msg_count        OUT NOCOPY NUMBER,
7706   x_msg_data         OUT NOCOPY VARCHAR2,
7707   p_close_visit_rec  IN         close_visit_rec_type
7708 )
7709 IS
7710 
7711 l_api_name               VARCHAR2(30) := 'close_visit';
7712 l_return_status          VARCHAR2(1);
7713 l_msg_count              NUMBER;
7714 l_msg_data               VARCHAR2(2000);
7715 l_wo_actual_start_date   DATE;
7716 l_wo_actual_end_date     DATE;
7717 l_def_actual_start_date  DATE;
7718 l_def_actual_end_date    DATE;
7719 l_wo_name                VARCHAR2(80);
7720 -- rroy
7721 -- R12 Tech UIs
7722 -- cursor to retrieve the workorder actual dates
7723 CURSOR get_wo_dates(x_wo_id NUMBER)
7724 IS
7725 SELECT Actual_start_date,
7726 Actual_end_date,
7727 Workorder_name
7728 FROM AHL_WORKORDERS
7729 WHERE workorder_id = x_wo_id;
7730 
7731 -- To get the Visit and it's master workorder details
7732 CURSOR     get_visit_details( c_visit_id NUMBER ) IS
7733 SELECT     VST.visit_id visit_id,
7734            VST.visit_number visit_number,
7735            VST.object_version_number object_version_number,
7736            VST.status_code status_code,
7737            WO.workorder_id workorder_id,
7738            WO.object_version_number wo_object_version_number,
7739            WO.workorder_name workorder_name,
7740            WIP.organization_id,
7741            WO.wip_entity_id wip_entity_id,
7742            VST.item_instance_id item_instance_id,
7743            WIP.scheduled_start_date scheduled_start_date,
7744            WIP.scheduled_completion_date scheduled_end_date,
7745            WO.actual_start_date actual_start_date,
7746            WO.actual_end_date actual_end_date,
7747            WO.status_code wo_status_code,
7748            WO.plan_id wo_plan_id,
7749            WO.collection_id wo_collection_id
7750 FROM       WIP_DISCRETE_JOBS WIP,
7751            AHL_WORKORDERS WO,
7752            AHL_VISITS_B VST
7753 WHERE      WIP.wip_entity_id = WO.wip_entity_id
7754 AND        WO.visit_task_id IS NULL
7755 AND        WO.master_workorder_flag = 'Y'
7756 AND        WO.visit_id = VST.visit_id
7757 AND        VST.visit_id = c_visit_id;
7758 
7759 -- To get the Top Unit Effectivity Details for the Visit
7760 -- altering this so that unassociated tasks that are created
7761 -- as a result of sr creation which have an originating task id
7762 -- are also picked up for signing off
7763 /*
7764 CURSOR     get_visit_ue_details( c_visit_id NUMBER ) IS
7765 SELECT     UE.unit_effectivity_id unit_effectivity_id,
7766            UE.title title,
7767            UE.object_version_number object_version_number,
7768            UE.ump_status_code ump_status_code,
7769            UE.qa_inspection_type_code qa_inspection_type_code,
7770            UE.qa_plan_id qa_plan_id,
7771            UE.qa_collection_id qa_collection_id
7772 FROM       AHL_UE_DEFERRAL_DETAILS_V UE,
7773            AHL_VISIT_TASKS_B VT
7774 WHERE      UE.unit_effectivity_id = VT.unit_effectivity_id
7775 AND        ((VT.originating_task_id IS NULL
7776 AND        VT.task_type_code = 'SUMMARY')
7777 OR (TASK_TYPE_CODE = 'UNASSOCIATED' ))
7778 AND        VT.visit_id = c_visit_id;
7779 */
7780 -- Bug # 6815689 start
7781 /*CURSOR     get_visit_ue_details( c_visit_id NUMBER ) IS
7782 SELECT     UE.unit_effectivity_id unit_effectivity_id,
7783            UE.title title,
7784            UE.object_version_number object_version_number,
7785            UE.ump_status_code ump_status_code,
7786            UE.qa_inspection_type_code qa_inspection_type_code,
7787            UE.qa_plan_id qa_plan_id,
7788            UE.qa_collection_id qa_collection_id
7789 FROM       AHL_UE_DEFERRAL_DETAILS_V UE,
7790            AHL_VISIT_TASKS_B VT,
7791 	   ahl_workorders awo
7792 WHERE      UE.unit_effectivity_id = VT.unit_effectivity_id
7793 AND       ( (VT.task_type_code = 'SUMMARY')
7794 OR (TASK_TYPE_CODE = 'UNASSOCIATED' ) )
7795 AND vt.visit_task_id = awo.visit_task_id
7796 and awo.wip_entity_id in (  SELECT
7797 			  wsch.child_object_id
7798 			FROM
7799 			  wip_sched_relationships wsch,
7800 			  ahl_workorders awo1
7801 			WHERE
7802 			  wsch.parent_object_id = awo1.wip_entity_id
7803 			  and awo1.visit_task_id is null
7804 			  and awo1.master_workorder_flag = 'Y'
7805 			  and awo1.visit_id = c_visit_id
7806 			 );*/
7807 -- Bug # 6815689 end
7808 --fix for bug number 7295717 (Sunil)
7809 CURSOR     get_visit_ue_details( c_visit_id NUMBER ) IS
7810 SELECT     UE.unit_effectivity_id unit_effectivity_id,
7811            DECODE( UE.Mr_header_id, null,
7812            (select cit.name || '-' || cs.incident_number from cs_incidents_all_vl cs, cs_incident_types_vl cit WHERE cs.incident_type_id = cit.incident_type_id AND cs.incident_id = UE.Cs_Incident_id),
7813            (select title from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id )) title,
7814            UE.object_version_number object_version_number,
7815            UE.status_code ump_status_code,
7816            DECODE( UE.Mr_header_id, null,null,(select QA_INSPECTION_TYPE from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id ))  qa_inspection_type_code,
7817            -1 qa_plan_id,
7818            UE.qa_collection_id qa_collection_id
7819            FROM AHL_UNIT_EFFECTIVITIES_B UE,
7820            AHL_VISIT_TASKS_B VT,
7821 	   ahl_workorders awo
7822 WHERE      UE.unit_effectivity_id = VT.unit_effectivity_id
7823 AND       ( (VT.task_type_code = 'SUMMARY')
7824 OR (TASK_TYPE_CODE = 'UNASSOCIATED' ) )
7825 AND vt.visit_task_id = awo.visit_task_id
7826 and awo.wip_entity_id in (  SELECT
7827 			  wsch.child_object_id
7828 			FROM
7829 			  wip_sched_relationships wsch,
7830 			  ahl_workorders awo1
7831 			WHERE
7832 			  wsch.parent_object_id = awo1.wip_entity_id
7833 			  and awo1.visit_task_id is null
7834 			  and awo1.master_workorder_flag = 'Y'
7835 			  and awo1.visit_id = c_visit_id
7836 			 );
7837 
7838 CURSOR get_qa_plan_id_csr1(p_collection_id IN NUMBER)IS
7839 SELECT qa.plan_id from qa_results qa
7840 where qa.collection_id = p_collection_id and rownum < 2;
7841 
7842 CURSOR get_qa_plan_id_csr2(p_org_id IN NUMBER, p_qa_inspection_type IN VARCHAR2)IS
7843 SELECT QP.plan_id FROM QA_PLANS_VAL_V QP, QA_PLAN_TRANSACTIONS QPT, QA_PLAN_COLLECTION_TRIGGERS QPCT
7844 WHERE QP.plan_id = QPT.plan_id AND QPT.plan_transaction_id = QPCT.plan_transaction_id
7845 AND QP.organization_id = p_org_id
7846 AND QPT.transaction_number in (9999,2001)
7847 AND QPCT.collection_trigger_id = 87
7848 AND QPCT.low_value = p_qa_inspection_type
7849 group by qp.plan_id, qpt.transaction_number having transaction_number = MAX(transaction_number);
7850 
7851 
7852 -- To get the Child Unit Effectivity Details
7853 /*CURSOR     get_child_ue_details( c_unit_effectivity_id NUMBER ) IS
7854 SELECT     unit_effectivity_id,
7855            object_version_number,
7856            title,
7857            ump_status_code,
7858            qa_inspection_type_code,
7859            qa_plan_id,
7860            qa_collection_id
7861 FROM       AHL_UE_DEFERRAL_DETAILS_V
7862 WHERE      unit_effectivity_id IN
7863            (
7864              SELECT     related_ue_id
7865              FROM       AHL_UE_RELATIONSHIPS
7866              WHERE      unit_effectivity_id = related_ue_id
7867              START WITH ue_id = c_unit_effectivity_id
7868                     AND relationship_code = 'PARENT'
7869              CONNECT BY ue_id = PRIOR related_ue_id
7870                     AND relationship_code = 'PARENT'
7871            );*/
7872 --fix for bug number 7295717 (Sunil)
7873 CURSOR     get_child_ue_details( c_unit_effectivity_id NUMBER ) IS
7874 SELECT     unit_effectivity_id,
7875            object_version_number,
7876            DECODE( UE.Mr_header_id, null,
7877            (select cit.name || '-' || cs.incident_number from cs_incidents_all_vl cs, cs_incident_types_vl cit WHERE cs.incident_type_id = cit.incident_type_id AND cs.incident_id = UE.Cs_Incident_id),
7878            (select title from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id )) title,
7879            status_code ump_status_code,
7880            DECODE( UE.Mr_header_id, null,null,(select QA_INSPECTION_TYPE from AHL_MR_HEADERS_B MR where MR.mr_header_id = UE.mr_header_id ))  qa_inspection_type_code,
7881            -1 qa_plan_id,
7882            qa_collection_id
7883 FROM       AHL_UNIT_EFFECTIVITIES_B UE,(SELECT     related_ue_id
7884 FROM       AHL_UE_RELATIONSHIPS
7885   START WITH ue_id = c_unit_effectivity_id
7886   AND relationship_code = 'PARENT'
7887   CONNECT BY ue_id = PRIOR related_ue_id
7888   AND relationship_code = 'PARENT') CH
7889 WHERE      UE.unit_effectivity_id = CH.related_ue_id ORDER BY unit_effectivity_id ASC;
7890 
7891 -- Balaji commented out the order by clause for the issue # 3 in bug #4613940(CMRO)
7892 -- and this fix has reference to bug #3085871(ST) where it is described that order by level
7893 -- should not be used without a reference to "start with.. connect by clause" starting 10g
7894 --ORDER BY   level DESC;
7895 
7896 -- To get the Child Workorder Details for a Visit
7897 CURSOR     get_visit_workorders( c_visit_id NUMBER ) IS
7898 SELECT     WO.workorder_id workorder_id,
7899            WO.object_version_number object_version_number,
7900            WO.workorder_name workorder_name,
7901            WO.wip_entity_id wip_entity_id,
7902            WIP.scheduled_start_date scheduled_start_date,
7903            WIP.scheduled_completion_date scheduled_end_date,
7904            WO.actual_start_date actual_start_date,
7905            WO.actual_end_date actual_end_date,
7906            WO.status_code status_code,
7907            WO.master_workorder_flag master_workorder_flag,
7908            WO.plan_id plan_id,
7909            WO.collection_id collection_id
7910 FROM       WIP_DISCRETE_JOBS WIP,
7911            AHL_WORKORDERS WO
7912 WHERE      WIP.wip_entity_id = WO.wip_entity_id
7913 AND        WO.status_code <> G_JOB_STATUS_DELETED
7914 AND        WO.visit_task_id IS NOT NULL
7915 AND        WO.visit_id = c_visit_id
7916 ORDER BY   WO.master_workorder_flag;
7917 
7918 -- To get all the Child Operation Details for a Visit
7919 CURSOR     get_visit_operations( c_visit_id NUMBER ) IS
7920 SELECT     WOP.workorder_operation_id workorder_operation_id,
7921            WOP.object_version_number object_version_number,
7922            WO.workorder_name workorder_name,
7923            WIP.wip_entity_id wip_entity_id,
7924            WIP.operation_seq_num operation_seq_num,
7925            WIP.first_unit_start_date scheduled_start_date,
7926            WIP.last_unit_completion_date scheduled_end_date,
7927            WOP.actual_start_date actual_start_date,
7928            WOP.actual_end_date actual_end_date,
7929            WOP.status_code status_code,
7930            WOP.plan_id plan_id,
7931            WOP.collection_id collection_id
7932 FROM       AHL_WORKORDER_OPERATIONS WOP,
7933            WIP_OPERATIONS WIP,
7934            AHL_WORKORDERS WO
7935 WHERE      WOP.operation_sequence_num = WIP.operation_seq_num
7936 AND        WOP.workorder_id = WO.workorder_id
7937 AND        WIP.wip_entity_id = WO.wip_entity_id
7938 AND        WO.status_code NOT IN
7939            (
7940              G_JOB_STATUS_COMPLETE_NC,
7941              G_JOB_STATUS_COMPLETE,
7942              G_JOB_STATUS_CLOSED,
7943              G_JOB_STATUS_CANCELLED,
7944              G_JOB_STATUS_DELETED
7945            )
7946 AND        WO.visit_task_id IS NOT NULL
7947 AND        WO.visit_id = c_visit_id;
7948 
7949 -- To get all the Resource Requirements for a Visit
7950 CURSOR     get_visit_resource_req( c_visit_id NUMBER ) IS
7951 SELECT     WOR.wip_entity_id wip_entity_id,
7952            WO.workorder_name,
7953            WO.workorder_id,
7954            WOP.workorder_operation_id,
7955            WOR.operation_seq_num operation_seq_num,
7956            WOR.resource_seq_num resource_seq_num,
7957            WOR.organization_id organization_id,
7958            WOR.department_id department_id,
7959            BOM.resource_code resource_name,
7960            WOR.resource_id resource_id,
7961            BOM.resource_type,
7962            WOR.uom_code uom_code,
7963            WOR.usage_rate_or_amount usage_rate_or_amount
7964 FROM       BOM_RESOURCES BOM,
7965            WIP_OPERATION_RESOURCES WOR,
7966            AHL_WORKORDER_OPERATIONS WOP,
7967            AHL_WORKORDERS WO
7968 WHERE      BOM.resource_type IN ( 1 , 2 )
7969 AND        BOM.resource_id = WOR.resource_id
7970 AND        WOR.operation_seq_num = WOP.operation_sequence_num
7971 AND        WOR.wip_entity_id = WO.wip_entity_id
7972 AND        WOP.status_code <> G_OP_STATUS_COMPLETE
7973 AND        WOP.workorder_id = WO.workorder_id
7974 AND        WO.status_code NOT IN
7975            (
7976              G_JOB_STATUS_COMPLETE_NC,
7977              G_JOB_STATUS_COMPLETE,
7978              G_JOB_STATUS_CLOSED,
7979              G_JOB_STATUS_CANCELLED,
7980              G_JOB_STATUS_DELETED
7981            )
7982 AND        WO.visit_task_id IS NOT NULL
7983 AND        WO.visit_id = c_visit_id;
7984 
7985 -- To get the Resource Transactions performed for a Resource Requirement
7986 CURSOR     get_resource_txns( c_wip_entity_id NUMBER,
7987                               c_operation_seq_num NUMBER,
7988                               c_resource_seq_num NUMBER ) IS
7989 SELECT     NVL( SUM( transaction_quantity ), 0 )
7990 FROM       WIP_TRANSACTIONS
7991 WHERE      wip_entity_id = c_wip_entity_id
7992 AND        operation_seq_num = c_operation_seq_num
7993 AND        resource_seq_num = c_resource_seq_num;
7994 
7995 -- To get the Pending Resource Transactions for a Resource Requirement
7996 -- Confirm
7997 CURSOR     get_pending_resource_txns( c_wip_entity_id NUMBER,
7998                                       c_operation_seq_num NUMBER,
7999                                       c_resource_seq_num NUMBER ) IS
8000 SELECT     NVL( SUM( transaction_quantity ), 0 )
8001 FROM       WIP_COST_TXN_INTERFACE
8002 WHERE      wip_entity_id = c_wip_entity_id
8003 AND        operation_seq_num = c_operation_seq_num
8004 AND        resource_seq_num = c_resource_seq_num
8005 AND        process_status = 1;
8006 
8007 l_ctr                    NUMBER := 0;
8008 l_actual_start_date      DATE;
8009 l_actual_end_date        DATE;
8010 l_transaction_qty        NUMBER := 0;
8011 l_txn_qty                NUMBER := 0;
8012 l_pending_txn_qty        NUMBER := 0;
8013 l_cost_session_id        NUMBER;
8014 l_mr_session_id          NUMBER;
8015 l_employee_id            NUMBER;
8016 l_ue_status_code         VARCHAR2(30);
8017 l_visit_rec              get_visit_details%ROWTYPE;
8018 l_child_mr_tbl           mr_tbl_type;
8019 l_workorder_tbl          workorder_tbl_type;
8020 l_operation_tbl          operation_tbl_type;
8021 l_resource_req_tbl       resource_req_tbl_type;
8022 l_counter_tbl            counter_tbl_type;
8023 --l_res_txn_tbl            AHL_WIP_JOB_PVT.ahl_res_txn_tbl_type;
8024 l_status_meaning         VARCHAR2(80);
8025 
8026 TYPE child_ue_tbl_type IS TABLE OF get_child_ue_details%ROWTYPE INDEX BY BINARY_INTEGER;
8027 
8028 l_child_ue_tbl child_ue_tbl_type;
8029 l_ue_ctr NUMBER := 0;
8030 
8031 l_op_actual_start_date DATE;
8032 l_op_actaul_end_date DATE;
8033 
8034 -- parameters to call process_resource_txns.
8035 l_prd_resrc_txn_tbl     AHL_PRD_RESOURCE_TRANX_PVT.PRD_RESOURCE_TXNS_TBL;
8036 
8037 BEGIN
8038 
8039   -- Enable Debug (optional)
8040   IF ( G_DEBUG = 'Y' ) THEN
8041     AHL_DEBUG_PUB.enable_debug;
8042   END IF;
8043 
8044   -- Initialize API return status to success
8045   x_return_status := FND_API.G_RET_STS_SUCCESS;
8046 
8047   -- Standard Start of API savepoint
8048   SAVEPOINT close_visit_PVT;
8049 
8050   -- Initialize message list if p_init_msg_list is set to TRUE.
8051   IF FND_API.to_boolean( p_init_msg_list ) THEN
8052     FND_MSG_PUB.initialize;
8053   END IF;
8054 
8055   IF ( G_DEBUG = 'Y' ) THEN
8056     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Validating Inputs' );
8057   END IF;
8058 
8059   -- Validate all the inputs of the API
8060   l_return_status :=
8061   validate_cv_inputs
8062   (
8063     p_close_visit_rec      => p_close_visit_rec
8064   );
8065 
8066   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
8067     RAISE FND_API.G_EXC_ERROR;
8068   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
8069     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8070   END IF;
8071 
8072   IF ( G_DEBUG = 'Y' ) THEN
8073     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8074     || ' : Inputs - p_close_visit_rec.visit_id - ' || p_close_visit_rec.visit_id );
8075     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8076     || ' : Inputs - p_close_visit_rec.object_version_number - ' || p_close_visit_rec.object_version_number );
8077     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8078     || ' : Inputs - p_close_visit_rec.signoff_mrs_flag - ' || p_close_visit_rec.signoff_mrs_flag );
8079     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8080     || ' : Inputs - p_close_visit_rec.complete_job_ops_flag - ' || p_close_visit_rec.complete_job_ops_flag );
8081     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8082     || ' : Inputs - p_close_visit_rec.default_actual_dates_flag - '
8083     || p_close_visit_rec.default_actual_dates_flag );
8084     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8085     || ' : Inputs - p_close_visit_rec.actual_start_date - ' || p_close_visit_rec.actual_start_date );
8086     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8087     || ' : Inputs - p_close_visit_rec.actual_end_date - ' || p_close_visit_rec.actual_end_date );
8088     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8089     || ' : Inputs - p_close_visit_rec.transact_resource_flag - '
8090     || p_close_visit_rec.transact_resource_flag );
8091     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8092     || ' : Inputs - p_close_visit_rec.employee_number - ' || p_close_visit_rec.employee_number );
8093     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8094     || ' : Inputs - p_close_visit_rec.serial_number - ' || p_close_visit_rec.serial_number );
8095   END IF;
8096 
8097   -- Invoke VWP Close Visit API if this is not a top-down signoff
8098   IF ( p_close_visit_rec.signoff_mrs_flag = 'N' AND
8099        p_close_visit_rec.complete_job_ops_flag = 'N' AND
8100        p_close_visit_rec.transact_resource_flag = 'N' ) THEN
8101 
8102     IF ( G_DEBUG = 'Y' ) THEN
8103       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Not Top Down Signoff ' );
8104     END IF;
8105 
8106     AHL_VWP_VISITS_PVT.close_visit
8107     (
8108       p_api_version            => 1.0,
8109       p_init_msg_list          => FND_API.G_FALSE,
8110       p_commit                 => FND_API.G_TRUE,
8111       p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
8112       p_module_type            => NULL,
8113       p_visit_id               => p_close_visit_rec.visit_id,
8114       p_x_cost_session_id      => l_cost_session_id,
8115       p_x_mr_session_id        => l_mr_session_id,
8116       x_return_status          => l_return_status,
8117       x_msg_count              => l_msg_count,
8118       x_msg_data               => l_msg_data
8119     );
8120 
8121     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
8122       RAISE FND_API.G_EXC_ERROR;
8123     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
8124       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8125     END IF;
8126 
8127     RETURN;
8128 
8129   END IF;
8130 
8131   IF ( G_DEBUG = 'Y' ) THEN
8132     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing Visit' );
8133   END IF;
8134 
8135   -- Get the Visit Details
8136   OPEN  get_visit_details( p_close_visit_rec.visit_id );
8137   FETCH get_visit_details
8138   INTO  l_visit_rec;
8139 
8140   IF ( get_visit_details%NOTFOUND ) THEN
8141     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_VST_REC_NOT_FOUND' );
8142     FND_MSG_PUB.add;
8143     CLOSE get_visit_details;
8144     RAISE FND_API.G_EXC_ERROR;
8145   END IF;
8146 
8147   CLOSE get_visit_details;
8148 
8149   -- Validate Object Version Number
8150   IF ( l_visit_rec.object_version_number <> p_close_visit_rec.object_version_number ) THEN
8151     FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
8152     FND_MSG_PUB.add;
8153     RAISE FND_API.G_EXC_ERROR;
8154   END IF;
8155 
8156   -- Validate the status of the Visit for Top-down Closure
8157   IF ( l_visit_rec.status_code <> G_VISIT_STATUS_RELEASED ) THEN
8158     FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INV_CLOSE_STATUS');
8159     FND_MESSAGE.set_token( 'VISIT_NUM', l_visit_rec.visit_number );
8160     FND_MESSAGE.set_token( 'STATUS', l_visit_rec.status_code );
8161     FND_MSG_PUB.add;
8162   END IF;
8163 
8164   IF ( G_DEBUG = 'Y' ) THEN
8165     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing MRs in the Visit' );
8166   END IF;
8167 
8168   -- Get all the Top UE Details for the Visit
8169   FOR mr_csr IN get_visit_ue_details( p_close_visit_rec.visit_id ) LOOP
8170 
8171     -- Initialize child UE counter to 0.
8172     l_ue_ctr := 0;
8173 
8174     -- Check if MRs in the Visit need to be Signed off
8175     IF ( p_close_visit_rec.signoff_mrs_flag = 'Y' ) THEN
8176       -- fix for bug number 7295717 (Sunil)
8177       IF(mr_csr.qa_inspection_type_code IS NULL)THEN
8178          mr_csr.qa_plan_id := NULL;
8179       ELSIF(mr_csr.qa_collection_id IS NOT NULL)THEN
8180          OPEN get_qa_plan_id_csr1(mr_csr.qa_collection_id);
8181          FETCH get_qa_plan_id_csr1 INTO mr_csr.qa_plan_id;
8182          CLOSE get_qa_plan_id_csr1;
8183       ELSE
8184          OPEN get_qa_plan_id_csr2(l_visit_rec.organization_id,mr_csr.qa_inspection_type_code);
8185          FETCH get_qa_plan_id_csr2 INTO mr_csr.qa_plan_id;
8186          CLOSE get_qa_plan_id_csr2;
8187       END IF;
8188 
8189       -- Check if the Top UE is complete
8190       l_return_status:=
8191       is_mr_complete
8192       (
8193         p_mr_title             => mr_csr.title,
8194         p_status_code          => mr_csr.ump_status_code,
8195         p_status               => NULL,
8196         p_qa_inspection_type   => mr_csr.qa_inspection_type_code,
8197         p_qa_plan_id           => mr_csr.qa_plan_id,
8198         p_qa_collection_id     => mr_csr.qa_collection_id
8199       );
8200 
8201       IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
8202         RAISE FND_API.G_EXC_ERROR;
8203       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
8204         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8205       END IF;
8206 
8207       -- Balaji added the following loop for the BAE bug.
8208       -- The cursor get_child_ue_details doesnt UEs at the leaf node first
8209       -- their parent next, etc., instead it returns Mrs in Top down fashion.
8210       -- Hence below loop fetches all the child UEs in top down fashion and in
8211       -- subsequent code the top down will be converted into bottom up to
8212       -- circumvent the "At least one child Maintenance Requirement is unaccomplished"
8213       /*FOR child_ue_rec IN get_child_ue_details( mr_csr.unit_effectivity_id ) LOOP
8214          l_ue_ctr := l_ue_ctr + 1;
8215          l_child_ue_tbl(l_ue_ctr) := child_ue_rec;
8216       END LOOP;*/
8217       -- fix for bug number 7295717 (Sunil)
8218       FOR child_ue_rec IN get_child_ue_details( mr_csr.unit_effectivity_id ) LOOP
8219         l_ue_ctr := l_ue_ctr + 1;
8220         l_child_ue_tbl(l_ue_ctr) := child_ue_rec;
8221         IF(l_child_ue_tbl(l_ue_ctr).qa_inspection_type_code IS NULL)THEN
8222          l_child_ue_tbl(l_ue_ctr).qa_plan_id := NULL;
8223         ELSIF(l_child_ue_tbl(l_ue_ctr).qa_collection_id IS NOT NULL)THEN
8224          OPEN get_qa_plan_id_csr1(l_child_ue_tbl(l_ue_ctr).qa_collection_id);
8225          FETCH get_qa_plan_id_csr1 INTO l_child_ue_tbl(l_ue_ctr).qa_plan_id;
8226          CLOSE get_qa_plan_id_csr1;
8227         ELSE
8228          OPEN get_qa_plan_id_csr2(l_visit_rec.organization_id,l_child_ue_tbl(l_ue_ctr).qa_inspection_type_code);
8229          FETCH get_qa_plan_id_csr2 INTO l_child_ue_tbl(l_ue_ctr).qa_plan_id;
8230          CLOSE get_qa_plan_id_csr2;
8231         END IF;
8232       END LOOP;
8233 
8234       -- Get the Child UE Details
8235       IF l_child_ue_tbl.COUNT > 0 THEN
8236       -- Get the Child UEs for a given UE
8237   	    -- Reverse the order of signing off the Ues. First child UE then its parent
8238   	    -- etc.,Balaji modified the code for BAE bug.
8239 	    FOR l_ue_count IN REVERSE l_child_ue_tbl.FIRST..l_child_ue_tbl.LAST LOOP
8240 
8241 		-- Check if the Child UE is complete
8242 		/*l_return_status:=
8243 		is_mr_complete
8244 		(
8245 		  p_mr_title             => l_child_ue_tbl(l_ue_count).title,
8246 		  p_status_code          => l_child_ue_tbl(l_ue_count).ump_status_code,
8247 		  p_status               => NULL,
8248 		  p_qa_inspection_type   => l_child_ue_tbl(l_ue_count).qa_inspection_type_code,
8249 		  p_qa_plan_id           => l_child_ue_tbl(l_ue_count).qa_plan_id,
8250 		  p_qa_collection_id     => l_child_ue_tbl(l_ue_count).qa_collection_id
8251 		);
8252 
8253 		IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
8254 		  RAISE FND_API.G_EXC_ERROR;
8255 		ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
8256 		  RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8257 		END IF;*/
8258 
8259 		-- Store the Child UEs in a table of records for Signing off
8260 		IF ( nvl(l_child_ue_tbl(l_ue_count).ump_status_code,'x') <> nvl(G_MR_STATUS_SIGNED_OFF,'y') ) THEN
8261 
8262           l_ue_status_code := get_mr_status( l_child_ue_tbl(l_ue_count).unit_effectivity_id );
8263 
8264 		  IF (
8265 		      l_ue_status_code <> G_MR_STATUS_DEFERRED AND
8266 		      l_ue_status_code <> G_MR_STATUS_TERMINATED AND
8267 		      l_ue_status_code <> G_MR_STATUS_CANCELLED
8268 
8269 		   ) THEN
8270 		   -- Check if the Child UE is complete
8271 	      l_return_status:=
8272 	      is_mr_complete
8273 	      (
8274 		    p_mr_title             => l_child_ue_tbl(l_ue_count).title,
8275 		    p_status_code          => l_child_ue_tbl(l_ue_count).ump_status_code,
8276 		    p_status               => NULL,
8277 		    p_qa_inspection_type   => l_child_ue_tbl(l_ue_count).qa_inspection_type_code,
8278 		    p_qa_plan_id           => l_child_ue_tbl(l_ue_count).qa_plan_id,
8279 		    p_qa_collection_id     => l_child_ue_tbl(l_ue_count).qa_collection_id
8280 	        );
8281 
8282            IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
8283 		     RAISE FND_API.G_EXC_ERROR;
8284 	       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
8285 		     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8286 	       END IF;
8287 
8288 			IF ( G_DEBUG = 'Y' ) THEN
8289 			   AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : l_ue_status_code '||l_ue_status_code );
8290 			END IF;
8291              IF ( G_DEBUG = 'Y' ) THEN
8292 		      AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8293 		       || ' : Child MR needs Signoff - ' || l_child_ue_tbl(l_ue_count).unit_effectivity_id );
8294 		    END IF;
8295 			l_ctr := l_ctr + 1;
8296 		    l_child_mr_tbl(l_ctr).unit_effectivity_id := l_child_ue_tbl(l_ue_count).unit_effectivity_id;
8297 		    l_child_mr_tbl(l_ctr).ue_object_version_no := l_child_ue_tbl(l_ue_count).object_version_number;
8298 		    l_child_mr_tbl(l_ctr).mr_title := l_child_ue_tbl(l_ue_count).title;
8299 		    l_child_mr_tbl(l_ctr).qa_collection_id := l_child_ue_tbl(l_ue_count).qa_collection_id;
8300 		  END IF;
8301 		 END IF;
8302 
8303        END LOOP;
8304       END IF;
8305 
8306       -- Store the Top UEs in a table of records for Signing off
8307       IF ( nvl(mr_csr.ump_status_code,'x') <> nvl(G_MR_STATUS_SIGNED_OFF,'y') ) THEN
8308 
8309         IF ( G_DEBUG = 'Y' ) THEN
8310           AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8311           || ' : Top MR needs Signoff - ' || mr_csr.unit_effectivity_id );
8312         END IF;
8313 
8314         l_ctr := l_ctr + 1;
8315         l_child_mr_tbl(l_ctr).unit_effectivity_id := mr_csr.unit_effectivity_id;
8316         l_child_mr_tbl(l_ctr).ue_object_version_no := mr_csr.object_version_number;
8317         l_child_mr_tbl(l_ctr).mr_title := mr_csr.title;
8318         l_child_mr_tbl(l_ctr).qa_collection_id := mr_csr.qa_collection_id;
8319       END IF;
8320 
8321     ELSE
8322       -- Validate Status of Child UEs
8323       -- Null check added by balaji for bug # 4078536
8324       IF (
8325            mr_csr.ump_status_code IS NULL OR
8326            (
8327             mr_csr.ump_status_code <> G_MR_STATUS_SIGNED_OFF AND
8328             mr_csr.ump_status_code <> G_MR_STATUS_DEFERRED AND
8329             mr_csr.ump_status_code <> G_MR_STATUS_TERMINATED AND
8330             mr_csr.ump_status_code <> G_MR_STATUS_CANCELLED
8331            )
8332          ) THEN
8333         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_VST_MRS_NOT_CMPL' );
8334         FND_MESSAGE.set_token( 'VISIT_NUM', l_visit_rec.visit_number );
8335         FND_MESSAGE.set_token( 'MAINT_REQ', mr_csr.title );
8336         FND_MSG_PUB.add;
8337         RAISE FND_API.G_EXC_ERROR;
8338       END IF;
8339     END IF;
8340   END LOOP;
8341 
8342 	l_ctr := 0;
8343 
8344   IF ( G_DEBUG = 'Y' ) THEN
8345     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing Visit WOs' );
8346   END IF;
8347 
8348   -- Get all the Workorders for the Visit
8349   FOR wo_csr IN get_visit_workorders( l_visit_rec.visit_id ) LOOP
8350 
8351     -- Check if Jobs and Operations need to be completed
8352     IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' ) THEN
8353 
8354       -- Check if User entered Actual Dates need to be used
8355        /* start ER # 4757222
8356       IF ( p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
8357 
8358         -- Ensure that the actual start date entered is less than any WO
8359         IF ( wo_csr.actual_start_date IS NOT NULL AND
8360              wo_csr.actual_start_date < p_close_visit_rec.actual_start_date ) THEN
8361           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_ST_DATE_LESS' );
8362           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
8363           FND_MESSAGE.set_token( 'START_DT', TO_CHAR( wo_csr.actual_start_date , 'DD-MON-YYYY HH24:MI' ) );
8364           FND_MSG_PUB.add;
8365           RAISE FND_API.G_EXC_ERROR;
8366         END IF;
8367 
8368         -- Ensure that the actual end date entered is greater than any WO
8369         IF ( wo_csr.actual_end_date IS NOT NULL AND
8370              wo_csr.actual_end_date > p_close_visit_rec.actual_end_date ) THEN
8371           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_END_DATE_GT' );
8372           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
8373           FND_MESSAGE.set_token( 'END_DT', TO_CHAR( wo_csr.actual_end_date , 'DD-MON-YYYY HH24:MI' ) );
8374           FND_MESSAGE.set_token( 'END_DT', wo_csr.actual_end_date );
8375           FND_MSG_PUB.add;
8376           RAISE FND_API.G_EXC_ERROR;
8377         END IF;
8378       END IF;
8379       */--end ER # 4757222
8380       -- Do not process Workorders which are already Complete
8381       IF ( wo_csr.status_code <> G_JOB_STATUS_COMPLETE AND
8382            wo_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
8383            wo_csr.status_code <> G_JOB_STATUS_CLOSED AND
8384            wo_csr.status_code <> G_JOB_STATUS_CANCELLED ) THEN
8385          --To show jon status meaning instead code modifed by srini
8386 	 -- replacing with call to get_status function
8387          -- so no exceptions are thrown if the
8388 	 -- lookup does not exist
8389 	 l_status_meaning := get_status(wo_csr.status_code,
8390 	                                'AHL_JOB_STATUS');
8391 
8392          /*SELECT meaning INTO l_status_meaning
8393 		  FROM fnd_lookup_values_vl
8394 		  WHERE lookup_type = 'AHL_JOB_STATUS'
8395 		    AND lookup_code = wo_csr.status_code;
8396 	*/
8397         --
8398         -- Validate whether the Workorders can be completed
8399         IF ( wo_csr.status_code = G_JOB_STATUS_UNRELEASED OR
8400              wo_csr.status_code = G_JOB_STATUS_ON_HOLD OR
8401              wo_csr.status_code = G_JOB_STATUS_PARTS_HOLD OR
8402              wo_csr.status_code = G_JOB_STATUS_DEFERRAL_PENDING ) THEN
8403           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_NOT_ALL_WOS_OPEN' );
8404           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
8405           FND_MESSAGE.set_token( 'STATUS', l_status_meaning );
8406           FND_MSG_PUB.add;
8407           RAISE FND_API.G_EXC_ERROR;
8408         END IF;
8409 
8410         -- Validate whether Quality Results are Submitted
8411         IF ( wo_csr.plan_id IS NOT NULL AND
8412              wo_csr.collection_id IS NULL ) THEN
8413           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_QA_PENDING' );
8414           FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
8415           FND_MSG_PUB.add;
8416           RAISE FND_API.G_EXC_ERROR;
8417         END IF;
8418 
8419         -- Add the Workorder for Completion
8420         l_ctr := l_ctr + 1;
8421         l_workorder_tbl(l_ctr).workorder_id := wo_csr.workorder_id;
8422         l_workorder_tbl(l_ctr).object_version_number := wo_csr.object_version_number;
8423         l_workorder_tbl(l_ctr).workorder_name := wo_csr.workorder_name;
8424         l_workorder_tbl(l_ctr).wip_entity_id := wo_csr.wip_entity_id;
8425         l_workorder_tbl(l_ctr).master_workorder_flag := wo_csr.master_workorder_flag;
8426         l_workorder_tbl(l_ctr).collection_id := wo_csr.collection_id;
8427 
8428 	IF wo_csr.master_workorder_flag = 'N' THEN
8429 	   -- dont default if actual dates for a workorder are already provided.
8430 	   l_workorder_tbl(l_ctr).actual_start_date := wo_csr.actual_start_date;
8431 	   l_workorder_tbl(l_ctr).actual_end_date := wo_csr.actual_end_date;
8432 	ELSE
8433           -- Do not Update Actual Date of Master WO
8434           l_workorder_tbl(l_ctr).actual_start_date := NULL;
8435           l_workorder_tbl(l_ctr).actual_end_date := NULL;
8436 	END IF;
8437 
8438         -- Store the Actual Dates for Workorders
8439         -- No need to store actual dates for Master Workorders because it can be
8440         -- done only after updating the Actual dates of child Workorders
8441         /*Start ER # 4757222
8442          -- Balaji commented out the code as per the requirement in the BAE ER # 4757222.
8443          -- As per the new requirement, Work Order actual dates will be defaulted based
8444          -- on following logic.
8445          -- 1. Work Order actual start date is minimum of operation actual start dates.
8446          -- 2. Work Order actual end date is maximum of operation actual end dates.
8447         IF ( wo_csr.master_workorder_flag = 'N' ) THEN
8448 
8449           -- Check if Actual Date is already entered
8450           IF ( wo_csr.actual_start_date IS NULL ) THEN
8451 
8452 
8453             -- R12
8454 	    -- actual dates should be defaulted from res txn dates
8455             /*IF ( p_close_visit_rec.default_actual_dates_flag = 'Y' ) THEN
8456 
8457               -- Update Actual Date with Scheduled Date
8458               l_workorder_tbl(l_ctr).actual_start_date := wo_csr.scheduled_start_date;
8459             ELSE
8460 
8461               -- Update Actual Date with User Entered Value
8462               l_workorder_tbl(l_ctr).actual_start_date := p_close_visit_rec.actual_start_date;
8463             END IF;
8464 	    */
8465             /*IF ( p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
8466               -- Update Actual Date with User Entered Value
8467               l_workorder_tbl(l_ctr).actual_start_date := p_close_visit_rec.actual_start_date;
8468             END IF;
8469           ELSE
8470 
8471             -- Update Actual Date with DB Value if already entered
8472             l_workorder_tbl(l_ctr).actual_start_date := wo_csr.actual_start_date;
8473           END IF;
8474 
8475           -- Check if Actual Date is already entered
8476           IF ( wo_csr.actual_end_date IS NULL ) THEN
8477 
8478             -- R12
8479 	    -- actual dates should be defaulted from res txn dates
8480             /*IF ( p_close_visit_rec.default_actual_dates_flag = 'Y' ) THEN
8481 
8482               -- Update Actual Date with Scheduled Date
8483               l_workorder_tbl(l_ctr).actual_end_date := LEAST( SYSDATE , wo_csr.scheduled_end_date );
8484             ELSE
8485 
8486               -- Update Actual Date with User Entered Value
8487               l_workorder_tbl(l_ctr).actual_end_date := p_close_visit_rec.actual_end_date;
8488             END IF;
8489 	    */
8490             /*IF ( p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
8491               -- Update Actual Date with User Entered Value
8492               l_workorder_tbl(l_ctr).actual_end_date := p_close_visit_rec.actual_end_date;
8493             END IF;
8494           ELSE
8495 
8496             -- Update Actual Date with DB Value if already entered
8497             l_workorder_tbl(l_ctr).actual_end_date := wo_csr.actual_end_date;
8498           END IF;
8499 
8500         ELSIF ( wo_csr.master_workorder_flag = 'Y' ) THEN
8501 
8502           -- Do not Update Actual Date of Master WO
8503           l_workorder_tbl(l_ctr).actual_start_date := NULL;
8504           l_workorder_tbl(l_ctr).actual_end_date := NULL;
8505 
8506         END IF;
8507         */
8508 	/*End ER # 4757222*/
8509 
8510         IF ( G_DEBUG = 'Y' ) THEN
8511           AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
8512           || ' : Wo Name - ' || l_workorder_tbl(l_ctr).workorder_name
8513           || ' WO ID - ' || l_workorder_tbl(l_ctr).workorder_id
8514           || ' Actual Start Date - ' || l_workorder_tbl(l_ctr).actual_start_date
8515           || ' Actual End Date - ' || l_workorder_tbl(l_ctr).actual_end_date );
8516         END IF;
8517 
8518       END IF;
8519     ELSE
8520       -- Validate to ensure that the Workorders are already completed
8521       -- This check shou
8522       -- This validation should not be done for master workorders
8523       -- since their status is determined internally. Balaji added this
8524       -- fix for the BAE bug # 4626717.
8525       IF ( wo_csr.status_code <> G_JOB_STATUS_COMPLETE AND
8526            wo_csr.status_code <> G_JOB_STATUS_COMPLETE_NC AND
8527            wo_csr.status_code <> G_JOB_STATUS_CLOSED AND
8528            wo_csr.status_code <> G_JOB_STATUS_CANCELLED AND
8529            wo_csr.master_workorder_flag = 'N') THEN
8530         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_VST_WO_NOT_CMPL' );
8531         FND_MESSAGE.set_token( 'VISIT_NUM', l_visit_rec.visit_number );
8532         FND_MESSAGE.set_token( 'WO_NAME', wo_csr.workorder_name );
8533         FND_MSG_PUB.add;
8534         RAISE FND_API.G_EXC_ERROR;
8535       END IF;
8536     END IF;
8537   END LOOP;
8538 
8539   IF ( G_DEBUG = 'Y' ) THEN
8540     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing Visit WO' );
8541   END IF;
8542 
8543   -- Add the Visit Workorder for Updates
8544   -- Do not process Visit Workorder if it is already Complete
8545   IF ( l_visit_rec.wo_status_code <> G_JOB_STATUS_COMPLETE AND
8546        l_visit_rec.wo_status_code <> G_JOB_STATUS_COMPLETE_NC AND
8547        l_visit_rec.wo_status_code <> G_JOB_STATUS_CLOSED AND
8548        l_visit_rec.wo_status_code <> G_JOB_STATUS_CANCELLED ) THEN
8549 
8550     IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' ) THEN
8551 
8552       -- Validate Whether Quality Results are submitted for WO
8553       IF ( l_visit_rec.wo_plan_id IS NOT NULL AND
8554            l_visit_rec.wo_collection_id IS NULL ) THEN
8555         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_QA_PENDING' );
8556         FND_MESSAGE.set_token( 'WO_NAME', l_visit_rec.workorder_name );
8557         FND_MSG_PUB.add;
8558         RAISE FND_API.G_EXC_ERROR;
8559       END IF;
8560 
8561       /*start ER # 4757222
8562       IF ( p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
8563 
8564         -- Validate if the actual start dates entered is less than any WO
8565 
8566         IF ( l_visit_rec.actual_start_date IS NOT NULL AND
8567              l_visit_rec.actual_start_date < p_close_visit_rec.actual_start_date ) THEN
8568           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_ST_DATE_LESS' );
8569           FND_MESSAGE.set_token( 'WO_NAME', l_visit_rec.workorder_name );
8570           FND_MESSAGE.set_token( 'START_DT', TO_CHAR( l_visit_rec.actual_start_date , 'DD-MON-YYYY HH24:MI' ) );
8571           FND_MSG_PUB.add;
8572           RAISE FND_API.G_EXC_ERROR;
8573         END IF;
8574 
8575         -- Validate if the actual end dates entered is greater than any WO
8576         IF ( l_visit_rec.actual_end_date IS NOT NULL AND
8577              l_visit_rec.actual_end_date > p_close_visit_rec.actual_end_date ) THEN
8578           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_WO_ACT_END_DATE_GT' );
8579           FND_MESSAGE.set_token( 'WO_NAME', l_visit_rec.workorder_name );
8580           FND_MESSAGE.set_token( 'END_DT', TO_CHAR( l_visit_rec.actual_end_date , 'DD-MON-YYYY HH24:MI' ) );
8581           FND_MSG_PUB.add;
8582           RAISE FND_API.G_EXC_ERROR;
8583         END IF;
8584       END IF;
8585       */--End ER # 4757222
8586       -- Add the Visit WO to the Workorder Table of Records
8587       l_ctr := l_ctr + 1;
8588       l_workorder_tbl(l_ctr).workorder_id := l_visit_rec.workorder_id;
8589       l_workorder_tbl(l_ctr).object_version_number := l_visit_rec.wo_object_version_number;
8590       l_workorder_tbl(l_ctr).workorder_name := l_visit_rec.workorder_name;
8591       l_workorder_tbl(l_ctr).wip_entity_id := l_visit_rec.wip_entity_id;
8592       l_workorder_tbl(l_ctr).master_workorder_flag := 'Y';
8593       l_workorder_tbl(l_ctr).collection_id := l_visit_rec.wo_collection_id;
8594       l_workorder_tbl(l_ctr).actual_start_date := NULL;
8595       l_workorder_tbl(l_ctr).actual_end_date := NULL;
8596 
8597     END IF;
8598   END IF;
8599 
8600   /* Bug # 4955278 - start */
8601   /*
8602    * Interchanged resource txn logic before processing operations.
8603    */
8604   l_ctr := 0;
8605 
8606   IF ( G_DEBUG = 'Y' ) THEN
8607     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing Resource Transactions' );
8608   END IF;
8609 
8610   -- Check if Resource Transactions are required
8611   IF ( p_close_visit_rec.transact_resource_flag = 'Y' ) THEN
8612 
8613     -- Get all the Resource Requirements for the Visit Operations
8614     FOR res_csr IN get_visit_resource_req( l_visit_rec.visit_id ) LOOP
8615 
8616       -- Check if Serial Number is entered for Machine Type Resource
8617       IF ( res_csr.resource_type = 1 AND
8618            ( p_close_visit_rec.serial_number IS NULL OR
8619              p_close_visit_rec.serial_number = FND_API.G_MISS_CHAR ) ) THEN
8620         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_MACH_RES_REQD' );
8621         FND_MESSAGE.set_token( 'WO_NAME', res_csr.workorder_name );
8622         FND_MESSAGE.set_token( 'OP_SEQ', res_csr.operation_seq_num );
8623         FND_MESSAGE.set_token( 'RES_SEQ', res_csr.resource_seq_num );
8624         FND_MSG_PUB.add;
8625         RAISE FND_API.G_EXC_ERROR;
8626       END IF;
8627 
8628       -- Check if Employee Number is entered for Machine Type Resource
8629       IF ( res_csr.resource_type = 2 AND
8630            ( p_close_visit_rec.employee_number IS NULL OR
8631              p_close_visit_rec.employee_number = FND_API.G_MISS_NUM ) ) THEN
8632         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EMP_RES_REQD' );
8633         FND_MESSAGE.set_token( 'WO_NAME', res_csr.workorder_name );
8634         FND_MESSAGE.set_token( 'OP_SEQ', res_csr.operation_seq_num );
8635         FND_MESSAGE.set_token( 'RES_SEQ', res_csr.resource_seq_num );
8636         FND_MSG_PUB.add;
8637         RAISE FND_API.G_EXC_ERROR;
8638       END IF;
8639 
8640       -- Add the Resource Requirement Record for Transaction Processing
8641       l_ctr := l_ctr + 1;
8642       l_resource_req_tbl(l_ctr).wip_entity_id := res_csr.wip_entity_id;
8643       l_resource_req_tbl(l_ctr).workorder_name := res_csr.workorder_name;
8644       l_resource_req_tbl(l_ctr).workorder_id  := res_csr.workorder_id;
8645       l_resource_req_tbl(l_ctr).operation_seq_num := res_csr.operation_seq_num;
8646       l_resource_req_tbl(l_ctr).workorder_operation_id := res_csr.workorder_operation_id;
8647       l_resource_req_tbl(l_ctr).resource_seq_num := res_csr.resource_seq_num;
8648       l_resource_req_tbl(l_ctr).organization_id := res_csr.organization_id;
8649       l_resource_req_tbl(l_ctr).department_id := res_csr.department_id;
8650       l_resource_req_tbl(l_ctr).resource_name := res_csr.resource_name;
8651       l_resource_req_tbl(l_ctr).resource_id := res_csr.resource_id;
8652       l_resource_req_tbl(l_ctr).resource_type := res_csr.resource_type;
8653       l_resource_req_tbl(l_ctr).uom_code := res_csr.uom_code;
8654       l_resource_req_tbl(l_ctr).usage_rate_or_amount := res_csr.usage_rate_or_amount;
8655 
8656     END LOOP;
8657 
8658     l_ctr := 0;
8659   END IF;
8660 
8661   IF ( l_resource_req_tbl.COUNT > 0 ) THEN
8662 
8663    /*
8664     SELECT  person_id
8665     INTO    l_employee_id
8666     FROM    PER_ALL_PEOPLE_F
8667     WHERE   employee_number = p_close_visit_rec.employee_number
8668       AND   rownum = 1;
8669 
8670 
8671     IF ( SQL%NOTFOUND ) THEN
8672       FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EMPLOYEE_NOT_FOUND' );
8673       FND_MESSAGE.set_token( 'EMP_NUM', p_close_visit_rec.employee_number );
8674       FND_MSG_PUB.add;
8675       RAISE FND_API.G_EXC_ERROR;
8676     END IF;
8677     */
8678 
8679     BEGIN
8680        -- Fix for bug# 4553747.
8681        SELECT employee_id
8682        INTO l_employee_id
8683        FROM  mtl_employees_current_view
8684        WHERE organization_id = l_visit_rec.organization_id
8685          AND employee_num =   p_close_visit_rec.employee_number
8686          AND rownum = 1;
8687 
8688     EXCEPTION
8689       WHEN no_data_found THEN
8690         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_EMPLOYEE_NOT_FOUND' );
8691         FND_MESSAGE.set_token( 'EMP_NUM', p_close_visit_rec.employee_number );
8692         FND_MSG_PUB.add;
8693         RAISE FND_API.G_EXC_ERROR;
8694     END;
8695 
8696     -- Iterate through all the Resource Requirements
8697     FOR i IN l_resource_req_tbl.FIRST..l_resource_req_tbl.LAST LOOP
8698 
8699       -- Get all the Resource Txns performed for a Resource Requirement
8700       OPEN  get_resource_txns( l_resource_req_tbl(i).wip_entity_id,
8701                                l_resource_req_tbl(i).operation_seq_num,
8702                                l_resource_req_tbl(i).resource_seq_num );
8703       FETCH get_resource_txns
8704       INTO  l_txn_qty;
8705       CLOSE get_resource_txns;
8706       /*
8707       IF ( l_transaction_qty > 0 ) THEN
8708 
8709         -- Subtract the consumed quantity from the required quantity
8710         l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).usage_rate_or_amount - l_transaction_qty;
8711         l_transaction_qty := 0;
8712       END IF;
8713       */
8714       -- Get all the Pending Resource Txns performed for a Resource Requirement
8715       OPEN  get_pending_resource_txns( l_resource_req_tbl(i).wip_entity_id,
8716                                        l_resource_req_tbl(i).operation_seq_num,
8717                                        l_resource_req_tbl(i).resource_seq_num );
8718       FETCH get_pending_resource_txns
8719       INTO  l_pending_txn_qty;
8720       CLOSE get_pending_resource_txns;
8721       /*
8722       IF ( l_transaction_qty > 0 ) THEN
8723         IF ( l_resource_req_tbl(i).transaction_quantity <> 0 ) THEN
8724 
8725           -- Subtract the consumed quantity from the required quantity
8726           l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).transaction_quantity - l_transaction_qty;
8727         ELSE
8728 
8729           -- Subtract the consumed quantity from the required quantity
8730           l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).usage_rate_or_amount - l_transaction_qty;
8731         END IF;
8732 
8733         l_transaction_qty := 0;
8734       END IF;
8735       */
8736       -- Subtract the consumed quantity from the required quantity
8737       l_resource_req_tbl(i).transaction_quantity := l_resource_req_tbl(i).usage_rate_or_amount - l_txn_qty - l_pending_txn_qty;
8738 
8739       -- If the required qty is greater than zero then txn needs to be performed
8740       IF ( l_resource_req_tbl(i).transaction_quantity > 0 ) THEN
8741 
8742         -- Add a Resource Transaction Record
8743         l_ctr := l_ctr + 1;
8744 
8745         /*
8746         l_res_txn_tbl(l_ctr).wip_entity_id := l_resource_req_tbl(i).wip_entity_id;
8747         --l_res_txn_tbl(l_ctr).organization_id := l_resource_req_tbl(i).organization_id;
8748         l_res_txn_tbl(l_ctr).department_id := l_resource_req_tbl(i).department_id;
8749         l_res_txn_tbl(l_ctr).operation_seq_num := l_resource_req_tbl(i).operation_seq_num;
8750         l_res_txn_tbl(l_ctr).resource_seq_num := l_resource_req_tbl(i).resource_seq_num;
8751         l_res_txn_tbl(l_ctr).resource_id := l_resource_req_tbl(i).resource_id;
8752         l_res_txn_tbl(l_ctr).transaction_quantity := l_resource_req_tbl(i).transaction_quantity;
8753         l_res_txn_tbl(l_ctr).transaction_uom := l_resource_req_tbl(i).uom_code;
8754         */
8755 
8756         l_prd_resrc_txn_tbl(l_ctr).workorder_id := l_resource_req_tbl(i).workorder_id;
8757         l_prd_resrc_txn_tbl(l_ctr).organization_id := l_resource_req_tbl(i).organization_id;
8758         l_prd_resrc_txn_tbl(l_ctr).dml_operation := 'C';
8759         l_prd_resrc_txn_tbl(l_ctr).operation_sequence_num := l_resource_req_tbl(i).operation_seq_num;
8760         l_prd_resrc_txn_tbl(l_ctr).workorder_operation_id := l_resource_req_tbl(i).workorder_operation_id;
8761         l_prd_resrc_txn_tbl(l_ctr).resource_sequence_num := l_resource_req_tbl(i).resource_seq_num;
8762         l_prd_resrc_txn_tbl(l_ctr).resource_id := l_resource_req_tbl(i).resource_id;
8763         l_prd_resrc_txn_tbl(l_ctr).resource_name := l_resource_req_tbl(i).resource_name;
8764 
8765         l_prd_resrc_txn_tbl(l_ctr).department_id := l_resource_req_tbl(i).department_id;
8766 
8767         l_prd_resrc_txn_tbl(l_ctr).qty := l_resource_req_tbl(i).transaction_quantity;
8768         l_prd_resrc_txn_tbl(l_ctr).uom_code := l_resource_req_tbl(i).uom_code;
8769 
8770         -- Pass the Employee ID or the Serial Number
8771         IF ( l_resource_req_tbl(i).resource_type = 2 ) THEN
8772           --l_res_txn_tbl(l_ctr).employee_id := l_employee_id;
8773          l_prd_resrc_txn_tbl(l_ctr).employee_num := p_close_visit_rec.employee_number;
8774         ELSIF ( l_resource_req_tbl(i).resource_type = 1 ) THEN
8775           --l_res_txn_tbl(l_ctr).serial_number := p_close_visit_rec.serial_number;
8776           l_prd_resrc_txn_tbl(l_ctr).serial_number := p_close_visit_rec.serial_number;
8777         END IF;
8778       END IF;
8779 
8780     END LOOP;
8781 
8782     --IF ( l_res_txn_tbl.COUNT > 0 ) THEN
8783     IF ( l_prd_resrc_txn_tbl.COUNT > 0 ) THEN
8784 
8785       /*
8786       -- Perform the Resource Txns
8787       AHL_WIP_JOB_PVT.insert_resource_txn
8788       (
8789         p_api_version        => 1.0,
8790         p_init_msg_list      => FND_API.G_FALSE,
8791         p_commit             => FND_API.G_FALSE,
8792         p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
8793         x_return_status      => l_return_status,
8794         x_msg_count          => l_msg_count,
8795         x_msg_data           => l_msg_data,
8796         p_ahl_res_txn_tbl    => l_res_txn_tbl
8797       );
8798       */
8799 
8800 
8801       AHL_PRD_RESOURCE_TRANX_PVT.PROCESS_RESOURCE_TXNS
8802       (
8803         p_api_version        => 1.0,
8804         p_init_msg_list      => FND_API.G_FALSE,
8805         p_commit             => FND_API.G_FALSE,
8806         p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
8807         x_return_status      => l_return_status,
8808         x_msg_count          => l_msg_count,
8809         x_msg_data           => l_msg_data,
8810         p_x_prd_resrc_txn_tbl => l_prd_resrc_txn_tbl
8811       );
8812 
8813       IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
8814         RAISE FND_API.G_EXC_ERROR;
8815       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
8816         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8817       END IF;
8818 
8819     END IF;
8820 
8821   END IF;
8822   /* Bug # 4955278 - end */
8823 
8824   l_ctr := 0;
8825 
8826   IF ( G_DEBUG = 'Y' ) THEN
8827     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Processing WO Operations' );
8828   END IF;
8829 
8830   -- Get all the Workorder Operations for the Visit
8831   FOR op_csr IN get_visit_operations( l_visit_rec.visit_id ) LOOP
8832 
8833     -- Check if Operations need to be completed
8834     IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' ) THEN
8835 
8836       -- Do not process Workorder Operations which are already Complete
8837       IF ( op_csr.status_code <> G_OP_STATUS_COMPLETE ) THEN
8838 
8839         /*Start ER # 4757222*/
8840         /*
8841          * Moved this validation here since there is no need to validate
8842          * the actual dates entered against completed operations. Need to validate dates
8843          * against only those operations which need to be completed.
8844          */
8845         /* No need for this validation as the default dates entered by the user should not
8846         -- be modified. Balaji commented out the code for the ER # 4757222
8847         IF ( p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
8848 
8849         -- Validate if the actual start dates entered is less than any WO Op
8850         IF ( op_csr.actual_start_date IS NOT NULL AND
8851              op_csr.actual_start_date < p_close_visit_rec.actual_start_date ) THEN
8852           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ACT_ST_DATE_LESS' );
8853           FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
8854           FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
8855           FND_MESSAGE.set_token( 'START_DT', TO_CHAR( op_csr.actual_start_date, 'DD-MON-YYYY HH24:MI' ) );
8856           FND_MSG_PUB.add;
8857           RAISE FND_API.G_EXC_ERROR;
8858         END IF;
8859 
8860         -- Validate if the actual end dates entered is greater than any WO Op
8861         IF ( op_csr.actual_end_date IS NOT NULL AND
8862              op_csr.actual_end_date > p_close_visit_rec.actual_end_date ) THEN
8863           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_ACT_END_DATE_GT' );
8864           FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
8865           FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
8866           FND_MESSAGE.set_token( 'END_DT', TO_CHAR( op_csr.actual_end_date, 'DD-MON-YYYY HH24:MI' ) );
8867           FND_MSG_PUB.add;
8868           RAISE FND_API.G_EXC_ERROR;
8869         END IF;
8870 
8871       END IF;*/
8872 
8873        /*End ER # 4757222*/
8874         -- Validate whether Quality Results are Submitted
8875         IF ( op_csr.plan_id IS NOT NULL AND
8876              op_csr.collection_id IS NULL ) THEN
8877           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_OP_QA_PENDING' );
8878           FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
8879           FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
8880           FND_MSG_PUB.add;
8881           RAISE FND_API.G_EXC_ERROR;
8882         END IF;
8883 
8884         l_ctr := l_ctr + 1;
8885         l_operation_tbl(l_ctr).workorder_operation_id := op_csr.workorder_operation_id;
8886         l_operation_tbl(l_ctr).object_version_number := op_csr.object_version_number;
8887         l_operation_tbl(l_ctr).workorder_name := op_csr.workorder_name;
8888         l_operation_tbl(l_ctr).collection_id := op_csr.collection_id;
8889 
8890 	IF (op_csr.actual_end_date IS NULL OR op_csr.actual_start_date IS NULL)
8891 	   AND
8892 	   (p_close_visit_rec.default_actual_dates_flag = 'Y')
8893 	THEN
8894 		-- Derive operation actual dates from res txn dates.
8895 		-- Balaji added this code for R12. Also refer ER # 4955278
8896    		Get_Op_Act_from_Res_Txn( p_wip_entity_id	=>	op_csr.wip_entity_id,
8897 					 p_operation_seq_num	=>	op_csr.operation_seq_num,
8898 					 x_actual_start_date	=>	l_def_actual_start_date,
8899 					 x_actual_end_date	=>	l_def_actual_end_date
8900 					);
8901 
8902 		IF (l_def_actual_start_date IS NULL OR l_def_actual_end_date IS NULL )
8903 		THEN
8904 		  FND_MESSAGE.set_name( 'AHL', 'AHL_OP_DEF_NO_RES_TXN' );
8905 		  FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
8906 		  FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
8907 		  FND_MSG_PUB.add;
8908 		  RAISE FND_API.G_EXC_ERROR;
8909 		END IF;
8910 	END IF;
8911 
8912 	/* Start ER # 4757222 */
8913         IF ( op_csr.actual_end_date IS NULL ) THEN
8914 
8915          IF ( p_close_visit_rec.default_actual_dates_flag = 'Y' ) THEN
8916 
8917             -- Update Actual Date with Scheduled Date
8918             l_operation_tbl(l_ctr).actual_end_date := LEAST( SYSDATE , l_def_actual_end_date );
8919           ELSE
8920             -- Update Actual Date with User Entered Value
8921             l_operation_tbl(l_ctr).actual_end_date := p_close_visit_rec.actual_end_date;
8922           END IF;
8923         ELSE
8924 
8925           -- Update Actual Date with DB Value if already entered
8926           l_operation_tbl(l_ctr).actual_end_date := op_csr.actual_end_date;
8927         END IF;
8928 
8929         -- Check if Actual Date is already entered
8930         IF ( op_csr.actual_start_date IS NULL ) THEN
8931           IF ( p_close_visit_rec.default_actual_dates_flag = 'Y' ) THEN
8932             -- Update Actual Date with Scheduled Date
8933 
8934             -- Update with Scheduled Date
8935             IF ( l_def_actual_start_date < SYSDATE ) THEN
8936                l_operation_tbl(l_ctr).actual_start_date := l_def_actual_start_date;
8937             ELSE
8938                l_operation_tbl(l_ctr).actual_start_date := l_operation_tbl(l_ctr).actual_end_date - (l_def_actual_end_date - l_def_actual_start_date);
8939             END IF;
8940 
8941 
8942           ELSE
8943             -- Update Actual Date with User Entered Value
8944             l_operation_tbl(l_ctr).actual_start_date := p_close_visit_rec.actual_start_date;
8945           END IF;
8946         ELSE
8947 
8948           -- Update Actual Date with DB Value if already entered
8949           l_operation_tbl(l_ctr).actual_start_date := op_csr.actual_start_date;
8950         END IF;
8951         /* End ER # 4757222 */
8952 
8953         /* commenting out the code as this was fixed for ER # 4757192
8954         -- Check if Actual Date is already entered
8955         IF ( op_csr.actual_start_date IS NULL ) THEN
8956           -- R12
8957 	  -- actual dates should be defaulted from res txn dates
8958 	  -- commented out
8959           IF ( p_close_visit_rec.default_actual_dates_flag = 'Y' ) THEN
8960             -- Update Actual Date with Scheduled Date
8961             l_operation_tbl(l_ctr).actual_start_date := op_csr.scheduled_start_date;
8962           ELSE
8963             -- Update Actual Date with User Entered Value
8964             l_operation_tbl(l_ctr).actual_start_date := p_close_visit_rec.actual_start_date;
8965           END IF;
8966 	  -- commented out
8967 	  IF ( p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
8968             -- Update Actual Date with User Entered Value
8969             l_operation_tbl(l_ctr).actual_start_date := p_close_visit_rec.actual_start_date;
8970           END IF;
8971         ELSE
8972 
8973           -- Update Actual Date with DB Value if already entered
8974           l_operation_tbl(l_ctr).actual_start_date := op_csr.actual_start_date;
8975         END IF;
8976 
8977         -- Check if Actual Date is already entered
8978         IF ( op_csr.actual_end_date IS NULL ) THEN
8979           -- R12
8980 	  -- actual dates should be defaulted from res txn dates
8981 
8982           -- commented out
8983           IF ( p_close_visit_rec.default_actual_dates_flag = 'Y' ) THEN
8984 
8985             -- Update Actual Date with Scheduled Date
8986             l_operation_tbl(l_ctr).actual_end_date := LEAST( SYSDATE , op_csr.scheduled_end_date );
8987           ELSE
8988 
8989             -- Update Actual Date with User Entered Value
8990             l_operation_tbl(l_ctr).actual_end_date := p_close_visit_rec.actual_end_date;
8991           END IF;
8992 	  -- commented out
8993           IF ( p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
8994             -- Update Actual Date with User Entered Value
8995             l_operation_tbl(l_ctr).actual_end_date := p_close_visit_rec.actual_end_date;
8996           END IF;
8997         ELSE
8998 
8999           -- Update Actual Date with DB Value if already entered
9000           l_operation_tbl(l_ctr).actual_end_date := op_csr.actual_end_date;
9001         END IF;
9002         */
9003 
9004         IF ( G_DEBUG = 'Y' ) THEN
9005           AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name
9006           || ' : Wo Name - ' || l_operation_tbl(l_ctr).workorder_name
9007           || ' OP Seq - ' || op_csr.operation_seq_num || ' WO OP ID - '
9008           || l_operation_tbl(l_ctr).workorder_operation_id || ' Actual Start Date - '
9009           || l_operation_tbl(l_ctr).actual_start_date || ' Actual End Date - '
9010           || l_operation_tbl(l_ctr).actual_end_date );
9011         END IF;
9012 
9013       END IF;
9014     ELSE
9015       -- Validate to ensure that the Workorder Ops are already completed
9016       IF ( op_csr.status_code <> G_OP_STATUS_COMPLETE ) THEN
9017         FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_VST_WO_OP_NOT_CMPL' );
9018         FND_MESSAGE.set_token( 'VISIT_NUM', l_visit_rec.visit_number );
9019         FND_MESSAGE.set_token( 'WO_NAME', op_csr.workorder_name );
9020         FND_MESSAGE.set_token( 'OP_SEQ', op_csr.operation_seq_num );
9021         FND_MSG_PUB.add;
9022         RAISE FND_API.G_EXC_ERROR;
9023       END IF;
9024     END IF;
9025   END LOOP;
9026 
9027 
9028   IF ( G_DEBUG = 'Y' ) THEN
9029     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Updating Operation Actual Dates' );
9030   END IF;
9031 
9032   -- perform the Operation Updates
9033   -- If the dates are to be defaulted then this will be done in the Completions API itself
9034   -- if p_default is passed as FND_API.G_TRUE
9035   --Balaji remvoed p_close_visit_rec.default_actual_dates_flag = 'N' condition for bug # 4955278
9036 
9037   IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' ) THEN
9038   --AND p_close_visit_rec.default_actual_dates_flag = 'N'
9039 
9040   IF ( l_operation_tbl.COUNT > 0 ) THEN
9041     FOR i IN l_operation_tbl.FIRST..l_operation_tbl.LAST LOOP
9042       UPDATE  AHL_WORKORDER_OPERATIONS
9043       SET     object_version_number = object_version_number + 1,
9044               actual_start_date = l_operation_tbl(i).actual_start_date,
9045               actual_end_date = l_operation_tbl(i).actual_end_date,
9046               LAST_UPDATE_DATE = SYSDATE,
9047               LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
9048               LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
9049       WHERE   workorder_operation_id = l_operation_tbl(i).workorder_operation_id
9050       AND     object_version_number = l_operation_tbl(i).object_version_number;
9051 
9052       IF ( SQL%ROWCOUNT = 0 ) THEN
9053         FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
9054         FND_MSG_PUB.add;
9055         RAISE FND_API.G_EXC_ERROR;
9056       END IF;
9057 
9058       l_operation_tbl(i).object_version_number := l_operation_tbl(i).object_version_number + 1;
9059     END LOOP;
9060   END IF;
9061 
9062   END IF;
9063 
9064   IF ( G_DEBUG = 'Y' ) THEN
9065     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Completing Operations' );
9066   END IF;
9067 
9068   -- Invoke Complete Operation API to Complete All Operations
9069   IF ( l_operation_tbl.COUNT > 0 ) THEN
9070     FOR i IN l_operation_tbl.FIRST..l_operation_tbl.LAST LOOP
9071       complete_operation
9072       (
9073         p_api_version            => 1.0,
9074         p_init_msg_list          => FND_API.G_FALSE,
9075         p_commit                 => FND_API.G_FALSE,
9076         p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
9077         p_default                => FND_API.G_FALSE,
9078         p_module_type            => NULL,
9079         x_return_status          => l_return_status,
9080         x_msg_count              => l_msg_count,
9081         x_msg_data               => l_msg_data,
9082         p_workorder_operation_id => l_operation_tbl(i).workorder_operation_id,
9083         p_object_version_no      => l_operation_tbl(i).object_version_number
9084       );
9085 
9086       IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9087         RAISE FND_API.G_EXC_ERROR;
9088       ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9089         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9090       END IF;
9091 
9092     END LOOP;
9093   END IF;
9094 
9095   IF ( G_DEBUG = 'Y' ) THEN
9096     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Updating WO Actual Dates' );
9097   END IF;
9098 
9099   -- Perform the Workorder Updates
9100   -- After operation updates and operation completion
9101   IF ( l_workorder_tbl.COUNT > 0 ) THEN
9102     FOR i IN l_workorder_tbl.FIRST..l_workorder_tbl.LAST LOOP
9103 
9104      /*Start ER # 4757222*/
9105      IF ( l_workorder_tbl(i).master_workorder_flag = 'N' AND
9106           p_close_visit_rec.complete_job_ops_flag  = 'Y') THEN
9107 
9108       -- Derive actual dates for the workorder from operation dates.
9109       Get_default_wo_actual_dates(x_return_status => l_return_status,
9110                                 p_workorder_id => l_workorder_tbl(i).workorder_id,
9111 				x_actual_start_date => l_def_actual_start_date,
9112 				x_actual_end_date => l_def_actual_end_date
9113 				);
9114 
9115       -- update the actual dates in the table
9116       IF l_workorder_tbl(i).actual_start_date IS NULL THEN
9117         UPDATE AHL_WORKORDERS
9118         SET OBJECT_VERSION_NUMBER = OBJECT_VERSION_NUMBER + 1,
9119         ACTUAL_START_DATE = l_def_actual_start_date,
9120         LAST_UPDATE_DATE = SYSDATE,
9121         LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
9122         LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
9123         WHERE WORKORDER_ID = l_workorder_tbl(i).workorder_id
9124         AND OBJECT_VERSION_NUMBER = l_workorder_tbl(i).object_version_number;
9125         IF SQL%ROWCOUNT = 0 THEN
9126           FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
9127 	  FND_MESSAGE.set_token('WO_NAME', l_workorder_tbl(i).workorder_name);
9128      	  FND_MSG_PUB.add;
9129           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9130         END IF;
9131         l_workorder_tbl(i).object_version_number := l_workorder_tbl(i).object_version_number + 1;
9132       END IF;-- IF l_actual_start_date IS NULL THEN
9133 
9134       -- update the actual dates in the table
9135       IF l_workorder_tbl(i).actual_end_date IS NULL THEN
9136         UPDATE AHL_WORKORDERS
9137         SET OBJECT_VERSION_NUMBER = OBJECT_VERSION_NUMBER + 1,
9138         ACTUAL_END_DATE = l_def_actual_end_date,
9139         LAST_UPDATE_DATE = SYSDATE,
9140         LAST_UPDATED_BY = FND_GLOBAL.USER_ID,
9141         LAST_UPDATE_LOGIN = FND_GLOBAL.LOGIN_ID
9142         WHERE WORKORDER_ID = l_workorder_tbl(i).workorder_id
9143         AND OBJECT_VERSION_NUMBER = l_workorder_tbl(i).object_version_number;
9144         IF SQL%ROWCOUNT = 0 THEN
9145           FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
9146   	  FND_MESSAGE.set_token('WO_NAME', l_workorder_tbl(i).workorder_name);
9147    	  FND_MSG_PUB.add;
9148           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9149         END IF;
9150         l_workorder_tbl(i).object_version_number := l_workorder_tbl(i).object_version_number + 1;
9151       END IF; -- IF l_actual_end_date IS NULL THEN
9152 
9153      END IF;
9154      /*End ER # 4757222*/
9155       /*Start ER # 4757222
9156       -- Ignore Master Workorders since they are post processed seperately
9157       IF ( l_workorder_tbl(i).master_workorder_flag = 'N' ) THEN
9158         UPDATE  AHL_WORKORDERS
9159         SET     object_version_number = object_version_number + 1,
9160                 actual_start_date = l_workorder_tbl(i).actual_start_date,
9161                 actual_end_date = l_workorder_tbl(i).actual_end_date
9162         WHERE   workorder_id = l_workorder_tbl(i).workorder_id
9163         AND     object_version_number = l_workorder_tbl(i).object_version_number;
9164 
9165         IF ( SQL%ROWCOUNT = 0 ) THEN
9166           FND_MESSAGE.set_name( 'AHL', 'AHL_COM_RECORD_CHANGED' );
9167           FND_MSG_PUB.add;
9168           RAISE FND_API.G_EXC_ERROR;
9169         END IF;
9170 
9171         l_workorder_tbl(i).object_version_number := l_workorder_tbl(i).object_version_number + 1;
9172       END IF;
9173       */
9174       /*End ER # 4757222*/
9175     END LOOP;
9176 
9177     -- Check if Workorders need to be completed
9178     IF ( p_close_visit_rec.complete_job_ops_flag = 'Y' AND
9179          p_close_visit_rec.default_actual_dates_flag = 'N' ) THEN
9180       l_actual_start_date := p_close_visit_rec.actual_start_date;
9181       l_actual_end_date := p_close_visit_rec.actual_end_date;
9182     END IF;
9183 
9184     IF ( G_DEBUG = 'Y' ) THEN
9185       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Updating Actual Dates for Master WOs in Visit' );
9186     END IF;
9187 
9188     -- Update the Actual Dates for Master Workorders in the Visit
9189     l_return_status :=
9190     update_mwo_actual_dates
9191     (
9192       p_wip_entity_id     => l_visit_rec.wip_entity_id,
9193       p_default_flag      => p_close_visit_rec.default_actual_dates_flag,
9194       p_actual_start_date => l_actual_start_date,
9195       p_actual_end_date   => l_actual_end_date
9196     );
9197 
9198     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9199       RAISE FND_API.G_EXC_ERROR;
9200     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9201       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9202     END IF;
9203 
9204   END IF;
9205 
9206 
9207   IF ( G_DEBUG = 'Y' ) THEN
9208     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Completing WOs' );
9209   END IF;
9210 
9211   -- Complete All Visit Workorders in the Order of Completion Dependencies
9212   IF ( l_workorder_tbl.COUNT > 0 ) THEN
9213     l_return_status :=
9214     complete_visit_mr_wos
9215     (
9216       p_wip_entity_id   => l_visit_rec.wip_entity_id,
9217       p_x_workorder_tbl => l_workorder_tbl
9218     );
9219 
9220     IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9221       RAISE FND_API.G_EXC_ERROR;
9222     ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9223       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9224     END IF;
9225 
9226   END IF;
9227 
9228   IF ( G_DEBUG = 'Y' ) THEN
9229     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Signing off MRs' );
9230   END IF;
9231 
9232   -- Invoke Complete MR Instance API to Complete All UEs
9233   IF ( l_child_mr_tbl.COUNT > 0 ) THEN
9234     FOR i IN l_child_mr_tbl.FIRST..l_child_mr_tbl.LAST LOOP
9235 
9236       -- Check Status again because MR could be completed automatically
9237       l_ue_status_code := get_mr_status( l_child_mr_tbl(i).unit_effectivity_id );
9238       --IF ( l_ue_status_code <> G_MR_STATUS_SIGNED_OFF ) THEN
9239       -- Balaji added additional MR status checks for BAE Bug
9240       IF (
9241 	      l_ue_status_code <> G_MR_STATUS_SIGNED_OFF AND
9242 	      l_ue_status_code <> G_MR_STATUS_DEFERRED AND
9243 	      l_ue_status_code <> G_MR_STATUS_TERMINATED AND
9244 	      l_ue_status_code <> G_MR_STATUS_CANCELLED
9245 
9246       ) THEN
9247 
9248         IF ( l_ue_status_code <> G_MR_STATUS_JOBS_COMPLETE ) THEN
9249           FND_MESSAGE.set_name( 'AHL', 'AHL_PRD_INV_SIGNOFF_STATUS');
9250           FND_MESSAGE.set_token( 'MAINT_REQ', l_child_mr_tbl(i).mr_title);
9251 		-- to be changed
9252 		-- write a global function later
9253 		-- replacing with call to get_status function
9254 				-- so no exceptions are thrown if the
9255 				-- lookup does not exist
9256 				l_status_meaning := get_status(l_ue_status_code,
9257 																																											'AHL_PRD_MR_STATUS');
9258 
9259       /*SELECT meaning INTO l_status_meaning
9260 	   FROM fnd_lookup_values_vl
9261         WHERE lookup_type = 'AHL_PRD_MR_STATUS'
9262           AND LOOKUP_CODE = l_ue_status_code;
9263 					*/
9264           FND_MESSAGE.set_token( 'STATUS', l_status_meaning );
9265           FND_MSG_PUB.add;
9266           RAISE FND_API.G_EXC_ERROR;
9267         END IF;
9268         complete_mr_instance
9269         (
9270           p_api_version            => 1.0,
9271           p_init_msg_list          => FND_API.G_FALSE,
9272           p_commit                 => FND_API.G_FALSE,
9273           p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
9274           p_default                => FND_API.G_FALSE,
9275           p_module_type            => NULL,
9276           x_return_status          => l_return_status,
9277           x_msg_count              => l_msg_count,
9278           x_msg_data               => l_msg_data,
9279           p_x_mr_rec               => l_child_mr_tbl(i)
9280         );
9281 
9282         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9283           RAISE FND_API.G_EXC_ERROR;
9284         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9285           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9286         END IF;
9287       END IF;
9288 
9289     END LOOP;
9290   END IF;
9291 
9292   IF ( G_DEBUG = 'Y' ) THEN
9293     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Closing Visit' );
9294   END IF;
9295 
9296   -- Invoke close_visit API to close the Visit in VWP and Projects
9297   AHL_VWP_VISITS_PVT.close_visit
9298   (
9299     p_api_version            => 1.0,
9300     p_init_msg_list          => FND_API.G_FALSE,
9301     p_commit                 => FND_API.G_FALSE,
9302     p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
9303     p_module_type            => NULL,
9304     p_visit_id               => p_close_visit_rec.visit_id,
9305     p_x_cost_session_id      => l_cost_session_id,
9306     p_x_mr_session_id        => l_mr_session_id,
9307     x_return_status          => l_return_status,
9308     x_msg_count              => l_msg_count,
9309     x_msg_data               => l_msg_data
9310   );
9311 
9312   IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9313     RAISE FND_API.G_EXC_ERROR;
9314   ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9315     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9316   END IF;
9317 
9318   -- Record Counter Readings for all WOs
9319   IF ( l_workorder_tbl.COUNT > 0 AND
9320        G_CTR_READING_PLAN_ID IS NOT NULL AND
9321        l_visit_rec.item_instance_id IS NOT NULL ) THEN
9322 
9323     IF ( G_DEBUG = 'Y' ) THEN
9324       AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Getting Counters' );
9325     END IF;
9326 
9327     -- Bug # 6750836 -- Start
9328 
9329     --IF ( l_counter_tbl.COUNT > 0 ) THEN
9330 
9331       IF ( G_DEBUG = 'Y' ) THEN
9332         AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Recording WO Counter Readings' );
9333       END IF;
9334 
9335       -- Record Counter Readings for all the Workorders.
9336       FOR i IN l_workorder_tbl.FIRST..l_workorder_tbl.LAST LOOP
9337 
9338         -- Get the Current Counter Readings for the Item Instance.
9339         l_return_status :=
9340         get_cp_counters
9341         (
9342           p_item_instance_id  => l_visit_rec.item_instance_id,
9343           p_wip_entity_id     => l_workorder_tbl(i).wip_entity_id,
9344           p_actual_date       => l_workorder_tbl(i).actual_end_date,
9345           x_counter_tbl       => l_counter_tbl
9346         );
9347 
9348         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9349           RAISE FND_API.G_EXC_ERROR;
9350         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9351           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9352         END IF;
9353 
9354         IF ( l_counter_tbl.COUNT > 0 ) THEN
9355 
9356 		l_return_status :=
9357 		record_wo_ctr_readings
9358 		(
9359 		  x_msg_data           => l_msg_data,
9360 		  x_msg_count          => l_msg_count,
9361 		  p_wip_entity_id      => l_workorder_tbl(i).wip_entity_id,
9362 		  p_counter_tbl        => l_counter_tbl
9363 		);
9364 
9365 		IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9366 		  RAISE FND_API.G_EXC_ERROR;
9367 		ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9368 		  RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9369 		END IF;
9370 
9371 		-- Re-set the API savepoint because, Quality Results submission commits
9372 		SAVEPOINT close_visit_PVT;
9373 
9374         END IF;
9375 
9376       END LOOP;
9377     --END IF;
9378     -- Bug # 6750836 -- end
9379   END IF;
9380 
9381   IF ( G_DEBUG = 'Y' ) THEN
9382     AHL_DEBUG_PUB.debug( G_PKG_NAME || '.' || l_api_name || ' : Before Firing QA Actions' );
9383   END IF;
9384 
9385   -- Fire QA Actions for all MRs
9386   IF ( l_child_mr_tbl.COUNT > 0 ) THEN
9387     FOR i IN l_child_mr_tbl.FIRST..l_child_mr_tbl.LAST LOOP
9388       IF ( l_child_mr_tbl(i).qa_collection_id IS NOT NULL ) THEN
9389 
9390         QA_SS_RESULTS.wrapper_fire_action
9391         (
9392           q_collection_id    => l_child_mr_tbl(i).qa_collection_id,
9393           q_return_status    => l_return_status,
9394           q_msg_count        => l_msg_count,
9395           q_msg_data         => l_msg_data
9396         );
9397 
9398         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9399           x_msg_data := l_msg_data;
9400           x_msg_count := l_msg_count;
9401           RETURN;
9402         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9403           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9404         END IF;
9405 
9406         -- Re-set the API savepoint because, the wrapper_fire_action commits.
9407         SAVEPOINT close_visit_PVT;
9408 
9409       END IF;
9410     END LOOP;
9411   END IF;
9412 
9413   -- Fire QA Actions for all Operations
9414   IF ( l_operation_tbl.COUNT > 0 ) THEN
9415     FOR i IN l_operation_tbl.FIRST..l_operation_tbl.LAST LOOP
9416       IF ( l_operation_tbl(i).collection_id IS NOT NULL ) THEN
9417 
9418         QA_SS_RESULTS.wrapper_fire_action
9419         (
9420           q_collection_id    => l_operation_tbl(i).collection_id,
9421           q_return_status    => l_return_status,
9422           q_msg_count        => l_msg_count,
9423           q_msg_data         => l_msg_data
9424         );
9425 
9426         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9427           x_msg_data := l_msg_data;
9428           x_msg_count := l_msg_count;
9429           RETURN;
9430         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9431           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9432         END IF;
9433 
9434         -- Re-set the API savepoint because, the wrapper_fire_action commits.
9435         SAVEPOINT close_visit_PVT;
9436 
9437       END IF;
9438     END LOOP;
9439   END IF;
9440 
9441   -- Fire QA Actions for all Workorders
9442   IF ( l_workorder_tbl.COUNT > 0 ) THEN
9443     FOR i IN l_workorder_tbl.FIRST..l_workorder_tbl.LAST LOOP
9444       IF ( l_workorder_tbl(i).collection_id IS NOT NULL ) THEN
9445 
9446         QA_SS_RESULTS.wrapper_fire_action
9447         (
9448           q_collection_id    => l_workorder_tbl(i).collection_id,
9449           q_return_status    => l_return_status,
9450           q_msg_count        => l_msg_count,
9451           q_msg_data         => l_msg_data
9452         );
9453 
9454         IF ( l_return_status = FND_API.G_RET_STS_ERROR ) THEN
9455           x_msg_data := l_msg_data;
9456           x_msg_count := l_msg_count;
9457           RETURN;
9458         ELSIF ( l_return_status = FND_API.G_RET_STS_UNEXP_ERROR ) THEN
9459           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9460         END IF;
9461 
9462         -- Re-set the API savepoint because, the wrapper_fire_action commits.
9463         SAVEPOINT close_visit_PVT;
9464 
9465       END IF;
9466     END LOOP;
9467   END IF;
9468 
9469   -- Perform the Commit (if requested)
9470   IF FND_API.to_boolean( p_commit ) THEN
9471     COMMIT WORK;
9472   END IF;
9473 
9474   -- Disable debug (if enabled)
9475   IF ( G_DEBUG = 'Y' ) THEN
9476     AHL_DEBUG_PUB.disable_debug;
9477   END IF;
9478 
9479 EXCEPTION
9480 
9481   WHEN FND_API.G_EXC_ERROR THEN
9482     ROLLBACK TO close_visit_PVT;
9483     x_return_status := FND_API.G_RET_STS_ERROR;
9484     FND_MSG_PUB.count_and_get
9485     (
9486       p_encoded  => FND_API.G_FALSE,
9487       p_count    => x_msg_count,
9488       p_data     => x_msg_data
9489     );
9490 
9491     IF ( G_DEBUG = 'Y' ) THEN
9492       AHL_DEBUG_PUB.disable_debug;
9493     END IF;
9494 
9495   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
9496     ROLLBACK TO close_visit_PVT;
9497     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
9498     FND_MSG_PUB.count_and_get
9499     (
9500       p_encoded  => FND_API.G_FALSE,
9501       p_count    => x_msg_count,
9502       p_data     => x_msg_data
9503     );
9504 
9505     IF ( G_DEBUG = 'Y' ) THEN
9506       AHL_DEBUG_PUB.disable_debug;
9507     END IF;
9508 
9509   WHEN OTHERS THEN
9510     ROLLBACK TO close_visit_PVT;
9511     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
9512     IF FND_MSG_PUB.check_msg_level( FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR )
9513     THEN
9514       FND_MSG_PUB.add_exc_msg
9515       (
9516         p_pkg_name         => G_PKG_NAME,
9517         p_procedure_name   => l_api_name,
9518         p_error_text       => SUBSTRB(SQLERRM,1,240)
9519       );
9520     END IF;
9521     FND_MSG_PUB.count_and_get
9522     (
9523       p_encoded  => FND_API.G_FALSE,
9524       p_count    => x_msg_count,
9525       p_data     => x_msg_data
9526     );
9527 
9528     IF ( G_DEBUG = 'Y' ) THEN
9529       AHL_DEBUG_PUB.disable_debug;
9530     END IF;
9531 END close_visit;
9532 
9533 ------------------------------------------------------------------------------------------------
9534 -- Function to check if the workorder completion operation can be carried out. Following factors
9535 -- determine the same...
9536 -- 1. Unit is quarantined.
9537 -- 2. Workorder is in a status where it can be completed.
9538 -- 3. Status of child workorders.
9539 -- 4. Status of containing operations.
9540 -- 5. Quality collection has been done for the workorder or not.
9541 ------------------------------------------------------------------------------------------------
9542 
9543 FUNCTION Is_Complete_Enabled(
9544 		p_workorder_id		IN	NUMBER,
9545 		P_operation_seq_num	IN	NUMBER,
9546 		p_ue_id                 IN      NUMBER,
9547                 p_check_unit            IN      VARCHAR2 DEFAULT FND_API.G_TRUE
9548 )
9549 RETURN VARCHAR2
9550 IS
9551 
9552 /*
9553  * Cursor for getting workorder_operation_id from workorder_id and op_seq_no
9554  */
9555 CURSOR c_get_wo_op_id(p_workorder_id IN NUMBER, p_op_seq_no IN NUMBER)
9556 IS
9557 SELECT
9558 	workorder_operation_id
9559 FROM
9560 	AHL_WORKORDER_OPERATIONS
9561 WHERE
9562 	workorder_id = p_workorder_id AND
9563 	operation_sequence_num = p_op_seq_no;
9564 
9565 -- To get the Unit Effectivity Details and it's master workorder details
9566 CURSOR     get_ue_details( c_unit_effectivity_id NUMBER ) IS
9567 SELECT     --UE.unit_effectivity_id unit_effectivity_id,
9568            --UE.title ue_title,
9569            --UE.ump_status_code ue_status_code,
9570            UE.status_code ue_status_code,
9571            --UE.qa_inspection_type_code ue_qa_inspection_type_code,
9572            --UE.qa_plan_id ue_qa_plan_id,
9573            --UE.qa_collection_id ue_qa_collection_id,
9574            WO.workorder_id workorder_id,
9575            WO.wip_entity_id wip_entity_id
9576 FROM       AHL_WORKORDERS WO,
9577            AHL_VISIT_TASKS_B VT,
9578            --AHL_UE_DEFERRAL_DETAILS_V UE
9579            AHL_UNIT_EFFECTIVITIES_B UE
9580 WHERE      WO.visit_task_id = VT.visit_task_id
9581 AND        VT.task_type_code IN ( 'SUMMARY' , 'UNASSOCIATED' )
9582 AND        VT.unit_effectivity_id = UE.unit_effectivity_id
9583 AND        UE.unit_effectivity_id = c_unit_effectivity_id;
9584 
9585 -- Cursor to get the child ue details
9586 -- fix for bug number 7295717 (Sunil)
9587 /*CURSOR     get_child_ue_details( c_unit_effectivity_id NUMBER ) IS
9588 SELECT     unit_effectivity_id,
9589            title,
9590            ump_status_code,
9591            qa_inspection_type_code,
9592            qa_plan_id,
9593            qa_collection_id
9594 FROM       AHL_UE_DEFERRAL_DETAILS_V
9595 WHERE      unit_effectivity_id IN
9596            (
9597              SELECT     related_ue_id
9598              FROM       AHL_UE_RELATIONSHIPS
9599              WHERE      unit_effectivity_id = related_ue_id
9600              START WITH ue_id = c_unit_effectivity_id
9601                     AND relationship_code = 'PARENT'
9602              CONNECT BY ue_id = PRIOR related_ue_id
9603                     AND relationship_code = 'PARENT'
9604            );*/
9605 --ORDER BY   level DESC;
9606 
9607 -- To get the Child Workorder Details for a UE
9608 CURSOR     get_ue_workorders( c_wip_entity_id NUMBER ) IS
9609 SELECT     CWO.workorder_id workorder_id
9610 FROM       WIP_DISCRETE_JOBS WIP,
9611            AHL_WORKORDERS CWO,
9612            WIP_SCHED_RELATIONSHIPS REL
9613 WHERE      WIP.wip_entity_id = CWO.wip_entity_id
9614 AND        CWO.wip_entity_id = REL.child_object_id
9615 AND        CWO.status_code NOT IN (G_JOB_STATUS_DELETED, G_JOB_STATUS_COMPLETE, G_JOB_STATUS_COMPLETE_NC, G_JOB_STATUS_CANCELLED, G_JOB_STATUS_CLOSED)
9616 AND        REL.parent_object_type_id = 1
9617 AND        REL.child_object_type_id = 1
9618 START WITH REL.parent_object_id = c_wip_entity_id
9619 AND        REL.relationship_type = 1
9620 CONNECT BY REL.parent_object_id = PRIOR REL.child_object_id
9621 AND        REL.relationship_type = 1
9622 ORDER BY   level DESC;
9623 
9624 -- To get all the UE Operations
9625 CURSOR     get_ue_operations( c_wip_entity_id NUMBER ) IS
9626 SELECT					WOP.workorder_id workorder_id,
9627            WIP.operation_seq_num operation_seq_num
9628 FROM       AHL_WORKORDER_OPERATIONS WOP,
9629            WIP_OPERATIONS WIP,
9630            AHL_WORKORDERS CWO
9631 WHERE      WOP.operation_sequence_num = WIP.operation_seq_num
9632 AND        WOP.workorder_id = CWO.workorder_id
9633 AND        WIP.wip_entity_id = CWO.wip_entity_id
9634 AND        WIP.WIP_ENTITY_ID IN (
9635              SELECT     CWO.wip_entity_id
9636 FROM       WIP_DISCRETE_JOBS WIP,
9637            AHL_WORKORDERS CWO,
9638            WIP_SCHED_RELATIONSHIPS REL
9639 WHERE      WIP.wip_entity_id = CWO.wip_entity_id
9640 AND        CWO.wip_entity_id = REL.child_object_id
9641 AND        CWO.status_code <> G_JOB_STATUS_DELETED
9642 AND        REL.parent_object_type_id = 1
9643 AND        REL.child_object_type_id = 1
9644 START WITH REL.parent_object_id = c_wip_entity_id
9645 AND        REL.relationship_type = 1
9646 CONNECT BY REL.parent_object_id = PRIOR REL.child_object_id
9647 AND        REL.relationship_type = 1);
9648 --ORDER BY   level DESC;
9649 
9650 --declare local variables here
9651 l_mr_rec        get_ue_details%ROWTYPE;
9652 l_workorder_rec AHL_COMPLETIONS_PVT.workorder_rec_type;
9653 l_operation_tbl AHL_COMPLETIONS_PVT.operation_tbl_type;
9654 l_operation_rec AHL_COMPLETIONS_PVT.operation_rec_type;
9655 l_workorder_operation_id NUMBER;
9656 l_object_version_no NUMBER;
9657 l_date_validation VARCHAR2(1);
9658 l_return_status VARCHAR2(1);
9659 
9660 BEGIN
9661 	-- If all inputs to the API are null then dont proceed any further.
9662 	IF p_workorder_id IS NULL AND p_operation_seq_num IS NULL AND p_ue_id IS NULL
9663 	THEN
9664 		RETURN FND_API.G_FALSE;
9665 	END IF;
9666 
9667 	-- If the unit is locked then workorder or operation cant be completed hence return
9668 	-- false.
9669         -- rroy
9670 	-- Commenting out the is unit locked check here
9671 	-- since this is being done in the validate_cop_Rec and validate_cwo_rec
9672 	-- functions as well
9673 	-- Hence, this becomes redundant
9674 
9675 	/*IF AHL_PRD_UTIL_PKG.Is_Unit_Locked(
9676 			  p_workorder_id 	=> p_workorder_id,
9677 			  P_ue_id		=>	null,
9678 			  P_visit_id		=>	null,
9679 			  P_item_instance_id	=>	null
9680 			 ) = FND_API.G_TRUE
9681 	THEN
9682 		RETURN FND_API.G_FALSE;
9683 	END IF;
9684 	*/
9685 
9686  -- Get workorder record details. This also performs workorder status validation.
9687 	IF p_workorder_id IS NOT NULL THEN
9688 	l_return_status := get_workorder_rec (p_workorder_id		=>	p_workorder_id,
9689 	    				      p_object_version_no	=>	l_object_version_no,
9690 	   				      x_workorder_rec		=>	l_workorder_rec
9691 	     		   );
9692 	IF l_return_status <> FND_API.G_RET_STS_SUCCESS
9693 	THEN
9694 		RETURN FND_API.G_FALSE;
9695 	END IF;
9696 	END IF;
9697 
9698 	-- If operation sequence number is passed to this API then the info is for operation completion
9699 	IF p_operation_seq_num IS NOT NULL
9700 	THEN
9701 		-- Get workorder_operation_id.
9702 		OPEN c_get_wo_op_id(p_workorder_id, p_operation_seq_num);
9703 		FETCH c_get_wo_op_id INTO l_workorder_operation_id;
9704 		CLOSE c_get_wo_op_id;
9705 
9706 		IF l_workorder_operation_id IS NULL
9707 		THEN
9708 			RETURN FND_API.G_FALSE;
9709 		END IF;
9710 
9711 		-- Get workorder operation details rec.
9712 		l_return_status := get_operation_rec(
9713 					p_workorder_operation_id	=>	l_workorder_operation_id,
9714 					p_object_version_no		=>	l_object_version_no,
9715 					x_operation_rec			=>	l_operation_rec
9716 	  			   );
9717 
9718 		IF l_return_status <> FND_API.G_RET_STS_SUCCESS
9719 		THEN
9720 			RETURN FND_API.G_FALSE;
9721 		END IF;
9722 		-- If p_ue_id is not null
9723 		-- then this is a check to see if mr signoff should be enabled
9724 		-- in that case operation status validations should be skipped
9725 		-- Just assign a dummy Uncomplete status to it so that status validations go thru without errors
9726 		IF p_ue_id IS NOT NULL THEN
9727 		  l_operation_rec.status_code := G_OP_STATUS_UNCOMPLETE;
9728 		END IF;
9729 		-- Validate if the workorder operation can be completed. Skip date validations since
9730 		-- that is required only during completion operation.
9731 
9732 		l_return_status := validate_cop_rec(
9733   					p_operation_rec		=>	l_operation_rec,
9734   					p_workorder_rec		=>	l_workorder_rec,				     			  	             p_validate_date	     =>	     l_date_validation,
9735 					p_check_unit            =>      p_check_unit
9736 				   );
9737 
9738 		IF l_return_status <> FND_API.G_RET_STS_SUCCESS
9739 		THEN
9740 			RETURN FND_API.G_FALSE;
9741 		END IF;
9742 
9743 	ELSIF p_workorder_id IS NOT NULL THEN
9744 		-- Get workorder and operation details for the given workorder.
9745 		-- Operations will be validated only if the p_ue_id is null,
9746 		-- that is this is not to check that mr signoff is enabled
9747 		IF p_ue_id IS NULL THEN
9748 		l_return_status := get_workorder_operations(
9749 					p_workorder_id		=>	p_workorder_id,
9750 					p_object_version_no	=>	l_object_version_no,
9751 		   	  		x_operation_tbl		=>	l_operation_tbl
9752  				 );
9753 		IF l_return_status <> FND_API.G_RET_STS_SUCCESS
9754 		THEN
9755 			RETURN FND_API.G_FALSE;
9756 		END IF;
9757 		ELSE
9758 		-- If p_ue_id is not null
9759 		-- then this is a check to see if mr signoff should be enabled
9760 		-- in that case workorder status validations should be skipped
9761 		-- Just assign a dummy Uncomplete status to it so that status validations go thru without errors
9762     l_workorder_rec.status_code := G_JOB_STATUS_RELEASED;
9763 		END IF;
9764 		-- Validate if the workorder can be completed. Date validation is not required
9765 		-- in this case and required only during completion operation.
9766 
9767 		l_return_status := validate_cwo_rec(
9768 					  p_workorder_rec	=>	l_workorder_rec,
9769 					  p_operation_tbl	=>	l_operation_tbl,
9770 					  p_validate_date	=>	l_date_validation,
9771 				    	  p_check_unit          =>      p_check_unit
9772 				   );
9773 
9774 		IF l_return_status <> FND_API.G_RET_STS_SUCCESS
9775 		THEN
9776 			RETURN FND_API.G_FALSE;
9777 		END IF;
9778 	ELSIF p_ue_id IS NOT NULL THEN
9779 	-- As of now we dont check for mr signoff enabled
9780 	-- This code to validate if mr signoff is enabled will be added later
9781 
9782 	-- Validate the status of this MR
9783 	-- If the status is already signed off, then return false
9784  OPEN  get_ue_details(p_ue_id);
9785  FETCH get_ue_details INTO l_mr_rec;
9786 	IF get_ue_details%NOTFOUND THEN
9787 	  CLOSE get_ue_details;
9788 			RETURN FND_API.G_FALSE;
9789 	END IF;
9790 	CLOSE get_ue_details;
9791 
9792 	IF (l_mr_rec.ue_status_code = G_MR_STATUS_SIGNED_OFF) THEN
9793 	  RETURN FND_API.G_FALSE;
9794 	END IF;
9795 
9796  /*l_return_status := is_mr_complete(p_mr_title             => l_mr_rec.ue_title,
9797                                    p_status_code          => l_mr_rec.ue_status_code,
9798                                    p_status               => NULL,
9799                                    p_qa_inspection_type   => l_mr_rec.ue_qa_inspection_type_code,
9800                                    p_qa_plan_id           => l_mr_rec.ue_qa_plan_id,
9801                                    p_qa_collection_id     => l_mr_rec.ue_qa_collection_id
9802                                    );
9803 	IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
9804 	  RETURN FND_API.G_FALSE;
9805 	END IF;
9806 
9807  FOR child_csr IN get_child_ue_details(p_ue_id) LOOP
9808    IF (NVL(child_csr.ump_status_code,'X') <> NVL(G_MR_STATUS_SIGNED_OFF, 'Y')) THEN
9809      -- Check if the Child UE is complete
9810      l_return_status := is_mr_complete(p_mr_title             => child_csr.title,
9811                                        p_status_code          => child_csr.ump_status_code,
9812                                        p_status               => NULL,
9813                                        p_qa_inspection_type   => child_csr.qa_inspection_type_code,
9814                                        p_qa_plan_id           => child_csr.qa_plan_id,
9815                                        p_qa_collection_id     => child_csr.qa_collection_id
9816                                       );
9817 
9818 	    IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
9819 	      RETURN FND_API.G_FALSE;
9820 	    END IF;
9821 			END IF;
9822 	END LOOP;
9823 
9824 	-- Get all the Workorders for the UE
9825  FOR wo_csr IN get_ue_workorders(l_mr_rec.wip_entity_id) LOOP
9826    l_return_status := is_complete_enabled(p_workorder_id => wo_csr.workorder_id,
9827 			                                       p_operation_seq_num => NULL,
9828 																																										p_ue_id => p_ue_id,
9829 																																										p_check_unit => FND_API.G_FALSE
9830 																																										);
9831 		 IF l_return_status = FND_API.G_FALSE THEN
9832 			  RETURN FND_API.G_FALSE;
9833 			END IF;
9834 	END LOOP;
9835 
9836 	FOR op_csr IN get_ue_operations(l_mr_rec.wip_entity_id) LOOP
9837    l_return_status := is_complete_enabled(p_workorder_id => op_csr.workorder_id,
9838 			                                       p_operation_seq_num => op_csr.operation_seq_num,
9839 																																										p_ue_id => p_ue_id,
9840 																																										p_check_unit => FND_API.G_FALSE
9841 																																										);
9842 		 IF l_return_status = FND_API.G_FALSE THEN
9843 			  RETURN FND_API.G_FALSE;
9844 			END IF;
9845 	END LOOP;*/
9846 
9847 	END IF;
9848 
9849 	-- When control reaches here, none of the conditions are violated. Hence return true.
9850 	RETURN FND_API.G_TRUE;
9851 
9852 END Is_Complete_Enabled;
9853 
9854 
9855 /*##################################################################################################*/
9856 --# NAME
9857 --#     PROCEDURE: Get_Default_Op_Actual_Dates
9858 --# PARAMETERS
9859 --# Standard IN Parameters
9860 --#  None
9861 --#
9862 --# Standard OUT Parameters
9863 --#  x_return_status    OUT NOCOPY VARCHAR2
9864 --#  x_msg_count        OUT NOCOPY NUMBER
9865 --#  x_msg_data         OUT NOCOPY VARCHAR2
9866 --#
9867 --# Get_Default_Op_Actual_Dates Parameters
9868 --#  P_x_operation_tbl   IN AHL_COMPLETIONS_PVT.operation_tbl_type - Table holding the operation records
9869 --#
9870 --# DESCRIPTION
9871 --#  This function will be used to default the actual dates before completing operations using the
9872 --#  My Workorders or Update Workorders Uis. Calling APIs need to populate only the workorder_id and
9873 --#  operation_sequence_num Get_Default_Wo_Actual_Datesfields of the operations records.
9874 --#
9875 --# HISTORY
9876 --#   16-Jun-2005   rroy  Created
9877 --###################################################################################################*/
9878 
9879 PROCEDURE Get_Default_Op_Actual_Dates
9880 (
9881   x_return_status    OUT NOCOPY VARCHAR2,
9882   x_msg_count        OUT NOCOPY NUMBER,
9883   x_msg_data         OUT NOCOPY VARCHAR2,
9884   P_x_operation_tbl  IN OUT NOCOPY AHL_COMPLETIONS_PVT.operation_tbl_type
9885 )
9886 IS
9887 L_workorder_operation_id NUMBER;
9888 L_ovn NUMBER;
9889 L_wip_entity_id NUMBER;
9890 L_scheduled_start_date DATE;
9891 L_scheduled_end_date DATE;
9892 L_min_txn_date DATE;
9893 L_max_txn_date DATE;
9894 L_min_pending_txn_date DATE;
9895 L_max_pending_txn_date DATE;
9896 l_start_date DATE;
9897 l_end_date DATE;
9898 
9899 -- cursor to retrieve the relevant operation details from AHL_WORKORDER_OPERATIONS table
9900 CURSOR c_get_op_details(x_workorder_id NUMBER,
9901                         x_operation_seq_num NUMBER)
9902 IS
9903 SELECT WORKORDER_OPERATION_ID,
9904        OBJECT_VERSION_NUMBER,
9905        SCHEDULED_START_DATE,
9906        SCHEDULED_END_DATE,
9907        ACTUAL_START_DATE,
9908        ACTUAL_END_DATE
9909 FROM AHL_WORKORDER_OPERATIONS_V
9910 WHERE WORKORDER_ID = x_workorder_id
9911 AND OPERATION_SEQUENCE_NUM = x_operation_seq_num;
9912 
9913 -- cursor to retrieve the wip_entity_id
9914 CURSOR c_get_wo_details(x_workorder_id NUMBER)
9915 IS
9916 SELECT WIP_ENTITY_ID
9917 FROM AHL_WORKORDERS
9918 WHERE WORKORDER_ID = x_workorder_id;
9919 
9920 -- cursor to retrieve minimum and maximum resource transactions dates for this
9921 -- operation for resource transactions of type 'Person'
9922 CURSOR c_get_txn_dates(x_wip_entity_id NUMBER,
9923 			                    x_operation_seq_num NUMBER)
9924 IS
9925 SELECT MIN(WIPT.TRANSACTION_DATE),
9926 MAX(WIPT.TRANSACTION_DATE + (WIPT.TRANSACTION_QUANTITY/24))
9927 -- Using the transaction quantity above since we know the
9928 -- transaction uom is in hours
9929 FROM WIP_TRANSACTIONS WIPT,
9930 BOM_RESOURCES BOMR
9931 WHERE WIPT.RESOURCE_ID = BOMR.RESOURCE_ID
9932 AND WIPT.WIP_ENTITY_ID = x_wip_entity_id
9933 AND WIPT.OPERATION_SEQ_NUM = x_operation_seq_num
9934 AND BOMR.RESOURCE_TYPE = 2; -- Person
9935 
9936 -- cursor to retrieve the maximum and minimum transaction dates from
9937 -- pending resource transactions for this operation which are of
9938 -- type 'Person' and are in status 'Pending'.
9939 CURSOR c_get_pending_txn_dates(x_wip_entity_id NUMBER,
9940 			                            x_operation_seq_num NUMBER)
9941 IS
9942 SELECT MIN(WIPT.TRANSACTION_DATE),
9943        MAX(WIPT.TRANSACTION_DATE + (WIPT.TRANSACTION_QUANTITY/24))
9944 FROM WIP_COST_TXN_INTERFACE WIPT
9945 WHERE WIPT.WIP_ENTITY_ID = x_wip_entity_id
9946 AND WIPT.OPERATION_SEQ_NUM = x_operation_seq_num
9947 AND WIPT.RESOURCE_TYPE = 2 -- Person
9948 AND WIPT.PROCESS_STATUS = 1; -- Pending
9949 
9950 BEGIN
9951   x_return_status := FND_API.G_RET_STS_SUCCESS;
9952 
9953   IF p_x_operation_tbl.COUNT > 0 THEN
9954     FOR i IN p_x_operation_tbl.FIRST..p_x_operation_tbl.LAST LOOP
9955       -- Get the operation and workorder details
9956       OPEN c_get_op_details(p_x_operation_tbl (i).workorder_id, p_x_operation_tbl (i).operation_sequence_num);
9957       FETCH c_get_op_details INTO l_workorder_operation_id, l_ovn, l_scheduled_start_date, l_scheduled_end_date, p_x_operation_tbl(i).actual_start_date, p_x_operation_tbl(i).actual_end_date;
9958       IF c_get_op_details%NOTFOUND THEN
9959 	CLOSE c_get_op_details;
9960        	FND_MESSAGE.set_name('AHL', 'AHL_PRD_WO_OP_NOT_FND');
9961 	FND_MSG_PUB.add;
9962 	x_return_status := FND_API.G_RET_STS_ERROR;
9963 	RETURN;
9964        	--RAISE FND_API.G_RET_STS_ERROR;
9965       END IF;
9966       CLOSE c_get_op_details;
9967 
9968       OPEN c_get_wo_details(p_x_operation_tbl (i).workorder_id);
9969       FETCH c_get_wo_details INTO l_wip_entity_id;
9970       IF c_get_wo_details%NOTFOUND THEN
9971         CLOSE c_get_wo_details;
9972         FND_MESSAGE.set_name('AHL', 'AHL_PRD_WO_NOT_FND');
9973         FND_MSG_PUB.add;
9974         X_return_status := FND_API.G_RET_STS_ERROR;
9975 	RETURN;
9976        	--RAISE FND_API.G_RET_STS_ERROR;
9977       END IF;
9978       CLOSE c_get_wo_details;
9979       -- Get the minimum and maximum transaction dates from the
9980       -- WIP_TRANSACTIONS and WIP_COST_TXN_INTERFACE tables for the
9981       -- resource transactions and pending resource transactions
9982       OPEN c_get_txn_dates(l_wip_entity_id, p_x_operation_tbl(i).operation_sequence_num);
9983       FETCH c_get_txn_dates INTO l_min_txn_date, l_max_txn_date;
9984       OPEN c_get_pending_txn_dates(l_wip_entity_id, p_x_operation_tbl(i).operation_sequence_num);
9985       FETCH c_get_txn_dates INTO l_min_pending_txn_date, l_max_pending_txn_date;
9986       -- Balaji added this logic for bug # 5333796 - start
9987       IF  l_min_txn_date IS NULL AND l_max_txn_date IS NULL AND l_min_pending_txn_date IS NULL AND l_max_pending_txn_date IS NULL THEN
9988 
9989         IF p_x_operation_tbl (i).actual_end_date IS NULL THEN
9990           p_x_operation_tbl (i).actual_end_date := LEAST(l_scheduled_end_date,SYSDATE);
9991         END IF;
9992 
9993         IF p_x_operation_tbl (i).actual_start_date IS NULL THEN
9994           IF l_scheduled_start_date < SYSDATE THEN
9995           	p_x_operation_tbl (i).actual_start_date:= l_scheduled_start_date;
9996           ELSE
9997           	p_x_operation_tbl (i).actual_start_date:= p_x_operation_tbl (i).actual_end_date - (l_scheduled_end_date - l_scheduled_start_date);
9998           END IF;
9999         END IF;
10000 
10001       ELSE
10002 
10003         l_end_date:= GREATEST(NVL(l_max_txn_date, l_max_pending_txn_date), NVL(l_max_pending_txn_date, l_max_txn_date));
10004 	l_start_date := LEAST(NVL(l_min_txn_date, l_min_pending_txn_date), NVL(l_min_pending_txn_date, l_min_txn_date));
10005 
10006         IF p_x_operation_tbl (i).actual_end_date IS NULL THEN
10007           p_x_operation_tbl (i).actual_end_date := LEAST(l_end_date, SYSDATE);
10008         END IF;
10009 
10010         -- At least one of completed or pending resource transaction dates have been found
10011         IF p_x_operation_tbl (i).actual_start_date IS NULL THEN
10012           IF l_start_date < SYSDATE THEN
10013           	p_x_operation_tbl (i).actual_start_date := l_start_date;
10014           ELSE
10015           	p_x_operation_tbl (i).actual_start_date := p_x_operation_tbl (i).actual_end_date - (l_end_date - l_start_date);
10016           END IF;
10017         END IF;
10018 
10019       END IF;-- IF c_get_txn_dates%NOTFOUND AND c_get_pending_txn_dates%NOTFOUND THEN
10020       -- Balaji added this logic for bug # 5333796 - end
10021       CLOSE c_get_pending_txn_dates;
10022       CLOSE c_get_txn_dates;
10023 
10024     END LOOP;
10025   END IF; --IF p_x_operation_tbl.COUNT > 0 THEN
10026 
10027 END Get_Default_Op_Actual_Dates;
10028 
10029 /*##################################################################################################*/
10030 --# NAME
10031 --#     PROCEDURE: Get_Op_Actual_Dates
10032 --# PARAMETERS
10033 --# Standard IN Parameters
10034 --#  None
10035 --#
10036 --# Standard OUT Parameters
10037 --#  x_return_status    OUT NOCOPY VARCHAR2
10038 --#
10039 --# Get_Op_Actual_Dates Parameters
10040 --#  P_x_operation_tbl   IN AHL_COMPLETIONS_PVT.operation_tbl_type - Table holding the operation records
10041 --#
10042 --# DESCRIPTION
10043 --#  This function will be used to retrieve the current actual dates of operations. This is API
10044 --#  is needed for the defaulting logic of actual dates on the Operations subtab of the
10045 --#  Update Workorders page. Calling APIs need to populate only the workorder_id and
10046 --#  operation_sequence_num fields of the operations records.
10047 --#
10048 --# HISTORY
10049 --#   16-Jun-2005   rroy  Created
10050 --###################################################################################################*/
10051 
10052 PROCEDURE Get_Op_Actual_Dates
10053 (
10054   x_return_status    OUT NOCOPY VARCHAR2,
10055   p_x_operation_tbl  IN OUT NOCOPY AHL_COMPLETIONS_PVT.operation_tbl_type
10056 )
10057 IS
10058 
10059 -- cursor to retrieve the relevant operation details from AHL_WORKORDER_OPERATIONS table
10060 CURSOR c_get_op_details(x_workorder_id NUMBER,
10061                         x_operation_seq_num NUMBER)
10062 IS
10063 SELECT ACTUAL_START_DATE,
10064 ACTUAL_END_DATE,
10065 WORKORDER_OPERATION_ID
10066 FROM AHL_WORKORDER_OPERATIONS
10067 WHERE WORKORDER_ID = x_workorder_id
10068 AND OPERATION_SEQUENCE_NUM = x_operation_seq_num;
10069 
10070 BEGIN
10071   x_return_status := FND_API.G_RET_STS_SUCCESS;
10072   IF p_x_operation_tbl.COUNT > 0 THEN
10073     FOR i IN p_x_operation_tbl.FIRST..p_x_operation_tbl.LAST LOOP
10074       OPEN c_get_op_details(p_x_operation_tbl (i).workorder_id, p_x_operation_tbl (i).operation_sequence_num);
10075       FETCH c_get_op_details INTO p_x_operation_tbl(i).actual_start_date, p_x_operation_tbl(i).actual_end_date, p_x_operation_tbl(i).WORKORDER_OPERATION_ID;
10076       IF c_get_op_details%NOTFOUND THEN
10077         CLOSE c_get_op_details;
10078        	FND_MESSAGE.set_name('AHL', 'AHL_PRD_WO_OP_NOT_FND');
10079        	FND_MSG_PUB.add;
10080        	x_return_status := FND_API.G_RET_STS_ERROR;
10081         RETURN;
10082        	--RAISE FND_API.G_RET_STS_ERROR;
10083       END IF; --IF c_get_op_details%NOTFOUND THEN
10084       CLOSE c_get_op_details;
10085     END LOOP;
10086   END IF; -- IF p_x_operation_tbl.COUNT > 0 THEN
10087 
10088 END Get_Op_Actual_Dates;
10089 
10090 /*##################################################################################################*/
10091 --# NAME
10092 --#     PROCEDURE: Get_Default_Wo_Actual_Dates
10093 --#
10094 --# PARAMETERS
10095 --# Standard IN Parameters
10096 --#  None
10097 --#
10098 --# Standard OUT Parameters
10099 --#  x_return_status    OUT NOCOPY VARCHAR2
10100 --#
10101 --# Get_Default_Wo_Actual_Dates Parameters
10102 --#  p_workorder_id      IN         NUMBER - The workorder id for which the actual dates are retrieved
10103 --#  x_actual_start_date OUT NOCOPY DATE   - Actual workorder start date
10104 --#  x_actual_end_date   OUT NOCOPY DATE   - Actual workorder end date
10105 --#
10106 --# DESCRIPTION
10107 --# 	This function will be used to default the actual dates before completing workorders using
10108 --#  the My Workorders or Update Workorders Uis. Calling APIs need to ensure that they call
10109 --#  this API after updating the operation actual dates.
10110 --#
10111 --# HISTORY
10112 --#   16-Jun-2005   rroy  Created
10113 --###################################################################################################*/
10114 
10115 PROCEDURE Get_Default_Wo_Actual_Dates
10116 (
10117   x_return_status     OUT NOCOPY VARCHAR2,
10118   p_workorder_id      IN         NUMBER,
10119   x_actual_start_date OUT NOCOPY DATE,
10120   x_actual_end_date   OUT NOCOPY DATE
10121 )
10122 IS
10123 
10124 -- cursor to retrieve minimum actual start date and maximum actual
10125 -- end date from all the operations within this workorder
10126 CURSOR c_get_wo_actual_dates(x_workorder_id NUMBER)
10127 IS
10128 SELECT MIN(ACTUAL_START_DATE),
10129 MAX(ACTUAL_END_DATE)
10130 FROM AHL_WORKORDER_OPERATIONS
10131 WHERE WORKORDER_ID = x_workorder_id;
10132 
10133 CURSOR c_get_mwo_flag(x_workorder_id NUMBER)
10134 IS
10135 SELECT MASTER_WORKORDER_FLAG
10136 FROM AHL_WORKORDERS
10137 WHERE WORKORDER_ID = x_workorder_id;
10138 
10139 BEGIN
10140 
10141   OPEN c_get_wo_actual_dates(p_workorder_id);
10142   FETCH c_get_wo_actual_dates INTO x_actual_start_date, x_actual_end_date;
10143   CLOSE c_get_wo_actual_dates;
10144 
10145 END Get_Default_Wo_Actual_Dates;
10146 
10147 FUNCTION get_ue_mr_status_code(p_unit_effectivity_id IN NUMBER) RETURN VARCHAR2
10148 IS
10149 
10150   CURSOR get_mr_status_ue(c_unit_effectivity_id NUMBER) IS
10151   SELECT ( CASE
10152    WHEN UE.STATUS_CODE IN ('ACCOMPLISHED', 'DEFERRED', 'TERMINATED','CANCELLED')
10153                  THEN UE.STATUS_CODE
10154    WHEN UE.orig_deferral_ue_id IS NOT NULL
10155                  THEN ORIG_DEF.approval_status_code
10156    WHEN DEF.APPROVAL_STATUS_CODE IS NOT NULL
10157                  THEN DEF.APPROVAL_STATUS_CODE
10158    ELSE UE.STATUS_CODE
10159    END)UMP_STATUS_CODE
10160    FROM AHL_UNIT_DEFERRALS_B ORIG_DEF,AHL_UNIT_DEFERRALS_B
10161 DEF,AHL_UNIT_EFFECTIVITIES_APP_V UE
10162    WHERE UE.orig_deferral_ue_id = orig_def.unit_effectivity_id(+)
10163    AND orig_def.unit_deferral_type(+) = 'DEFERRAL'
10164    AND UE.unit_effectivity_id = def.unit_effectivity_id(+)
10165    AND def.unit_deferral_type(+) = 'DEFERRAL'
10166    AND UE.unit_effectivity_id = c_unit_effectivity_id;
10167 
10168    l_mr_status_code VARCHAR2(30);
10169 
10170 BEGIN
10171    l_mr_status_code := NULL;
10172    OPEN get_mr_status_ue(p_unit_effectivity_id);
10173    FETCH get_mr_status_ue INTO l_mr_status_code;
10174    CLOSE get_mr_status_ue;
10175    RETURN l_mr_status_code;
10176 END get_ue_mr_status_code;
10177 
10178 -- Wrapper function to complete the visit master workorder
10179 -- If the visit id is passed, then the visit master workorder id queried and completed
10180 -- If the UE Id is passed, then the UE Master workorder is queried and completed
10181 -- If the workorder id is passed, then the workorder is completed.
10182 -- Bug 4626717 - Issue 6
10183 FUNCTION complete_master_wo
10184 (
10185  p_visit_id              IN            NUMBER,
10186  p_workorder_id          IN            NUMBER,
10187  p_ue_id                 IN            NUMBER
10188 ) RETURN VARCHAR2
10189 IS
10190   l_return_status         VARCHAR2(1);
10191   l_msg_count             NUMBER;
10192   l_msg_data              VARCHAR2(2000);
10193 
10194   l_workorder_tbl         AHL_PRD_WORKORDER_PVT.PRD_WORKORDER_TBL;
10195   l_workorder_rel_tbl     AHL_PRD_WORKORDER_PVT.PRD_WORKORDER_REL_TBL;
10196   l_wo_count              NUMBER;
10197 
10198   -- cursor to retrieve the visit master workorder
10199   CURSOR  get_visit_master_wo(c_visit_id NUMBER )
10200   IS
10201   SELECT  workorder_id, object_version_number, wip_entity_id
10202   FROM AHL_WORKORDERS
10203   WHERE visit_id = c_visit_id
10204   AND master_workorder_flag = 'Y'
10205   --AND status_code NOT IN ('7', '22', '4', '12', '5')
10206   AND VISIT_TASK_ID IS NULL;
10207 
10208   CURSOR get_ue_master_wo(c_ue_id NUMBER)
10209   IS
10210   SELECT WO.workorder_id,
10211          WO.object_version_number, VTS.task_type_code,
10212          WO.wip_entity_id
10213   FROM AHL_WORKORDERS WO,
10214        AHL_VISIT_TASKS_B VTS
10215   WHERE WO.visit_task_id = VTS.visit_task_id
10216         AND VTS.unit_effectivity_id = c_ue_id
10217         --AND WO.status_code NOT IN ('7', '22', '4', '12', '5')
10218         AND VTS.task_type_code IN ('SUMMARY', 'UNASSOCIATED');
10219 
10220   CURSOR get_wo_ovn(c_workorder_id NUMBER)
10221   IS
10222   SELECT object_version_number, wip_entity_id
10223   FROM AHL_WORKORDERS
10224   WHERE workorder_id = c_workorder_id;
10225   --AND status_code NOT IN ('7', '22', '4', '12', '5');
10226 
10227   -- Fix for FP bug# 5138909 (issue#2).
10228   -- If all workorders in a visit are cancelled then the Visit Master Workorder
10229   -- needs to be cancelled instead of being completed.
10230 
10231   -- cursor to check if all workorders in a visit are cancelled.
10232   CURSOR  chk_cmplt_wo_exists(c_wip_entity_id NUMBER )
10233   IS
10234     SELECT 'x'
10235     FROM AHL_WORKORDERS AWO, WIP_DISCRETE_JOBS WDJ
10236     WHERE awo.wip_entity_id = wdj.wip_entity_id
10237        AND wdj.date_completed IS NOT NULL
10238        --AND master_workorder_flag = 'N'
10239        --AND status_code NOT IN ('7', '22', '12')
10240        AND VISIT_TASK_ID IS NOT NULL
10241        AND awo.wip_entity_id IN (SELECT rel.child_object_id
10242                                 FROM wip_sched_relationships rel
10243                                 START WITH REL.parent_object_id = c_wip_entity_id
10244                                 CONNECT BY REL.parent_object_id = PRIOR REL.child_object_id
10245                                 AND REL.parent_object_type_id = PRIOR REL.child_object_type_id
10246                                 AND REL.relationship_type = 1);
10247 
10248   l_workorder_id NUMBER;
10249   l_ovn          NUMBER;
10250   l_api_name     VARCHAR2(30) := 'Complete_Master_Wo';
10251   l_task_type_code VARCHAR2(30);
10252 
10253   -- added for FP bug# 5138909.
10254   l_wip_entity_id  NUMBER;
10255   l_junk           VARCHAR2(1);
10256 
10257 BEGIN
10258 
10259   IF ( G_DEBUG = 'Y' ) THEN
10260      AHL_DEBUG_PUB.debug( 'Start complete_master_wo: Input Params:');
10261      AHL_DEBUG_PUB.debug( 'In complete_master_wo: p_visit_id:' || p_visit_id);
10262      AHL_DEBUG_PUB.debug( 'In complete_master_wo: p_ue_id:' || p_ue_id);
10263      AHL_DEBUG_PUB.debug( 'In complete_master_wo: p_workorder_id:' || p_workorder_id);
10264   END IF;
10265 
10266   IF(p_visit_id IS NOT NULL) THEN
10267        OPEN get_visit_master_wo(p_visit_id);
10268        FETCH get_visit_master_wo INTO l_workorder_id, l_ovn, l_wip_entity_id;
10269        CLOSE get_visit_master_wo;
10270   ELSIF(p_ue_id IS NOT NULL) THEN
10271        OPEN get_ue_master_wo(p_ue_id);
10272        FETCH get_ue_master_wo INTO l_workorder_id, l_ovn, l_task_type_code, l_wip_entity_id;
10273        CLOSE get_ue_master_wo;
10274        IF l_task_type_code = 'UNASSOCIATED' THEN
10275             RETURN FND_API.G_RET_STS_SUCCESS;
10276        END IF;
10277   ELSIF(p_workorder_id IS NOT NULL) THEN
10278        OPEN get_wo_ovn(p_workorder_id);
10279        FETCH get_wo_ovn INTO l_ovn, l_wip_entity_id;
10280        CLOSE get_wo_ovn;
10281        l_workorder_id := p_workorder_id;
10282   ELSE
10283        -- All three input params are null
10284        -- throw an error
10285        FND_MESSAGE.set_name('AHL','AHL_PRD_WRONG_ARGUMENTS');
10286        FND_MESSAGE.set_token('PROC_NAME', l_api_name);
10287         FND_MSG_PUB.add;
10288         RETURN FND_API.G_RET_STS_ERROR;
10289   END IF;
10290 
10291   IF ( G_DEBUG = 'Y' ) THEN
10292      AHL_DEBUG_PUB.debug( 'In complete_master_wo: workorder_id:ovn:wip_entity_id:' || l_workorder_id
10293                            || ':' || l_ovn || ':' || l_wip_entity_id);
10294   END IF;
10295 
10296   -- Check if all workorders are cancelled.
10297   OPEN chk_cmplt_wo_exists(l_wip_entity_id);
10298   FETCH chk_cmplt_wo_exists INTO l_junk;
10299   IF (chk_cmplt_wo_exists%NOTFOUND) THEN
10300       IF ( G_DEBUG = 'Y' ) THEN
10301          AHL_DEBUG_PUB.debug('In complete_master_wo: processing for cancelled mwo');
10302       END IF;
10303 
10304       CLOSE chk_cmplt_wo_exists;
10305       -- all jobs cancelled.
10306       -- cancel master workorder.
10307       IF (p_visit_id IS NOT NULL) THEN
10308           AHL_PRD_WORKORDER_PVT.cancel_visit_jobs
10309            (
10310              p_api_version         => 1.0,
10311              p_init_msg_list       => FND_API.G_TRUE,
10312              p_commit              => FND_API.G_FALSE,
10313              p_validation_level    => FND_API.G_VALID_LEVEL_FULL,
10314              p_default             => FND_API.G_FALSE,
10315              p_module_type         => 'API',
10316              x_return_status       => l_return_status,
10317              x_msg_count           => l_msg_count,
10318              x_msg_data            => l_msg_data,
10319              p_visit_id            => p_visit_id,
10320              p_unit_effectivity_id => NULL,
10321              p_workorder_id        => NULL
10322            );
10323       ELSIF (p_ue_id IS NOT NULL) THEN
10324           AHL_PRD_WORKORDER_PVT.cancel_visit_jobs
10325            (
10326              p_api_version         => 1.0,
10327              p_init_msg_list       => FND_API.G_TRUE,
10328              p_commit              => FND_API.G_FALSE,
10329              p_validation_level    => FND_API.G_VALID_LEVEL_FULL,
10330              p_default             => FND_API.G_FALSE,
10331              p_module_type         => 'API',
10332              x_return_status       => l_return_status,
10333              x_msg_count           => l_msg_count,
10334              x_msg_data            => l_msg_data,
10335              p_visit_id            => NULL,
10336              p_unit_effectivity_id => p_ue_id,
10337              p_workorder_id        => NULL
10338            );
10339       ELSIF (p_workorder_id IS NOT NULL) THEN
10340           AHL_PRD_WORKORDER_PVT.cancel_visit_jobs
10341            (
10342              p_api_version         => 1.0,
10343              p_init_msg_list       => FND_API.G_TRUE,
10344              p_commit              => FND_API.G_FALSE,
10345              p_validation_level    => FND_API.G_VALID_LEVEL_FULL,
10346              p_default             => FND_API.G_FALSE,
10347              p_module_type         => 'API',
10348              x_return_status       => l_return_status,
10349              x_msg_count           => l_msg_count,
10350              x_msg_data            => l_msg_data,
10351              p_visit_id            => NULL,
10352              p_unit_effectivity_id => NULL,
10353              p_workorder_id        => p_workorder_id
10354            );
10355       END IF;  -- p_visit_id IS NOT NULL
10356 
10357   ELSE -- chk_cmplt_wo_exists
10358      CLOSE chk_cmplt_wo_exists;
10359 
10360      IF l_workorder_id IS NOT NULL AND l_ovn IS NOT NULL THEN
10361            AHL_COMPLETIONS_PVT.complete_workorder
10362            (
10363                     p_api_version            => 1.0,
10364                     p_init_msg_list          => FND_API.G_TRUE,
10365                     p_commit                 => FND_API.G_FALSE,
10366                     p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
10367                     p_default                => FND_API.G_FALSE,
10368                     p_module_type            => NULL,
10369                     x_return_status          => l_return_status,
10370                     x_msg_count              => l_msg_count,
10371                     x_msg_data               => l_msg_data,
10372                     p_workorder_id           => l_workorder_id,
10373                     p_object_version_no      => l_ovn
10374            );
10375 
10376          --RETURN l_return_status;
10377      ELSE
10378         FND_MESSAGE.SET_NAME('AHL', 'AHL_PP_WORKORDER_NOT_EXISTS');
10379         FND_MSG_PUB.ADD;
10380         --RETURN FND_API.G_RET_STS_ERROR;
10381         l_return_status := FND_API.G_RET_STS_ERROR;
10382 
10383      END IF; -- l_workorder_id IS NOT NULL ..
10384   END IF;  -- chk_cmplt_wo_exists%NOTFOUND
10385 
10386   IF ( G_DEBUG = 'Y' ) THEN
10387     AHL_DEBUG_PUB.debug('End complete_master_wo: l_return_status:' || l_return_status);
10388   END IF;
10389 
10390   RETURN l_return_status;
10391 
10392 END complete_master_wo;
10393 
10394 ------------------------------------------------------------------------------------------------
10395 -- API added for the concurrent program "Close Work Orders".
10396 -- This API is to be used with Concurrent program.
10397 -- Bug # 6991393 (FP for Bug # 6500568)
10398 ------------------------------------------------------------------------------------------------
10399 PROCEDURE Close_WorkOrders (
10400     errbuf                  OUT NOCOPY  VARCHAR2,
10401     retcode                 OUT NOCOPY  NUMBER,
10402     p_api_version           IN          NUMBER
10403 )
10404 IS
10405 
10406 l_api_name          VARCHAR2(30) := 'Close_WorkOrders';
10407 l_api_version       NUMBER := 1.0;
10408 
10409 CURSOR c_get_eligible_wos
10410 IS
10411 SELECT
10412    AWO.workorder_id,
10413    AWO.workorder_name,
10414    AWO.visit_task_id,
10415    AWO.master_workorder_flag,
10416    AWO.object_version_number,
10417    'Y'  valid_for_close,
10418    WIPJ.scheduled_start_date,
10419    WIPJ.scheduled_completion_date,
10420    AWO.actual_start_date,
10421    AWO.actual_end_date,
10422    WIPJ.completion_subinventory,
10423    WIPJ.completion_locator_id,
10424    AWO.security_group_id,
10425    AWO.attribute_category,
10426    AWO.attribute1,
10427    AWO.attribute2,
10428    AWO.attribute3,
10429    AWO.attribute4,
10430    AWO.attribute5,
10431    AWO.attribute6,
10432    AWO.attribute7,
10433    AWO.attribute8,
10434    AWO.attribute9,
10435    AWO.attribute10,
10436    AWO.attribute11,
10437    AWO.attribute12,
10438    AWO.attribute13,
10439    AWO.attribute14,
10440    AWO.attribute15
10441 FROM
10442    AHL_WORKORDERS AWO,
10443    WIP_DISCRETE_JOBS WIPJ,
10444    WIP_ENTITIES WIPE
10445 WHERE
10446 	AWO.status_code in (4,5,7)
10447    AND  AWO.wip_entity_id = WIPJ.wip_entity_id
10448    AND  WIPE.entity_type = 7
10449    AND  WIPE.wip_entity_id = WIPJ.wip_entity_id
10450    AND  WIPJ.status_type = 12;
10451 
10452 
10453 CURSOR chk_inst_in_job (p_workorder_id IN NUMBER) IS
10454 SELECT
10455   'x'
10456 FROM
10457   CSI_ITEM_INSTANCES CII,
10458   AHL_WORKORDERS AWO
10459 WHERE
10460   CII.WIP_JOB_ID = AWO.WIP_ENTITY_ID
10461   AND AWO.workorder_id = p_workorder_id
10462   AND ACTIVE_START_DATE <= SYSDATE
10463   AND ((ACTIVE_END_DATE IS NULL) OR (ACTIVE_END_DATE >= SYSDATE))
10464   AND LOCATION_TYPE_CODE = 'WIP'
10465   AND NOT EXISTS (SELECT 'X' FROM CSI_II_RELATIONSHIPS CIR
10466 		 WHERE CIR.SUBJECT_ID = CII.INSTANCE_ID
10467 		   AND CIR.RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
10468 		   AND SYSDATE BETWEEN NVL(ACTIVE_START_DATE,SYSDATE) AND NVL(ACTIVE_END_DATE,SYSDATE));
10469 
10470 -- actual work order related table definitions
10471 TYPE workorder_id_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
10472 TYPE workorder_name_tbl_type IS TABLE OF VARCHAR2(80) INDEX BY BINARY_INTEGER;
10473 TYPE visit_task_id_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
10474 TYPE master_workorder_flag_tbl_type IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
10475 TYPE object_version_number_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
10476 TYPE valid_for_close_type IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
10477 
10478 l_workorder_id_tbl workorder_id_tbl_type;
10479 l_workorder_name_tbl workorder_name_tbl_type;
10480 l_visit_task_id_tbl visit_task_id_tbl_type;
10481 l_master_workorder_flag_tbl master_workorder_flag_tbl_type;
10482 l_object_version_number_tbl object_version_number_tbl_type;
10483 l_valid_for_close_tbl valid_for_close_type;
10484 -- actual work order related table definitions
10485 
10486 -- Txn related table definitions
10487 TYPE l_wo_sch_str_tbl_type IS TABLE OF DATE INDEX BY BINARY_INTEGER;
10488 TYPE l_wo_sch_end_tbl_type IS TABLE OF DATE INDEX BY BINARY_INTEGER;
10489 TYPE l_wo_act_str_tbl_type IS TABLE OF DATE INDEX BY BINARY_INTEGER;
10490 TYPE l_wo_act_end_tbl_type IS TABLE OF DATE INDEX BY BINARY_INTEGER;
10491 TYPE l_wo_comp_subinv_tbl_type IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
10492 TYPE l_wo_comp_loc_id_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
10493 TYPE l_wo_sc_grp_id_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
10494 TYPE l_wo_att_category_tbl_type IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;
10495 TYPE l_wo_att_1_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10496 TYPE l_wo_att_2_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10497 TYPE l_wo_att_3_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10498 TYPE l_wo_att_4_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10499 TYPE l_wo_att_5_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10500 TYPE l_wo_att_6_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10501 TYPE l_wo_att_7_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10502 TYPE l_wo_att_8_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10503 TYPE l_wo_att_9_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10504 TYPE l_wo_att_10_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10505 TYPE l_wo_att_11_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10506 TYPE l_wo_att_12_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10507 TYPE l_wo_att_13_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10508 TYPE l_wo_att_14_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10509 TYPE l_wo_att_15_tbl_type IS TABLE OF VARCHAR2(150) INDEX BY BINARY_INTEGER;
10510 
10511 l_wo_sch_str_tbl l_wo_sch_str_tbl_type;
10512 l_wo_sch_end_tbl l_wo_sch_end_tbl_type;
10513 l_wo_act_str_tbl l_wo_act_str_tbl_type;
10514 l_wo_act_end_tbl l_wo_act_end_tbl_type;
10515 l_wo_comp_subinv_tbl l_wo_comp_subinv_tbl_type;
10516 l_wo_comp_loc_id_tbl l_wo_comp_loc_id_tbl_type;
10517 l_wo_sc_grp_id_tbl l_wo_sc_grp_id_tbl_type;
10518 l_wo_att_category_tbl l_wo_att_category_tbl_type;
10519 l_wo_att_1_tbl l_wo_att_1_tbl_type;
10520 l_wo_att_2_tbl l_wo_att_2_tbl_type;
10521 l_wo_att_3_tbl l_wo_att_3_tbl_type;
10522 l_wo_att_4_tbl l_wo_att_4_tbl_type;
10523 l_wo_att_5_tbl l_wo_att_5_tbl_type;
10524 l_wo_att_6_tbl l_wo_att_6_tbl_type;
10525 l_wo_att_7_tbl l_wo_att_7_tbl_type;
10526 l_wo_att_8_tbl l_wo_att_8_tbl_type;
10527 l_wo_att_9_tbl l_wo_att_9_tbl_type;
10528 l_wo_att_10_tbl l_wo_att_10_tbl_type;
10529 l_wo_att_11_tbl l_wo_att_11_tbl_type;
10530 l_wo_att_12_tbl l_wo_att_12_tbl_type;
10531 l_wo_att_13_tbl l_wo_att_13_tbl_type;
10532 l_wo_att_14_tbl l_wo_att_14_tbl_type;
10533 l_wo_att_15_tbl l_wo_att_15_tbl_type;
10534 -- Txn related table definitions
10535 
10536 
10537 l_junk                  VARCHAR2(1);
10538 l_return_status         VARCHAR2(1);
10539 l_msg_count             NUMBER;
10540 l_msg_data              VARCHAR2(2000);
10541 l_err_msg               VARCHAR2(2000);
10542 l_buffer_limit          NUMBER   := 1000;
10543 l_index                 NUMBER;
10544 
10545 BEGIN
10546 
10547     -- Initialize error message stack by default
10548     FND_MSG_PUB.Initialize;
10549 
10550     -- Standard call to check for call compatibility
10551     IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name, G_PKG_NAME)
10552     THEN
10553         retcode := 2;
10554         errbuf := FND_MSG_PUB.Get;
10555 
10556         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
10557     END IF;
10558 
10559     -- perform validations -- start
10560 
10561     fnd_file.put_line(fnd_file.log, 'At the begining of the process...');
10562 
10563     OPEN c_get_eligible_wos;
10564 
10565     --FOR l_eligible_wos IN c_get_eligible_wos
10566     LOOP
10567 
10568        SAVEPOINT close_workorders_pvt;
10569 
10570        FETCH c_get_eligible_wos BULK COLLECT INTO l_workorder_id_tbl,
10571                                                   l_workorder_name_tbl,
10572                                                   l_visit_task_id_tbl,
10573                                                   l_master_workorder_flag_tbl,
10574                                                   l_object_version_number_tbl,
10575                                                   l_valid_for_close_tbl,
10576                                                   l_wo_sch_str_tbl,
10577 						  l_wo_sch_end_tbl,
10578 						  l_wo_act_str_tbl,
10579 						  l_wo_act_end_tbl,
10580 						  l_wo_comp_subinv_tbl,
10581 						  l_wo_comp_loc_id_tbl,
10582 						  l_wo_sc_grp_id_tbl,
10583 						  l_wo_att_category_tbl,
10584 						  l_wo_att_1_tbl,
10585 						  l_wo_att_2_tbl,
10586 						  l_wo_att_3_tbl,
10587 						  l_wo_att_4_tbl,
10588 						  l_wo_att_5_tbl,
10589 						  l_wo_att_6_tbl,
10590 						  l_wo_att_7_tbl,
10591 						  l_wo_att_8_tbl,
10592 						  l_wo_att_9_tbl,
10593 						  l_wo_att_10_tbl,
10594 						  l_wo_att_11_tbl,
10595 						  l_wo_att_12_tbl,
10596 						  l_wo_att_13_tbl,
10597 						  l_wo_att_14_tbl,
10598 						  l_wo_att_15_tbl
10599        LIMIT l_buffer_limit;
10600 
10601        IF l_workorder_id_tbl.COUNT <= 0
10602        THEN
10603 
10604           CLOSE c_get_eligible_wos;
10605           EXIT;
10606 
10607        END IF;
10608 
10609        fnd_file.put_line(fnd_file.log, 'Total Work Orders selected for processing -> '||l_workorder_id_tbl.COUNT);
10610 
10611        FOR l_index IN l_workorder_id_tbl.FIRST .. l_workorder_id_tbl.LAST
10612        LOOP
10613 		-- 1. validate if the Work Order Unit is locked.
10614 		--    If the Unit is locked we cant close the workorder. Skip the Work Order. Log the message and continue
10615 		l_return_status := AHL_PRD_UTIL_PKG.Is_Unit_Locked(
10616 								    p_workorder_id     => l_workorder_id_tbl(l_index),
10617 								    p_ue_id            => NULL,
10618 								    p_visit_id         => NULL,
10619 								    p_item_instance_id => NULL
10620 								  );
10621 
10622 
10623 		IF l_return_status = FND_API.G_TRUE THEN
10624 
10625 				FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_LGN_UNTLCKD');
10626 				FND_MESSAGE.set_token('WO_NUM', l_workorder_name_tbl(l_index));
10627 				FND_MSG_PUB.ADD;
10628 
10629 				l_valid_for_close_tbl(l_index) := 'N';
10630 
10631 				-- log a warning
10632 				fnd_file.put_line(fnd_file.log, 'Work Order -> '||l_workorder_name_tbl(l_index)||' is not closed due to following error(s)');
10633 				fnd_file.put_line(fnd_file.log, FND_MSG_PUB.GET(p_encoded  => FND_API.G_FALSE));
10634 				FND_MSG_PUB.Delete_Msg;
10635 
10636 		END IF;
10637 
10638 
10639 
10640 		IF
10641 		  l_valid_for_close_tbl(l_index) IS NULL OR
10642 		  l_valid_for_close_tbl(l_index) <> 'N'
10643 		THEN
10644 			-- 2. Validate if the there are any work order materials.
10645 			--    If so log a message and continue. No need to skip the Work Order
10646 			OPEN chk_inst_in_job(l_workorder_id_tbl(l_index));
10647 			FETCH chk_inst_in_job INTO l_junk;
10648 			CLOSE chk_inst_in_job;
10649 
10650 			IF l_junk IS NOT NULL
10651 			THEN
10652 			        -- No need to skip the Work Order but just log a message.
10653 				fnd_file.put_line(fnd_file.log, 'Work Order -> '||l_workorder_name_tbl(l_index)||' is processed but with following warning(s)...');
10654 				fnd_file.put_line(fnd_file.log, 'Work Order '||l_workorder_name_tbl(l_index)||' has material');
10655 
10656 			END IF;
10657 
10658 			-- 3. Update the status of all materials of the Work Order to History before closing them.
10659 			-- Call LTP API to update material requirement status to History.
10660 			IF l_master_workorder_flag_tbl(l_index) = 'N'
10661 			THEN
10662 
10663 				AHL_LTP_REQST_MATRL_PVT.Update_Material_Reqrs_status(
10664 					   p_api_version      => 1.0,
10665 					   p_init_msg_list    => FND_API.G_TRUE,
10666 					   p_commit           => FND_API.G_FALSE,
10667 					   p_validation_level => FND_API.G_VALID_LEVEL_FULL,
10668 					   p_module_type      => NULL,
10669 					   p_visit_task_id    => l_visit_task_id_tbl(l_index),
10670 					   x_return_status    => l_return_status,
10671 					   x_msg_count        => l_msg_count,
10672 					   x_msg_data         => l_msg_data
10673 				 );
10674 
10675 				 IF l_return_status <> FND_API.G_RET_STS_SUCCESS
10676 				 THEN
10677 				    l_valid_for_close_tbl(l_index) := 'N';
10678 				    -- log a warning
10679 				    fnd_file.put_line(fnd_file.log, 'Work Order -> '||l_workorder_name_tbl(l_index)||' is not closed due to following error(s)');
10680 				    fnd_file.put_line(fnd_file.log, '---------------------------------------------------------------------------------');
10681 
10682 				    LOOP
10683 				       l_err_msg := FND_MSG_PUB.GET;
10684 				       IF l_err_msg IS NULL
10685 				       THEN
10686 					 EXIT;
10687 				       END IF;
10688 				       fnd_file.put_line(fnd_file.log, l_err_msg);
10689 				    END LOOP;
10690 
10691 				 END IF;
10692 
10693 			 END IF; --l_master_workorder_flag_tbl(l_index) = 'N'
10694 
10695 		END IF; -- l_valid_for_close_tbl(l_index) <> 'N'
10696 
10697 	    END LOOP; -- l_workorder_id_tbl loop
10698 
10699 	    -- Update Eligigble Work Orders
10700 	    BEGIN
10701 
10702 		 FORALL l_count IN l_workorder_id_tbl.FIRST .. l_workorder_id_tbl.LAST
10703                     SAVE EXCEPTIONS
10704 		    UPDATE
10705 		      AHL_WORKORDERS
10706 		    SET
10707 		      status_code = 12,
10708 		      last_update_date = sysdate,
10709 		      last_updated_by = fnd_global.user_id,
10710 		      last_update_login = fnd_global.login_id,
10711 		      object_version_number = object_version_number + 1
10712 		    WHERE
10713 		      workorder_id = l_workorder_id_tbl(l_count)
10714 		      AND object_version_number = l_object_version_number_tbl(l_count)
10715 		      AND l_valid_for_close_tbl(l_count) = 'Y';
10716 
10717 	    EXCEPTION
10718 
10719 		   WHEN OTHERS THEN
10720 
10721 		        fnd_file.put_line(fnd_file.log, 'Following error(s) occured while closing Work Orders..');
10722 
10723                         FOR j IN 1..sql%bulk_exceptions.count
10724                         LOOP
10725 			    fnd_file.put_line(fnd_file.log,
10726 			    sql%bulk_exceptions(j).error_index || ', ' ||
10727 			    Sqlerrm(-sql%bulk_exceptions(j).error_code) );
10728                         END LOOP;
10729 
10730 			FND_MESSAGE.set_name('AHL', 'AHL_PRD_WO_CANNOT_CLOSE');
10731 			FND_MSG_PUB.add;
10732 			errbuf := FND_MSG_PUB.Get;
10733 
10734 			retcode := 2; -- error!!
10735 
10736 			ROLLBACK TO close_workorders_pvt;
10737 
10738 			RETURN;
10739 	    END;
10740 
10741 	    -- Log the transaction. - start
10742 	    -- Work Order transaction logging is done in 2 steps.
10743 	    -- This is to take advantage of batch processing to reduce the overhead.
10744 
10745 	    BEGIN
10746 
10747 	           -- Step 1. Log all the Work Orders collected.
10748 
10749 		    FORALL l_txn_count IN l_workorder_id_tbl.FIRST .. l_workorder_id_tbl.LAST
10750                     SAVE EXCEPTIONS
10751 
10752 			    INSERT INTO AHL_WORKORDER_TXNS
10753 			    (
10754 			      WORKORDER_TXN_ID,
10755 			      OBJECT_VERSION_NUMBER,
10756 			      LAST_UPDATE_DATE,
10757 			      LAST_UPDATED_BY,
10758 			      CREATION_DATE,
10759 			      CREATED_BY,
10760 			      LAST_UPDATE_LOGIN,
10761 			      WORKORDER_ID,
10762 			      TRANSACTION_TYPE_CODE,
10763 			      STATUS_CODE,
10764 			      SCHEDULED_START_DATE,
10765 			      SCHEDULED_END_DATE,
10766 			      ACTUAL_START_DATE,
10767 			      ACTUAL_END_DATE,
10768 			      LOT_NUMBER,
10769 			      COMPLETION_SUBINVENTORY,
10770 			      COMPLETION_LOCATOR_ID,
10771 			      SECURITY_GROUP_ID,
10772 			      ATTRIBUTE_CATEGORY,
10773 			      ATTRIBUTE1,
10774 			      ATTRIBUTE2,
10775 			      ATTRIBUTE3,
10776 			      ATTRIBUTE4,
10777 			      ATTRIBUTE5,
10778 			      ATTRIBUTE6,
10779 			      ATTRIBUTE7,
10780 			      ATTRIBUTE8,
10781 			      ATTRIBUTE9,
10782 			      ATTRIBUTE10,
10783 			      ATTRIBUTE11,
10784 			      ATTRIBUTE12,
10785 			      ATTRIBUTE13,
10786 			      ATTRIBUTE14,
10787 			      ATTRIBUTE15
10788 			    ) VALUES
10789 			    (
10790 			      AHL_WORKORDER_TXNS_S.NEXTVAL,
10791 			      l_object_version_number_tbl(l_txn_count) + 1,
10792 			      sysdate,
10793 			      fnd_global.user_id,
10794 			      sysdate,
10795 			      fnd_global.user_id,
10796 			      fnd_global.login_id,
10797 			      l_workorder_id_tbl(l_txn_count),
10798 			      0,
10799 			      12, -- this is close workorder. On successful update the Workorder will be in status 12.
10800 			      l_wo_sch_str_tbl(l_txn_count),
10801 			      l_wo_sch_end_tbl(l_txn_count),
10802 			      l_wo_act_str_tbl(l_txn_count),
10803 			      l_wo_act_end_tbl(l_txn_count),
10804 			      NULL,
10805 			      l_wo_comp_subinv_tbl(l_txn_count),
10806 			      l_wo_comp_loc_id_tbl(l_txn_count),
10807 			      l_wo_sc_grp_id_tbl(l_txn_count),
10808 			      l_wo_att_category_tbl(l_txn_count),
10809 			      l_wo_att_1_tbl(l_txn_count),
10810 			      l_wo_att_2_tbl(l_txn_count),
10811 			      l_wo_att_3_tbl(l_txn_count),
10812 			      l_wo_att_4_tbl(l_txn_count),
10813 			      l_wo_att_5_tbl(l_txn_count),
10814 			      l_wo_att_6_tbl(l_txn_count),
10815 			      l_wo_att_7_tbl(l_txn_count),
10816 			      l_wo_att_8_tbl(l_txn_count),
10817 			      l_wo_att_9_tbl(l_txn_count),
10818 			      l_wo_att_10_tbl(l_txn_count),
10819 			      l_wo_att_11_tbl(l_txn_count),
10820 			      l_wo_att_12_tbl(l_txn_count),
10821 			      l_wo_att_13_tbl(l_txn_count),
10822 			      l_wo_att_14_tbl(l_txn_count),
10823 			      l_wo_att_15_tbl(l_txn_count)
10824 			     );
10825 
10826                     -- Step 2. Delete those Work Orders which are not actually updated to closed status
10827 
10828 		    FORALL l_txn_del_count IN l_workorder_id_tbl.FIRST .. l_workorder_id_tbl.LAST
10829                     SAVE EXCEPTIONS
10830 
10831 			    DELETE
10832 				 ahl_workorder_txns WOTXNO
10833 			    WHERE
10834 				wotxno.workorder_txn_id = (
10835 						    select
10836 						      MAX(wotxn.workorder_txn_id)
10837 						    from
10838 						      AHL_WORKORDER_TXNS WOTXN
10839 						    WHERE
10840 						      wotxn.workorder_id = l_workorder_id_tbl(l_txn_del_count)
10841 						      AND l_valid_for_close_tbl(l_txn_del_count) = 'N'
10842 						   );
10843 	    EXCEPTION
10844 
10845 		   WHEN OTHERS THEN
10846 
10847 		        fnd_file.put_line(fnd_file.log, 'Following error(s) occured while closing Work Orders..');
10848 
10849                         FOR j IN 1..sql%bulk_exceptions.count
10850                         LOOP
10851 			    fnd_file.put_line(fnd_file.log,
10852 			    sql%bulk_exceptions(j).error_index || ', ' ||
10853 			    Sqlerrm(-sql%bulk_exceptions(j).error_code) );
10854                         END LOOP;
10855 
10856 			FND_MESSAGE.set_name('AHL', 'AHL_PRD_WO_CANNOT_CLOSE');
10857 			FND_MSG_PUB.add;
10858 			errbuf := FND_MSG_PUB.Get;
10859 
10860 			retcode := 2; -- error!!
10861 
10862 			ROLLBACK TO close_workorders_pvt;
10863 
10864 			RETURN;
10865 	    END;
10866 
10867 	    COMMIT;
10868 
10869     END LOOP; -- blind for loop
10870     -- perform validations -- end
10871 
10872     retcode := 0;  -- success, since nothing is wrong
10873 
10874     fnd_file.put_line(fnd_file.log, 'End of processing the close Work Orders..');
10875 
10876 END Close_WorkOrders;
10877 
10878 --for fix of bug number 6467963
10879 PROCEDURE get_mr_details_rec
10880 (
10881   p_unit_effectivity_id     IN         NUMBER,
10882   p_object_version_number   IN         NUMBER,
10883   x_mr_rec                  OUT NOCOPY mr_rec_type
10884 ) IS
10885 
10886 l_mr_rec mr_rec_type;
10887 
10888 CURSOR get_mr_details_csr(p_unit_effectivity_id NUMBER, p_ue_object_version_no NUMBER)
10889    IS SELECT
10890    UE.unit_effectivity_id,
10891    UE.object_version_number,
10892    UE.csi_item_instance_id,
10893    UE.mr_header_id,
10894    UE.cs_incident_id,
10895    --FL.Lookup_code,
10896    --FL.Meaning,
10897    UE.qa_collection_id
10898    from ahl_unit_effectivities_b UE--, FND_LOOKUP_VALUES_VL FL
10899    where --FL.Lookup_type = 'AHL_PRD_MR_STATUS'
10900    --AND FL.Lookup_code = AHL_COMPLETIONS_PVT.get_mr_status( p_unit_effectivity_id ) AND
10901    UE.unit_effectivity_id = p_unit_effectivity_id
10902    AND UE.object_version_number = p_ue_object_version_no;
10903 
10904    CURSOR get_mr_status_csr(p_status_code VARCHAR2) IS
10905    Select FL.Meaning FROM FND_LOOKUP_VALUES_VL FL
10906    Where FL.Lookup_type = 'AHL_PRD_MR_STATUS'
10907    AND FL.Lookup_code = p_status_code;
10908 
10909    CURSOR fmp_mr_csr (p_mr_header_id IN NUMBER )
10910    IS select title, QA_INSPECTION_TYPE from AHL_MR_HEADERS_B MR where MR.mr_header_id = p_mr_header_id;
10911 
10912    CURSOR sr_csr (p_cs_incident_id IN NUMBER )
10913    IS select cit.name || '-' || cs.incident_number
10914    from cs_incidents_all_vl cs, cs_incident_types_vl cit
10915    WHERE cs.incident_type_id = cit.incident_type_id
10916    AND cs.incident_id = p_cs_incident_id;
10917 
10918    CURSOR visit_task_csr(p_unit_effectivity_id IN NUMBER)IS
10919    SELECT VST.ORGANIZATION_ID,VT.visit_task_id
10920    FROM  AHL_VISIT_TASKS_B VT, AHL_VISITS_B VST
10921    WHERE VT.TASK_TYPE_CODE IN ( 'SUMMARY' ,  'UNASSOCIATED' )
10922    AND VST.VISIT_ID = VT.VISIT_ID
10923    AND VT.UNIT_EFFECTIVITY_ID =  p_unit_effectivity_id;
10924 
10925    l_organization_id NUMBER;
10926    l_visit_task_id NUMBER;
10927 
10928    CURSOR act_end_dt_csr(p_visit_task_id IN NUMBER) IS
10929    SELECT wo.actual_end_date FROM ahl_workorders WO
10930    WHERE WO.visit_task_id = p_visit_task_id
10931    AND master_workorder_flag = 'Y';
10932 
10933    CURSOR get_qa_plan_id_csr1(p_collection_id IN NUMBER)IS
10934    SELECT qa.plan_id from qa_results qa
10935    where qa.collection_id = p_collection_id and rownum < 2;
10936 
10937    CURSOR get_qa_plan_id_csr2(p_org_id IN NUMBER, p_qa_inspection_type IN VARCHAR2)IS
10938    SELECT QP.plan_id FROM QA_PLANS_VAL_V QP, QA_PLAN_TRANSACTIONS QPT, QA_PLAN_COLLECTION_TRIGGERS QPCT
10939    WHERE QP.plan_id = QPT.plan_id AND QPT.plan_transaction_id = QPCT.plan_transaction_id
10940    AND QP.organization_id = p_org_id
10941    AND QPT.transaction_number in (9999,2001)
10942    AND QPCT.collection_trigger_id = 87
10943    AND QPCT.low_value = p_qa_inspection_type
10944    group by qp.plan_id, qpt.transaction_number having transaction_number = MAX(transaction_number);
10945 
10946 BEGIN
10947 
10948    OPEN get_mr_details_csr(p_unit_effectivity_id,p_object_version_number);
10949    FETCH get_mr_details_csr INTO
10950      l_mr_rec.unit_effectivity_id,
10951      l_mr_rec.ue_object_version_no,
10952      l_mr_rec.item_instance_id,
10953      l_mr_rec.mr_header_id,
10954      l_mr_rec.incident_id,
10955      l_mr_rec.qa_collection_id;
10956    CLOSE get_mr_details_csr;
10957 
10958    OPEN visit_task_csr(l_mr_rec.unit_effectivity_id);
10959    FETCH visit_task_csr INTO l_organization_id, l_visit_task_id;
10960    CLOSE visit_task_csr;
10961 
10962    l_mr_rec.ue_status_code := AHL_COMPLETIONS_PVT.get_mr_status( p_unit_effectivity_id );
10963 
10964    OPEN get_mr_status_csr(l_mr_rec.ue_status_code);
10965    FETCH get_mr_status_csr INTO l_mr_rec.ue_status;
10966    CLOSE get_mr_status_csr;
10967 
10968    IF(l_mr_rec.ue_status_code IN('ACCOMPLISHED', 'ALL_JOBS_COMPLETE','ALL_JOBS_CLOSED')) THEN
10969      OPEN act_end_dt_csr(l_visit_task_id);
10970      FETCH act_end_dt_csr INTO l_mr_rec.actual_end_date;
10971      CLOSE act_end_dt_csr;
10972    ELSE
10973        l_mr_rec.actual_end_date := NULL;
10974    END IF;
10975 
10976    IF(l_mr_rec.mr_header_id IS NOT NULL)THEN
10977      OPEN fmp_mr_csr(l_mr_rec.mr_header_id);
10978      FETCH fmp_mr_csr INTO l_mr_rec.mr_title,l_mr_rec.qa_inspection_type;
10979      CLOSE fmp_mr_csr;
10980    ELSIF (l_mr_rec.incident_id IS NOT NULL)THEN
10981      OPEN sr_csr(l_mr_rec.incident_id);
10982      FETCH sr_csr INTO l_mr_rec.mr_title;
10983      CLOSE sr_csr;
10984    END IF;
10985 
10986 
10987    IF(l_mr_rec.qa_inspection_type IS NULL)THEN
10988       l_mr_rec.qa_plan_id := NULL;
10989    ELSIF(l_mr_rec.qa_collection_id IS NOT NULL)THEN
10990       OPEN get_qa_plan_id_csr1(l_mr_rec.qa_collection_id);
10991       FETCH get_qa_plan_id_csr1 INTO l_mr_rec.qa_plan_id;
10992       CLOSE get_qa_plan_id_csr1;
10993    ELSE
10994       OPEN get_qa_plan_id_csr2(l_organization_id,l_mr_rec.qa_inspection_type);
10995       FETCH get_qa_plan_id_csr2 INTO l_mr_rec.qa_plan_id;
10996       CLOSE get_qa_plan_id_csr2;
10997    END IF;
10998 
10999    x_mr_rec := l_mr_rec;
11000 
11001 END get_mr_details_rec;
11002 
11003 -- added for FP ER# 6435803
11004 -- Function to test whether all operations for a WO are complete
11005 FUNCTION are_all_operations_complete
11006 (
11007   p_workorder_id    IN NUMBER
11008 ) RETURN VARCHAR2 IS
11009 
11010 l_all_operations_complete VARCHAR2(1);
11011 
11012 
11013 CURSOR all_operations_comp_csr(p_workorder_id    IN NUMBER, p_status_code IN
11014 VARCHAR2) IS
11015 SELECT 'x' from ahl_workorder_operations
11016 WHERE status_code = p_status_code
11017 AND workorder_id = p_workorder_id
11018 AND rownum < 2;
11019 l_junk VARCHAR2(1);
11020 
11021 BEGIN
11022   l_all_operations_complete := 'N';
11023   OPEN all_operations_comp_csr(p_workorder_id,G_OP_STATUS_UNCOMPLETE);
11024   FETCH all_operations_comp_csr INTO l_junk;
11025   IF(all_operations_comp_csr%NOTFOUND)THEN
11026     l_all_operations_complete := 'Y';
11027   END IF;
11028   CLOSE all_operations_comp_csr;
11029   RETURN l_all_operations_complete;
11030 
11031 END are_all_operations_complete;
11032 
11033 
11034 END AHL_COMPLETIONS_PVT;