DBA Data[Home] [Help]

PACKAGE BODY: APPS.BOM_RTG_NETWORK_VALIDATE_API

Source


4 /*-------------------------------------------------------------------------
1 PACKAGE BODY BOM_RTG_NETWORK_VALIDATE_API AS
2 /* $Header: BOMRNWVB.pls 115.2 99/08/05 13:21:58 porting ship  $ */
3 
5     Name
6 	get_routing_sequence_id
7     Description
8 	Function to get the routing_sequence_id when the alternate key
9 	IDs are specified.
10     Returns
11         routing_sequence_id
12 +--------------------------------------------------------------------------*/
13 FUNCTION get_routing_sequence_id (
14        	 	p_assy_item_id      IN  NUMBER,
15         	p_org_id            IN  NUMBER,
16         	p_alt_rtg_desig     IN  VARCHAR2 DEFAULT NULL) RETURN NUMBER IS
17 
18   l_rtg_seq_id NUMBER := NULL;
19 
20   BEGIN
21      SELECT routing_sequence_id
22      INTO   l_rtg_seq_id
23      FROM   bom_operational_routings
24      WHERE  assembly_item_id = p_assy_item_id
25         AND    organization_id  = p_org_id
26         AND    NVL(alternate_routing_designator, 'NONE') =
27                                 NVL(p_alt_rtg_desig, 'NONE');
28 
29      RETURN (l_rtg_seq_id);
30 
31   EXCEPTION WHEN NO_DATA_FOUND THEN
32      RETURN NULL;
33   END;
34 
35 /*-------------------------------------------------------------------------
36     Name
37 	check_network_exists
38     Description
39 	Function to get the routing_sequence_id when the alternate key
40 	IDs are specified.
41     Returns
42 	TRUE if a network of p_operation_type exists for p_rtg_sequence_id;
43 	FALSE otherwise.
44 +--------------------------------------------------------------------------*/
45 FUNCTION check_network_exists (
46 		p_rtg_sequence_id IN NUMBER,
47 		p_operation_type  IN NUMBER) RETURN BOOLEAN IS
48   net_exists NUMBER;
49   BEGIN
50      SELECT 1
51      INTO   net_exists
52      FROM dual
53      WHERE EXISTS (SELECT null
54 		   FROM bom_operation_networks_v
55 		   WHERE routing_sequence_id = p_rtg_sequence_id
56 			AND   operation_type = p_operation_type);
57 
58      RETURN (TRUE);
59   EXCEPTION WHEN NO_DATA_FOUND THEN
60      RETURN (FALSE);
61   END check_network_exists;
62 
63 /*-------------------------------------------------------------------------
64     Name
65 	ref_pos
66     Description
67 	Function to get the reference position which is the first row from
68 	the top of the table with flag = 'C'.
69     Returns
70 	Reference, if there exists rows with flag = 'C';
71 	-1, otherwise.
72 +--------------------------------------------------------------------------*/
73 FUNCTION ref_pos (
74 		p_lnk_tbl  IN Lnk_Tbl_Type) RETURN NUMBER IS
75   i INTEGER;
76   BEGIN
77      FOR i IN 1..p_lnk_tbl.COUNT LOOP
78          IF p_lnk_tbl(i).flag = 'C' THEN
79             RETURN (i);
80          END IF;
81      END LOOP;
82      RETURN (-1);
83   END ref_pos;
84 
85 /*-------------------------------------------------------------------------
86     Name
87 	ref_rev_pos
88     Description
89 	Function to get the reference position which is the first row from
90 	the bottom of the table with flag = 'C'.
91     Returns
92 	Reference, if there exists rows with flag = 'C';
93 	-1, otherwise.
94 +--------------------------------------------------------------------------*/
95 FUNCTION ref_rev_pos (
96 		p_lnk_tbl  IN Lnk_Tbl_Type) RETURN NUMBER IS
97   i INTEGER;
98   BEGIN
99      FOR i IN REVERSE 1..p_lnk_tbl.COUNT LOOP
100          IF p_lnk_tbl(i).flag = 'C' THEN
101             RETURN (i);
102          END IF;
103      END LOOP;
104      RETURN (-1);
105   END ref_rev_pos;
106 
107 /*-------------------------------------------------------------------------
108     Name
109 	find_op
110     Description
111 	Function to search the table for a particular operation seq.
112     Returns
113 	TRUE, if p_op_seq_num in p_op_tbl;
114 	FALSE, otherwise.
115 +--------------------------------------------------------------------------*/
116 FUNCTION find_op (
120   BEGIN
117                 p_op_seq_num IN NUMBER,
118                 p_op_tbl     IN Op_Tbl_Type) RETURN BOOLEAN IS
119   i INTEGER;
121         FOR i IN 1..p_op_tbl.COUNT LOOP
122             IF p_op_tbl(i).operation_seq_num = p_op_seq_num THEN
123                RETURN (TRUE);
124             END IF;
125         END LOOP;
126         RETURN (FALSE);
127   END find_op;
128 
129 /*-------------------------------------------------------------------------
130     Name
131 	is_connected
132     Description
133 	Function to to see if there are any rows common in the two tables
134 	i.e. if the two tables are connected.
135     Returns
136 	TRUE, if p_con_tbl is connected to p_mst_tbl;
137 	FALSE, otherwise.
138 +--------------------------------------------------------------------------*/
139 FUNCTION is_connected (
140                 p_con_tbl  IN Op_Tbl_Type,
141                 p_mst_tbl  IN Op_Tbl_Type) RETURN BOOLEAN IS
142   i INTEGER;
143   j INTEGER;
144   BEGIN
145 	--dbms_output.put_line('check if connected');
146      FOR i IN 1..p_mst_tbl.COUNT LOOP
147         FOR j IN 1..p_con_tbl.COUNT LOOP
148             IF p_mst_tbl(i).operation_seq_num
149                         = p_con_tbl(j).operation_seq_num THEN
150 		 --dbms_output.put_line('TRUE');
151                 RETURN (TRUE);
152             END IF;
153         END LOOP;
154      END LOOP;
155  	--dbms_output.put_line('FALSE');
156      RETURN (FALSE);
157   END is_connected;
158 
159 /*-------------------------------------------------------------------------
160     Name
161 	get_all_links
162     Description
163 	This PROCEDURE gets all the operation links on the network for
164         the routing.
165     Returns
166         A PL/SQL table of Lnk_Tbl_Type type as OUT parameter that includes
167         a list of all operation links for the routing network of
168 	p_operation_type.
169 +--------------------------------------------------------------------------*/
170 PROCEDURE get_all_links (
171     p_rtg_sequence_id   IN  NUMBER,
172     p_operation_type    IN  NUMBER,
173     x_Lnk_Tbl           OUT Lnk_Tbl_Type ) IS
174 
175   i INTEGER := 1;
176   CURSOR all_links  IS
177     SELECT from_op_seq_id,from_seq_num,
178            to_op_seq_id
179     FROM bom_operation_networks_v
180     WHERE routing_sequence_id = p_rtg_sequence_id
181       AND   operation_type = p_operation_type
182       AND   transition_type <> 3
183     ORDER BY from_seq_num;
184 
185   BEGIN
186     FOR all_links_rec IN all_links LOOP
187         x_Lnk_Tbl(i).from_op_seq_id := all_links_rec.from_op_seq_id;
188         x_Lnk_Tbl(i).to_op_seq_id := all_links_rec.to_op_seq_id;
189         x_Lnk_Tbl(i).flag := 'C';
190 	--dbms_output.put_line('Row #'||to_char(i)||' '||
191 	--		to_char(x_Lnk_Tbl(i).from_op_seq_id)||' '||
192 	--		to_char(x_Lnk_Tbl(i).to_op_seq_id)||' '||
193 	--		x_Lnk_Tbl(i).flag);
194         i := i + 1;
195     END LOOP;
196   END get_all_links;
197 
198 /*-------------------------------------------------------------------------
199     Name
200 	get_all_start_nodes
201     Description
202 	This PROCEDURE gets all the starting nodes of the operation links on
203 	the network for the routing.
204     Returns
205         A PL/SQL table of Op_Tbl_Type type as OUT parameter that includes
206         a list of all starting nodes for the routing network of type
207 	p_operation_type.
208 +--------------------------------------------------------------------------*/
209 PROCEDURE get_all_start_nodes (
210     p_rtg_sequence_id   IN  NUMBER,
211     p_operation_type    IN  NUMBER,
212     x_Op_Tbl           OUT Op_Tbl_Type ) IS
213 
214   i INTEGER := 1;
215   CURSOR all_start_nodes  IS
216     SELECT DISTINCT from_op_seq_id, from_seq_num
217     FROM bom_operation_networks_v bonv
218     WHERE routing_sequence_id = p_rtg_sequence_id
219       AND   operation_type = p_operation_type
220       AND   transition_type <> 3
221       AND NOT EXISTS (SELECT NULL
222 			FROM  bom_operation_networks_v net
223 			WHERE net.to_op_seq_id = bonv.from_op_seq_id)
224     ORDER BY from_seq_num;
225 
226   BEGIN
227     FOR all_start_nodes_rec IN all_start_nodes LOOP
228         x_Op_Tbl(i).operation_seq_id := all_start_nodes_rec.from_op_seq_id;
229         x_Op_Tbl(i).operation_seq_num := all_start_nodes_rec.from_seq_num;
230 	--dbms_output.put_line('Row# '||to_char(i)||' '||
231 	--			to_char(x_Op_Tbl(i).operation_seq_id)||' '||
232 	--			to_char(x_Op_Tbl(i).operation_seq_num));
233         i := i + 1;
234     END LOOP;
235   END get_all_start_nodes;
236 
237 /*-------------------------------------------------------------------------
238     Name
239 	create_con_op_list
240     Description
241 	This PROCEDURE gets all the connected nodes on the network for the
242 	routing starting from the p_str_op_num node.
243     Returns
244         A PL/SQL table of Op_Tbl_Type type as OUT parameter that includes
245         a list of all connected nodes for the routing network of type
246 	p_operation_type.
247 +--------------------------------------------------------------------------*/
248 PROCEDURE create_con_op_list (
249     p_str_op_id		IN  NUMBER,
250     p_str_op_num	IN  NUMBER,
251     x_Op_Tbl           OUT Op_Tbl_Type ) IS
252 
253   i INTEGER := 2;
254   l_op_seq_num NUMBER;
255 
256   CURSOR all_con_ops (c_str_op_id NUMBER) IS
257     SELECT DISTINCT to_op_seq_id operation_sequence_id
258     FROM bom_operation_networks
259     CONNECT BY PRIOR to_op_seq_id = from_op_seq_id
260         AND transition_type <> 3
261     START WITH from_op_seq_id = c_str_op_id
262         AND transition_type <> 3;
263 
264   BEGIN
268     x_Op_Tbl(1).operation_seq_id := p_str_op_id;
265     --dbms_output.put_line('Connected lst----');
266     -- create a list of connected nodes starting from the start node
267     -- add the start node
269     x_Op_Tbl(1).operation_seq_num := p_str_op_num;
270     --dbms_output.put_line('Row# 1'||' '||to_char(x_Op_Tbl(1).operation_seq_id)||' '||
271     --					to_char(x_Op_Tbl(1).operation_seq_num));
272     FOR all_con_op_rec IN all_con_ops(p_str_op_id) LOOP
273 	SELECT operation_seq_num
274         INTO   l_op_seq_num
275         FROM   bom_operation_sequences
276         WHERE  operation_sequence_id =
277                    all_con_op_rec.operation_sequence_id;
278         x_Op_Tbl(i).operation_seq_id :=
279                         all_con_op_rec.operation_sequence_id;
280         x_Op_Tbl(i).operation_seq_num := l_op_seq_num;
281 	--dbms_output.put_line('Row# '||to_char(i)||' '||to_char(x_Op_Tbl(i).operation_seq_id)||' '||
282 	--				to_char(x_Op_Tbl(i).operation_seq_num));
283         i := i + 1;
284     END LOOP;
285   EXCEPTION WHEN NO_DATA_FOUND THEN
286         NULL;
287 
288   END create_con_op_list;
289 
290 /*-------------------------------------------------------------------------
291     Name
292 	append_to_mst_lst
293     Description
294 	This PROCEDURE appends p_Con_Op_Tbl to the master list x_Mst_Op_Tbl
295 	making sure that there is no redundancy.
296     Returns
297         A PL/SQL table of Op_Tbl_Type type as IN OUT parameter that is
298 	the master list of the connected nodes in the network.
299 +--------------------------------------------------------------------------*/
300 PROCEDURE append_to_mst_lst (
301 	p_Con_Op_Tbl IN     Op_Tbl_Type,
302 	x_Mst_Op_Tbl IN OUT Op_Tbl_Type) IS
303 
304   i INTEGER;
305   mst_ctr INTEGER;
306   BEGIN
307     mst_ctr := x_Mst_Op_Tbl.COUNT + 1;
308 	   --dbms_output.put_line('Append to Mst lst');
309     FOR i IN 1..p_Con_Op_Tbl.COUNT LOOP
310 	IF NOT find_op(p_Con_Op_Tbl(i).operation_seq_num, x_Mst_Op_Tbl) THEN
311 	   x_Mst_Op_Tbl(mst_ctr).operation_seq_id :=
312 				p_Con_Op_Tbl(i).operation_seq_id;
313 	   x_Mst_Op_Tbl(mst_ctr).operation_seq_num :=
314 				p_Con_Op_Tbl(i).operation_seq_num;
315 	   --dbms_output.put_line('Mst: row# '||to_char(mst_ctr)||' '||
316 	   --			to_char(x_Mst_Op_Tbl(mst_ctr).operation_seq_id)||' '||
317 	   --			to_char(x_Mst_Op_Tbl(mst_ctr).operation_seq_num));
318     	   mst_ctr := mst_ctr + 1;
319 	END IF;
320     END LOOP;
321 
322   END append_to_mst_lst;
323 
324 
325 /*-------------------------------------------------------------------------
326     Name
327 	validate_routing_network
328     Description
329 	This PROCEDURE is the main procedure thats called from the form,
330 	java applet code, or the Routing Open Interface code to validate
331 	the Routing Network.
332     Returns
333 	x_status  -- Result of the validation.
334 	x_message -- Message to include the LOOP or Broken Link it they exist.
335 +--------------------------------------------------------------------------*/
336 PROCEDURE validate_routing_network(
337     p_rtg_sequence_id 	IN  NUMBER,
338     p_assy_item_id      IN  NUMBER,
339     p_org_id            IN  NUMBER,
340     p_alt_rtg_desig     IN  VARCHAR2 DEFAULT NULL,
341     p_operation_type	IN  NUMBER,
342     x_status		OUT VARCHAR2,
343     x_message		OUT VARCHAR2) IS
344 
345   l_rtg_seq_id NUMBER := NULL;
346   l_Lnk_Tbl Lnk_Tbl_Type;
347   l_connected INTEGER;
348   l_top_ptr INTEGER;
349   l_bot_ptr INTEGER;
350   l_flag_changed INTEGER := 1;
354 
351   l_Str_Op_Tbl Op_Tbl_Type;
352   l_Mtr_Op_Tbl Op_Tbl_Type;
353   l_Con_Op_Tbl Op_Tbl_Type;
355   BEGIN
356      IF p_rtg_sequence_id is NOT NULL THEN
357 	--dbms_output.put_line('rtg seq specified');
358 	l_rtg_seq_id := p_rtg_sequence_id;
359      ELSE
360 	--dbms_output.put_line('rtg seq retreived');
361         l_rtg_seq_id := get_routing_sequence_id (
362                                         p_assy_item_id,
363                                         p_org_id,
364                                         p_alt_rtg_desig);
365      END IF;
366 
367      IF check_network_exists(l_rtg_seq_id, p_operation_type) THEN
368 	--dbms_output.put_line('network EXISTS');
369 
370 	-- Check For LOOPS
371 	-- Create the PL/SQL table
372 	get_all_links (l_rtg_seq_id,
373 			p_operation_type,
374 			l_Lnk_Tbl);
375 
376 	--dbms_output.put_line('START check for loops');
377 	-- get the top and bottom reference pointers
378 	l_top_ptr := ref_pos(l_Lnk_Tbl);
379 	l_bot_ptr := ref_rev_pos(l_Lnk_Tbl);
380 	--dbms_output.put_line('top_ptr:'|| to_char(l_top_ptr));
381 	--dbms_output.put_line('bot_ptr:'|| to_char(l_bot_ptr));
382 
383 	-- While there are rows with flag='C'
384 	WHILE (l_top_ptr <> -1 and l_bot_ptr <> -1 and l_flag_changed = 1) LOOP
385 	    l_flag_changed := 0;
386 	    FOR t_counter IN l_top_ptr..l_bot_ptr LOOP
387 		IF l_Lnk_Tbl(t_counter).flag = 'C' THEN
388 		    l_connected := 0;
389 	    	    --dbms_output.put_line('in loop1 :'||to_char(t_counter)||' time');
390 	    	    FOR j IN l_top_ptr..l_bot_ptr LOOP
391 			IF (l_Lnk_Tbl(t_counter).from_op_seq_id = l_Lnk_Tbl(j).to_op_seq_id
392 					AND l_Lnk_Tbl(j).flag = 'C') THEN
393 		  		l_connected := 1;
394 			END IF;
395 	    	    END LOOP;
396 	    	    IF (l_connected = 0) THEN
397 			l_Lnk_Tbl(t_counter).flag := 'D';
398 			l_flag_changed := 1;
399 	    		--dbms_output.put_line('changing row# '||to_char(t_counter)
400 			--					||' '||'flag to D');
401 	    	    END IF;
402 	    	END IF;
403 	    END LOOP;
404 
405 	    l_top_ptr := ref_pos(l_Lnk_Tbl);
406             l_bot_ptr := ref_rev_pos(l_Lnk_Tbl);
407 	    --dbms_output.put_line('top_ptr:'|| to_char(l_top_ptr));
408 	    --dbms_output.put_line('bot_ptr:'|| to_char(l_bot_ptr));
409 
410 	    l_flag_changed := 0;
411 	    IF (l_top_ptr <> -1 and l_bot_ptr <> -1) THEN
412 	   	FOR b_counter IN REVERSE l_top_ptr..l_bot_ptr LOOP
413 	      	    IF l_Lnk_Tbl(b_counter).flag = 'C' THEN
414 	     		l_connected := 0;
415 	     		--dbms_output.put_line('in loop2 :'||to_char(b_counter)||' time');
416 	     		FOR j IN REVERSE l_top_ptr..l_bot_ptr LOOP
417 	 	    	    IF (l_Lnk_Tbl(b_counter).to_op_seq_id = l_Lnk_Tbl(j).from_op_seq_id
418 							and l_Lnk_Tbl(j).flag = 'C') THEN
419 				l_connected := 1;
420 		    	    END IF;
421 	        	END LOOP;
422 	        	IF (l_connected = 0) THEN
423 			    l_Lnk_Tbl(b_counter).flag := 'D';
424 			    l_flag_changed := 1;
425 	        	    --dbms_output.put_line('changing row# '||to_char(b_counter)||' '||
426 			--							'flag to D');
427 	        	END IF;
428 	      	    END IF;
429 	   	END LOOP;
430 	    END IF;
431 	    l_top_ptr := ref_pos(l_Lnk_Tbl);
432 	    l_bot_ptr := ref_rev_pos(l_Lnk_Tbl);
433 	    --dbms_output.put_line('top_ptr:'|| to_char(l_top_ptr));
434 	    --dbms_output.put_line('bot_ptr:'|| to_char(l_bot_ptr));
435 	END LOOP; -- while
436 
437 	IF (l_top_ptr <> -1 or l_bot_ptr <> -1) THEN
438 	    FND_MESSAGE.SET_NAME('BOM','BOM_RTG_NTWK_LOOP_EXISTS');
439 	    x_status := 'F'; -- LOOP exists
440             x_message:= FND_MESSAGE.GET;
441 	    RETURN;
442 	END IF;
443 	--dbms_output.put_line('END check for loops');
444 
445 	-- Check For BROKEN LINKS
446 	--dbms_output.put_line('START check for BROKEN links');
447 
448 	get_all_start_nodes(l_rtg_seq_id,
449                         	p_operation_type,
450                         	l_Str_Op_Tbl);
451 	-- add the first start node into the master list
452 	l_Mtr_Op_Tbl(1).operation_seq_id := l_Str_Op_Tbl(1).operation_seq_id;
453 	l_Mtr_Op_Tbl(1).operation_seq_num := l_Str_Op_Tbl(1).operation_seq_num;
454 	--dbms_output.put_line('Mst: row# 1 '||to_char(l_Mtr_Op_Tbl(1).operation_seq_id)||' '||
455 	--			to_char(l_Mtr_Op_Tbl(1).operation_seq_num));
456 	-- get each start node, get the nodes it is connected to, compare with
457 	-- the master list to see if there is any common node i.e. connected.
458 	-- if there is, add the nodes to the master list. if there is none,
459 	-- this is the broken link; print the broken link.
460 
461 	FOR i IN 1..l_Str_Op_Tbl.COUNT LOOP
462 	  create_con_op_list(l_Str_Op_Tbl(i).operation_seq_id,
463 				l_Str_Op_Tbl(i).operation_seq_num,
464 				l_Con_Op_Tbl);
465 	 IF is_connected(l_Con_Op_Tbl, l_Mtr_Op_Tbl) THEN
466 	    -- add the nodes to the master list
467 	    append_to_mst_lst(l_Con_Op_Tbl, l_Mtr_Op_Tbl);
468             -- add the starting node into the Master list
469             IF NOT find_op (l_Str_Op_Tbl(i).operation_seq_num, l_Mtr_Op_Tbl) THEN
470                 l_Mtr_Op_Tbl(l_Mtr_Op_Tbl.COUNT+1).operation_seq_id :=
471                                                 l_Str_Op_Tbl(i).operation_seq_id;
472                 l_Mtr_Op_Tbl(l_Mtr_Op_Tbl.COUNT+1).operation_seq_num :=
473                                                 l_Str_Op_Tbl(i).operation_seq_num;
474             END IF;
475 	    -- delete the connected list for re-use
476 	    l_Con_Op_Tbl.DELETE;
477 	 ELSE
478 	    --dbms_output.put_line('BROKEN link exists');
479 	    FND_MESSAGE.SET_NAME('BOM','BOM_RTG_NTWK_BROKEN_LINK_EXIST');
480 	    x_status := 'F'; -- BROKEN Link exists
481             x_message:= FND_MESSAGE.GET;
482 	    RETURN;
483 	 END IF;
484 	END LOOP;
485 
486 	FND_MESSAGE.SET_NAME('BOM','BOM_RTG_NTWK_VALID');
487 	x_status := 'S'; -- NO LOOPS or BROKEN Link exists
488 	x_message:= FND_MESSAGE.GET;
489 
490      ELSE
491 		-- nothing done when NO network exists
492 		x_status := 'F'; -- NO Network
493 		x_message:= '';
494      END IF;
495 
496   END validate_routing_network;
497 
498 
499 END BOM_RTG_NETWORK_VALIDATE_API;