DBA Data[Home] [Help]

PACKAGE BODY: APPS.AHL_PRD_UTIL_PKG

Source


1 PACKAGE BODY AHL_PRD_UTIL_PKG AS
2 /* $Header: AHLUPRDB.pls 120.16.12000000.2 2007/10/06 00:22:14 sikumar ship $ */
3 
4 -- Purpose: Briefly explain the functionality of the package body
5 -- Contains common utility procedures to be used by parts change and material transactions.
6 -- MODIFICATION HISTORY
7 -- Person      Date    Comments
8 -- ---------   ------  ------------------------------------------
9 --Validates locator for a given organization. Also if subinventory is provided then chekcs if the loctaor belongs to the
10 -- subinventory.
11   PROCEDURE validate_locators
12      ( p_locator_id IN number,
13        p_org_id IN number,
14        p_subinventory_code in varchar2,
15        X_Return_Status      Out NOCOPY Varchar2,
16        X_Msg_Data           Out NOCOPY Varchar2
17     )
18     AS
19  l_subinv_code varchar2(20):= null;
20  CURSOR ahl_locator_csr(p_org_id number, p_locator_id number) is
21   select subinventory_code
22      from mtl_item_locations_kfv
23      where organization_id = p_org_id
24      and inventory_location_id = p_locator_id
25      and nvl(disable_Date, sysdate) >= sysdate;
26 
27    BEGIN
28     -- Initialize API return status to success
29   x_return_status := FND_API.G_RET_STS_SUCCESS;
30 -- test if subinventory si null;
31 if (p_subinventory_code is null ) then
32 
33   FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_PC_SUBINV_MANDATORY');
34 
35   FND_MSG_PUB.ADD;
36   RAISE FND_API.G_EXC_ERROR;
37 end if;
38 
39  -- Commented the following validation as locator id need not exist in
40  -- mtl_item_locations if it is setup as dynamic entry.
41 
42  --          OPEN ahl_locator_csr(p_Org_Id,p_locator_id);
43  --          FETCH ahl_locator_csr INTO l_subinv_code;
44  --          CLOSE ahl_locator_csr;
45 
46 
47  /*        if (l_subinv_code is null) then
48              x_return_status :=  FND_API.G_RET_STS_ERROR;
49               FND_MESSAGE.Set_Name('AHL','AHL_PRD_LOCATOR_INVALID');
50              FND_MSG_PUB.ADD;
51 
52          END if;*/
53 
54          --Check if the locator is attached to the subinventory if subinventory is provided
55   --       if (l_subinv_code is not null
56   --       and l_subinv_code <> p_subinventory_code ) then
57   --           x_return_status :=  FND_API.G_RET_STS_ERROR;
58   --            FND_MESSAGE.Set_Name('AHL','AHL_PRD_LOCATOR_SUBINV_INVALID');
59   --           FND_MSG_PUB.ADD;
60 
61   --       END if;
62  EXCEPTION
63 --        WHEN NO_DATA_FOUND THEN
64 --          x_return_status := FND_API.G_RET_STS_ERROR;
65 --          FND_MESSAGE.Set_Name('AHL','AHL_PRD_LOCATOR_INVALID');
66 --          FND_MSG_PUB.ADD;
67 
68 
69          WHEN FND_API.G_EXC_ERROR THEN
70             x_return_status := FND_API.G_RET_STS_ERROR;
71         WHEN OTHERS THEN
72            x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
73 END;
74 --Validates a removal condition
75  procedure validate_condition
76     (
77         p_condition_id  In number,
78         x_return_status out NOCOPY varchar2,
79         x_msg_data out NOCOPY varchar2
80 
81     )
82     AS
83 
84     l_junk varchar2(1):= null;
85 
86     CURSOR ahl_condition_csr (p_condn_id number) IS
87      select 'x'
88             from mtl_material_statuses
89             where status_id=p_condn_id
90             and enabled_flag =1;
91     BEGIN
92 
93      -- Initialize API return status to success
94         x_return_status := FND_API.G_RET_STS_SUCCESS;
95 
96            OPEN ahl_condition_csr(p_condition_id);
97            FETCH ahl_condition_csr INTO l_junk;
98            CLOSE ahl_condition_csr;
99 
100             if (l_junk is null) then
101                 x_return_status :=  FND_API.G_RET_STS_ERROR;
102                 FND_MESSAGE.Set_Name('AHL','AHL_PRD_PC_CONDN_MISSING');
103                 FND_MSG_PUB.ADD;
104             END if;
105     END;
106 
107 --Validates a removal reason.
108     procedure validate_reason
109     (
110         p_reason_id  In number,
111         x_return_status out NOCOPY varchar2,
112         x_msg_data out NOCOPY varchar2
113 
114     )
115 
116     AS
117       CURSOR ahl_reason_csr (p_reason_id number) IS
118       select 'x'
119             from MTL_TRANSACTION_REASONS
120             where reason_id=p_reason_id
121             and nvl(disable_date, sysdate) >= sysdate;
122 
123     l_junk varchar2(1) := null;
124     begin
125             -- Initialize API return status to success
126             x_return_status := FND_API.G_RET_STS_SUCCESS;
127 
128             OPEN ahl_reason_csr(p_reason_id);
129            FETCH ahl_reason_csr INTO l_junk;
130            CLOSE ahl_reason_csr;
131 
132 
133             if (l_junk is null) then
134                  x_return_status :=  FND_API.G_RET_STS_ERROR;
135                  FND_MESSAGE.Set_Name('AHL','AHL_PRD_INVALID_REASON');
136                    FND_MESSAGE.Set_Token('REASON',p_reason_id);
137 
138                 FND_MSG_PUB.ADD;
139             END if;
140     end;
141 
142 
143 /********************************************************
144 This procedure checks the condition of the item and validates
145 if the sub inventory is valid for this codnition.
146 *********************************************************/
147 
148 
149 PROCEDURE VALIDATE_MATERIAL_STATUS(p_Organization_Id 	IN   NUMBER,
150 		  						p_Subinventory_Code IN 	 VARCHAR2,-- not null
151 								p_Condition_id		IN 	 NUMBER,-- null/not null
152 								x_return_status 	OUT NOCOPY  VARCHAR2
153 								)
154 IS
155 l_status_id NUMBER;
156 --for inventory sttaus
157 CURSOR ahl_inv_status_csr(p_org_id number, p_subinv_code varchar2) is
158 	SELECT status_id
159 		FROM MTL_SECONDARY_INVENTORIES
160 		WHERE ORGANIZATION_ID = p_org_Id
161 		AND SECONDARY_INVENTORY_NAME = p_Subinv_Code;
162 
163 BEGIN
164 
165 
166 
167 	-- Initialize API return status to success
168 	x_return_status := FND_API.G_RET_STS_SUCCESS;
169 
170          OPEN ahl_inv_status_csr(p_Organization_Id,p_Subinventory_Code);
171            FETCH ahl_inv_status_csr INTO l_status_id;
172            CLOSE ahl_inv_status_csr;
173 
174 		if l_status_id is null THEN
175 			FND_MESSAGE.Set_Name('AHL','AHL_PRD_INVALID_SUBINVENTORY');
176             FND_MESSAGE.set_token('INV', p_Subinventory_Code);
177 			FND_MSG_PUB.ADD;
178            x_return_status :=  FND_API.G_RET_STS_ERROR;
179 
180         End if;
181         --dbms_output.put_line('ahl_prd_util_pkg - Condition id'|| p_condition_id);
182           -- dbms_output.put_line('ahl_prd_util_pkg - status id'|| l_status_id);
183               --dbms_output.put_line('ahl_prd_util_pkg - org id'|| p_organization_id);
184         if (p_condition_id is not null
185         and
186            (    (FND_PROFILE.VALUE('AHL_MTL_MAT_STATUS_SERVICABLE')is not null and
187                   p_condition_id = FND_PROFILE.VALUE('AHL_MTL_MAT_STATUS_SERVICABLE'))
188                 OR
189                     ( FND_PROFILE.VALUE('AHL_MTL_MAT_STATUS_UNSERVICABLE') is not null and
190                         p_condition_id=FND_PROFILE.VALUE('AHL_MTL_MAT_STATUS_UNSERVICABLE'))
191                 OR
192                     (FND_PROFILE.VALUE('AHL_MTL_MAT_STATUS_MRB')is not null and
193                      p_condition_id = FND_PROFILE.VALUE('AHL_MTL_MAT_STATUS_MRB'))
194             )
195           AND
196             p_condition_id <> l_status_id ) then
197 
198 
199 					FND_MESSAGE.Set_Name('AHL','AHL_PRD_CONDN_SUBINV_MISMATCH');
200 					FND_MSG_PUB.ADD;
201                     x_return_status :=  FND_API.G_RET_STS_ERROR;
202 
203 	END IF;
204 
205 END ;--VALIDATE_MATERIAL_STATUS;
206 
207 ------------------------------------------------------------------------------------------------
208 -- Function to test if the Unit in context is locked or not. The input to the API can be one of
209 -- workorder_id, mr_id, visit_id or item_instance_id.
210 ------------------------------------------------------------------------------------------------
211 FUNCTION Is_Unit_Locked(
212 	P_workorder_id		IN 	NUMBER,
213 	P_ue_id			IN 	NUMBER,
214 	P_visit_id		IN 	NUMBER,
215 	P_item_instance_id	IN 	NUMBER
216 )
217 RETURN VARCHAR2
218 IS
219 /*
220  * Cursor to get workorder_ids of a given visit.
221  */
222 CURSOR c_get_visit_workorders(p_visit_id IN NUMBER)
223 IS
224 SELECT
225 	workorder_id
226 FROM
227 	ahl_workorders
228 WHERE
229 	visit_id = p_visit_id AND
230 	status_code not in (22, 7, 17) AND
231 	master_workorder_flag <> 'Y';
232 /*
233  * Cursor for getting item details from a workorder.
234  * Detailed are retrieved by joining workorder and visit tables.
235  * If the visit header has item instance info then use that else
236  * get the info from visit task tables.
237  */
238 CURSOR c_get_wo_item_details(p_workorder_id IN NUMBER)
239 IS
240 SELECT
241 	vst.item_instance_id,
242 	vtk.instance_id
243 FROM
244 	ahl_visit_tasks_b vtk,
245 	ahl_visits_b vst,
246 	ahl_workorders wo
247 WHERE
248 	wo.workorder_id = p_workorder_id AND
249 	vtk.visit_task_id = wo.visit_task_id AND
250 	vtk.visit_id = vst.visit_id;
251 
252 /*
253  * Cursor for getting csi_item_instance_id given mr_id.
254  */
255 CURSOR  c_get_ue_instance_id(p_ue_id IN NUMBER)
256 IS
257 SELECT
258 	csi_item_instance_id
259 FROM
260 	AHL_UNIT_EFFECTIVITIES_B
261 WHERE
262 	unit_effectivity_id = p_ue_id;
263 
264 -- declare all local variables here
265 l_item_instance_id NUMBER;
266 l_instance_id NUMBER;
267 
268 BEGIN
269 	-- Check if item_instance_id is input to the API.
270 	IF p_item_instance_id IS NOT NULL
271 	THEN
272 		RETURN AHL_UTIL_UC_PKG.Is_Unit_Quarantined(
273 							p_unit_header_id	=>	null,
274 							p_instance_id		=> p_item_instance_id
275 							);
276 	-- If visit_id is input
277 	ELSIF p_visit_id IS NOT NULL
278 	THEN
279 		-- get all visit workorders
280 		FOR vst_wos IN c_get_visit_workorders(p_visit_id)
281 		LOOP
282 			-- for each workorder get item instance info.
283 			OPEN c_get_wo_item_details(vst_wos.workorder_id);
284 			FETCH c_get_wo_item_details INTO l_item_instance_id, l_instance_id;
285 			CLOSE c_get_wo_item_details;
286 
287 			-- If visit header has item instance info.
288 			IF l_instance_id IS NOT NULL
289 			THEN
290 				IF AHL_UTIL_UC_PKG.Is_Unit_Quarantined(
291 							p_unit_header_id	=>	null,
292 							p_instance_id		=> l_instance_id
293 							) = FND_API.G_TRUE
294 				THEN
295 					RETURN FND_API.G_TRUE;
296 				END IF;
297 
298 			ELSE
299 				-- If visit task has item instance info.
300 				RETURN AHL_UTIL_UC_PKG.Is_Unit_Quarantined(
301 							p_unit_header_id	=>	null,
302 							p_instance_id		=>	l_item_instance_id
303 						);
304 			END IF;
305 		END LOOP;
306 
307 		RETURN FND_API.G_FALSE;
308 	-- if mr header id is input to the API.
309 	ELSIF p_ue_id IS NOT NULL
310 	THEN
311 		OPEN c_get_ue_instance_id(p_ue_id);
312 		FETCH c_get_ue_instance_id INTO l_instance_id;
313 		CLOSE c_get_ue_instance_id;
314 		RETURN AHL_UTIL_UC_PKG.Is_Unit_Quarantined(
315 						p_unit_header_id	=>	null,
316 						p_instance_id		=>	l_instance_id
317 						);
318 	-- If workorder id is input to the API.
319 	ELSIF p_workorder_id IS NOT NULL
320 	THEN
321 		OPEN c_get_wo_item_details(p_workorder_id);
322 		FETCH c_get_wo_item_details INTO l_item_instance_id, l_instance_id;
323 		CLOSE c_get_wo_item_details;
324 		RETURN AHL_UTIL_UC_PKG.Is_Unit_Quarantined(
325 				p_unit_header_id	=>	null,
326 				p_instance_id		=>	nvl(l_instance_id, l_item_instance_id) );
327 	END IF;
328 
329 	-- Control will reach here if all inputs to the API are null. return false then.
330 	RETURN FND_API.G_FALSE;
331 
332 END Is_Unit_Locked;
333 
334 ------------------------------------------------------------------------------------------------
335 -- Function to test if the workorder can be updated.
336 -- Determined based on following factors
337 -- 1. If the unit is quarantined then it cannot be updated.
338 -- 2. If the workorder status is any of 22, 12 and 7 then it cannot be updated.
339 ------------------------------------------------------------------------------------------------
340 FUNCTION Is_Wo_Updatable(
341 	P_workorder_id		IN 	NUMBER,
342 	p_check_unit            IN      VARCHAR2 DEFAULT FND_API.G_TRUE
343 )
344 RETURN VARCHAR2
345 IS
346 /*
347  * Cursor for selecting workorder status validity.
348  */
349 CURSOR c_validate_wo_status(p_workorder_id IN NUMBER) IS
350 SELECT
351 	'X'
352 FROM
353 	ahl_workorders
354 WHERE
355 	workorder_id = p_workorder_id AND
356 	status_code in (7, 12, 22);
357 
358 -- declare local variables here
359 l_exists VARCHAR2(1);
360 
361 BEGIN
362 	-- If workorder_id is null then immediately return false.
363 	IF p_workorder_id IS NULL
364 	THEN
365 		RETURN FND_API.G_FALSE;
366 	END IF;
367 
368 	-- Check if the unit is locked... If so then return false to indicate
369 	-- the workorder can't be updated.
370 	IF p_check_unit = FND_API.G_TRUE THEN
371 	IF Is_Unit_Locked(
372 			p_workorder_id		=> 	p_workorder_id,
373 			P_ue_id			=>	null,
374 			P_visit_id		=>	null,
375 			P_item_instance_id	=>	null
376 		 ) = FND_API.G_TRUE
377 	THEN
378 		RETURN FND_API.G_FALSE;
379 	END IF;
380 	END IF;
381 
382 	-- If the unit is not locked and the workorder is in any of
383 	-- 7, 12 or 22 then return false.
384 	OPEN c_validate_wo_status(p_workorder_id);
385 	FETCH c_validate_wo_status INTO l_exists;
386 	CLOSE c_validate_wo_status;
387 
388 	IF l_exists IS NOT NULL
389 	THEN
390 		RETURN FND_API.G_FALSE;
391 	END IF;
392 
393 	-- If this point is reached then neither the unit is locked nor the workorder is
394 	-- in invalid status. Return true here.
395 	RETURN FND_API.G_TRUE;
396 
397 END Is_Wo_Updatable;
398 
399 ------------------------------------------------------------------------------------------------
400 -- Function to test if the workorder operation can be updated.
401 -- Determined based on following factors
402 -- 1. If the unit associated with the workorder to which the operation belongs is quarantined
403 --    then it cannot be updated.
404 -- 2. If the workorder status is any of 22, 12 and 7 then it cannot be updated.
405 -- 3. If the operation status is 'COMPLETE' then it cannot be updated
406 ------------------------------------------------------------------------------------------------
407 FUNCTION Is_Op_Updatable(
408 	p_workorder_id		IN	NUMBER,
409 	p_operation_seq_num	IN	NUMBER,
410 	p_check_unit            IN      VARCHAR2 DEFAULT FND_API.G_TRUE
411 )
412 RETURN VARCHAR2
413 IS
414 
415 /*
416  * Cursor for selecting workorder status validity.
417  */
418 CURSOR c_validate_wo_status(p_workorder_id IN NUMBER)
419 IS
420 SELECT
421 	'X'
422 FROM
423 	ahl_workorders
424 WHERE
425 	workorder_id = p_workorder_id AND
426 	status_code in (4, 5, 7, 12, 22);
427 /*
428  * Cursor for checking workorder operation status validity
429  */
430 CURSOR c_validate_op_status(p_workorder_id IN NUMBER, p_op_seq_no IN NUMBER)
431 IS
432 SELECT
433 	'X'
434 FROM
435 	ahl_workorder_operations
436 WHERE
437 	workorder_id = p_workorder_id AND
438 	operation_sequence_num = p_op_seq_no AND
439 	status_code = 1;
440 
441 -- declare local variables here
442 l_exists VARCHAR2(1);
443 
444 BEGIN
445 	-- If either of workorder_id or operation sequence number is null then
446 	-- return false as it is incorrect input to this API.
447 	IF p_workorder_id IS NULL OR p_operation_seq_num IS NULL
448 	THEN
449 		RETURN FND_API.G_FALSE;
450 	END IF;
451 
452 	-- If the unit associated with this workorder is locked then
453 	-- operation should not be updatable.
454 	IF p_check_unit = FND_API.G_TRUE THEN
455 	IF Is_Unit_Locked(
456 			p_workorder_id		=> 	p_workorder_id,
457 			P_ue_id			=>	null,
458 			P_visit_id		=>	null,
459 			P_item_instance_id	=>	null
460 		 ) = FND_API.G_TRUE
461 	THEN
462 		RETURN FND_API.G_FALSE;
463 	END IF;
464 	END IF;
465 
466 	-- If the workorder status is any of 7, 12 or 22 then return false.
467 	OPEN c_validate_wo_status(p_workorder_id);
468 	FETCH c_validate_wo_status INTO l_exists;
469 	CLOSE c_validate_wo_status;
470 	IF l_exists IS NOT NULL
471 	THEN
472 		RETURN FND_API.G_FALSE;
473 	END IF;
474 
475 	-- If the operation status is 'Complete' then return false
476 	-- to indicate the operation is not updatable.
477 	OPEN c_validate_op_status(p_workorder_id, p_operation_seq_num);
478 	FETCH c_validate_op_status INTO l_exists;
479 	IF l_exists IS NOT NULL
480 	THEN
481 		RETURN FND_API.G_FALSE;
482 	END IF;
483 
484 	-- Control reaching here indicates above three checks are not valid for
485 	-- the input hence return true to indicate the operation is updatable.
486 	RETURN FND_API.G_TRUE;
487 
488 END Is_Op_Updatable;
489 
490 ------------------------------------------------------------------------------------------------
491 -- Function to determine if a MR requires Quality collection to be done.
492 -- (Whether QA Collection is required)
493 -- The function returns QA Plan id or null if one is not associated with the MR.
494 ------------------------------------------------------------------------------------------------
495 FUNCTION Is_Mr_Qa_Enabled(
496 	p_ue_id			IN	NUMBER,
497 	p_check_unit            IN      VARCHAR2 DEFAULT FND_API.G_TRUE
498 )
499 RETURN NUMBER
500 IS
501 
502 /*
503  * Cursor to retrieve mr_header_id and qa_collection_id from ue_effectivities table.
504  */
505 CURSOR  c_get_mr_details(p_ue_id IN NUMBER)
506 IS
507 SELECT
508 	mr_header_id,
509 	qa_collection_id
510 FROM
511 	AHL_UNIT_EFFECTIVITIES_B
512 WHERE
513 	unit_effectivity_id = p_ue_id;
514 
515 /*
516  * Cursor to retrieve plan id given qa collection id.
517  */
518 CURSOR c_get_plan_from_col(p_qa_collection_id IN NUMBER)
519 IS
520 SELECT
521 	DISTINCT plan_id
522 FROM
523 	QA_RESULTS
524 WHERE
525 	collection_id = p_qa_collection_id;
526 
527 /*
528  * Cursor to retrieve mr_qa_inspection_type given mr_header_id
529  */
530 CURSOR c_get_mr_insp_type(p_mr_header_id IN  NUMBER)
531 IS
532 SELECT
533 	qa_inspection_type
534 FROM
535 	AHL_MR_HEADERS_B
536 WHERE
537 	mr_header_id = p_mr_header_id;
538 
539 /*
540  * Cursor for getting qa plan id from MR qa_inspection_type and ue_id.
541  */
542 CURSOR c_get_plan_from_insp_type(p_qa_insp_type IN VARCHAR2, p_ue_id IN NUMBER)
543 IS
544 SELECT
545   QP.PLAN_ID
546 FROM
547   QA_PLANS_VAL_V QP,
548   QA_PLAN_TRANSACTIONS QPT,
549   QA_PLAN_COLLECTION_TRIGGERS QPCT
550 WHERE
551   QP.PLAN_ID = QPT.PLAN_ID AND
552   QPT.PLAN_TRANSACTION_ID = QPCT.PLAN_TRANSACTION_ID AND
553   QP.ORGANIZATION_ID =   (SELECT
554   				ORGANIZATION_ID
555   			  FROM
556   			  	AHL_VISITS_B VST,
557   			  	AHL_VISIT_TASKS_B TSK
558   			  WHERE VST.VISIT_ID = TSK.VISIT_ID AND
559 				TSK.UNIT_EFFECTIVITY_ID = p_ue_id AND
560 			  ROWNUM < 2) AND
561   QPT.TRANSACTION_NUMBER IN (9999,2001)	AND
562   QPCT.COLLECTION_TRIGGER_ID = 87 AND
563   QPCT.LOW_VALUE = p_qa_insp_type
564 GROUP BY
565 	QP.PLAN_ID,
566 	QPT.TRANSACTION_NUMBER
567 HAVING
568 	TRANSACTION_NUMBER = MAX(TRANSACTION_NUMBER);
569 
570 --declare all local variables here
571 l_mr_id NUMBER;
572 l_qa_collection_id NUMBER;
573 l_plan_id NUMBER;
574 l_qa_insp_type VARCHAR2(150);
575 
576 BEGIN
577 	-- If ue id which is only input to this API is null then return null.
578 	IF p_ue_id IS NULL
579 	THEN
580 		RETURN NULL;
581 	END IF;
582 
583 	-- retrieve mr_header_id and qa_collection_id for the given ue.
584 	OPEN c_get_mr_details(p_ue_id);
585 	FETCH c_get_mr_details INTO l_mr_id, l_qa_collection_id;
586 	CLOSE c_get_mr_details;
587 
588 	-- If mr_header_id is null dont proceed further and return null.
589 	IF l_mr_id IS NULL
590 	THEN
591 		RETURN NULL;
592 	END IF;
593 
594 	-- If the unit associated with this workorder is locked then
595 	-- operation should not be updatable.
596 	IF p_check_unit = FND_API.G_TRUE THEN
597 	IF Is_Unit_Locked(
598 			p_workorder_id		=> 	null,
599 			P_ue_id			=>	l_mr_id,
600 			P_visit_id		=>	null,
601 			P_item_instance_id	=>	null
602 		 ) = FND_API.G_TRUE
603 	THEN
604 		RETURN NULL;
605 	END IF;
606 	END IF;
607 
608 	-- retrieve plan_id for information gathered above.
609 	IF l_qa_collection_id IS NOT NULL
610 	THEN
611 		-- Get qa_plan_id from qa_collection_id
612 		OPEN c_get_plan_from_col(l_qa_collection_id);
613 		FETCH c_get_plan_from_col INTO l_plan_id;
614 		CLOSE c_get_plan_from_col;
615 	ELSE
616 		-- Get qa_inspection_type from mr header.
617 		OPEN c_get_mr_insp_type(l_mr_id);
618 		FETCH c_get_mr_insp_type INTO l_qa_insp_type;
619 		CLOSE c_get_mr_insp_type;
620 
621 		-- retrieve qa_plan_id from qa_inspection_type and ue_id.
622 		IF l_qa_insp_type IS NOT NULL
623 		THEN
624 			OPEN c_get_plan_from_insp_type(l_qa_insp_type, p_ue_id);
625 			FETCH c_get_plan_from_insp_type INTO l_plan_id;
626 			CLOSE c_get_plan_from_insp_type;
627 		END IF;
628 	END IF;
629 
630 	-- return plan_id collected. could be null also if no plan is associated.
631 	RETURN l_plan_id;
632 
633 END Is_Mr_Qa_Enabled;
634 
635 
636 ------------------------------------------------------------------------------------------------
637 -- Function to determine if parts changes are allowed for a workorder
638 -- 1. If the unit is quarantined then part changes are not allowed.
639 -- 2. If the workorder status is anything other than Released (3) or On Parts Hold (19) then part changes
640 --    are not allowed.
641 ------------------------------------------------------------------------------------------------
642 FUNCTION Is_PartChange_Enabled(
643 	P_workorder_id		IN	NUMBER,
644 	p_check_unit            IN      VARCHAR2 DEFAULT FND_API.G_TRUE
645 )
646 RETURN VARCHAR2
647 IS
648 /*
649  * Cursor for getting the status of the workorder id passed as input to this API.
650  * workorder status mapping
651  * ------------------------
652  * 3 Released
653  * 19 on parts hold
654  */
655 CURSOR c_get_workorder_details(p_workorder_id IN NUMBER)
656 IS
657 SELECT AWOS.STATUS_CODE,
658        NVL(VTS.INSTANCE_ID, VST.ITEM_INSTANCE_ID)
659 FROM
660 	AHL_WORKORDERS AWOS,
661 	AHL_VISITS_B VST,
662 	AHL_VISIT_TASKS_B VTS
663 WHERE
664         AWOS.VISIT_TASK_ID = VTS.VISIT_TASK_ID   AND
665         VST.VISIT_ID = VTS.VISIT_ID  AND
666 	WORKORDER_ID = p_workorder_id;
667 
668 -- declare local variables here
669 l_status_code      VARCHAR2(30);
670 l_item_instance_id NUMBER;
671 
672 l_unit_config_name ahl_unit_config_headers.name%TYPE;
673 l_unit_config_id   NUMBER;
674 l_return_status    VARCHAR2(1);
675 BEGIN
676 	-- If sole input to this API p_workorder_id is null then return false
677 	IF p_workorder_id IS NULL
678 	THEN
679 		RETURN FND_API.G_FALSE;
680 	END IF;
681 
682 	-- If the Unit is locked then part changes cannot be done hence return false
683 	IF p_check_unit = FND_API.G_TRUE THEN
684 	IF Is_Unit_Locked(
685 			  p_workorder_id => p_workorder_id,
686 			  P_ue_id		=>	null,
687 			  P_visit_id		=>	null,
688 			  P_item_instance_id	=>	null
689 			 ) = FND_API.G_TRUE THEN
690 		RETURN FND_API.G_FALSE;
691 	END IF;
692 	END IF;
693 
694 	-- If workorder is in an invalid status where part changes cannot be done then
695 	-- return false;
696 	OPEN c_get_workorder_details(p_workorder_id);
697 	FETCH c_get_workorder_details INTO l_status_code, l_item_instance_id;
698 	CLOSE c_get_workorder_details;
699 
700 	IF l_status_code NOT IN ('3', '19') THEN
701 		RETURN FND_API.G_FALSE;
702 	END IF;
703 
704         AHL_PRD_PARTS_CHANGE_PVT.get_unit_config_information(
705                                     p_item_instance_id => l_item_instance_id,
706                                     p_workorder_id => null,
707                                     x_unit_config_id   => l_unit_config_id,
708                                     x_unit_config_name => l_unit_config_name,
709                                     x_return_status    => l_return_status);
710        IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
711          RETURN FND_API.G_FALSE;
712        END IF;
713 
714         -- All above conditions are false hence part changes can be done. return true.
715 	RETURN FND_API.G_TRUE;
716 
717 END Is_PartChange_Enabled;
718 
719 
720 ------------------------------------------------------------------------------------------------
721 -- Function to check if resource assignment should be allowed. The logic is based on following
722 -- factors :
723 -- 1. The unit is quarantined.
724 -- 2. A user is currently logged into the resource assignment.
725 -- 3. Resource transactions have been posted corresponding to this resource assignment.
726 ------------------------------------------------------------------------------------------------
727 FUNCTION IsDelAsg_Enabled(
728 		P_assignment_id		IN	NUMBER,
729 		P_workorder_id		IN	NUMBER,
730 	        p_check_unit            IN      VARCHAR2 DEFAULT FND_API.G_TRUE
731 )
732 RETURN VARCHAR2
733 IS
734 
735 /*
736  * Cursor for getting resource assignment details given assingment id.
737  */
738 CURSOR c_get_ass_details(p_assignment_id IN NUMBER)
739 IS
740 SELECT
741 	WREQ.operation_sequence,
742 	WREQ.resource_sequence
743 FROM
744 	AHL_WORK_ASSIGNMENTS WASS,
745 	AHL_PP_REQUIREMENT_V WREQ
746 WHERE
747 	WASS.assignment_id = p_assignment_id AND
748 	WREQ.resource_id = WASS.operation_resource_id AND
749 	login_date IS NOT NULL;
750 
751 -- declare local variables here
752 --l_login_date DATE;
753 l_op_seq_num NUMBER;
754 l_res_seq_num NUMBER;
755 
756 BEGIN
757 
758 	-- If sole input to this API p_workorder_id is null then return false
759 	IF P_assignment_id IS NULL
760 	THEN
761 		RETURN FND_API.G_FALSE;
762 	END IF;
763 	-- If the Unit is locked then Assignment cant be deleted return false.
764 	IF p_check_unit = FND_API.G_TRUE THEN
765 	IF Is_Unit_Locked(
766 			  p_workorder_id 	=> p_workorder_id,
767 			  P_ue_id		=>	null,
768 			  P_visit_id		=>	null,
769 			  P_item_instance_id	=>	null
770 			 ) = FND_API.G_TRUE
771 	THEN
772 		Fnd_Message.Set_Name('AHL', 'AHL_PP_DEL_RESASG_UNTLCKD');
773 		Fnd_Msg_Pub.ADD;
774 		RETURN FND_API.G_FALSE;
775 	END IF;
776 	END IF;
777 
778 	OPEN c_get_ass_details(p_assignment_id);
779 	FETCH c_get_ass_details INTO l_op_seq_num, l_res_seq_num;
780 
781 	IF c_get_ass_details%FOUND
782 	THEN
783 		FND_MESSAGE.Set_Name('AHL', 'AHL_PP_DELASG_LOGDIN');
784 		FND_MESSAGE.set_token( 'OP_SEQ' , l_op_seq_num);
785 		FND_MESSAGE.set_token( 'RES_SEQ' , l_res_seq_num);
786 		Fnd_Msg_Pub.ADD;
787 
788 		CLOSE c_get_ass_details;
789 		RETURN FND_API.G_FALSE;
790 	END IF;
791 	CLOSE c_get_ass_details;
792 
793 
794 	/*IF l_login_date IS NOT NULL
795 	THEN
796 		-- the user is currently logged in corresponding to this resource assignment
797 		-- the resource assignment cannot be deleted
798 		RETURN FND_API.G_FALSE;
799 	END IF;
800 	*/
801 
802 	RETURN FND_API.G_TRUE;
803 
804 END IsDelAsg_Enabled;
805 
806 FUNCTION Is_Wo_Completable(
807 	P_workorder_id		IN 	NUMBER
808 )
809 RETURN VARCHAR2
810 IS
811 /*
812  * Cursor for selecting workorder status validity.
813  */
814 CURSOR c_validate_wo_status(p_workorder_id IN NUMBER) IS
815 SELECT
816 	'X'
817 FROM
818 	ahl_workorders
819 WHERE
820 	workorder_id = p_workorder_id AND
821 	status_code in (1,4,5,7, 12,21, 22);
822 
823 /*
824  * Cursor for selecting operation status validity.
825  */
826 CURSOR c_validate_op_status(p_workorder_id IN NUMBER) IS
827 SELECT
828 	'X'
829 FROM
830 	ahl_workorder_operations
831 WHERE
832 	workorder_id = p_workorder_id AND
833 	status_code in (0,2);
834 
835 -- declare local variables here
836 l_exists VARCHAR2(1);
837 
838 BEGIN
839 	-- If workorder_id is null then immediately return false.
840 	IF p_workorder_id IS NULL
841 	THEN
842 		RETURN FND_API.G_FALSE;
843 	END IF;
844 
845 	OPEN c_validate_wo_status(p_workorder_id);
846 	FETCH c_validate_wo_status INTO l_exists;
847 	CLOSE c_validate_wo_status;
848 
849 	IF l_exists IS NOT NULL
850 	THEN
851 		RETURN FND_API.G_FALSE;
852 	END IF;
853 
854 	OPEN c_validate_op_status(p_workorder_id);
855 	FETCH c_validate_op_status INTO l_exists;
856 	CLOSE c_validate_op_status;
857 
858 	IF l_exists IS NOT NULL
859 	THEN
860 		RETURN FND_API.G_FALSE;
861 	END IF;
862 
863 	-- If this point is reached then neither the unit is locked nor the workorder is
864 	-- in invalid status. Return true here.
865 	RETURN FND_API.G_TRUE;
866 
867 END Is_Wo_Completable;
868 
869 ------------------------------------------------------------------------------------------------
870 -- Function to test if resource transactions are allowed for a workorder
871 ------------------------------------------------------------------------------------------------
872 -- Start of Comments
873 -- Function name               : Is_ResTxn_Allowed
874 -- Type                        : Private
875 -- Pre-reqs                    :
876 -- Parameters                  :
877 -- Return		       : FND_API.G_TRUE or FND_API.G_FALSE.
878 --
879 -- Standard IN  Parameters :
880 --	None
881 --
882 -- Standard OUT Parameters :
883 --	None
884 --
885 -- Is_Unit_Locked IN parameters:
886 --      P_workorder_id		NUMBER		Required
887 --
888 -- Is_Unit_Locked IN OUT parameters:
889 --      None
890 --
891 -- Is_Unit_Locked OUT parameters:
892 --      None.
893 --
894 -- Version :
895 --          Current version        1.0
896 --
897 -- End of Comments
898 
899 FUNCTION Is_ResTxn_Allowed(
900 	P_workorder_id		IN 	NUMBER,
901 	p_check_unit            IN      VARCHAR2 DEFAULT FND_API.G_TRUE
902 )
903 RETURN VARCHAR2
904 IS
905 -- cursor to retrieve the workorder status
906 CURSOR get_wo_status (c_wo_id NUMBER)
907 IS
908 SELECT STATUS_CODE
909 FROM AHL_WORKORDERS
910 WHERE WORKORDER_ID = c_wo_id;
911 
912 l_return_value VARCHAR2(1);
913 l_wo_status    VARCHAR2(30);
914 BEGIN
915 
916 l_return_value := FND_API.G_FALSE;
917 IF p_check_unit = FND_API.G_TRUE THEN
918 l_return_value := is_unit_locked(p_workorder_id => p_workorder_id,
919                                  p_ue_id => NULL,
920 				p_item_instance_id => NULL,
921 				p_visit_id => NULL
922 				);
923 -- If the unit is locked, then resource transactions are not allowed
924 IF l_return_value = FND_API.G_TRUE THEN
925   RETURN FND_API.G_FALSE;
926 END IF;
927 END IF;
928 
929 OPEN get_wo_status(p_workorder_id);
930 FETCH get_wo_status INTO l_wo_status;
931 CLOSE get_wo_status;
932 
933 -- If the workorder is in status On Hold, Closed, Complete No Charge, Unreleased, Cancelled
934 -- then resource transactions are not allowed
935 IF l_wo_status IS NULL OR l_wo_status IN ('6','12','5','1', '7', '13') THEN
936   RETURN FND_API.G_FALSE;
937 END IF;
938 
939 RETURN FND_API.G_TRUE;
940 
941 END Is_ResTxn_Allowed;
942 
943 ------------------------------------------------------------------------------------------------
944 -- Function to test if user has privileges to cancel a workorder that is not un-released
945 -- or if user has privileges to cancel any work order.
946 ------------------------------------------------------------------------------------------------
947 -- Start of Comments
948 -- Function name               : Is_Wo_Cancel_Allowed
949 -- Type                        : Private
950 -- Pre-reqs                    :
951 -- Parameters                  :
952 -- Return		       : FND_API.G_TRUE or FND_API.G_FALSE.
953 --
954 -- Standard IN  Parameters :
955 --	None
956 --
957 -- Standard OUT Parameters :
958 --	None
959 --
960 --
961 --
962 -- Version :
963 --          Current version        1.0
964 --
965 -- End of Comments
966 
967 FUNCTION Is_Wo_Cancel_Allowed(
968 	P_workorder_id		IN 	  NUMBER := NULL
969 ) RETURN VARCHAR2
970 IS
971 -- cursor to retrieve whether workorder is released
972 CURSOR is_workorders_released(c_wo_id NUMBER)
973 IS
974 SELECT 'x'
975 FROM AHL_WORKORDERS WO,wip_discrete_jobs WIP
976 WHERE WO.wip_entity_id = WIP.wip_entity_id
977 AND WIP.date_released IS NOT NULL AND
978 WO.WORKORDER_ID = c_wo_id;
979 
980 l_junk VARCHAR2(1);
981 
982 BEGIN
983 
984 IF NOT(FND_FUNCTION.TEST('AHL_PRD_DISALLOW_CANCEL_JOBS',null)) THEN
985 
986    -- if no workorder ID is passed, then check for only AHL_PRD_DISALLOW_CANCEL_JOBS
987    -- function access.
988    IF (p_workorder_id IS NULL) THEN
989     return FND_API.G_TRUE;
990    ELSE
991       OPEN is_workorders_released(p_workorder_id);
992       FETCH is_workorders_released INTO l_junk;
993       IF(is_workorders_released%NOTFOUND)THEN
994         CLOSE is_workorders_released;
995         return FND_API.G_TRUE;
996       END IF;
997       CLOSE is_workorders_released;
998 
999       IF(FND_FUNCTION.TEST('AHL_PRD_CANCEL_REL_JOBS',null))THEN
1000         return FND_API.G_TRUE;
1001       END IF;
1002    END IF;
1003 
1004 END IF;
1005 
1006 RETURN FND_API.G_FALSE;
1007 
1008 END Is_Wo_Cancel_Allowed;
1009 
1010 -- Start of Comments --
1011 --  Function name : Get_Op_TotalHours_Assigned
1012 --
1013 --  Parameters  :
1014 --
1015 --                  p_employee_id    --  Optional Input Employee Id.
1016 --                  p_workorder_id   --  Mandatory Workorder ID.
1017 --                  p_operation_seq_num -- Mandatory Operation Seq Number
1018 --                  p_fnd_function_name   -- Mandatory fnd_function to identify User role.
1019 --
1020 --
1021 --  Description   : This function returns the total hours assigned to an operation.
1022 --                  If the user role is technician or line maintenance technician, then the
1023 --                  total hours are calculated for that particular employee resource,
1024 --                  otherwise the total hours are calculated for all the person type
1025 --                  resources in the operation. If the employee id is not passed to the
1026 --                  function then the calculations are done for the user who is currently
1027 --                  logged into the application.
1028 --
1029 
1030 FUNCTION Get_Op_TotalHours_Assigned (p_employee_id       IN NUMBER := NULL,
1031                                      p_workorder_id      IN NUMBER,
1032                                      p_operation_seq_num IN NUMBER,
1033                                      p_fnd_function_name IN VARCHAR2)
1034 RETURN NUMBER
1035 
1036 IS
1037 
1038   -- query to retrieve total hrs assigned to an employee for an operation.
1039   CURSOR c_get_total_hours_emp(p_employee_id IN NUMBER,
1040                                p_workorder_id IN NUMBER,
1041                                p_operation_seq_num IN NUMBER) IS
1042     SELECT SUM((AWAS.assign_end_date - AWAS.assign_start_date) * 24)
1043     FROM AHL_WORKORDER_OPERATIONS WO, AHL_OPERATION_RESOURCES AOR,
1044          AHL_WORK_ASSIGNMENTS AWAS, BOM_RESOURCES BOM
1045     WHERE WO.workorder_operation_id = AOR.workorder_operation_id
1046       AND AOR.operation_resource_id = AWAS.operation_resource_id
1047       AND BOM.resource_id = AOR.resource_id
1048       AND BOM.resource_type = 2  -- Person
1049       AND WO.workorder_id = p_workorder_id
1050       AND WO.operation_sequence_num = p_operation_seq_num
1051       AND AWAS.employee_id = p_employee_id;
1052 
1053   -- query to retrieve total hrs required for all employees for an operation.
1054   CURSOR c_get_total_hours_op(p_workorder_id IN NUMBER,
1055                               p_operation_seq_num IN NUMBER) IS
1056     SELECT SUM(NVL(AOR.duration, 0))
1057     FROM AHL_OPERATION_RESOURCES AOR,
1058          BOM_RESOURCES BOMR,
1059          AHL_WORKORDER_OPERATIONS AWOP
1060     WHERE AOR.RESOURCE_ID = BOMR.RESOURCE_ID
1061       AND BOMR.resource_type = 2  -- Person
1062       AND AOR.WORKORDER_OPERATION_ID = AWOP.WORKORDER_OPERATION_ID
1063       AND AWOP.workorder_id = p_workorder_id
1064       AND AWOP.operation_sequence_num = p_operation_seq_num;
1065 
1066   l_employee_id  NUMBER;
1067   l_total_hours  NUMBER;
1068 
1069 BEGIN
1070 
1071   l_total_hours := 0;
1072   IF (p_fnd_function_name = G_TECH_MYWO) THEN  -- Technician.
1073     -- Get logged in user's emp ID if input employee ID is null.
1074     IF (p_employee_id IS NULL) THEN
1075        l_employee_id := AHL_PRD_WO_LOGIN_PVT.Get_Employee_ID;
1076     ELSE
1077        l_employee_id := p_employee_id;
1078     END IF;
1079 
1080     -- get total hrs.
1081     OPEN c_get_total_hours_emp(l_employee_id, p_workorder_id, p_operation_seq_num);
1082     FETCH c_get_total_hours_emp INTO l_total_hours;
1083     CLOSE c_get_total_hours_emp;
1084   ELSE    -- Data Clerk, Transit role.
1085     OPEN c_get_total_hours_op(p_workorder_id, p_operation_seq_num);
1086     FETCH c_get_total_hours_op INTO l_total_hours;
1087     CLOSE c_get_total_hours_op;
1088   END IF;
1089 
1090   RETURN round(l_total_hours,3);
1091 
1092 END Get_Op_TotalHours_Assigned;
1093 -----------------------------------------------------------------------------------------
1094 
1095 -- Start of Comments --
1096 --  Function name : Get_Res_TotalHours_Assigned
1097 --
1098 --  Parameters  :
1099 --
1100 --                  p_employee_id    --  Optional Input Employee Id.
1101 --                  p_workorder_id   --  Mandatory Workorder ID.
1102 --                  p_operation_seq_num -- Mandatory Operation Seq Number
1103 --                  p_resource_id       -- Mandatory resource ID.
1104 --                  p_fnd_function_name   -- Mandatory fnd_function to identify User role.
1105 --
1106 --
1107 --  Description   : This function returns the total hours assigned for a specific resource
1108 --                  within an operation. If the employee id passed to the function is null,
1109 --                  then the calculations are done for the user who is currently logged
1110 --                  into the application.
1111 
1112 FUNCTION Get_Res_TotalHours_Assigned (p_employee_id       IN NUMBER := NULL,
1113                                       p_workorder_id      IN NUMBER,
1114                                       p_operation_seq_num IN NUMBER,
1115                                       p_resource_id       IN NUMBER,
1116                                       p_fnd_function_name IN VARCHAR2)
1117 RETURN NUMBER
1118 IS
1119   -- query to retrieve total hrs assigned to an employee for an operation-resource.
1120   CURSOR c_get_total_hours_emp(p_employee_id IN NUMBER,
1121                                p_workorder_id IN NUMBER,
1122                                p_operation_seq_num IN NUMBER,
1123                                p_resource_id       IN NUMBER) IS
1124     SELECT SUM((AWAS.assign_end_date - AWAS.assign_start_date) * 24)
1125     FROM AHL_WORKORDER_OPERATIONS WO, AHL_OPERATION_RESOURCES AOR,
1126          AHL_WORK_ASSIGNMENTS AWAS, BOM_RESOURCES BOM
1127     WHERE WO.workorder_operation_id = AOR.workorder_operation_id
1128       AND AOR.operation_resource_id = AWAS.operation_resource_id
1129       AND BOM.resource_id = AOR.resource_id
1130       AND BOM.resource_type = 2  -- Person
1131       AND WO.workorder_id = p_workorder_id
1132       AND WO.operation_sequence_num = p_operation_seq_num
1133       AND AOR.resource_id = p_resource_id
1134       AND AWAS.employee_id = p_employee_id;
1135 
1136   -- query to retrieve total hrs assigned to all employees for an operation-resource.
1137   CURSOR c_get_total_hours_op(p_workorder_id IN NUMBER,
1138                               p_operation_seq_num IN NUMBER,
1139                               p_resource_id       IN NUMBER) IS
1140     SELECT SUM((AWAS.assign_end_date - AWAS.assign_start_date) * 24)
1141     FROM AHL_WORKORDER_OPERATIONS WO, AHL_OPERATION_RESOURCES AOR,
1142          AHL_WORK_ASSIGNMENTS AWAS, BOM_RESOURCES BOM
1143     WHERE WO.workorder_operation_id = AOR.workorder_operation_id
1144       AND AOR.operation_resource_id = AWAS.operation_resource_id
1145       AND BOM.resource_id = AOR.resource_id
1146       AND BOM.resource_type = 2  -- Person
1147       AND WO.workorder_id = p_workorder_id
1148       AND WO.operation_sequence_num = p_operation_seq_num
1149       AND AOR.resource_id = p_resource_id;
1150 
1151   l_total_hours  NUMBER;
1152   l_employee_id  NUMBER;
1153 
1154 BEGIN
1155 
1156   l_total_hours := 0;
1157   IF (p_fnd_function_name = G_TECH_MYWO) THEN  -- Technician.
1158       -- Get logged in user's emp ID if input employee ID is null.
1159       IF (p_employee_id IS NULL) THEN
1160          l_employee_id := AHL_PRD_WO_LOGIN_PVT.Get_Employee_ID;
1161       ELSE
1162          l_employee_id := p_employee_id;
1163     END IF;
1164 
1165     -- get total hrs.
1166     OPEN c_get_total_hours_emp(l_employee_id, p_workorder_id, p_operation_seq_num,
1167                                p_resource_id);
1168     FETCH c_get_total_hours_emp INTO l_total_hours;
1169     CLOSE c_get_total_hours_emp;
1170   ELSE
1171     -- Data Clerk, Transit.
1172     OPEN c_get_total_hours_op(p_workorder_id, p_operation_seq_num, p_resource_id);
1173     FETCH c_get_total_hours_op INTO l_total_hours;
1174     CLOSE c_get_total_hours_op;
1175   END IF;
1176 
1177   RETURN round(l_total_hours,3);
1178 
1179 END Get_Res_TotalHours_Assigned;
1180 -----------------------------------------------------------------------------------------
1181 
1182 -- Start of Comments --
1183 --  Function name : Get_Op_Transacted_Hours
1184 --
1185 --  Parameters  :
1186 --                  p_employee_id    --  Optional Input Employee Id.
1187 --                  p_wip_entity_id   --  Mandatory Workorder ID.
1188 --                  p_operation_seq_num -- Mandatory Operation Seq Number
1189 --                  p_fnd_function_name   -- Mandatory fnd_function to identify User role.
1190 --
1191 --  Description   : This function returns the number of hours transacted by an employee
1192 --                  accross all resources within an operation. If the employee id passed to the
1193 --                  function is null then the calculations are based on the user currently logged
1194 --                  into the application.
1195 
1196 FUNCTION Get_Op_Transacted_Hours (p_employee_id       IN NUMBER := NULL,
1197                                   p_wip_entity_id     IN NUMBER,
1198                                   p_operation_seq_num IN NUMBER,
1199                                   p_fnd_function_name IN VARCHAR2)
1200 RETURN NUMBER
1201 IS
1202   -- query to retrieve total hrs transacted by an employee.
1203   CURSOR c_get_res_txns_emp(p_wip_entity_id     IN NUMBER,
1204                             p_operation_seq_num IN NUMBER,
1205                             p_employee_id       IN NUMBER ) IS
1206     SELECT   NVL( SUM( transaction_quantity ), 0 )
1207       FROM    WIP_TRANSACTIONS WT, BOM_RESOURCES BRS
1208       WHERE   WT.resource_id = BRS.resource_id
1209         AND   BRS.resource_type = 2  -- person.
1210         AND   wt.wip_entity_id = p_wip_entity_id
1211         AND   wt.operation_seq_num = p_operation_seq_num
1212         AND   wt.employee_id = p_employee_id;
1213 
1214   -- query to get pending resource txns for an employee.
1215   CURSOR c_get_pend_res_txns_emp(p_wip_entity_id NUMBER,
1216                                  p_operation_seq_num NUMBER,
1217                                  p_employee_id NUMBER ) IS
1218     SELECT NVL( SUM( transaction_quantity ), 0 )
1219     FROM   WIP_COST_TXN_INTERFACE wcti, bom_resources br, wip_operation_resources wor
1220     WHERE  wcti.wip_entity_id = wor.wip_entity_id
1221       AND  wcti.operation_seq_num = wor.operation_seq_num
1222       AND  wcti.resource_seq_num = wor.resource_seq_num
1223       AND  wcti.organization_id = wor.organization_id
1224       AND  wor.resource_id = br.resource_id
1225       AND  br.resource_type = 2
1226       AND  wcti.wip_entity_id = p_wip_entity_id
1227       AND  wcti.operation_seq_num = p_operation_seq_num
1228       AND  wcti.employee_id = p_employee_id
1229       AND  wcti.process_status <> 3; -- skip errored txns.
1230 
1231   -- query to retrieve total hrs transacted by all employees.
1232   CURSOR c_get_res_txns_op(p_wip_entity_id     IN NUMBER,
1233                            p_operation_seq_num IN NUMBER) IS
1234     SELECT   NVL( SUM( transaction_quantity ), 0 )
1235       FROM   WIP_TRANSACTIONS WT, BOM_RESOURCES BRS
1236       WHERE  WT.resource_id = BRS.resource_id
1237         AND  BRS.resource_type = 2  -- person.
1238         AND  WT.wip_entity_id = p_wip_entity_id
1239         AND  WT.operation_seq_num = p_operation_seq_num;
1240 
1241   -- query to get pending resource txns for all employees.
1242   CURSOR c_get_pend_res_txns_op(p_wip_entity_id NUMBER,
1243                                 p_operation_seq_num NUMBER) IS
1244 		-- Here we cannot join with wcti.resource_id column
1245 		-- since this col can be null.
1246     SELECT NVL( SUM( transaction_quantity ), 0 )
1247     FROM   WIP_COST_TXN_INTERFACE wcti, bom_resources br, wip_operation_resources wor
1248     WHERE  wcti.wip_entity_id = wor.wip_entity_id
1249       AND  wcti.operation_seq_num = wor.operation_seq_num
1250       AND  wcti.resource_seq_num = wor.resource_seq_num
1251       AND  wcti.organization_id = wor.organization_id
1252       AND  wor.resource_id = br.resource_id
1253       AND  br.resource_type = 2
1254       AND  wcti.wip_entity_id = p_wip_entity_id
1255       AND  wcti.operation_seq_num = p_operation_seq_num
1256       AND  wcti.process_status <> 3; -- skip errored txns.
1257 
1258   l_total_hrs  NUMBER;
1259   l_pending_hrs  NUMBER;
1260   l_employee_id  NUMBER;
1261 
1262 BEGIN
1263 
1264   l_total_hrs := 0;
1265   l_pending_hrs := 0;
1266     IF (p_fnd_function_name = G_TECH_MYWO OR p_fnd_function_name = G_LINE_TECH) THEN
1267 
1268     -- Get logged in user's emp ID if input employee ID is null.
1269     IF (p_employee_id IS NULL) THEN
1270        l_employee_id := AHL_PRD_WO_LOGIN_PVT.Get_Employee_ID;
1271     ELSE
1272        l_employee_id := p_employee_id;
1273     END IF;
1274     -- get emp txns for an wo-oper.
1275     OPEN c_get_res_txns_emp(p_wip_entity_id, p_operation_seq_num, l_employee_id);
1276     FETCH c_get_res_txns_emp INTO l_total_hrs;
1277     CLOSE c_get_res_txns_emp;
1278     -- get pending txns.
1279     OPEN c_get_pend_res_txns_emp(p_wip_entity_id, p_operation_seq_num, l_employee_id);
1280     FETCH c_get_pend_res_txns_emp INTO l_pending_hrs;
1281     CLOSE c_get_pend_res_txns_emp;
1282     l_total_hrs := l_total_hrs + l_pending_hrs;
1283 
1284   ELSE -- Data Clerk
1285 
1286     -- get operation txns.
1287       OPEN c_get_res_txns_op(p_wip_entity_id, p_operation_seq_num);
1288       FETCH c_get_res_txns_op INTO l_total_hrs;
1289       CLOSE c_get_res_txns_op;
1290 
1291       -- get pending txns.
1292       OPEN c_get_pend_res_txns_op(p_wip_entity_id, p_operation_seq_num);
1293       FETCH c_get_pend_res_txns_op INTO  l_pending_hrs;
1294       CLOSE c_get_pend_res_txns_op;
1295 
1296     l_total_hrs := l_total_hrs + l_pending_hrs;
1297   END IF;  -- p_fnd_function_name.
1298 
1299   RETURN round(l_total_hrs,3);
1300 
1301 END Get_Op_Transacted_Hours;
1302 -----------------------------------------------------------------------------------------
1303 
1304 -- Start of Comments --
1305 --  Function name : Get_Res_Transacted_Hours
1306 --
1307 --  Parameters  :
1308 --                  p_employee_id    --  Optional Input Employee Id.
1309 --                  p_wip_entity_id   --  Mandatory Workorder ID.
1310 --                  p_operation_seq_num -- Mandatory Operation Seq Number
1311 --                  p_resource_seq_num  -- Mandatory Resource ID.
1312 --                  p_fnd_function_name  -- Mandatory fnd_function to identify user role.
1313 --
1314 --  Description   : This function returns the number of hours transacted by an employee
1315 --                  for a particular resource requirement within an operation if the user is
1316 --                  has a role of a technician or line maintenance technician. It returns the
1317 --                  number of hours transacted by all employees for a resource requirement
1318 --                  within an operation if the user is a data clerk.
1319 --
1320 
1321 FUNCTION Get_Res_Transacted_Hours (p_employee_id      IN NUMBER := NULL,
1322                                    p_wip_entity_id     IN NUMBER,
1323                                    p_operation_seq_num IN NUMBER,
1324                                    p_resource_seq_num  IN NUMBER,
1325                                    p_fnd_function_name IN VARCHAR2)
1326 RETURN NUMBER
1327 IS
1328   -- query to retrieve total hrs transacted by an employee.
1329   CURSOR c_get_res_txns_emp(p_wip_entity_id     IN NUMBER,
1330                             p_operation_seq_num IN NUMBER,
1331                             p_resource_seq_num  IN NUMBER,
1332                             p_employee_id       IN NUMBER ) IS
1333     SELECT   NVL( SUM( transaction_quantity ), 0 )
1334       FROM    WIP_TRANSACTIONS WT, BOM_RESOURCES BRS
1335       WHERE   WT.resource_id = BRS.resource_id
1336         AND   BRS.resource_type = 2  -- person.
1337         AND   WT.transaction_type = 1 -- resource txn.
1338         AND   wt.wip_entity_id = p_wip_entity_id
1339         AND   wt.operation_seq_num = p_operation_seq_num
1340         AND   wt.resource_seq_num = p_resource_seq_num
1341         AND   wt.employee_id = p_employee_id;
1342 
1343   -- query to get pending resource txns for an employee.
1344   CURSOR c_get_pend_res_txns_emp(p_wip_entity_id NUMBER,
1345                                  p_operation_seq_num NUMBER,
1346                                  p_resource_seq_num  IN NUMBER,
1347                                  p_employee_id NUMBER ) IS
1348     SELECT NVL( SUM( transaction_quantity ), 0 )
1349     FROM   WIP_COST_TXN_INTERFACE wcti, bom_resources br,
1350            wip_operation_resources wor
1351     WHERE  wcti.wip_entity_id = wor.wip_entity_id
1352       AND  wcti.operation_seq_num = wor.operation_seq_num
1353       AND  wcti.resource_seq_num = wor.resource_seq_num
1354       AND  wcti.organization_id = wor.organization_id
1355       AND  wor.resource_id = br.resource_id
1356       AND  br.resource_type = 2  -- person
1357       AND  wcti.transaction_type = 1  -- resource txn.
1358       AND  wcti.wip_entity_id = p_wip_entity_id
1359       AND  wcti.operation_seq_num = p_operation_seq_num
1360       AND  wcti.resource_seq_num = p_resource_seq_num
1361       AND  wcti.employee_id = p_employee_id
1362       AND  wcti.process_status <> 3; -- skip errored txns.
1363 
1364   -- query to retrieve total hrs transacted by all employees.
1365   CURSOR c_get_res_txns_res(p_wip_entity_id     IN NUMBER,
1366                             p_operation_seq_num IN NUMBER,
1367                             p_resource_seq_num  IN NUMBER) IS
1368     SELECT   NVL( SUM( transaction_quantity ), 0 )
1369       FROM    WIP_TRANSACTIONS WT, BOM_RESOURCES BRS
1370       WHERE   WT.resource_id = BRS.resource_id
1371         AND   BRS.resource_type = 2  -- person.
1372         AND   WT.transaction_type = 1 -- resource txn.
1373         AND   wt.wip_entity_id = p_wip_entity_id
1374         AND   wt.operation_seq_num = p_operation_seq_num
1375         AND   wt.resource_seq_num = p_resource_seq_num;
1376 
1377   -- query to get pending resource txns for all employees.
1378   -- Here we cannot join with wcti.resource_id column
1379   -- since this col maybe null
1380   CURSOR c_get_pend_res_txns_res(p_wip_entity_id IN NUMBER,
1381                                  p_operation_seq_num IN NUMBER,
1382                                  p_resource_seq_num  IN NUMBER) IS
1383     SELECT NVL( SUM( transaction_quantity ), 0 )
1384     FROM   WIP_COST_TXN_INTERFACE wcti, bom_resources br,
1385            wip_operation_resources wor
1386     WHERE  wcti.wip_entity_id = wor.wip_entity_id
1387       AND  wcti.operation_seq_num = wor.operation_seq_num
1388       AND  wcti.resource_seq_num = wor.resource_seq_num
1389       AND  wcti.organization_id = wor.organization_id
1390       AND  wor.resource_id = br.resource_id
1391       AND  br.resource_type = 2  -- person
1392       AND  wcti.transaction_type = 1  -- resource txn.
1393       AND  wcti.wip_entity_id = p_wip_entity_id
1394       AND  wcti.operation_seq_num = p_operation_seq_num
1395       AND  wcti.resource_seq_num = p_resource_seq_num
1396       AND  wcti.process_status <> 3; -- skip errored txns.
1397 
1398   l_total_hrs    NUMBER;
1399   l_pending_hrs  NUMBER;
1400   l_employee_id  NUMBER;
1401   l_fnd_function_name VARCHAR2(80);
1402 
1403 BEGIN
1404 
1405   l_total_hrs := 0;
1406   l_pending_hrs := 0;
1407 
1408   -- Though p_fnd_function_name is mandatory it cannot be passed from the OA Tech Search UI
1409   -- due to the limitation with OA inner table. Hence putting the code here.
1410   l_fnd_function_name := p_fnd_function_name;
1411   IF (l_fnd_function_name IS NULL) THEN
1412   	l_fnd_function_name := AHL_PRD_WO_LOGIN_PVT.Get_User_Role;
1413   END IF;
1414 
1415   -- Technician or Transit Technician
1416   IF (l_fnd_function_name = G_TECH_MYWO OR l_fnd_function_name = G_LINE_TECH) THEN
1417 
1418     -- Get logged in user's emp ID if input employee ID is null.
1419     IF (p_employee_id IS NULL) THEN
1420        l_employee_id := AHL_PRD_WO_LOGIN_PVT.Get_Employee_ID;
1421     ELSE
1422        l_employee_id := p_employee_id;
1423     END IF;
1424 
1425     -- get emp txns for an wo-oper.
1426     OPEN c_get_res_txns_emp(p_wip_entity_id, p_operation_seq_num, p_resource_seq_num,l_employee_id);
1427     FETCH c_get_res_txns_emp INTO l_total_hrs;
1428     CLOSE c_get_res_txns_emp;
1429 
1430     -- get pending txns.
1431     OPEN c_get_pend_res_txns_emp(p_wip_entity_id, p_operation_seq_num, p_resource_seq_num,l_employee_id);
1432     FETCH c_get_pend_res_txns_emp INTO l_pending_hrs;
1433     CLOSE c_get_pend_res_txns_emp;
1434 
1435     l_total_hrs := l_total_hrs + l_pending_hrs;
1436 
1437   ELSE -- Data Clerk
1438       -- get operation txns.
1439       OPEN c_get_res_txns_res(p_wip_entity_id, p_operation_seq_num, p_resource_seq_num);
1440       FETCH c_get_res_txns_res INTO l_total_hrs;
1441       CLOSE c_get_res_txns_res;
1442 
1443       -- get pending txns.
1444       OPEN c_get_pend_res_txns_res(p_wip_entity_id, p_operation_seq_num, p_resource_seq_num);
1445       FETCH c_get_pend_res_txns_res INTO  l_pending_hrs;
1446       CLOSE c_get_pend_res_txns_res;
1447 
1448     l_total_hrs := l_total_hrs + l_pending_hrs;
1449   END IF;  -- p_fnd_function_name.
1450 
1451   RETURN round(l_total_hrs,3);
1452 
1453 END Get_Res_Transacted_Hours;
1454 -----------------------------------------------------------------------------------------
1455 
1456 -- Start of Comments --
1457 --  Function name : Get_Op_Assigned_Start_Date
1458 --
1459 --  Parameters  :
1460 --
1461 --                  p_employee_id    --  Optional Input Employee Id.
1462 --                  p_workorder_id   --  Mandatory Workorder ID.
1463 --                  p_operation_seq_num -- Mandatory Operation Seq Number
1464 --                  p_fnd_function_name   -- Mandatory fnd_function to identify User role.
1465 --
1466 --
1467 --  Description   : This function will be used to retrieve the Assigned Start Date for an
1468 --                  operation as displayed on the Operations subtab of the Update Workorders
1469 --                  page. The logic for retrieving the correct date is as follows:
1470 --                      1. If the user is a technician, then assigned start time is the
1471 --                         assign_start_date for the employee if he is assigned to only
1472 --                         one resource within the operation.
1473 --                         If the employee is assigned to more than one resource within
1474 --                         the operation, then the assigned start date is the earliest
1475 --                         of all the assignment dates for the employee.
1476 ---2.	If the user is a data clerk or a line maintenance technician, then the assigned
1477 ---        start date is the scheduled start date for the operation.
1478 
1479 --
1480 
1481 FUNCTION Get_Op_Assigned_Start_Date(p_employee_id       IN NUMBER := NULL,
1482                                     p_workorder_id      IN NUMBER,
1483                                     p_operation_seq_num IN NUMBER,
1484                                     p_fnd_function_name IN VARCHAR2)
1485 RETURN DATE
1486 
1487 IS
1488 
1489   -- query to retrieve min of assigned to an employee for an operation.
1490   CURSOR c_get_assigned_start_emp(p_employee_id IN NUMBER,
1491                                   p_workorder_id IN NUMBER,
1492                                   p_operation_seq_num IN NUMBER) IS
1493     SELECT MIN(AWAS.ASSIGN_START_DATE)
1494     FROM WIP_Operation_Resources WOR, AHL_OPERATION_RESOURCES AOR,
1495          AHL_WORK_ASSIGNMENTS AWAS, AHL_WORKORDERS AW
1496     WHERE WOR.resource_id = AOR.resource_id
1497       AND WOR.RESOURCE_SEQ_NUM = AOR.RESOURCE_SEQUENCE_NUM
1498       AND AOR.operation_resource_id = AWAS.operation_resource_id
1499       AND WOR.wip_entity_id = AW.wip_entity_id
1500       AND AWAS.employee_id = p_employee_id
1501       AND AW.workorder_id = p_workorder_id
1502       AND WOR.operation_seq_num = p_operation_seq_num;
1503 
1504   -- query to retrieve min of assigned to all employees for an operation.
1505   CURSOR c_get_op_sched_start(p_workorder_id IN NUMBER,
1506                               p_operation_seq_num IN NUMBER) IS
1507     SELECT SCHEDULED_START_DATE
1508     FROM AHL_WORKORDER_OPERATIONS_V  AO
1509     WHERE AO.workorder_id = p_workorder_id
1510       AND AO.operation_sequence_num = p_operation_seq_num;
1511 
1512   l_employee_id  NUMBER;
1513   l_assigned_start  DATE;
1514 
1515 BEGIN
1516 
1517   IF (p_fnd_function_name = G_TECH_MYWO) THEN  -- Technician.
1518     -- Get logged in user's emp ID if input employee ID is null.
1519     IF (p_employee_id IS NULL) THEN
1520        l_employee_id := AHL_PRD_WO_LOGIN_PVT.Get_Employee_ID;
1521     ELSE
1522        l_employee_id := p_employee_id;
1523     END IF;
1524 
1525     -- get assigned start.
1526     OPEN c_get_assigned_start_emp(l_employee_id, p_workorder_id, p_operation_seq_num);
1527     FETCH c_get_assigned_start_emp INTO l_assigned_start;
1528     CLOSE c_get_assigned_start_emp;
1529   ELSE    -- Data Clerk, Transit role.
1530     OPEN c_get_op_sched_start(p_workorder_id, p_operation_seq_num);
1531     FETCH c_get_op_sched_start INTO l_assigned_start;
1532     CLOSE c_get_op_sched_start;
1533   END IF;
1534 
1535   RETURN l_assigned_start;
1536 
1537 END Get_Op_Assigned_Start_Date;
1538 -----------------------------------------------------------------------------------------
1539 
1540 -- Start of Comments --
1541 --  Function name : Get_Op_Assigned_End_Date
1542 --
1543 --  Parameters  :
1544 --
1545 --                  p_employee_id    --  Optional Input Employee Id.
1546 --                  p_workorder_id   --  Mandatory Workorder ID.
1547 --                  p_operation_seq_num -- Mandatory Operation Seq Number
1548 --                  p_fnd_function_name   -- Mandatory fnd_function to identify User role.
1549 --
1550 --
1551 --  Description   : This function will be used to retrieve the Assigned End Date for an
1552 --                  operation as displayed on the Operations subtab of the Update Workorders
1553 --                  page. The logic for retrieving the correct date is as follows:
1554 --                      1. If the user is a technician, then assigned end time is the
1555 --                         assign_end_date for the employee if he is assigned to only
1556 --                         one resource within the operation.
1557 --                         If the employee is assigned to more than one resource within
1558 --                         the operation, then the assigned end date is the latest
1559 --                         of all the assignment dates for the employee.
1560 ---                     2. If the user is a data clerk or a line maintenance technician, then
1561 --                         the assigned end date is the scheduled start date for the operation.
1562 --
1563 
1564 FUNCTION Get_Op_Assigned_End_Date(p_employee_id       IN NUMBER := NULL,
1565                                   p_workorder_id      IN NUMBER,
1566                                   p_operation_seq_num IN NUMBER,
1567                                   p_fnd_function_name IN VARCHAR2)
1568 RETURN DATE
1569 
1570 IS
1571 
1572   -- query to retrieve min of assigned to an employee for an operation.
1573   CURSOR c_get_assigned_end_emp(p_employee_id IN NUMBER,
1574                                 p_workorder_id IN NUMBER,
1575                                 p_operation_seq_num IN NUMBER) IS
1576     SELECT MAX(AWAS.ASSIGN_END_DATE)
1577     FROM WIP_Operation_Resources WOR, AHL_OPERATION_RESOURCES AOR,
1578          AHL_WORK_ASSIGNMENTS AWAS, AHL_WORKORDERS AW
1579     WHERE WOR.resource_id = AOR.resource_id
1580       AND WOR.RESOURCE_SEQ_NUM = AOR.RESOURCE_SEQUENCE_NUM
1581       AND AOR.operation_resource_id = AWAS.operation_resource_id
1582       AND WOR.wip_entity_id = AW.wip_entity_id
1583       AND AWAS.employee_id = p_employee_id
1584       AND AW.workorder_id = p_workorder_id
1585       AND WOR.operation_seq_num = p_operation_seq_num;
1586 
1587   -- query to retrieve min of assigned to all employees for an operation.
1588   CURSOR c_get_op_sched_end(p_workorder_id IN NUMBER,
1589                             p_operation_seq_num IN NUMBER) IS
1590     SELECT SCHEDULED_END_DATE
1591     FROM AHL_WORKORDER_OPERATIONS_V  AO
1592     WHERE AO.workorder_id = p_workorder_id
1593       AND AO.operation_sequence_num = p_operation_seq_num;
1594 
1595   l_employee_id  NUMBER;
1596   l_assigned_end  DATE;
1597 
1598 BEGIN
1599 
1600   IF (p_fnd_function_name = G_TECH_MYWO) THEN  -- Technician.
1601     -- Get logged in user's emp ID if input employee ID is null.
1602     IF (p_employee_id IS NULL) THEN
1603        l_employee_id := AHL_PRD_WO_LOGIN_PVT.Get_Employee_ID;
1604     ELSE
1605        l_employee_id := p_employee_id;
1606     END IF;
1607 
1608     -- get assigned start.
1609     OPEN c_get_assigned_end_emp(l_employee_id, p_workorder_id, p_operation_seq_num);
1610     FETCH c_get_assigned_end_emp INTO l_assigned_end;
1611     CLOSE c_get_assigned_end_emp;
1612   ELSE    -- Data Clerk, Transit role.
1613     OPEN c_get_op_sched_end(p_workorder_id, p_operation_seq_num);
1614     FETCH c_get_op_sched_end INTO l_assigned_end;
1615     CLOSE c_get_op_sched_end;
1616   END IF;
1617 
1618   RETURN l_assigned_end;
1619 
1620 END Get_Op_Assigned_End_Date;
1621 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1622 
1623 END AHL_PRD_UTIL_PKG; -- Package Body AHL_PRD_UTIL_PKG