DBA Data[Home] [Help]

PACKAGE BODY: APPS.GMD_EXPRESSION_UTIL

Source


4 
1 PACKAGE BODY GMD_EXPRESSION_UTIL AS
2 /* $Header: GMDPEXPB.pls 120.4 2011/09/20 15:24:00 rnalla ship $ */
3 G_PKG_NAME CONSTANT VARCHAR2(30) := 'GMD_EXPRESSION_UTIL';
5 P_Ingr_line_tab	line_tab;
6 P_Byp_line_tab	line_tab;
7 operator_tab	Operator_Table := Operator_Table('+', '-', '/', '*', '(', ')', 'SUM', 'ISUM', 'BSUM',
8                                                  'POWER', 'ABS', 'SQRT', 'EXP', 'LOG', 'LN', 'MOD',
9                                                  'ROUND', 'CEIL', ',');
10 
11   /*******************************************************************************
12   * Procedure parse_expression
13   *
14   * Procedure:-  This procedure parses the expression passed in into tokens.
15   *              Raju Cursor has been modified due to connect by errors in 8i env
16   *
17   *********************************************************************************/
18   PROCEDURE parse_expression
19   (     p_orgn_id		IN	       NUMBER	,
20         p_tech_parm_id		IN	       NUMBER	,
21         p_expression		IN	       VARCHAR2	,
22         x_return_status         OUT NOCOPY     VARCHAR2
23   ) IS
24 
25     CURSOR Cur_check_loop (V_tech_parm_id NUMBER) IS
29           START WITH p.tech_parm_id = V_tech_parm_id
26       SELECT max(level)
27           FROM   gmd_parsed_expression p
28           WHERE  expression_type <> -1
30           CONNECT BY PRIOR expression_parm_id = p.tech_parm_id
31           AND (p.data_type <> 11 OR p.tech_parm_id <> p.expression_parm_id);
32 
33       /*SELECT max(level)
34       FROM   gmd_parsed_expression p, gmd_tech_parameters_b b
35       WHERE  expression_type <> -1
36       AND    p.tech_parm_id = b.tech_parm_id (+)
37       START WITH p.tech_parm_id = V_tech_parm_id
38       CONNECT BY PRIOR expression_parm_id = p.tech_parm_id
39       AND (b.data_type <> 11 or p.tech_parm_id <> expression_parm_id);*/
40 
41     L_length		NUMBER;
42     L_str		VARCHAR2(200);
43     L_char		VARCHAR2(10);
44     L_expr		VARCHAR2(200);
45     L_return_status	VARCHAR2(1);
46     L_level		NUMBER(5);
47 
48     EXPRESSION_KEY_ERR	EXCEPTION;
49     CIRCULAR_REFERENCE	EXCEPTION;
50     PRAGMA EXCEPTION_INIT(circular_reference, -01436);
51   BEGIN
52     /* Establish the savepoint initially */
53     SAVEPOINT parse_expression;
54 
55     /* First let us assign the return status to success */
56     X_return_status := FND_API.g_ret_sts_success;
57 
58     /* Delete any parsed expression which was existing already */
59     DELETE FROM gmd_parsed_expression
60     WHERE tech_parm_id = p_tech_parm_id;
61 
62     L_length := LENGTH(P_expression);
63     FOR i IN 1..L_length LOOP
64       L_char := SUBSTR(P_expression, i, 1);
65       /*Check if the character is an operator */
66       IF is_operator (P_operator => L_char) THEN
67         /* If we have an operator then lets see if their are any preceding keys */
68         IF L_str IS NOT NULL THEN
69           /*If their is a preceding string then insert it as either an operator or operand */
70           insert_expression_key (P_orgn_id		=> P_orgn_id,
71                                  P_tech_parm_id 	=> P_tech_parm_id,
72                                  P_key 			=> L_str,
73                                  X_return_status 	=> L_return_status);
74           IF l_return_status <> x_return_status THEN
75             RAISE expression_key_err;
76           END IF;
77           L_str := NULL;
78         END IF;
79         /* Add the operator row */
80         add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
81                             P_key 		=> L_char,
82                             P_Type 		=> 1,
83                             P_exp_parm_id	=> NULL,
84                             X_return_status 	=> l_return_status);
85         IF l_return_status <> x_return_status THEN
86           RAISE expression_key_err;
87         END IF;
88       ELSE
89         L_str := RTRIM(L_str || L_char);
90       END IF;
91     END LOOP;
92     /* We have traversed through the expression, now lets see if we */
93     /* have a key which was not enclosed by an operator             */
94     IF L_str IS NOT NULL THEN
95       insert_expression_key (P_orgn_id		=> P_orgn_id,
96                              P_tech_parm_id	=> P_tech_parm_id,
97                              P_key 		=> L_str,
98                              X_return_status 	=> L_return_status);
99       IF l_return_status <> x_return_status THEN
100         RAISE expression_key_err;
101       END IF;
102     END IF;
103 
104     /* Now let us update all the existing parsed expressions which are referrring to this parameter */
105     UPDATE gmd_parsed_expression a
106     SET expression_type = -1,
107         expression_parm_id = P_tech_parm_id
108     WHERE expression_type = 0
109     AND   EXISTS (SELECT 1
110                   FROM gmd_tech_parameters_b b
111                   WHERE b.tech_parm_name = a.expression_key
112                   AND   b.tech_parm_id = p_tech_parm_id)
113     AND  EXISTS (SELECT 1
114                  FROM  gmd_tech_parameters_b c
115                  WHERE NVL(c.organization_id, -1) = NVL(p_orgn_id, -1)
116                  AND   c.tech_parm_id =  a.tech_parm_id);
117 
118     /* We have parsed the expression now, lets check if their are any circular references */
119     OPEN Cur_check_loop (p_tech_parm_id);
120     FETCH Cur_check_loop  INTO l_level;
121     CLOSE Cur_check_loop;
122 
123   EXCEPTION
124     WHEN expression_key_err THEN
125       x_return_status := l_return_status;
126       ROLLBACK TO SAVEPOINT parse_expression;
127     WHEN circular_reference THEN
128       GMD_API_GRP.log_message ('GMD_EXP_CIRC_REF');
129       x_return_status := FND_API.G_RET_STS_ERROR;
130     WHEN OTHERS THEN
131       ROLLBACK TO SAVEPOINT parse_expression;
132       fnd_msg_pub.add_exc_msg ('GMD_EXPRESSION_UTIL', 'Parse_Expression');
133       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
134   END parse_expression;
135 
136   /*******************************************************************************
137   * Procedure insert_expression_key
138   *
139   * Procedure:-  This procedure evaluates the key and inserts it as an operator or
140   *              a parameter based on its value.
141   *
142   *********************************************************************************/
143   PROCEDURE insert_expression_key
144   (     p_orgn_id		IN	       NUMBER,
145         p_tech_parm_id		IN	       NUMBER,
146         p_key			IN	       VARCHAR2,
147         x_return_status         OUT NOCOPY     VARCHAR2
148   ) IS
149 
150     L_expression	VARCHAR2(80);
151     L_parm_id		NUMBER(15);
152     L_data_type		NUMBER(5);
153     L_return_status	VARCHAR2(1);
154 
155     INSERT_EXPRESSION_ERR	EXCEPTION;
156   BEGIN
157     /* First let us assign the return status to success */
158     X_return_status := FND_API.g_ret_sts_success;
159 
163     /* First lets check if the passed in key is a technical parameter */
160     /* Lets initialize the message stack */
161     FND_MSG_PUB.initialize;
162 
164     IF is_parameter (P_orgn_id		=> P_orgn_id,
165                      P_parameter 	=> P_key,
166                      X_parm_id		=> l_parm_id,
167                      X_data_type	=> l_data_type) THEN
168       /* Yes the key is a parameter, now let us check if this parameter */
169       /* is of type expression which needs to be exploded               */
170       IF L_data_type IN (4,11) THEN
171         /* First insert the enclosing bracket to evaluate the expression piece seperately */
172         add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
173                             P_key 		=> '(',
174                             P_Type 		=> 1,
175                             P_exp_parm_id	=> NULL,
176                             X_return_status 	=> l_return_status);
177         IF l_return_status <> X_return_status THEN
178           RAISE insert_expression_err;
179         END IF;
180 
181         add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
182                             P_key 		=> P_key,
183                             P_Type 		=> -1,
184                             p_data_type 	=> l_data_type,
185                             P_exp_parm_id	=> l_parm_id,
186                             X_return_status 	=> l_return_status);
187         IF l_return_status <> X_return_status THEN
188           RAISE insert_expression_err;
189         END IF;
190 
191         /* Add the closing bracket for the parsed expression */
192         add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
193                             P_key 		=> ')',
194                             P_Type 		=> 1,
195                             P_exp_parm_id	=> NULL,
196                             X_return_status 	=> l_return_status);
197         IF l_return_status <> X_return_status THEN
198           RAISE insert_expression_err;
199         END IF;
200 
201       ELSE
202         /* This is a pure techical parameter so lets insert it as an operand */
203         add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
204                             P_key 		=> P_key,
205                             P_Type 		=> 0,
206                             P_exp_parm_id	=> NULL,
207                             X_return_status 	=> l_return_status);
208         IF l_return_status <> X_return_status THEN
209           RAISE insert_expression_err;
210         END IF;
211       END IF;
212     /*The key is not a technical parameter, it should be an operator */
213     ELSIF is_operator (P_operator => P_key) THEN
214       /* Insert rollup type operators with a different p type */
215       IF P_key IN ('ISUM', 'BSUM') THEN
216         add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
217                             P_key 		=> P_key,
218                             P_Type 		=> 2,
219                             P_exp_parm_id	=> NULL,
220                             X_return_status 	=> l_return_status);
221         IF l_return_status <> X_return_status THEN
222           RAISE insert_expression_err;
223         END IF;
224       ELSE
225         add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
226                             P_key 		=> P_key,
227                             P_Type 		=> 1,
228                             P_exp_parm_id	=> NULL,
229                             X_return_status 	=> X_return_status);
230         IF l_return_status <> X_return_status THEN
231           RAISE insert_expression_err;
232         END IF;
233       END IF;
234     ELSIF is_number(p_token => p_key) THEN
235       add_expression_row (P_tech_parm_id	=> P_tech_parm_id,
236                           P_key 		=> P_key,
237                           P_Type 		=> 1,
238                           P_exp_parm_id		=> NULL,
239                           X_return_status 	=> X_return_status);
240       IF l_return_status <> X_return_status THEN
241         RAISE insert_expression_err;
242       END IF;
243     ELSE
244       GMD_API_GRP.log_message ('GMD_EXP_PARM_NOT_DEF', 'PARAMETER', P_key);
245       RAISE fnd_api.g_exc_error;
246     END IF;
247   EXCEPTION
248     WHEN FND_API.G_EXC_ERROR THEN
249       x_return_status := FND_API.G_RET_STS_ERROR;
250     WHEN insert_expression_err THEN
251       x_return_status := l_return_status;
252     WHEN OTHERS THEN
253       fnd_msg_pub.add_exc_msg ('GMD_EXPRESSION_UTIL', 'Insert_Expression_Key');
254       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
255   END insert_expression_key;
256 
257   /*******************************************************************************
258   * Function is_operator
259   *
260   * Function:-  This function checks if the passed in token is an operator
261   *
262   *
263   *********************************************************************************/
264 
265   FUNCTION is_operator
266   (     p_operator		IN	VARCHAR2
267   ) RETURN BOOLEAN IS
268 
269   BEGIN
270     FOR i IN 1..Operator_Tab.COUNT LOOP
271       IF Operator_Tab(i) = P_Operator THEN
272         RETURN (TRUE);
273       END IF;
274     END LOOP;
275     RETURN(FALSE);
276   END is_operator;
277 
278 
279   /*******************************************************************************
280   * Function is_parameter
281   *
282   * Function:-  This function checks if the passed in token is a parameter
283   *
284   *
285   *********************************************************************************/
286 
287   FUNCTION is_parameter
288   (     p_orgn_id		IN	   NUMBER	,
289         p_parameter		IN	   VARCHAR2	,
290         x_parm_id		OUT NOCOPY NUMBER	,
291         x_data_type		OUT NOCOPY NUMBER
295       SELECT tech_parm_id, data_type
292   ) RETURN BOOLEAN IS
293 
294     CURSOR Cur_parameter (V_orgn_id NUMBER, V_parameter VARCHAR2) IS
296       FROM   gmd_tech_parameters_b
297       WHERE  tech_parm_name = V_parameter
298       AND    NVL(organization_id, -1) = NVL(v_orgn_id, -1)
299       AND    delete_mark = 0;
300   BEGIN
301     IF p_parameter IN ('QTY$', 'VOL$') THEN
302       X_data_type := 0;
303       RETURN(TRUE);
304     ELSE
305       /* Check if the passed in parameter is a technical parameter */
306       OPEN Cur_parameter (P_orgn_id, P_Parameter);
307       FETCH Cur_parameter INTO X_parm_id, X_data_type;
308       IF Cur_parameter%NOTFOUND THEN
309         CLOSE Cur_parameter;
310         RETURN (FALSE);
311       ELSE
312         CLOSE Cur_parameter;
313         RETURN (TRUE);
314       END IF;
315     END IF;
316   END is_parameter;
317 
318 
319   /*******************************************************************************
320   * Function is_number
321   *
322   * Function:-  This function checks if the passed in token is a number
323   *
324   *
325   *********************************************************************************/
326 
327   FUNCTION is_number
328   (     p_token			IN	   VARCHAR2
329   ) RETURN BOOLEAN IS
330     l_number	NUMBER;
331   BEGIN
332     l_number := TO_NUMBER(p_token);
333     RETURN (TRUE);
334   EXCEPTION
335     WHEN others THEN
336       RETURN (FALSE);
337   END is_number;
338 
339 
340   /*******************************************************************************
341   * Procedure add_expression_row
342   *
343   * Procedure:-  This procedure inserts the key to the temporary table
344   *
345   *********************************************************************************/
346   PROCEDURE add_expression_row
347   (     p_tech_parm_id		IN	        NUMBER,
348         p_key			IN	        VARCHAR2,
349         p_type		        IN     	        VARCHAR2,
350 	p_data_type		IN		NUMBER,
351         p_exp_parm_id		IN	        NUMBER,
352         x_return_status		OUT NOCOPY	VARCHAR2
353   ) IS
354     l_user_id		NUMBER(15) DEFAULT FND_PROFILE.VALUE('USER_ID');
355   BEGIN
356     /* First let us assign the return status to success */
357     X_return_status := FND_API.g_ret_sts_success;
358 
359     INSERT INTO GMD_PARSED_EXPRESSION (tech_exp_seq_id, tech_parm_id, expression_key, expression_type,
360                                        expression_parm_id, creation_date, created_by, last_updated_by,
361                                        last_update_date,data_type)
362     VALUES (gmd_tech_exp_seq_id_s.nextval, p_tech_parm_id, p_key, p_type, p_exp_parm_id, sysdate, l_user_id,
363             l_user_id, sysdate,p_data_type);
364   EXCEPTION
365     WHEN OTHERS THEN
366       fnd_msg_pub.add_exc_msg ('GMD_EXPRESSION_UTIL', 'Add_Expression_Row');
367       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
368   END add_expression_row;
369 
370   /*******************************************************************************
371   * Procedure evaluate_expression_value
372   *
373   * Procedure:-  This procedure evaluates the value for the expression passed in
374   *              p_expression_tab.
375   *********************************************************************************/
376 
377   PROCEDURE evaluate_expression_value
378   (     p_line_id		IN		NUMBER,
379         P_expression_tab	IN		EXPRESSION_TAB,
380         x_value			OUT NOCOPY	VARCHAR2,
381         x_return_status		OUT NOCOPY	VARCHAR2
382   ) IS
383     l_exp_tab		EXPRESSION_TAB;
384     l_expression_tab	EXPRESSION_TAB;
385     l_expr      	VARCHAR2(2000);
386     l_value		VARCHAR2(2000);
387     l_tot_value		NUMBER DEFAULT 0;
388     l_bracket_count	NUMBER(5) DEFAULT 0;
389     l_start		NUMBER(5);
390     l_end		NUMBER(5);
391     l_count		NUMBER(5) DEFAULT 0;
392     l_table_count	NUMBER(5);
393     i			BINARY_INTEGER DEFAULT 1;
394     l_temp 		VARCHAR2(2000);
395     l_return_status	VARCHAR2(1);
396 
397     EXPRESSION_EVAL_ERR	EXCEPTION;
398   BEGIN
399     /* First let us assign the return status to success */
400     X_return_status := FND_API.g_ret_sts_success;
401 
402     gmd_debug.put_line('Evaluating....Line:'||p_line_id);
403     FOR m IN 1..p_expression_tab.COUNT LOOP
404       l_temp := l_temp||p_expression_tab(m).expression_key;
405     END LOOP;
406     gmd_debug.put_line('Expr:'||l_temp);
407 
408     l_expression_tab := P_expression_tab;
409     l_table_count := l_expression_tab.COUNT;
410     WHILE i <= l_table_count LOOP
411       gmd_debug.put_line('Key:'||l_expression_tab(i).expression_key);
412       IF l_expression_tab(i).expression_type = 0 THEN
413         l_expr := l_expr||get_value (p_line_id => p_line_id
414                                     ,p_parameter => l_expression_tab(i).expression_key);
415       ELSIF l_expression_tab(i).expression_type = 2 THEN
416         l_start := i + 1;
417         l_bracket_count := 0;
418         /* Bug No.6181501 - Start*/
419         l_exp_tab.delete(1,l_count);
420         l_count := 0;
421         /* Bug No.6181501 - Start*/
422       /*  FOR k in i+2..l_expression_tab.COUNT LOOP */
423         FOR k in i+2..l_table_count LOOP /* Bug No.6181501 l_expression_tab.COUNT to l_table_count  */
424           l_end := k;
425           IF l_expression_tab(k).expression_key = ')' THEN
426             IF l_bracket_count = 0 THEN
427               EXIT;
428             ELSE
429               l_bracket_count := l_bracket_count - 1;
430             END IF;
431           ELSIF l_expression_tab(k).expression_key = '(' THEN
432             l_bracket_count := l_bracket_count + 1;
433           ELSE
437           END IF;
434             l_count := l_count + 1;
435             l_exp_tab(l_count).expression_key := l_expression_tab(k).expression_key;
436             l_exp_tab(l_count).expression_type := l_expression_tab(k).expression_type;
438         END LOOP;
439         l_tot_value := 0;
440         IF l_expression_tab(i).expression_key = 'ISUM' THEN
441           FOR j in 1..P_ingr_line_tab.COUNT LOOP
442             evaluate_expression_value (P_line_id => p_ingr_line_tab(j),
443                                        P_expression_tab => l_exp_tab,
444                                        x_value	=> l_value,
445                                        x_return_status => l_return_status);
446             IF l_return_status <> x_return_status THEN
447               RAISE expression_eval_err;
448             END IF;
449             gmd_debug.put_line('In ISUM procedure value:'||l_value||' Tot Value:'||l_tot_value);
450             IF NVL(l_value, 'NULL') <> 'NULL' THEN
451               l_tot_value := l_tot_value + l_value;
452             END IF;
453           END LOOP;
454         ELSE
455           FOR j in 1..P_byp_line_tab.COUNT LOOP
456             evaluate_expression_value (P_line_id => p_byp_line_tab(j),
457                                        P_expression_tab => l_exp_tab,
458                                        x_value	=> l_value,
459                                        x_return_status => l_return_status);
460             IF l_return_status <> x_return_status THEN
461               RAISE expression_eval_err;
462             END IF;
463             gmd_debug.put_line('Not In ISUM Value:'||l_value);
464             IF NVL(l_value, 'NULL') <> 'NULL' THEN
465               l_tot_value := l_tot_value + l_value;
466             END IF;
467           END LOOP;
468         END IF;
469         l_expression_tab(i).expression_key := l_tot_value;
470         l_expression_tab(i).expression_type := 1;
471         l_expression_tab.delete (l_start, l_end);
472         IF l_tot_value IS NULL THEN
473           l_expr := l_expr||'NULL';
474         ELSE
475           l_expr := l_expr||l_tot_value;
476         END IF;
477         i := l_end;
478         gmd_debug.put_line('Total:'||l_tot_value||' Start:'||l_start||' End:'||l_end||' Expr:'||l_expr);
479       ELSE
480         l_expr := l_expr||p_expression_tab(i).expression_key;
481       END IF;
482       i := i + 1;
483     END LOOP;
484     gmd_debug.put_line('Final Expr:'||l_expr);
485     IF l_expr IS NOT NULL THEN
486       GMD_UTILITY_PKG.execute_exp (pexp => l_expr,
487                                    pexp_test => FALSE,
488                                    x_result => x_value,
489                                    x_return_status => l_return_status);
490       IF l_return_status <> x_return_status THEN
491         RAISE expression_eval_err;
492       END IF;
493       gmd_debug.put_line('Value:'||x_value);
494     END IF;
495   EXCEPTION
496     WHEN expression_eval_err THEN
497       x_return_status := l_return_status;
498     WHEN OTHERS THEN
499       gmd_debug.put_line('ERROR:'||sqlerrm);
500       fnd_msg_pub.add_exc_msg ('GMD_EXPRESSION_UTIL', 'Evaluate_Expression_Value');
501       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
502   END evaluate_expression_value;
503 
504 
505   /*******************************************************************************
506   * Function get_value
507   *
508   * Function:-  This procedure returns the technical parameter value.
509   *********************************************************************************/
510 
511   FUNCTION get_value
512   (     p_line_id		IN	NUMBER,
513         p_parameter		IN	VARCHAR2
514   ) RETURN VARCHAR2 IS
515 
516     CURSOR Cur_get_line_qty (V_line_id NUMBER) IS
517       SELECT qty_mass, qty_vol
518       FROM   gmd_material_details_gtmp
519       WHERE  line_id = V_line_id;
520 
521     CURSOR Cur_value (V_line_id NUMBER, V_parameter VARCHAR2) IS
522       SELECT value
523       FROM gmd_technical_data_gtmp
524       WHERE line_id = v_line_id
525       AND   tech_parm_name = V_parameter;
526     l_value NUMBER;
527     l_mass_qty	NUMBER;
528     l_vol_qty	NUMBER;
529   BEGIN
530     gmd_debug.put_line(' In Get Value:'||p_parameter);
531     IF p_parameter IN ('QTY$', 'VOL$') THEN
532       OPEN Cur_get_line_qty (p_line_id);
533       FETCH Cur_get_line_qty INTO l_mass_qty, l_vol_qty;
534       CLOSE Cur_get_line_qty;
535       IF p_parameter = 'QTY$' THEN
536         l_value := l_mass_qty;
537       ELSE
538         l_value := l_vol_qty;
539       END IF;
540     ELSE
541       OPEN Cur_value (P_line_id, P_parameter);
542       FETCH Cur_value INTO l_value;
543       CLOSE Cur_value;
544     END IF;
545     gmd_debug.put_line('Returning:'||l_value);
546     IF l_value IS NULL THEN
547     gmd_debug.put_line(' Returning NULL');
548       RETURN('NULL');
549     ELSE
550       RETURN(l_value);
551     END IF;
552   END get_value;
553 
554 
555 
556   /*******************************************************************************
557   * Procedure evaluate_expression
558   *
559   * Procedure:-  This procedure evaluates the expression.
560   *********************************************************************************/
561 
562   PROCEDURE evaluate_expression
563   (     p_entity_id		IN		NUMBER,
564         p_line_id		IN		NUMBER,
565         p_tech_parm_id		IN		NUMBER,
566         x_value			OUT NOCOPY	NUMBER,
567         x_expression		OUT NOCOPY	VARCHAR2,
568         x_return_status		OUT NOCOPY	VARCHAR2
569   ) IS
570 
571     CURSOR Cur_get_expr (V_parm_id NUMBER) IS
572       SELECT expression_key, expression_type
573       FROM   gmd_parsed_expression p
577       CONNECT BY PRIOR expression_parm_id = p.tech_parm_id
574       WHERE  (expression_type <> -1 or
575               p.tech_parm_id = expression_parm_id)
576       START WITH p.tech_parm_id = V_parm_id
578       AND PRIOR p.tech_parm_id <> PRIOR expression_parm_id
579       ORDER SIBLINGS BY tech_exp_seq_id; /* Bug No. 6044965 */
580 
581 
582     CURSOR Cur_get_line (V_line_type NUMBER) IS
583       SELECT line_id
584       FROM   gmd_material_details_gtmp a
585       WHERE  entity_id = p_entity_id
586       AND    rollup_ind = 1
587       AND    EXISTS (SELECT 1
588                      FROM gmd_material_details_gtmp b
589                      WHERE  line_type = V_line_type
590                      AND    entity_id = p_entity_id
591                      AND    a.parent_line_id = b.parent_line_id);
592 
593     l_expression_tab	EXPRESSION_TAB;
594     i			BINARY_INTEGER := 0;
595     l_value		VARCHAR2 (2000);
596 
597     CIRCULAR_REFERENCE	EXCEPTION;
598     PRAGMA EXCEPTION_INIT(circular_reference, -01436);
599   BEGIN
600     /* First let us assign the return status to success */
601     X_return_status := FND_API.g_ret_sts_success;
602 
603     /* Lets initialize the message stack */
604     FND_MSG_PUB.initialize;
605 
606     /* Fetch the expression associated with the technical parameter */
607     FOR l_rec IN Cur_get_expr(P_tech_parm_id) LOOP
608       i := i + 1;
609       l_expression_tab(i).expression_key  := l_rec.expression_key;
610       l_expression_tab(i).expression_type := l_rec.expression_type;
611       x_expression := x_expression||l_rec.expression_key;
612     END LOOP;
613 
614     IF l_expression_tab.COUNT > 0 THEN
615       OPEN Cur_get_line(-1);
616       FETCH Cur_get_line BULK COLLECT INTO P_ingr_line_tab;
617       CLOSE Cur_get_line;
618 
619       OPEN Cur_get_line(2);
620       FETCH Cur_get_line BULK COLLECT INTO P_byp_line_tab;
621       CLOSE Cur_get_line;
622 
623       evaluate_expression_value (p_line_id =>  p_line_id,
624                                  p_expression_tab => l_expression_tab,
625                                  x_value => l_value,
626                                  x_return_status => x_return_status);
627       IF x_return_status = FND_API.g_ret_sts_success THEN
628         X_value := l_value;
629       END IF;
630     END IF;
631   EXCEPTION
632     WHEN circular_reference THEN
633       GMD_API_GRP.log_message ('GMD_EXP_CIRC_REF');
634       x_return_status := FND_API.G_RET_STS_ERROR;
635     WHEN OTHERS THEN
636       fnd_msg_pub.add_exc_msg ('GMD_EXPRESSION_UTIL', 'Evaluate_Expression');
637       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
638   END evaluate_expression;
639 
640 
641 END GMD_EXPRESSION_UTIL;