DBA Data[Home] [Help]

PACKAGE BODY: APPS.AHL_COMPLETIONS_PVT

Source


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