1 PACKAGE BODY EAM_WORKORDER_UTIL_PKG as
2 /* $Header: EAMWOUTB.pls 120.24.12020000.3 2012/11/06 14:17:47 vpasupur ship $ */
3 g_supply_type VARCHAR2(30) := EAM_CONSTANTS.G_SUPPLY_TYPE;
4
5 PROCEDURE retrieve_asset_bom(
6 i_organization_id IN NUMBER,
7 i_asset_number IN VARCHAR2,
8 i_asset_group_id IN NUMBER,
9 p_context IN VARCHAR2, -- stocked inventory or non-stocked inventory
10 o_bom_table OUT NOCOPY t_bom_table,
11 o_error_code OUT NOCOPY NUMBER) IS
12
13 l_index NUMBER;
14 l_index1 NUMBER;
15 l_bill_sequence_id NUMBER;
16 l_phantom_bom t_bom_table;
17
18 CURSOR components(l_stock_flag VARCHAR2) IS
19 select bic.component_sequence_id,
20 bic.component_item_id,
21 msik.concatenated_segments component_item,
22 msik.description,
23 bic.component_quantity,
24 bic.component_yield_factor component_yield,
25 msik.primary_uom_code uom,
26 bic.wip_supply_type,
27 lu.meaning wip_supply_type_disp
28 from bom_inventory_components bic,
29 mtl_system_items_kfv msik,
30 mfg_lookups lu
31 where bic.bill_sequence_id = l_bill_sequence_id
32 and bic.effectivity_date <= sysdate
33 and (bic.disable_date >= sysdate or
34 bic.disable_date is null)
35 and i_asset_number >= bic.from_end_item_unit_number
36 and (i_asset_number <= bic.to_end_item_unit_number or
37 bic.to_end_item_unit_number is null)
38 and msik.organization_id = i_organization_id
39 and msik.inventory_item_id = bic.component_item_id
40 and lu.lookup_type(+) = g_supply_type
41 and lu.lookup_code(+) = bic.wip_supply_type
42 --fix for 3371471.added following condition to fetch only stockable items
43 and msik.stock_enabled_flag= l_stock_flag
44 order by component_sequence_id;
45
46 /* Bug#3013574: If it is for rebuildable item
47 then the no check on BOM_INVENTORY_COMPONENTS.from_end_item_unit_number
48 and BOM_INVENTORY_COMPONENTS.to_end_item_unit_number is required */
49
50 CURSOR C_REBUILD_COMPONENTS( l_stock_flag VARCHAR2) IS
51 SELECT
52 bic.component_sequence_id,
53 bic.component_item_id,
54 msik.concatenated_segments component_item,
55 msik.description,
56 bic.component_quantity,
57 bic.component_yield_factor component_yield,
58 msik.primary_uom_code uom,
59 bic.wip_supply_type,
60 lu.meaning wip_supply_type_disp
61 FROM
62 bom_inventory_components bic,
63 mtl_system_items_kfv msik,
64 mfg_lookups lu
65 WHERE
66 bic.bill_sequence_id = l_bill_sequence_id
67 and bic.effectivity_date <= sysdate
68 and (bic.disable_date >= sysdate or
69 bic.disable_date is null)
70 and msik.organization_id = i_organization_id
71 and msik.inventory_item_id = bic.component_item_id
72 and lu.lookup_type(+) = g_supply_type
73 and lu.lookup_code(+) = bic.wip_supply_type
74 --fix for 3371471.added following condition to fetch only stockable items
75 and msik.stock_enabled_flag= l_stock_flag
76 ORDER BY component_sequence_id;
77
78 l_record components%ROWTYPE;
79
80 /* BUG#3013574 */
81 l_eam_item_type NUMBER;
82 l_record_rebuild C_REBUILD_COMPONENTS%ROWTYPE;
83 l_stock_enabled_flag VARCHAR2(1) ;
84
85 PROCEDURE explode_phantom_bom(
86 i_phantom_item_id IN NUMBER,
87 i_phantom_quantity IN NUMBER,
88 i_phantom_yield IN NUMBER,
89 o_phantom_bom OUT NOCOPY t_bom_table) IS
90 CURSOR phantom_comp IS
91 select bic.component_sequence_id,
92 bic.component_item_id,
93 msik.concatenated_segments component_item,
94 msik.description,
95 bic.component_quantity,
96 bic.component_yield_factor component_yield,
97 msik.primary_uom_code uom,
98 bic.wip_supply_type,
99 lu.meaning wip_supply_type_disp
100 from bom_inventory_components bic,
101 bom_bill_of_materials bbom,
102 mtl_system_items_kfv msik,
103 mfg_lookups lu
104 where bbom.assembly_item_id = i_phantom_item_id
105 and bbom.organization_id = i_organization_id
106 and bbom.alternate_bom_designator is null
107 and bic.bill_sequence_id = bbom.common_bill_sequence_id
108 and bic.effectivity_date <= sysdate
109 and (bic.disable_date >= sysdate or
110 bic.disable_date is null)
111 and i_asset_number >= bic.from_end_item_unit_number
112 and (i_asset_number <= bic.to_end_item_unit_number or
113 bic.to_end_item_unit_number is null)
114 and msik.organization_id = i_organization_id
115 and msik.inventory_item_id = bic.component_item_id
116 and lu.lookup_type(+) = g_supply_type
117 and lu.lookup_code(+) = bic.wip_supply_type
118 order by component_sequence_id;
119
120
121 BEGIN
122 -- Clear
123 l_phantom_bom.delete;
124 -- Select
125 /****************************************
126 * UNFINISHED!!!! *
127 ****************************************/
128 /*** We don't need phantom actually ***/
129
130
131 END explode_phantom_bom;
132
133
134 BEGIN
135 -- Clear
136 o_bom_table.delete;
137 -- Get the Bill-Sequence
138 begin
139 select common_bill_sequence_id
140 into l_bill_sequence_id
141 from bom_bill_of_materials
142 where organization_id = i_organization_id
143 and assembly_item_id = i_asset_group_id
144 and alternate_bom_designator is null;
145 exception
146 when NO_DATA_FOUND then /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
147 return;
148 end;
149
150 IF ( p_context = 'REQUIREMENTS') THEN
151 l_stock_enabled_flag := 'Y' ;
152 ELSIF ( p_context = 'DIRECT_ITEMS') THEN
153 l_stock_enabled_flag := 'N' ;
154 END IF ;
155
156 -- Retrieve the Asset BOM
157 l_index := 0;
158
159 /* Bug#3013574: Fetch rebuild/Asset BOM depending upon the type of workorder
160 for which it is being summoned. */
161 SELECT
162 NVL(msi.eam_item_type,-1) INTO l_eam_item_type
163 FROM
164 mtl_system_items_b msi
165 WHERE
166 msi.inventory_item_id = i_asset_group_id
167 and organization_id = i_organization_id;
168
169 /* Bug#3013574: If the i_asset_group_id being passed corresponds to Asset Group
170 continue doing the work as is being done. If it is for rebuildable item
171 then the no check on BOM_INVENTORY_COMPONENTS.from_end_item_unit_number
172 and BOM_INVENTORY_COMPONENTS.to_end_item_unit_number is required */
173
174 IF (l_eam_item_type = 1) THEN
175 OPEN components( l_stock_enabled_flag );
176 LOOP
177 fetch components into l_record;
178 exit when components%notfound;
179 if l_record.wip_supply_type = 6 then -- phantom
180 null;
181 else
182 o_bom_table(l_index).component_sequence_id := l_record.component_sequence_id;
183 o_bom_table(l_index).component_item_id := l_record.component_item_id;
184 o_bom_table(l_index).component_item := l_record.component_item;
185 o_bom_table(l_index).description := l_record.description;
186 o_bom_table(l_index).component_quantity := l_record.component_quantity;
187 o_bom_table(l_index).component_yield := l_record.component_yield;
188 o_bom_table(l_index).uom := l_record.uom;
189 o_bom_table(l_index).wip_supply_type := l_record.wip_supply_type;
190 o_bom_table(l_index).wip_supply_type_disp := l_record.wip_supply_type_disp;
191 l_index := l_index+1;
192 end if;
193 END LOOP;
194 CLOSE components;
195 ELSIF (l_eam_item_type = 3) THEN
196 OPEN C_REBUILD_COMPONENTS ( l_stock_enabled_flag );
197 LOOP
198 FETCH C_REBUILD_COMPONENTS INTO l_record_rebuild;
199 EXIT WHEN C_REBUILD_COMPONENTS%NOTFOUND;
200 IF l_record_rebuild.wip_supply_type = 6 THEN -- phantom
201 null;
202 ELSE
203 o_bom_table(l_index).component_sequence_id := l_record_rebuild.component_sequence_id;
204 o_bom_table(l_index).component_item_id := l_record_rebuild.component_item_id;
205 o_bom_table(l_index).component_item := l_record_rebuild.component_item;
206 o_bom_table(l_index).description := l_record_rebuild.description;
207 o_bom_table(l_index).component_quantity := l_record_rebuild.component_quantity;
208 o_bom_table(l_index).component_yield := l_record_rebuild.component_yield;
209 o_bom_table(l_index).uom := l_record_rebuild.uom;
210 o_bom_table(l_index).wip_supply_type := l_record_rebuild.wip_supply_type;
211 o_bom_table(l_index).wip_supply_type_disp := l_record_rebuild.wip_supply_type_disp;
212 l_index := l_index+1;
213 END IF;
214 END LOOP;
215 CLOSE C_REBUILD_COMPONENTS;
216 END IF;
217 END retrieve_asset_bom;
218
219
220 PROCEDURE copy_to_bom(
221 i_organization_id IN NUMBER,
222 i_organization_code IN VARCHAR2,
223 i_asset_number IN VARCHAR2,
224 i_asset_group_id IN NUMBER,
225 i_component_table IN t_component_table,
226 o_error_code OUT NOCOPY NUMBER) IS
227
228 -- PRAGMA AUTONOMOUS_TRANSACTION;
229
230 l_index1 NUMBER;
231 l_index2 NUMBER;
232
233 l_assembly_item_name VARCHAR2(81);
234
235 l_bom_header_rec BOM_BO_PUB.bom_head_rec_type;
236 l_bom_component_tbl BOM_BO_PUB.bom_comps_tbl_type;
237 o_bom_header_rec BOM_BO_PUB.bom_head_rec_type;
238 o_bom_revision_tbl BOM_BO_PUB.bom_revision_tbl_type;
239 o_bom_component_tbl BOM_BO_PUB.bom_comps_tbl_type;
240 o_bom_ref_designator_tbl BOM_BO_PUB.bom_ref_designator_tbl_type;
241 o_bom_sub_component_tbl BOM_BO_PUB.bom_sub_component_tbl_type;
242 o_return_status varchar2(100);
243 o_msg_count number;
244
245 l_error_msg Error_Handler.Error_tbl_type;
246 l_tmp number;
247 l_seq_increment NUMBER;
248 l_start_item_seq_number NUMBER;
249
250 -- Check whether the given component already in the bom of given assembly
251 FUNCTION comp_exists(i_organization_id IN NUMBER,
252 i_assembly_item_id IN NUMBER,
253 i_serial_number IN VARCHAR2,
254 i_component_item_id IN NUMBER)
255 RETURN BOOLEAN IS
256 l_component_item_id NUMBER;
257 BEGIN
258 select bic.component_item_id
259 into l_component_item_id
260 from bom_bill_of_materials bbom,
261 bom_inventory_components bic
262 where bbom.assembly_item_id = i_assembly_item_id
263 and bbom.organization_id = i_organization_id
264 and bbom.alternate_bom_designator is null
265 and bbom.common_bill_sequence_id = bic.bill_sequence_id
266 and bic.component_item_id = i_component_item_id
267 and bic.disable_date is null /*consider only enabled components, added for #6072910*/
268 and i_serial_number >= bic.from_end_item_unit_number
269 and (i_serial_number <= bic.to_end_item_unit_number or
270 bic.to_end_item_unit_number is null);
271 RETURN TRUE;
272 EXCEPTION
273 WHEN NO_DATA_FOUND THEN /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
274 RETURN FALSE;
275 END comp_exists;
276
277 -- Bug# 3844669 : Function to compute item sequence number
278 FUNCTION get_item_sequence_num(i_organization_id IN NUMBER,
279 i_assembly_item_id IN NUMBER)
280 RETURN NUMBER IS
281 l_bill_sequence_id NUMBER;
282 l_item_sequence_num NUMBER;
283 l_seq_increment NUMBER;
284 BEGIN
285 l_item_sequence_num := 100;
286
287 select common_bill_sequence_id
288 into l_bill_sequence_id
289 from bom_bill_of_materials
290 where organization_id = i_organization_id
291 and assembly_item_id = i_assembly_item_id
292 and alternate_bom_designator is null;
293
294 select nvl(max(item_num),100)
295 into l_item_sequence_num
296 from bom_inventory_components
297 where bill_sequence_id=l_bill_sequence_id;
298
299 l_seq_increment := to_number(nvl(fnd_profile.value('BOM:ITEM_SEQUENCE_INCREMENT'),'10'));
300 l_item_sequence_num := l_item_sequence_num + l_seq_increment;
301
302 RETURN l_item_sequence_num;
303 EXCEPTION
304 WHEN OTHERS THEN
305 RETURN l_item_sequence_num;
306 END get_item_sequence_num;
307
308 BEGIN
309 o_error_code := 0;
310 -- Return if no Components
311 if i_component_table.COUNT <= 0 then
312 RETURN;
313 end if;
314 -- Bug# 3844669 : Added code to compute current starting item sequence number in assembly item BOM.
315 l_start_item_seq_number := get_item_sequence_num(i_organization_id, i_asset_group_id);
316 l_seq_increment := to_number(nvl(fnd_profile.value('BOM:ITEM_SEQUENCE_INCREMENT'),'10'));
317 -- Construct the Components Table
318 l_index1 := i_component_table.FIRST;
319 l_index2 := 1;
320 select concatenated_segments
321 into l_assembly_item_name
322 from mtl_system_items_kfv
323 where organization_id = i_organization_id
324 and inventory_item_id = i_asset_group_id;
325 loop
326 if not comp_exists(i_organization_id, i_asset_group_id, i_asset_number,
327 i_component_table(l_index1).component_item_id) then
328 -- Add this Entry
329 -- Set the context
330 l_bom_component_tbl(l_index2).assembly_item_name := l_assembly_item_name;
331 l_bom_component_tbl(l_index2).organization_code := i_organization_code;
332 l_bom_component_tbl(l_index2).alternate_bom_code := null;
333 l_bom_component_tbl(l_index2).transaction_type := 'CREATE';
334 -- Copy the Data
335 l_bom_component_tbl(l_index2).component_item_name := i_component_table(l_index1).component_item;
336 l_bom_component_tbl(l_index2).start_effective_date := i_component_table(l_index1).start_effective_date;
337 l_bom_component_tbl(l_index2).quantity_per_assembly := i_component_table(l_index1).quantity_per_assembly;
338 l_bom_component_tbl(l_index2).wip_supply_type := i_component_table(l_index1).wip_supply_type;
339 l_bom_component_tbl(l_index2).supply_subinventory := i_component_table(l_index1).supply_subinventory;
340 l_bom_component_tbl(l_index2).location_name := i_component_table(l_index1).supply_locator_name;
341 l_bom_component_tbl(l_index2).from_end_item_unit_number := i_asset_number;
342 l_bom_component_tbl(l_index2).to_end_item_unit_number := i_asset_number;
343 -- Default In Required Fields. All hardcoded values are as per design. Pls refer to eTRM for object: BOM_INVENTORY_COMPONENTS to view description of below hardcoded columns.
344 l_bom_component_tbl(l_index2).operation_sequence_number := 1;
345 -- Modified for bug# 3844669.
346 l_bom_component_tbl(l_index2).item_sequence_number := l_start_item_seq_number + l_seq_increment*(l_index2 - 1);
347 l_bom_component_tbl(l_index2).projected_yield := 1;
348 l_bom_component_tbl(l_index2).planning_percent := 100;
349 l_bom_component_tbl(l_index2).quantity_related := 2;
350 l_bom_component_tbl(l_index2).include_in_cost_rollup := 1;
351 l_bom_component_tbl(l_index2).check_atp := 2;
352 l_bom_component_tbl(l_index2).so_basis := 2;
353 l_bom_component_tbl(l_index2).optional := 2;
354 l_bom_component_tbl(l_index2).mutually_exclusive := 2;
355 l_bom_component_tbl(l_index2).shipping_allowed := null;
356 l_bom_component_tbl(l_index2).required_to_ship := 2;
357 l_bom_component_tbl(l_index2).required_for_revenue := 2;
358 l_bom_component_tbl(l_index2).include_on_ship_docs := 2;
359 l_index2 := l_index2 + 1;
360 else
361 o_error_code := 1;
362 end if;
363 exit when l_index1 = i_component_table.LAST;
364 l_index1 := i_component_table.NEXT(l_index1);
365 end loop;
366
367 -- Construct header
368 l_bom_header_rec.organization_code := i_organization_code;
369 l_bom_header_rec.assembly_item_name := l_assembly_item_name;
370 l_bom_header_rec.alternate_bom_code := null;
371 l_bom_header_rec.transaction_type := 'SYNC';
372 l_bom_header_rec.assembly_type := 1;
373
374 -- Bug# 3844669: Initializes BOM Message List and associated variables.
375 Error_Handler.Initialize;
376
377 -- Call the BOM API
378 BOM_BO_PUB.Process_Bom(
379 p_bom_header_rec => l_bom_header_rec,
380 p_bom_component_tbl => l_bom_component_tbl,
381 x_bom_header_rec => o_bom_header_rec,
382 x_bom_revision_tbl => o_bom_revision_tbl,
383 x_bom_component_tbl => o_bom_component_tbl,
384 x_bom_ref_designator_tbl => o_bom_ref_designator_tbl,
385 x_bom_sub_component_tbl => o_bom_sub_component_tbl,
386 x_return_status => o_return_status,
387 x_msg_count => o_msg_count);
388
389 if o_return_status = 'S' then
390 commit;
391 else
392 rollback;
393 o_error_code := 2;
394 end if;
395 EXCEPTION
396 WHEN NO_DATA_FOUND THEN /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
397 o_error_code := 2;
398 END copy_to_bom;
399
400
401 PROCEDURE adjust_resources(i_wip_entity_id IN NUMBER) IS
402
403 CURSOR all_operations IS
404 select operation_seq_num
405 from wip_operations
406 where wip_entity_id = i_wip_entity_id;
407
408 l_wo_start_date DATE;
409 l_wo_completion_date DATE;
410 l_op_seq_num NUMBER;
411 l_op_start_date DATE;
412 l_op_completion_date DATE;
413
414 BEGIN
415 -- Update Operations
416 OPEN all_operations;
417 LOOP
418 -- Next Operation
419 FETCH all_operations INTO l_op_seq_num;
420 EXIT WHEN all_operations%NOTFOUND;
421 -- Check Resources
422 BEGIN
423 -- Get the New Date Range
424 select min(start_date), max(completion_date)
425 into l_op_start_date, l_op_completion_date
426 from wip_operation_resources
427 where wip_entity_id = i_wip_entity_id
428 and operation_seq_num = l_op_seq_num;
429 -- Update the Operation
430
431 if (l_op_start_date is not null) and (l_op_completion_date is not null) then -- Fix for operations with no resources
432 update wip_operations set
433 first_unit_start_date = l_op_start_date,
434 first_unit_completion_date = l_op_completion_date,
435 last_unit_start_date = l_op_start_date,
436 last_unit_completion_date = l_op_completion_date
437 where wip_entity_id = i_wip_entity_id
438 and operation_seq_num = l_op_seq_num;
439 end if;
440 EXCEPTION
441 WHEN NO_DATA_FOUND THEN /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
442 NULL;
443 END;
444 END LOOP;
445 CLOSE all_operations;
446 -- Update Work Order
447 BEGIN
448 select min(first_unit_start_date), max(last_unit_completion_date)
449 into l_wo_start_date, l_wo_completion_date
450 from wip_operations
451 where wip_entity_id = i_wip_entity_id;
452
453 if (l_wo_start_date is not null and l_wo_completion_date is not null) then
454 update wip_discrete_jobs set
455 scheduled_start_date = l_wo_start_date,
456 scheduled_completion_date = l_wo_completion_date
457 where wip_entity_id = i_wip_entity_id;
458 end if;
459 EXCEPTION
460 WHEN NO_DATA_FOUND THEN /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
461 NULL;
462 END;
463 END adjust_resources;
464
465
466 PROCEDURE adjust_operations(
467 i_wip_entity_id IN NUMBER,
468 i_operation_table IN t_optime_table) IS
469
470 CURSOR all_operations IS
471 select operation_seq_num
472 from wip_operations
473 where wip_entity_id = i_wip_entity_id;
474
475 l_index NUMBER;
476
477 l_wo_start_date DATE;
478 l_wo_completion_date DATE;
479 l_op_seq_num NUMBER;
480
481 l_op number;
482 l_shift number;
483 BEGIN
484 /*
485 | insert into lmtmp (wip_entity_id, op_count)values(
486 | i_wip_entity_id, 0);--i_operation_table.count);
487 | l_index := i_operation_table.first;
488 | loop
489 | insert into lmtmp(wip_entity_id, op_count)values(
490 | -1, l_index);
491 | l_op := i_operation_table(l_index).operation_seq_num;
492 | l_shift := i_operation_table(l_index).time_shift;
493 | insert into lmtmp (wip_entity_id, op_count)values(
494 | l_op, l_shift);
495 | exit when l_index = i_operation_table.last;
496 | l_index := i_operation_table.next(l_index);
497 | end loop;
498 | commit;
499 */
500 -- Work Order
501 BEGIN
502 select min(first_unit_start_date), max(last_unit_completion_date)
503 into l_wo_start_date, l_wo_completion_date
504 from wip_operations
505 where wip_entity_id = i_wip_entity_id;
506
507 update wip_discrete_jobs set
508 scheduled_start_date = l_wo_start_date,
509 scheduled_completion_date = l_wo_completion_date
510 where wip_entity_id = i_wip_entity_id;
511 EXCEPTION
512 WHEN NO_DATA_FOUND THEN /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
513 NULL;
514 END;
515 -- Resources
516 if i_operation_table is null or
517 i_operation_table.count <= 0 then
518 return;
519 end if;
520 l_index := i_operation_table.FIRST;
521 LOOP
522 update wip_operation_resources set
523 start_date = start_date, -- + i_operation_table(l_index).time_shift,
524 completion_date = completion_date --+ i_operation_table(l_index).time_shift
525 where wip_entity_id = i_wip_entity_id
526 and operation_seq_num = i_operation_table(l_index).operation_seq_num;
527 EXIT WHEN l_index = i_operation_table.LAST;
528 l_index := i_operation_table.NEXT(l_index);
529 END LOOP;
530 --*/ null;
531 END adjust_operations;
532
533
534 PROCEDURE adjust_workorder(
535 i_wip_entity_id IN NUMBER,
536 i_shift IN NUMBER) IS
537 BEGIN
538 -- Operations
539 update wip_operations set
540 first_unit_start_date = first_unit_start_date,
541 first_unit_completion_date = first_unit_completion_date,
542 last_unit_start_date = last_unit_start_date,
543 last_unit_completion_date = last_unit_completion_date
544 where wip_entity_id = i_wip_entity_id;
545 -- Resources
546 update wip_operation_resources set
547 start_date = start_date,
548 completion_date = completion_date
549 where wip_entity_id = i_wip_entity_id;
550 END adjust_workorder;
551
552
553 FUNCTION dependency_violated( i_wip_entity_id IN NUMBER)
554 RETURN BOOLEAN IS
555
556 CURSOR all_dependencies IS
557 select prior_operation, next_operation
558 from wip_operation_networks
559 where wip_entity_id = i_wip_entity_id;
560
561 l_from_op number;
562 l_to_op number;
563
564 l_start_date_from date;
565 l_end_date_from date;
566 l_start_date_to date;
567 l_end_date_to date;
568 BEGIN
569 OPEN all_dependencies;
570 LOOP
571 FETCH all_dependencies INTO l_from_op, l_to_op;
572 EXIT WHEN all_dependencies%NOTFOUND;
573 select first_unit_start_date, last_unit_completion_date
574 into l_start_date_from, l_end_date_from
575 from wip_operations
576 where wip_entity_id = i_wip_entity_id
577 and operation_seq_num = l_from_op;
578 select first_unit_start_date, last_unit_completion_date
579 into l_start_date_to, l_end_date_to
580 from wip_operations
581 where wip_entity_id = i_wip_entity_id
582 and operation_seq_num = l_to_op;
583 if l_start_date_to < l_end_date_from then
584 CLOSE all_dependencies;
585 RETURN TRUE;
586 end if;
587 END LOOP;
588 CLOSE all_dependencies;
589 RETURN FALSE;
590 EXCEPTION
591 WHEN NO_DATA_FOUND THEN /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
592 RETURN FALSE;
593 END dependency_violated;
594
595
596 /*Earlier, this function used to check whether there were multiple
597 *released work orders for the same maintenance object and asset
598 *activity. Now that restriction has been relaxed and multiple such
599 *released work orders are going to be allowed. Hence this function
600 *always returns 0 for success.
601
602 *This procedure is being still allowed
603 *to exist as we could add other checks later on.
604 */
605 FUNCTION check_released_onhold_allowed(
606 p_rebuild_flag in varchar2,
607 p_org_id in number,
608 p_item_id in number,
609 p_serial_number in varchar2,
610 p_activity_id in number) RETURN NUMBER IS
611 x_count number := null;
612 BEGIN
613
614 return 0;
615
616 END check_released_onhold_allowed;
617
618
619
620
621 /****************************************
622 * Get Responsibility Id *
623 ****************************************/
624 function menu_has_function
625 (
626 p_menu_id IN NUMBER
627 ,p_function_id IN NUMBER
628 ) RETURN NUMBER
629 IS
630
631 CURSOR COUNT_FUNC IS
632 select count(*) as func_count
633 from
634 ( select level as entry_level, function_id
635 from fnd_menu_entries me
636 start with menu_id = p_menu_id
637 connect by prior sub_menu_id = menu_id
638 ) e
639 where e.function_id = p_function_id;
640
641 l_count NUMBER;
642 BEGIN
643
644 open COUNT_FUNC;
645 fetch COUNT_FUNC into l_count;
646 if( COUNT_FUNC%NOTFOUND) then
647 l_count := 0;
648 end if;
649
650 return l_count;
651 END;
652
653 procedure get_resp_for_func
654 (
655 p_function_id IN NUMBER
656 ,p_user_id IN NUMBER
657 ,p_resp_app_id IN NUMBER
658 ,x_resp_id OUT NOCOPY NUMBER
659 ,x_out OUT NOCOPY VARCHAR2
660 ) IS
661
662 l_resp_key VARCHAR2(300);
663 l_resp_id NUMBER;
664 l_resp_app_id NUMBER;
665 l_menu_id NUMBER;
666 l_org_id VARCHAR2(240);
667
668 -- added Resposibility-User active date check (furg active date check) as per bug 3464424 fix */
669 CURSOR C_RESPS IS
670 select fr.responsibility_key, fr.responsibility_id, fr.application_id,
671 fr.menu_id
672 from fnd_user fu, fnd_responsibility fr, fnd_user_resp_groups furg
673 where fu.user_id = p_user_id
674 and furg.user_id = fu.user_id
675 and fr.responsibility_id = furg.responsibility_id
676 and fr.application_id = furg.responsibility_application_id
677 and nvl(fr.start_date, sysdate) <= sysdate
678 and nvl(fr.end_date, sysdate) >= sysdate
679 and nvl(furg.start_date, sysdate) <= sysdate
680 and nvl(furg.end_date, sysdate) >= sysdate
681 and nvl(p_resp_app_id, fr.application_id) = fr.application_id
682 and eam_workorder_util_pkg.menu_has_function(fr.menu_id, p_function_id) > 0
683 and NVL(l_org_id, fnd_profile.value_specific('ORG_ID', NULL,
684 fr.responsibility_id, furg.responsibility_application_id)) =
685 fnd_profile.value_specific('ORG_ID', NULL,
686 fr.responsibility_id, furg.responsibility_application_id)
687 and ROWNUM=1;
688
689 BEGIN
690 fnd_profile.get('ORG_ID', l_org_id);
691 open C_RESPS ;
692 fetch C_RESPS into l_resp_key, l_resp_id, l_resp_app_id, l_menu_id;
693 if( C_RESPS%NOTFOUND ) then
694 l_resp_id:=-1;
695 end if;
696 x_out := l_resp_key;
697 x_resp_id := l_resp_id;
698 END;
699
700 --Procedure will return responsibility id with valid organization access
701 procedure get_resp
702 (
703 p_function_id IN NUMBER
704 ,p_user_id IN NUMBER
705 ,p_resp_app_id IN NUMBER
706 ,x_resp_id OUT NOCOPY NUMBER
707 ,x_out OUT NOCOPY VARCHAR2
708 ) IS
709
710 l_resp_key VARCHAR2(300);
711 l_resp_id NUMBER;
712 l_resp_app_id NUMBER;
713 l_menu_id NUMBER;
714 l_organization_id NUMBER;
715
716 CURSOR C_RESPS IS
717 select fr.responsibility_key, fr.responsibility_id, fr.application_id,
718 fr.menu_id
719 from fnd_user fu, fnd_responsibility fr, fnd_user_resp_groups furg, org_access_view oav
720 where fu.user_id = p_user_id
721 and furg.user_id = fu.user_id
722 and fr.responsibility_id = furg.responsibility_id
723 and fr.application_id = furg.responsibility_application_id
724 and nvl(fr.start_date, sysdate) <= sysdate
725 and nvl(fr.end_date, sysdate) >= sysdate
726 and nvl(furg.start_date, sysdate) <= sysdate
727 and nvl(furg.end_date, sysdate) >= sysdate
728 and nvl(p_resp_app_id, fr.application_id) = fr.application_id
729 and eam_workorder_util_pkg.menu_has_function(fr.menu_id, p_function_id) > 0
730 and oav.responsibility_id=fr.responsibility_id
731 and oav.organization_id=l_organization_id
732 and oav.resp_application_id=426
733 and ROWNUM=1;
734
735 BEGIN
736 fnd_profile.get('MFG_ORGANIZATION_ID', l_organization_id);
737 open C_RESPS ;
738 fetch C_RESPS into l_resp_key, l_resp_id, l_resp_app_id, l_menu_id;
739 if( C_RESPS%NOTFOUND ) then
740 FND_MESSAGE.SET_NAME('EAM', 'EAM_ORG_ACCESS_VIOLATION');
741 APP_EXCEPTION.RAISE_EXCEPTION;
742 end if;
743 x_out := l_resp_key;
744 x_resp_id := l_resp_id;
745 END;
746
747 function get_ip_resp_id
748 (
749 p_user_id IN NUMBER
750 ) RETURN NUMBER IS
751
752 l_ip_function_id NUMBER;
753 l_ret NUMBER;
754 l_out VARCHAR2(300);
755 l_resp_id NUMBER;
756 l_ip_app_id NUMBER;
757 l_function_name fnd_form_functions.function_name%TYPE := 'POR_SSP_HOME';
758
759 BEGIN
760
761 BEGIN
762 select function_id
763 into l_ip_function_id
764 from fnd_form_functions
765 where function_name = l_function_name; -- Fix for Bug 3756518
766
767 -- IP use 178 (ICX) as app id
768 l_ip_app_id := 178;
769
770 get_resp_for_func(l_ip_function_id, p_user_id, null, l_resp_id,
771 l_out);
772
773 l_ret := l_resp_id;
774 EXCEPTION WHEN NO_DATA_FOUND THEN
775 l_ret := -2;
776 END;
777
778 return l_ret;
779 END;
780
781 --Function to return Responsibility Id for Maint. Super User.
782 --This returns -1 if resp. is not assigned to current user
783 FUNCTION Get_Eam_Resp_Id
784 RETURN NUMBER
785 IS
786 l_eam_function_id NUMBER;
787 l_function_name fnd_form_functions.function_name%TYPE := 'EAM_APPL_MENU_HOME';
788 l_resp_id NUMBER;
789 l_eam_app_id NUMBER;
790 l_resp_key VARCHAR2(300);
791 BEGIN
792
793 BEGIN
794 select function_id
795 into l_eam_function_id
796 from fnd_form_functions
797 where function_name = l_function_name;
798 EXCEPTION
799 WHEN NO_DATA_FOUND THEN
800 fnd_message.set_name('EAM','EAM_RESP_NOT_AVAILABLE'); --show message that resp. is not available
801 APP_EXCEPTION.RAISE_EXCEPTION;
802 END;
803
804 -- EAM uses 426 as application id
805 l_eam_app_id := 426;
806
807 get_resp_for_func(l_eam_function_id,FND_GLOBAL.user_id, null, l_resp_id, l_resp_key);
808
809 IF(l_resp_id = -1) THEN
810 fnd_message.set_name('EAM','EAM_RESP_NOT_AVAILABLE'); --show message that resp. is not available
811 APP_EXCEPTION.RAISE_EXCEPTION;
812 END IF;
813
814 RETURN l_resp_id;
815
816 END Get_Eam_Resp_Id;
817
818
819 FUNCTION Resource_Schedulable(X_Hour_UOM_Code VARCHAR2,
820 X_Unit_Of_Measure VARCHAR2) RETURN NUMBER IS
821 uom_class_code VARCHAR2(10);
822 hour_uom_class_code VARCHAR2(10);
823 conversion_exists NUMBER;
824 different_uom_class EXCEPTION;
825 uom_conversion_exists EXCEPTION;
826 no_uom_conversion EXCEPTION;
827
828 BEGIN
829 SELECT UOM_CLASS INTO hour_uom_class_code
830 FROM MTL_UNITS_OF_MEASURE
831 WHERE UOM_CODE = X_Hour_UOM_Code;
832
833 SELECT UOM_CLASS INTO uom_class_code
834 FROM MTL_UNITS_OF_MEASURE
835 WHERE UOM_CODE = X_Unit_Of_Measure;
836
837 IF hour_uom_class_code <> uom_class_code THEN
838 RAISE different_uom_class;
839 ELSE
840 SELECT COUNT(*) INTO conversion_exists
841 FROM MTL_UOM_CONVERSIONS muc1,
842 MTL_UOM_CONVERSIONS muc2
843 WHERE muc1.UOM_CLASS = uom_class_code
844 AND muc1.UOM_CODE = X_Unit_Of_Measure
845 AND muc1.inventory_item_id = 0
846 AND nvl(muc1.disable_date, sysdate +1) > sysdate
847 AND muc2.uom_code = X_Hour_Uom_Code
848 AND muc2.inventory_item_id = 0
849 AND muc2.uom_class = muc1.uom_class;
850 IF conversion_exists > 0 THEN
851 RAISE uom_conversion_exists;
852 ELSE
853 RAISE no_uom_conversion;
854 END IF;
855 END IF;
856
857 EXCEPTION
858 WHEN NO_DATA_FOUND THEN
859 RETURN(0);
860 WHEN different_uom_class THEN
861 RETURN(0);
862 WHEN no_uom_conversion THEN
863 RETURN(0);
864 WHEN uom_conversion_exists THEN
865 RETURN(1);
866
867 END Resource_Schedulable;
868
869
870 PROCEDURE UNRELEASE(x_org_id IN NUMBER,
871 x_wip_id IN NUMBER,
872 x_rep_id IN NUMBER,
873 x_line_id IN NUMBER,
874 x_ent_type IN NUMBER) IS
875
876 ops_exist VARCHAR2(2);
877 charges_exist VARCHAR2(2);
878 po_req_exist VARCHAR2(20);
879 quantity_left NUMBER := 0;
880
881 charges_exist_1 varchar2(2) := '0';
882 charges_exist_2 varchar2(2) := '0';
883 charges_exist_3 varchar2(2) := '0';
884
885
886
887 BEGIN
888
889 /* Check for OSP */
890
891 IF (WIP_OSP.PO_REQ_EXISTS( p_wip_entity_id => x_wip_id
892 ,p_rep_sched_id => x_rep_id
893 ,p_organization_id => x_org_id
894 ,p_entity_type => x_ent_type ) = TRUE) THEN
895 FND_MESSAGE.SET_NAME('WIP','WIP_UNRLS_JOB/SCHED_OPEN_PO');
896 APP_EXCEPTION.RAISE_EXCEPTION;
897 RETURN;
898 END IF;
899
900 /* End of OSP Check */
901
902 /* Check for Direct Items */
903
904 begin
905
906 /* select ((nvl(SUM(quantity_ordered),0)) - (nvl(SUM(quantity_received),0))) qty_left
907 into quantity_left
908 from wip_eam_direct_items_v
909 where work_order_number = x_wip_id; */
910
911
912 SELECT
913 ((nvl(SUM(quantity_ordered),0)) - (nvl(SUM(quantity_received),0))) qty_left into quantity_left
914 FROM
915 (
916 SELECT
917 rql.wip_entity_id,
918 rql.quantity quantity_ordered,
919 to_number(null) quantity_received
920 FROM po_requisition_lines_all rql,
921 po_requisition_headers_all rqh,
922 po_line_types plt
923 WHERE rql.requisition_header_id = rqh.requisition_header_id
924 AND rql.line_type_id = plt.line_type_id
925 AND upper(rqh.authorization_status) not in ('CANCELLED', 'REJECTED','SYSTEM_SAVED')
926 AND rql.line_location_id is NULL
927 AND upper(nvl(rql.cancel_flag, 'N')) <> 'Y'
928 AND upper(nvl(plt.outside_operation_flag, 'N')) = 'N'
929 AND rql.destination_type_code = 'SHOP FLOOR'
930 AND rql.wip_entity_id is not null
931 UNION
932 (
933 SELECT
934 pd.wip_entity_id,
935 sum(pd.quantity_ordered) quantity_ordered,
936 sum(pd.quantity_delivered) quantity_received
937 FROM po_line_types plt,
938 (
939 SELECT
940 pd1.wip_entity_id,
941 pd1.wip_operation_seq_num,
942 pd1.destination_organization_id,
943 pol.item_description,
944 pol.unit_price,
945 pol.quantity,
946 pd1.quantity_delivered,
947 pd1.quantity_ordered,
948 pd1.quantity_cancelled,
949 pol.po_line_id,
950 pol.po_header_id,
951 pd1.req_distribution_id,
952 pd1.line_location_id,
953 pol.line_type_id,
954 pd1.destination_type_code,
955 pol.cancel_flag,
956 pol.item_id,
957 pol.category_id ,
958 pd1.po_release_id,
959 pd1.amount_ordered,
960 pd1.amount_delivered
961 FROM po_lines_all pol,
962 po_distributions_all pd1
963 WHERE pol.po_line_id = pd1.po_line_id
964 )
965 pd
966 WHERE pd.line_type_id = plt.line_type_id
967 AND upper(nvl(plt.outside_operation_flag, 'N')) = 'N'
968 AND pd.destination_type_code = 'SHOP FLOOR'
969 AND upper(nvl(pd.cancel_flag, 'N')) <> 'Y'
970 AND pd.wip_entity_id is not null
971 GROUP BY pd.wip_entity_id,
972 pd.amount_ordered,
973 pd.amount_delivered
974 )
975 )
976 WHERE wip_entity_id = x_wip_id ;
977
978
979 -- bug fix 2675869: removed following group by clause for performance
980 -- group by work_order_number;
981
982 if (quantity_left > 0) then
983 FND_MESSAGE.SET_NAME('WIP','WIP_UNRLS_JOB/SCHED_OPEN_PO');
984 APP_EXCEPTION.RAISE_EXCEPTION;
985 /* Bug#3022963: The 'RETURN' was placed outside the quantity_left check causing
986 the procedure to return without making other checks */
987 RETURN;
988 END IF;
989 exception
990 WHEN NO_DATA_FOUND then -- Here the exception will not raise, hence commenting. fix for the bug 2551622
991 null;
992
993 end;
994
995 /* End of Check for Direct Items */
996
997 /* Check for Material and Resource Transactions */
998
999 begin
1000
1001 -- bug fix 2675869: removed 'distinct' from following query and added additonal ROWNUM<=1
1002 SELECT '1'
1003 into charges_exist_1
1004 FROM WIP_DISCRETE_JOBS DJ, WIP_PERIOD_BALANCES WPB
1005 WHERE DJ.WIP_ENTITY_ID = WPB.WIP_ENTITY_ID
1006 AND DJ.ORGANIZATION_ID = WPB.ORGANIZATION_ID
1007 AND DJ.WIP_ENTITY_ID = x_wip_id
1008 AND DJ.ORGANIZATION_ID = x_org_id
1009 AND (DJ.QUANTITY_COMPLETED <> 0
1010 OR DJ.QUANTITY_SCRAPPED <> 0
1011 OR WPB.TL_RESOURCE_IN <> 0
1012 OR WPB.TL_OVERHEAD_IN <> 0
1013 OR WPB.TL_OUTSIDE_PROCESSING_IN <> 0
1014 OR WPB.PL_MATERIAL_IN <> 0
1015 OR WPB.PL_MATERIAL_OVERHEAD_IN <> 0
1016 OR WPB.PL_RESOURCE_IN <> 0
1017 OR WPB.PL_OVERHEAD_IN <> 0
1018 OR WPB.PL_OUTSIDE_PROCESSING_IN <> 0
1019 OR WPB.TL_MATERIAL_OUT <> 0
1020 OR WPB.TL_RESOURCE_OUT <> 0
1021 OR WPB.TL_OVERHEAD_OUT <> 0
1022 OR WPB.TL_OUTSIDE_PROCESSING_OUT <> 0
1023 OR WPB.PL_MATERIAL_OUT <> 0
1024 OR WPB.PL_MATERIAL_OVERHEAD_OUT <> 0
1025 OR WPB.PL_RESOURCE_OUT <> 0
1026 OR WPB.PL_OVERHEAD_OUT <> 0
1027 OR WPB.PL_OUTSIDE_PROCESSING_OUT <> 0)
1028 AND ROWNUM <= 1;
1029
1030 if charges_exist_1 = '1' then
1031 FND_MESSAGE.SET_NAME('WIP','WIP_UNRLS_JOB/SCHED');
1032 APP_EXCEPTION.RAISE_EXCEPTION;
1033 /* Bug#3022963: The 'RETURN' was placed outside the quantity_left check causing
1034 the procedure to return without making other checks */
1035 RETURN;
1036 end if;
1037 exception
1038 WHEN NO_DATA_FOUND then /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
1039 null;
1040 end;
1041
1042 begin
1043
1044 SELECT '1'
1045 into charges_exist_2
1046 FROM DUAL /*fix for 2414244 */
1047 WHERE EXISTS (SELECT '1'
1048 FROM WIP_REQUIREMENT_OPERATIONS
1049 WHERE ORGANIZATION_ID = x_org_id
1050 AND WIP_ENTITY_ID = x_wip_id
1051 AND QUANTITY_ISSUED <> 0)
1052 OR EXISTS (SELECT '1'
1053 FROM WIP_MOVE_TXN_INTERFACE
1054 WHERE ORGANIZATION_ID = x_org_id
1055 AND WIP_ENTITY_ID = x_wip_id)
1056 OR EXISTS (SELECT '1'
1057 FROM WIP_COST_TXN_INTERFACE
1058 WHERE ORGANIZATION_ID = x_org_id
1059 AND WIP_ENTITY_ID = x_wip_id);
1060
1061 if charges_exist_2 = '1' then
1062 FND_MESSAGE.SET_NAME('WIP','WIP_UNRLS_JOB/SCHED');
1063 APP_EXCEPTION.RAISE_EXCEPTION;
1064 /* Bug#3022963: The 'RETURN' was placed outside the quantity_left check causing
1065 the procedure to return without making other checks */
1066 RETURN;
1067 end if;
1068 exception
1069 WHEN NO_DATA_FOUND then /* fix for the perf bug #2551622 */
1070 null;
1071 end;
1072
1073
1074 BEGIN
1075 -- Fix for Bug 3890165
1076
1077 SELECT '1'
1078 INTO charges_exist_3
1079 FROM dual
1080 WHERE EXISTS (SELECT '1'
1081 FROM mtl_material_transactions_temp
1082 WHERE organization_id = x_org_id
1083 AND transaction_source_type_id = 5
1084 AND transaction_source_id = x_wip_id);
1085 if charges_exist_3 = '1' then
1086 FND_MESSAGE.SET_NAME('WIP','WIP_UNRLS_JOB/SCHED');
1087 APP_EXCEPTION.RAISE_EXCEPTION;
1088 /* Bug#3022963: The 'RETURN' was placed outside the quantity_left check causing
1089 the procedure to return without making other checks */
1090 RETURN;
1091 end if;
1092 EXCEPTION
1093 WHEN NO_DATA_FOUND then /* fix for the perf bug #2551622 */
1094 begin
1095 SELECT DISTINCT '1'
1096 into charges_exist_3
1097 FROM dual
1098 where EXISTS (SELECT '1'
1099 FROM WIP_OPERATION_RESOURCES
1100 WHERE ORGANIZATION_ID = x_org_id
1101 AND WIP_ENTITY_ID = x_wip_id
1102 AND APPLIED_RESOURCE_UNITS <> 0);
1103
1104 if charges_exist_3 = '1' then
1105 FND_MESSAGE.SET_NAME('WIP','WIP_UNRLS_JOB/SCHED');
1106 APP_EXCEPTION.RAISE_EXCEPTION;
1107 /* Bug#3022963: The 'RETURN' was placed outside the quantity_left check causing
1108 the procedure to return without making other checks */
1109 RETURN;
1110 end if;
1111 exception
1112 WHEN NO_DATA_FOUND then /* fix for the perf bug #2551622 */
1113 null;
1114 end;
1115 END;
1116
1117 /* Bug#3022963: All 3 checks should be negative for the wok order to be
1118 put from released to unreleased */
1119 IF (charges_exist_1 = '0' and charges_exist_2 = '0' and charges_exist_3 = '0') THEN
1120
1121 UPDATE WIP_OPERATIONS
1122 SET QUANTITY_WAITING_TO_MOVE = 0,
1123 QUANTITY_SCRAPPED = 0,
1124 QUANTITY_REJECTED = 0,
1125 QUANTITY_IN_QUEUE = 0,
1126 QUANTITY_RUNNING = 0,
1127 QUANTITY_COMPLETED = 0
1128 WHERE WIP_ENTITY_ID = x_wip_id
1129 AND ORGANIZATION_ID = x_org_id;
1130 ELSE
1131 FND_MESSAGE.SET_NAME('WIP','WIP_UNRLS_JOB/SCHED');
1132 APP_EXCEPTION.RAISE_EXCEPTION;
1133 RETURN;
1134 END IF;
1135
1136 /* End of Check for Material and Resource Transactions */
1137
1138 DELETE FROM wip_period_balances
1139 WHERE wip_entity_id = x_wip_id
1140 AND NVL(repetitive_schedule_id, -1) =
1141 NVL(x_rep_id, -1)
1142 AND organization_id = x_org_id;
1143
1144 -- Undo changes to WRO as a result of Overcompletion
1145 wip_overcompletion.undo_overcompletion
1146 ( p_org_id => x_org_id,
1147 p_wip_entity_id => x_wip_id,
1148 p_rep_id => x_rep_id);
1149
1150 END UNRELEASE;
1151
1152
1153
1154 procedure create_default_operation
1155 ( p_organization_id IN NUMBER
1156 ,p_wip_entity_id IN NUMBER
1157 ) IS
1158
1159 l_wip_entity_id NUMBER;
1160 l_organization_id NUMBER;
1161
1162 BEGIN
1163
1164 l_organization_id := p_organization_id;
1165 l_wip_entity_id := p_wip_entity_id;
1166
1167 WIP_EAM_UTILS.create_default_operation(p_organization_id => l_organization_id
1168 , p_wip_entity_id => l_wip_entity_id);
1169
1170
1171 END create_default_operation; -- dml
1172
1173 /* bug no 3349197 */
1174
1175 PROCEDURE CK_MATERIAL_ALLOC_ON_HOLD(x_org_id IN NUMBER,
1176 x_wip_id IN NUMBER,
1177 x_rep_id IN NUMBER,
1178 x_line_id IN NUMBER,
1179 x_ent_type IN NUMBER,
1180 x_return_status OUT NOCOPY VARCHAR2) IS
1181
1182 ops_exist VARCHAR2(2) := '0';
1183 charges_exist VARCHAR2(2) := '0';
1184 po_req_exist VARCHAR2(20);
1185 quantity_left NUMBER := 0;
1186
1187 charges_exist_1 varchar2(2) := '0';
1188 charges_exist_2 varchar2(2) := '0';
1189 charges_exist_3 varchar2(2) := '0';
1190
1191 BEGIN
1192
1193 /* Check for OSP */
1194
1195 IF (WIP_OSP.PO_REQ_EXISTS( p_wip_entity_id => x_wip_id
1196 ,p_rep_sched_id => x_rep_id
1197 ,p_organization_id => x_org_id
1198 ,p_entity_type => x_ent_type ) = TRUE) THEN
1199 ops_exist := '1';
1200 END IF;
1201
1202 /* End of OSP Check */
1203
1204 /* Check for Direct Items */
1205
1206 begin
1207 /* select ((nvl(SUM(quantity_ordered),0)) - (nvl(SUM(quantity_received),0))) qty_left
1208 into quantity_left
1209 from wip_eam_direct_items_v
1210 where work_order_number = x_wip_id;
1211 */
1212
1213 SELECT
1214 ((nvl(SUM(quantity_ordered),0)) - (nvl(SUM(quantity_received),0))) qty_left into quantity_left
1215 FROM
1216 (
1217 SELECT
1218 rql.wip_entity_id,
1219 rql.quantity quantity_ordered,
1220 to_number(null) quantity_received
1221 FROM po_requisition_lines_all rql,
1222 po_requisition_headers_all rqh,
1223 po_line_types plt
1224 WHERE rql.requisition_header_id = rqh.requisition_header_id
1225 AND rql.line_type_id = plt.line_type_id
1226 AND upper(rqh.authorization_status) not in ('CANCELLED', 'REJECTED','SYSTEM_SAVED')
1227 AND rql.line_location_id is NULL
1228 AND upper(nvl(rql.cancel_flag, 'N')) <> 'Y'
1229 AND upper(nvl(plt.outside_operation_flag, 'N')) = 'N'
1230 AND rql.destination_type_code = 'SHOP FLOOR'
1231 AND rql.wip_entity_id is not null
1232 UNION
1233 (
1234 SELECT
1235 pd.wip_entity_id,
1236 sum(pd.quantity_ordered) quantity_ordered,
1237 sum(pd.quantity_delivered) quantity_received
1238 FROM po_line_types plt,
1239 (
1240 SELECT
1241 pd1.wip_entity_id,
1242 pd1.wip_operation_seq_num,
1243 pd1.destination_organization_id,
1244 pol.item_description,
1245 pol.unit_price,
1246 pol.quantity,
1247 pd1.quantity_delivered,
1248 pd1.quantity_ordered,
1249 pd1.quantity_cancelled,
1250 pol.po_line_id,
1251 pol.po_header_id,
1252 pd1.req_distribution_id,
1253 pd1.line_location_id,
1254 pol.line_type_id,
1255 pd1.destination_type_code,
1256 pol.cancel_flag,
1257 pol.item_id,
1258 pol.category_id ,
1259 pd1.po_release_id,
1260 pd1.amount_ordered,
1261 pd1.amount_delivered
1262 FROM po_lines_all pol,
1263 po_distributions_all pd1
1264 WHERE pol.po_line_id = pd1.po_line_id
1265 )
1266 pd
1267 WHERE pd.line_type_id = plt.line_type_id
1268 AND upper(nvl(plt.outside_operation_flag, 'N')) = 'N'
1269 AND pd.destination_type_code = 'SHOP FLOOR'
1270 AND upper(nvl(pd.cancel_flag, 'N')) <> 'Y'
1271 AND pd.wip_entity_id is not null
1272 GROUP BY pd.wip_entity_id,
1273 pd.amount_ordered,
1274 pd.amount_delivered
1275 )
1276 )
1277 WHERE wip_entity_id = x_wip_id;
1278
1279
1280 -- bug fix 2675869: removed following group by clause for performance
1281 -- group by work_order_number;
1282
1283 if (quantity_left > 0) then
1284 charges_exist := '1';
1285 END IF;
1286 exception
1287 WHEN NO_DATA_FOUND then -- Here the exception will not raise, hence commenting. fix for the bug 2551622
1288 null;
1289 end;
1290 /* End of Check for Direct Items */
1291
1292 /* Check for Material and Resource Transactions */
1293
1294 begin
1295 -- bug fix 2675869: removed 'distinct' from following query and added additonal ROWNUM<=1
1296 SELECT '1'
1297 into charges_exist_1
1298 FROM WIP_DISCRETE_JOBS DJ, WIP_PERIOD_BALANCES WPB
1299 WHERE DJ.WIP_ENTITY_ID = WPB.WIP_ENTITY_ID
1300 AND DJ.ORGANIZATION_ID = WPB.ORGANIZATION_ID
1301 AND DJ.WIP_ENTITY_ID = x_wip_id
1302 AND DJ.ORGANIZATION_ID = x_org_id
1303 AND (DJ.QUANTITY_COMPLETED <> 0
1304 OR DJ.QUANTITY_SCRAPPED <> 0
1305 OR WPB.TL_RESOURCE_IN <> 0
1306 OR WPB.TL_OVERHEAD_IN <> 0
1307 OR WPB.TL_OUTSIDE_PROCESSING_IN <> 0
1308 OR WPB.PL_MATERIAL_IN <> 0
1309 OR WPB.PL_MATERIAL_OVERHEAD_IN <> 0
1310 OR WPB.PL_RESOURCE_IN <> 0
1311 OR WPB.PL_OVERHEAD_IN <> 0
1312 OR WPB.PL_OUTSIDE_PROCESSING_IN <> 0
1313 OR WPB.TL_MATERIAL_OUT <> 0
1314 OR WPB.TL_RESOURCE_OUT <> 0
1315 OR WPB.TL_OVERHEAD_OUT <> 0
1316 OR WPB.TL_OUTSIDE_PROCESSING_OUT <> 0
1317 OR WPB.PL_MATERIAL_OUT <> 0
1318 OR WPB.PL_MATERIAL_OVERHEAD_OUT <> 0
1319 OR WPB.PL_RESOURCE_OUT <> 0
1320 OR WPB.PL_OVERHEAD_OUT <> 0
1321 OR WPB.PL_OUTSIDE_PROCESSING_OUT <> 0)
1322 AND ROWNUM <= 1;
1323 exception
1324 WHEN NO_DATA_FOUND then /* Here the exception is changed from OTHERS to NO_DATA_FOUND for the bug 2551622 */
1325 null;
1326 end;
1327
1328 begin
1329 SELECT '1'
1330 into charges_exist_2
1331 FROM DUAL /*fix for 2414244 */
1332 WHERE EXISTS (SELECT '1'
1333 FROM WIP_REQUIREMENT_OPERATIONS
1334 WHERE ORGANIZATION_ID = x_org_id
1335 AND WIP_ENTITY_ID = x_wip_id
1336 AND QUANTITY_ISSUED <> 0)
1337 OR EXISTS (SELECT '1'
1338 FROM WIP_MOVE_TXN_INTERFACE
1339 WHERE ORGANIZATION_ID = x_org_id
1340 AND WIP_ENTITY_ID = x_wip_id)
1341 OR EXISTS (SELECT '1'
1342 FROM WIP_COST_TXN_INTERFACE
1343 WHERE ORGANIZATION_ID = x_org_id
1344 AND WIP_ENTITY_ID = x_wip_id);
1345 exception
1346 WHEN NO_DATA_FOUND then /* fix for the perf bug #2551622 */
1347 null;
1348 end;
1349
1350 begin
1351 SELECT DISTINCT '1'
1352 into charges_exist_3
1353 FROM MTL_MATERIAL_TRANSACTIONS_TEMP
1354 WHERE ORGANIZATION_ID = x_org_id
1355 AND TRANSACTION_SOURCE_TYPE_ID = 5
1356 AND TRANSACTION_SOURCE_ID = x_wip_id;
1357 exception
1358 WHEN NO_DATA_FOUND then /* fix for the perf bug #2551622 */
1359 begin
1360 SELECT DISTINCT '1'
1361 into charges_exist_3
1362 FROM dual
1363 where EXISTS (SELECT '1'
1364 FROM WIP_OPERATION_RESOURCES
1365 WHERE ORGANIZATION_ID = x_org_id
1366 AND WIP_ENTITY_ID = x_wip_id
1367 AND APPLIED_RESOURCE_UNITS <> 0);
1368
1369 exception WHEN NO_DATA_FOUND then
1370 null;
1371 end;
1372 end;
1373
1374 IF (charges_exist_1 = '0' and charges_exist_2 = '0' and charges_exist_3 = '0' and ops_exist ='0' and charges_exist ='0') THEN
1375 x_return_status := 'S';
1376 else
1377 x_return_status := 'F';
1378 END IF;
1379
1380 END CK_MATERIAL_ALLOC_ON_HOLD;
1381
1382 --Fix for 3360801.Added the following procedure to show the messages from the api
1383 /********************************************************************
1384 * Procedure : show_mesg
1385 * Purpose : Procedure will concatenate all the messages
1386 from the workorder api and return 1 string
1387 *********************************************************************/
1388 PROCEDURE show_mesg IS
1389 l_msg_count NUMBER;
1390 mesg varchar2(2000);
1391 i NUMBER;
1392 msg_index number;
1393 temp varchar2(2000);
1394 BEGIN
1395 mesg := '';
1396
1397 l_msg_count := fnd_msg_pub.count_msg;
1398 IF(l_msg_count>0) THEN
1399
1400 msg_index := l_msg_count;
1401
1402 for i in 1..l_msg_count loop
1403 fnd_msg_pub.get(p_msg_index => FND_MSG_PUB.G_NEXT,
1404 p_encoded => 'F',
1405 p_data => temp,
1406 p_msg_index_out => msg_index);
1407 msg_index := msg_index-1;
1408 mesg := mesg || ' ' || to_char(i) || ' . '||temp ;
1409 end loop;
1410 fnd_message.set_name('EAM','EAM_WO_API_MESG');
1411
1412 fnd_message.set_token(token => 'MESG',
1413 value =>mesg,
1414 translate =>FALSE);
1415 APP_EXCEPTION.RAISE_EXCEPTION;
1416 END IF;
1417
1418 END show_mesg;
1419
1420
1421 --Fix for 3360801.the following procedure will return a directory to get the log directory path
1422 PROCEDURE log_path(
1423 x_output_dir OUT NOCOPY VARCHAR2
1424 )
1425 IS
1426 l_full_path VARCHAR2(2000);
1427 l_new_full_path VARCHAR2(2000);
1428 l_file_dir VARCHAR2(2000);
1429
1430 fileHandler UTL_FILE.FILE_TYPE;
1431 fileName VARCHAR2(50);
1432
1433 l_flag NUMBER;
1434 l_index NUMBER;
1435 BEGIN
1436 fileName:='test.log';--this is only a dummy filename to check if directory is valid or not
1437
1438 /* get output directory path from database */
1439 SELECT value
1440 INTO l_full_path
1441 FROM v$parameter
1442 WHERE name = 'utl_file_dir';
1443
1444 l_flag := 0;
1445 --l_full_path contains a list of comma-separated directories
1446 WHILE(TRUE)
1447 LOOP
1448 --get the first dir in the list. Removed select statement for bug# 3805306
1449 l_index := instr(l_full_path,',')-1;
1450 IF l_index = -1 THEN
1451 l_index := length(l_full_path);
1452 END IF;
1453 l_file_dir := trim( substr( l_full_path, 1, l_index ) );
1454
1455 -- check if the dir is valid
1456 BEGIN
1457 fileHandler := UTL_FILE.FOPEN(l_file_dir , filename, 'w');
1458 l_flag := 1;
1459 EXCEPTION
1460 WHEN utl_file.invalid_path THEN
1461 l_flag := 0;
1462 WHEN utl_file.invalid_operation THEN
1463 l_flag := 0;
1464 END;
1465
1466 IF l_flag = 1 THEN --got a valid directory
1467 utl_file.fclose(fileHandler);
1468 EXIT;
1469 END IF;
1470
1471 --earlier found dir was not a valid dir,
1472 --so remove that from the list, and get the new list
1473 l_new_full_path := trim(substr(l_full_path, instr(l_full_path, ',')+1, length(l_full_path)));
1474
1475 --if the new list has not changed, there are no more valid dirs left
1476 IF l_full_path = l_new_full_path THEN
1477 l_flag:=0;
1478 EXIT;
1479 END IF;
1480 l_full_path := l_new_full_path;
1481 END LOOP;
1482
1483 IF(l_flag=1) THEN --found a valid directory
1484 x_output_dir := l_file_dir;
1485 ELSE
1486 x_output_dir:= null;
1487
1488 END IF;
1489 EXCEPTION
1490 WHEN OTHERS THEN
1491 x_output_dir := null;
1492
1493 END log_path;
1494
1495 -- Fix for Bug 3489907 Start
1496
1497 PROCEDURE Check_open_txns(p_org_id IN NUMBER,
1498 p_wip_id IN NUMBER,
1499 p_ent_type IN NUMBER,
1500 p_return_status OUT NOCOPY NUMBER,
1501 p_return_string OUT NOCOPY VARCHAR2 /* Added for bug#5335940 */) IS
1502 quantity_left NUMBER := 0;
1503 charges_exist_2 varchar2(2) := '0';
1504 charges_exist_3 varchar2(2) := '0';
1505 charges_exist_4 varchar2(2) := '0';
1506 BEGIN
1507 p_return_status := 0; /* Added for bug#5253575 */
1508 /* Check for Direct Items and OSP*/
1509
1510
1511 BEGIN
1512
1513 /*
1514 SELECT ((nvl(SUM(quantity_ordered),0)) - (nvl(SUM(quantity_received),0)))
1515 qty_left
1516 INTO quantity_left
1517 FROM wip_eam_direct_items_v
1518 WHERE work_order_number = p_wip_id
1519 AND rownum <=1;
1520
1521 */
1522
1523 SELECT
1524 ((nvl(SUM(quantity_ordered),0)) - (nvl(SUM(quantity_received),0))) qty_left INTO quantity_left
1525 FROM
1526 (
1527 SELECT
1528 rql.wip_entity_id,
1529 rql.quantity quantity_ordered,
1530 to_number(null) quantity_received
1531 FROM po_requisition_lines_all rql,
1532 po_requisition_headers_all rqh,
1533 po_line_types plt
1534 WHERE rql.requisition_header_id = rqh.requisition_header_id
1535 AND rql.line_type_id = plt.line_type_id
1536 AND upper(rqh.authorization_status) not in ('CANCELLED', 'REJECTED','SYSTEM_SAVED')
1537 AND rql.line_location_id is NULL
1538 AND upper(nvl(rql.cancel_flag, 'N')) <> 'Y'
1539 AND upper(nvl(plt.outside_operation_flag, 'N')) = 'N'
1540 AND rql.destination_type_code = 'SHOP FLOOR'
1541 AND rql.wip_entity_id is not null
1542 UNION
1543 (
1544 SELECT
1545 pd.wip_entity_id,
1546 sum(pd.quantity_ordered) quantity_ordered,
1547 sum(pd.quantity_delivered) quantity_received
1548 FROM po_line_types plt,
1549 (
1550 SELECT
1551 pd1.wip_entity_id,
1552 pd1.wip_operation_seq_num,
1553 pd1.destination_organization_id,
1554 pol.item_description,
1555 pol.unit_price,
1556 pol.quantity,
1557 pd1.quantity_delivered,
1558 pd1.quantity_ordered,
1559 pd1.quantity_cancelled,
1560 pol.po_line_id,
1561 pol.po_header_id,
1562 pd1.req_distribution_id,
1563 pd1.line_location_id,
1564 pol.line_type_id,
1565 pd1.destination_type_code,
1566 pol.cancel_flag,
1567 pol.item_id,
1568 pol.category_id ,
1569 pd1.po_release_id,
1570 pd1.amount_ordered,
1571 pd1.amount_delivered
1572 FROM po_lines_all pol,
1573 po_distributions_all pd1
1574 WHERE pol.po_line_id = pd1.po_line_id
1575 )
1576 pd
1577 WHERE pd.line_type_id = plt.line_type_id
1578 AND upper(nvl(plt.outside_operation_flag, 'N')) = 'N'
1579 AND pd.destination_type_code = 'SHOP FLOOR'
1580 AND upper(nvl(pd.cancel_flag, 'N')) <> 'Y'
1581 AND pd.wip_entity_id is not null
1582 GROUP BY pd.wip_entity_id,
1583 pd.amount_ordered,
1584 pd.amount_delivered
1585 )
1586 )
1587 WHERE wip_entity_id = p_wip_id
1588 AND rownum <=1;
1589
1590 IF ( (quantity_left > 0) OR
1591 (WIP_OSP.PO_REQ_EXISTS( p_wip_entity_id => p_wip_id
1592 ,p_rep_sched_id => -1
1593 ,p_organization_id=> p_org_id
1594 ,p_entity_type => p_ent_type)=TRUE)
1595 )THEN
1596 p_return_status:= 1;
1597 p_return_string := 'Direct Item/ OSP';
1598 RETURN;
1599 END IF;
1600 EXCEPTION
1601 WHEN NO_DATA_FOUND then
1602 null;
1603 END;
1604 /* End Check for Direct Items and OSP*/
1605
1606 /*Start Check for Material Transactions */
1607 BEGIN
1608
1609 SELECT DISTINCT '1'
1610 INTO charges_exist_2
1611 FROM MTL_MATERIAL_TRANSACTIONS_TEMP
1612 WHERE (ORGANIZATION_ID = p_org_id
1613 AND TRANSACTION_SOURCE_TYPE_ID = 5
1614 AND TRANSACTION_SOURCE_ID = p_wip_id
1615 AND rownum <=1)
1616 OR EXISTS (SELECT '1'
1617 FROM WIP_REQUIREMENT_OPERATIONS
1618 WHERE ORGANIZATION_ID = p_org_id
1619 AND WIP_ENTITY_ID = p_wip_id
1620 AND QUANTITY_ISSUED <> 0);
1621 /*
1622 IF charges_exist_2 = '1' then
1623 p_return_status:= 2;
1624 RETURN;
1625 END IF;
1626
1627 */
1628
1629 exception
1630 WHEN NO_DATA_FOUND then /* fix for the perf bug #2551622 */
1631 BEGIN
1632 SELECT DISTINCT '1'
1633 into charges_exist_2
1634 FROM dual
1635 where EXISTS (SELECT '1'
1636 FROM WIP_OPERATION_RESOURCES
1637 WHERE ORGANIZATION_ID = p_org_id
1638 AND WIP_ENTITY_ID = p_wip_id
1639 AND APPLIED_RESOURCE_UNITS <> 0);
1640
1641 /* IF charges_exist_2 = '1' then
1642 p_return_status:= 2;
1643 RETURN;
1644 END IF;
1645 */
1646 EXCEPTION
1647 WHEN NO_DATA_FOUND then
1648 null;
1649 END;
1650 END;
1651 /*End Check for Material Transactions */
1652
1653 /* Check for Move Transactions */
1654 BEGIN
1655 SELECT '1'
1656 INTO charges_exist_3
1657 FROM DUAL
1658 WHERE EXISTS (SELECT '1'
1659 FROM WIP_REQUIREMENT_OPERATIONS
1660 WHERE ORGANIZATION_ID = p_org_id
1661 AND WIP_ENTITY_ID = p_wip_id
1662 AND QUANTITY_ISSUED <> 0)
1663 OR EXISTS(SELECT '1'
1664 FROM WIP_MOVE_TXN_INTERFACE
1665 WHERE ORGANIZATION_ID = p_org_id
1666 AND WIP_ENTITY_ID = p_wip_id)
1667 OR EXISTS(SELECT '1'
1668 FROM WIP_COST_TXN_INTERFACE
1669 WHERE ORGANIZATION_ID = p_org_id
1670 AND WIP_ENTITY_ID = p_wip_id);
1671 /* IF charges_exist_3 = '1' then
1672 p_return_status:= 3;
1673 RETURN;
1674 END IF;
1675 */
1676 EXCEPTION
1677 WHEN NO_DATA_FOUND then
1678 null;
1679 END;
1680 /*End Check for Move Transactions */
1681
1682 /* Code Added for bug#5335940 Start */
1683 IF ( charges_exist_2 = '1' AND charges_exist_3 = '0' ) THEN
1684 p_return_status := 1;
1685 fnd_message.set_name('EAM','EAM_UPDATE_WO_TXN_OPEN');
1686 fnd_message.set_token(token => 'TXN', value => 'EAM_MATERIAL', translate => TRUE );
1687 p_return_string := fnd_message.get;
1688 ELSIF ( charges_exist_2 = '0' AND charges_exist_3 = '1' ) THEN
1689 p_return_status := 1;
1690 fnd_message.set_name('EAM','EAM_UPDATE_WO_TXN_OPEN');
1691 fnd_message.set_token(token => 'TXN', value => 'EAM_RESOURCE', translate => TRUE );
1692 p_return_string := fnd_message.get;
1693 ElSIF ( charges_exist_2 = '1' AND charges_exist_3 = '1' ) THEN
1694 p_return_status := 1;
1695 fnd_message.set_name('EAM','EAM_UPDATE_WO_TXN_OPEN');
1696 fnd_message.set_token(token => 'TXN', value => 'EAM_MATERIAL_RESOURCE', translate => TRUE );
1697 p_return_string := fnd_message.get;
1698 ELSE
1699 p_return_status:=0; p_return_status:=0;
1700 p_return_string := null;
1701 END IF;
1702 /* Code Added for bug#5335940 Ends */
1703
1704 /* p_return_status:=0; --commented for bug#5335940 */
1705 END Check_open_txns;
1706
1707 PROCEDURE CANCEL( p_org_id IN NUMBER,
1708 p_wip_id IN NUMBER,
1709 x_return_status OUT NOCOPY NUMBER,
1710 x_return_string OUT NOCOPY VARCHAR2 /* Added for bug# 5335940 */) IS
1711
1712 CURSOR disc_check_po_req_cur IS
1713 SELECT 'PO/REQ Linked'
1714 FROM PO_DISTRIBUTIONS_ALL PD,
1715 PO_LINE_LOCATIONS_ALL PLL
1716 WHERE pd.po_line_id IS NOT NULL
1717 AND pd.line_location_id IS NOT NULL
1718 AND PD.WIP_ENTITY_ID = p_wip_id
1719 AND PD.DESTINATION_ORGANIZATION_ID = p_org_id
1720 AND PLL.LINE_LOCATION_ID = PD.LINE_LOCATION_ID
1721 AND NOT(
1722 NVL(PLL.CANCEL_FLAG,'N')='Y'
1723 OR NVL(PLL.CLOSED_CODE,'N')='FINALLY CLOSED'
1724 OR NVL(PLL.CLOSED_CODE,'N')='CANCELLED'
1725 OR NVL(PLL.CLOSED_CODE,'N')='CLOSED FOR INVOICE'
1726 OR NVL(PLL.CLOSED_CODE,'N')='CLOSED FOR RECEIVING'
1727 OR NVL(PLL.CLOSED_CODE,'N')='CLOSED'
1728 OR NVL(PLL.CLOSED_CODE,'N')='REJECTED'
1729 )
1730 UNION ALL
1731 SELECT 'PO/REQ Linked'
1732 FROM PO_REQUISITION_LINES_ALL PRL
1733 WHERE PRL.WIP_ENTITY_ID = p_wip_id
1734 AND PRL.DESTINATION_ORGANIZATION_ID = p_org_id
1735 AND NOT(
1736 NVL(PRL.CANCEL_FLAG,'N')='Y'
1737 OR NVL(PRL.CLOSED_CODE,'N')='FINALLY CLOSED'
1738 OR NVL(PRL.CLOSED_CODE,'N')='CANCELLED'
1739 OR NVL(PRL.CLOSED_CODE,'N')='CLOSED FOR INVOICE'
1740 OR NVL(PRL.CLOSED_CODE,'N')='CLOSED FOR RECEIVING'
1741 OR NVL(PRL.CLOSED_CODE,'N')='CLOSED'
1742 OR NVL(PRL.CLOSED_CODE,'N')='REJECTED'
1743 )
1744 UNION ALL
1745 SELECT 'PO/REQ Linked'
1746 FROM PO_REQUISITIONS_INTERFACE_ALL PRI
1747 WHERE PRI.WIP_ENTITY_ID = p_wip_id
1748 AND PRI.DESTINATION_ORGANIZATION_ID = p_org_id
1749 AND NVL(PRI.PROCESS_FLAG,'FUTURE') <> 'ERROR';
1750
1751 po_req_exists VARCHAR2(20);
1752 /* Added for bug#5335940 start */
1753 l_return_string VARCHAR2(2000);
1754 l_po_exists VARCHAR2(2) := '0';
1755 l_txn_exists VARCHAR2(2) := '0';
1756 /* Added for bug#5335940 end */
1757 BEGIN
1758 OPEN disc_check_po_req_cur;
1759 FETCH disc_check_po_req_cur INTO po_req_exists;
1760 IF (disc_check_po_req_cur%FOUND) THEN
1761 l_po_exists := '1';
1762 END IF;
1763 CLOSE disc_check_po_req_cur;
1764 /* Added for bug# 5335940 Start */
1765 Check_open_txns(p_org_id => p_org_id,
1766 p_wip_id => p_wip_id,
1767 p_ent_type => 6,
1768 p_return_status => x_return_status,
1769 p_return_string => l_return_string
1770 );
1771 IF x_return_status = 1 THEN
1772 l_txn_exists := '1';
1773 END IF;
1774
1775 IF ( l_po_exists = '0' AND l_txn_exists = '1' ) THEN
1776 x_return_status:=1;
1777 x_return_string := l_return_string;
1778 ELSIF ( l_po_exists = '1' AND l_txn_exists = '0' ) THEN
1779 x_return_status:=1;
1780 fnd_message.set_name ('EAM','EAM_UPDATE_WO_CONFIRM_CANCEL');
1781 x_return_string := fnd_message.get;
1782 ELSIF ( l_po_exists = '1' AND l_txn_exists = '1' ) THEN
1783 fnd_message.set_name ('EAM','EAM_UPDATE_WO_CONFIRM_CANCEL');
1784 x_return_string := fnd_message.get;
1785 x_return_string := l_return_string || x_return_string;
1786 ELSE
1787 x_return_status:=0;
1788 x_return_string := null;
1789 END IF;
1790 /* Added for bug#5335940 end */
1791
1792 END CANCEL;
1793
1794 -- Fix for Bug 3489907 End
1795
1796 /* Function to get rebuild description in eam_work_orders_v*/
1797
1798 FUNCTION get_rebuild_description( p_rebuild_item_id NUMBER, p_organization_id NUMBER)
1799 return VARCHAR2 IS
1800 l_description MTL_SYSTEM_ITEMS.DESCRIPTION%TYPE ;
1801 CURSOR get_description IS
1802 SELECT description
1803 FROM MTL_SYSTEM_ITEMS
1804 WHERE inventory_item_id = p_rebuild_item_id
1805 AND organization_id = p_organization_id ;
1806 BEGIN
1807 OPEN get_description ;
1808 FETCH get_description INTO l_description ;
1809 CLOSE get_description;
1810 return l_description;
1811 END get_rebuild_description;
1812
1813
1814 /*
1815 Procedure to populate the x_workflow_table with approver's details
1816 for a particular workflow item key
1817 p_item_type = Workflow Item Type
1818 p_item_key = Workflow Item key
1819 x_workflow_table = This table will be populated with approver's details like telephone, email etc.
1820 */
1821
1822 PROCEDURE get_workflow_details( p_item_type IN STRING,
1823 p_item_key IN STRING,
1824 x_workflow_table OUT NOCOPY t_workflow_table)
1825 IS
1826 l_transaction_id VARCHAR2(50);
1827 l_approvalProcessCompleteYNOut VARCHAR2(1);
1828 l_approversOut ame_util.approversTable2;
1829 l_temp NUMBER; -- for fix 9395270
1830
1831
1832 -- Fetch telephone no from per_addresses
1833 CURSOR per_addresses_csr( p_person_id NUMBER)IS
1834 SELECT telephone_number_1
1835 FROM per_addresses
1836 WHERE person_id = p_person_id
1837 AND sysdate BETWEEN date_from AND date_to
1838 AND primary_flag = 'Y';
1839
1840 -- Fetch telephone no from per_addresses with employee_id from fnd_user
1841 CURSOR per_addresses_fnd_csr(p_user_id NUMBER) IS
1842 SELECT telephone_number_1
1843 FROM per_addresses
1844 WHERE sysdate BETWEEN date_from AND date_to
1845 AND primary_flag = 'Y'
1846 AND person_id = (SELECT employee_id
1847 FROM fnd_user
1848 WHERE user_id = p_user_id);
1849
1850 -- Fetch email address per_all_people_f
1851 CURSOR per_all_people_csr(p_person_id NUMBER) IS
1852 SELECT email_address
1853 FROM per_all_people_f
1854 WHERE person_id = p_person_id
1855 AND sysdate between effective_start_date AND effective_end_date;
1856
1857 -- Fetch email address per_all_people_f
1858 CURSOR per_all_people_fnd_csr(p_user_id NUMBER) IS
1859 SELECT email_address
1860 FROM per_all_people_f
1861 WHERE sysdate between effective_start_date AND effective_end_date
1862 AND person_id = (SELECT employee_id
1863 FROM fnd_user
1864 WHERE user_id = p_user_id);
1865
1866 -- Fetch email address fnd_user
1867 CURSOR fnd_user_csr(p_user_id VARCHAR2) IS
1868 SELECT email_address
1869 FROM fnd_user
1870 WHERE user_id = p_user_id;
1871
1872 l_transaction_type VARCHAR2(250);
1873 l_transaction_appl_id NUMBER;
1874 l_ame_set VARCHAR2 (1);
1875
1876 BEGIN
1877
1878 BEGIN
1879 l_ame_set :='Y';
1880
1881 l_transaction_type := wf_engine.GetItemAttrtext( itemtype => p_item_type,
1882 itemkey => p_item_key, aname => 'AME_TRANSACTION_TYPE');
1883 EXCEPTION
1884 WHEN OTHERS THEN
1885 l_transaction_type := 'oracle.apps.eam.workorder.release.approval';
1886 END;
1887
1888 BEGIN
1889 l_transaction_id := wf_engine.GetItemAttrtext( itemtype => p_item_type,
1890 itemkey => p_item_key, aname => 'AME_TRANSACTION_ID');
1891 EXCEPTION
1892 WHEN OTHERS THEN
1893 l_transaction_id := p_item_key;
1894 END;
1895 -- BEGIN FIX 9395270
1896 BEGIN
1897
1898 select 1
1899 INTO l_temp
1900 from eam_work_order_details ewod, wip_discrete_jobs wdj
1901 where wdj.status_type not in (3,4,5,12)
1902 and ewod.pending_flag = 'Y'
1903 and ewod.wip_entity_id = wdj.wip_entity_id
1904 and ewod.wip_entity_id = (select wip_entity_id from EAM_WO_WORKFLOWS where wf_item_key=p_item_key);
1905
1906 EXCEPTION
1907 WHEN OTHERS THEN
1908 l_temp :=0;
1909 END;
1910 --start of bug 11072252
1911 BEGIN
1912 select fnd_application_id into l_transaction_appl_id from ame_calling_apps where transaction_type_id = l_transaction_type;
1913 EXCEPTION WHEN NO_DATA_FOUND THEN
1914 l_ame_set:='N';
1915 END;
1916 IF l_ame_set='Y' THEN
1917 --end of bug 11072252
1918 IF l_temp = 1 then -- work order in approval process
1919 Ame_api2.GetAllApprovers7(applicationIdIn => l_transaction_appl_id,
1920 transactionTypeIn => l_transaction_type,
1921 transactionIdIn => l_transaction_id,
1922 approvalProcessCompleteYNOut => l_approvalProcessCompleteYNOut,
1923 approversOut => l_approversOut);
1924 ELSE
1925 --call the ame api to get approval history instead of Ame_api2.GetAllApprovers7 fix for 9395270
1926 ame_api6.getApprovers(applicationIdIn => l_transaction_appl_id,
1927 transactionTypeIn => l_transaction_type,
1928 transactionIdIn => l_transaction_id,
1929 -- approvalProcessCompleteYNOut => l_approvalProcessCompleteYNOut,
1930 approversOut => l_approversOut);
1931
1932 END IF;
1933
1934 -- END FIX 9395270
1935
1936 IF l_approversOut.count > 0 THEN
1937 FOR i IN l_approversOut.FIRST..l_approversOut.LAST
1938 LOOP
1939 x_workflow_table(i).seq_no := l_approversOut(i).approver_order_number;
1940 x_workflow_table(i).approver := l_approversOut(i).display_name;
1941 x_workflow_table(i).status := l_approversOut(i).approval_status;
1942 -- x_workflow_table(i).status_date:=
1943
1944 IF (l_approversOut(i).orig_system = AME_UTIL.PERORIGSYSTEM) THEN
1945 OPEN per_addresses_csr(l_approversOut(i).orig_system_id);
1946 FETCH per_addresses_csr INTO x_workflow_table(i).telephone;
1947 CLOSE per_addresses_csr;
1948
1949 OPEN per_all_people_csr(l_approversOut(i).orig_system_id);
1950 FETCH per_all_people_csr INTO x_workflow_table(i).email;
1951 CLOSE per_all_people_csr;
1952
1953 ELSIF (l_approversOut(i).orig_system = AME_UTIL.FNDUSERORIGSYSTEM) THEN
1954 OPEN per_addresses_fnd_csr(l_approversOut(i).orig_system_id);
1955 FETCH per_addresses_fnd_csr INTO x_workflow_table(i).telephone;
1956 CLOSE per_addresses_fnd_csr;
1957
1958 OPEN per_all_people_fnd_csr(l_approversOut(i).orig_system_id);
1959 FETCH per_all_people_fnd_csr INTO x_workflow_table(i).email;
1960 IF per_all_people_fnd_csr%NOTFOUND THEN
1961 OPEN fnd_user_csr(l_approversOut(i).orig_system_id);
1962 FETCH fnd_user_csr INTO x_workflow_table(i).email;
1963 CLOSE fnd_user_csr;
1964 END IF;
1965 CLOSE per_all_people_fnd_csr;
1966
1967 END IF;
1968 --Added for bug 14123496 start
1969 IF l_approversOut(i).approval_status ='APPROVE' OR l_approversOut(i).approval_status ='REJECT' then
1970 BEGIN
1971 select TEXT_VALUE into x_workflow_table(i).comments from
1972 wf_notification_attributes where notification_id =(select notification_id from wf_notifications where item_key=p_item_key and
1973 responder=l_approversOut(i).name and status='CLOSED') and NAME='WF_NOTE';
1974 EXCEPTION
1975 WHEN NO_DATA_FOUND THEN
1976 x_workflow_table(i).comments:=NULL; --work flow notification purge program might have run
1977 END;
1978 ELSE
1979 x_workflow_table(i).comments:=NULL;
1980 END IF;
1981 --Added for bug 14123496 end
1982 END LOOP;
1983 END IF;
1984 END IF;
1985
1986 END get_workflow_details;
1987
1988 PROCEDURE callCostEstimatorSS(
1989 p_api_version IN NUMBER := 1.0,
1990 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
1991 p_commit IN VARCHAR2 := FND_API.G_FALSE,
1992 p_validation_level IN NUMBER := FND_API.G_VALID_LEVEL_FULL,
1993 p_wip_entity_id IN NUMBER,
1994 p_organization_id IN NUMBER,
1995 x_return_status OUT NOCOPY VARCHAR2,
1996 x_msg_count OUT NOCOPY NUMBER,
1997 x_msg_data OUT NOCOPY VARCHAR2
1998 ) IS
1999
2000 l_return_status VARCHAR2(1) := FND_API.G_RET_STS_SUCCESS;
2001 l_msg_count NUMBER ;
2002 l_msg_data VARCHAR2(2000) ;
2003
2004 BEGIN
2005
2006 -- Initialize API return status to success
2007 x_return_status := FND_API.G_RET_STS_SUCCESS;
2008
2009 UPDATE WIP_DISCRETE_JOBS
2010 SET estimation_status = 2
2011 WHERE wip_entity_id = p_wip_entity_id
2012 AND organization_id = p_organization_id;
2013
2014 CSTPECEP.Estimate_WorkOrder_GRP( p_api_version => p_api_version,
2015 p_init_msg_list => p_init_msg_list,
2016 p_commit => p_commit,
2017 p_validation_level => p_validation_level,
2018 x_return_status => l_return_status,
2019 x_msg_count => l_msg_count,
2020 x_msg_data => l_msg_data,
2021 p_organization_id => p_organization_id,
2022 p_wip_entity_id => p_wip_entity_id );
2023
2024
2025 x_return_status := l_return_status ;
2026 x_msg_count := l_msg_count ;
2027 x_msg_data := l_msg_data ;
2028
2029
2030 END callCostEstimatorSS ;
2031
2032 PROCEDURE GET_REPLACED_REBUILDS(
2033 p_wip_entity_id IN NUMBER,
2034 p_organization_id IN NUMBER,
2035 x_replaced_rebuild_tbl OUT NOCOPY REPLACE_REBUILD_TBL_TYPE,
2036 x_return_status OUT NOCOPY VARCHAR2,
2037 x_error_message OUT NOCOPY VARCHAR2
2038 )IS
2039 l_maint_objid_tbl EAM_WORKORDER_UTIL_PKG.REPLACE_REBUILD_TBL_TYPE;
2040 BEGIN
2041 x_return_status := FND_API.G_RET_STS_SUCCESS;
2042
2043
2044 SELECT wdj.maintenance_object_id
2045 bulk collect into l_maint_objid_tbl
2046 FROM WIP_DISCRETE_JOBS wdj
2047 WHERE wdj.parent_wip_entity_id = p_wip_entity_id
2048 AND wdj.organization_id = p_organization_id
2049 AND wdj.manual_rebuild_flag = 'N'
2050 AND wdj.maintenance_object_type = 3;
2051
2052 EXCEPTION WHEN NO_DATA_FOUND THEN
2053 null;
2054 x_return_status := FND_API.G_RET_STS_SUCCESS;
2055 WHEN OTHERS THEN
2056
2057 x_return_status := EAM_ERROR_MESSAGE_PVT.G_STATUS_ERROR;
2058 x_error_message := sqlerrm;
2059 END GET_REPLACED_REBUILDS;
2060
2061 -- For Failure Ananlysis Project Tools > Menu option
2062 FUNCTION get_msu_resp_id( p_user_id IN NUMBER)
2063 RETURN NUMBER
2064 IS
2065 l_function_name fnd_form_functions.function_name%TYPE := 'EAM_APPL_MENU_HOME';
2066 l_msu_function_id NUMBER;
2067 l_out VARCHAR2(300);
2068 l_resp_id NUMBER;
2069
2070 BEGIN
2071
2072 SELECT function_id
2073 INTO l_msu_function_id
2074 FROM fnd_form_functions
2075 WHERE function_name = l_function_name;
2076
2077 get_resp(l_msu_function_id, p_user_id, null, l_resp_id,l_out);
2078 RETURN l_resp_id;
2079
2080 EXCEPTION
2081 WHEN NO_DATA_FOUND THEN
2082 RETURN -2;
2083 END get_msu_resp_id;
2084
2085
2086 END EAM_WORKORDER_UTIL_PKG;
2087