DBA Data[Home] [Help]

PACKAGE BODY: APPS.GMD_SPREADSHEET_UPDATE

Source


1 PACKAGE BODY GMD_SPREADSHEET_UPDATE AS
2 /* $Header: GMDSPUPB.pls 120.11 2006/09/19 15:10:12 kmotupal noship $ */
3 G_PKG_NAME CONSTANT VARCHAR2(30) := 'GMD_SPREADSHEET_UPDATE';
4 
5   /*##############################################################
6   # NAME
7   #	lock_formula_hdr
8   # SYNOPSIS
9   #	proc   lock_formula_hdr
10   # DESCRIPTION
11   #      This procedure is used to lock the formula header.
12   ###############################################################*/
13 
14   PROCEDURE lock_formula_hdr (p_formula_id IN NUMBER, p_last_update_date IN DATE, X_return_status OUT NOCOPY VARCHAR2) IS
15     CURSOR Cur_lock_header IS
16       SELECT last_update_date
17       FROM   fm_form_mst
18       WHERE  formula_id = P_formula_id
19       FOR UPDATE OF LAST_UPDATE_DATE NOWAIT;
20     X_last_update_date  DATE;
21   BEGIN
22     X_return_status := FND_API.g_ret_sts_success;
23     OPEN Cur_lock_header;
24     FETCH Cur_lock_header INTO X_last_update_date;
25     CLOSE Cur_lock_header;
26     IF X_last_update_date <> P_last_update_date THEN
27       FND_MESSAGE.SET_NAME('GMD', 'GMD_RECORD_CHANGED');
28       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'FM_FORM_MST');
29       FND_MSG_PUB.ADD;
30       X_return_status := FND_API.g_ret_sts_error;
31     END IF;
32   EXCEPTION
33     WHEN APP_EXCEPTION.RECORD_LOCK_EXCEPTION THEN
34       IF Cur_lock_header%ISOPEN THEN
35         CLOSE Cur_lock_header;
36       END IF;
37       FND_MESSAGE.SET_NAME('GMD', 'GMD_RECORD_LOCK');
38       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'FM_FORM_MST');
39       FND_MESSAGE.SET_TOKEN('RECORD', 'FORMULA_ID');
40       FND_MESSAGE.SET_TOKEN('KEY', P_formula_id);
41       FND_MSG_PUB.ADD;
42       X_return_status := FND_API.g_ret_sts_error;
43     WHEN OTHERS THEN
44       fnd_msg_pub.add_exc_msg ('GMD_SPREADSHEET_UPDATE', 'Lock_Formula_Hdr');
45       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
46   END lock_formula_hdr;
47 
48   /*##############################################################
49   # NAME
50   #	lock_formula_dtl
51   # SYNOPSIS
52   #	proc   lock_formula_dtl
53   # DESCRIPTION
54   #      This procedure is used to lock the formula details.
55   ###############################################################*/
56 
57   PROCEDURE lock_formula_dtl (P_formulaline_id IN NUMBER, P_last_update_date IN DATE,
58                             X_return_status OUT NOCOPY VARCHAR2) IS
59     CURSOR Cur_lock_details IS
60       SELECT last_update_date
61       FROM   fm_matl_dtl
62       WHERE  formulaline_id = P_formulaline_id
63       FOR UPDATE OF LAST_UPDATE_DATE NOWAIT;
64     X_last_update_date  DATE;
65   BEGIN
66     X_return_status := FND_API.g_ret_sts_success;
67     OPEN Cur_lock_details;
68     FETCH Cur_lock_details INTO X_last_update_date;
69     CLOSE Cur_lock_details;
70     IF X_last_update_date <> P_last_update_date THEN
71       FND_MESSAGE.SET_NAME('GMD', 'GMD_RECORD_CHANGED');
72       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'FM_MATL_DTL');
73       FND_MSG_PUB.ADD;
74       X_return_status := FND_API.g_ret_sts_error;
75     END IF;
76   EXCEPTION
77     WHEN APP_EXCEPTION.RECORD_LOCK_EXCEPTION THEN
78       IF Cur_lock_details%ISOPEN THEN
79         CLOSE Cur_lock_details;
80       END IF;
81       FND_MESSAGE.SET_NAME('GMD', 'GMD_RECORD_LOCK');
82       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'FM_MATL_DTL');
83       FND_MESSAGE.SET_TOKEN('RECORD', 'FORMULALINE_ID');
84       FND_MESSAGE.SET_TOKEN('KEY', P_formulaline_id);
85       FND_MSG_PUB.ADD;
86       X_return_status := FND_API.g_ret_sts_error;
87     WHEN OTHERS THEN
88       fnd_msg_pub.add_exc_msg ('GMD_SPREADSHEET_UPDATE', 'Lock_Formula_Dtl');
89       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
90   END lock_formula_dtl;
91 
92   /*##############################################################
93   # NAME
94   #	lock_formula_record
95   # SYNOPSIS
96   #	proc   lock_formula_record
97   # DESCRIPTION
98   #      This procedure is used to lock the formula.
99   ###############################################################*/
100 
101   PROCEDURE lock_formula_record (P_formula_id IN NUMBER,X_return_status OUT NOCOPY VARCHAR2) IS
102     CURSOR Cur_get_hdr IS
103       SELECT last_update_date
104       FROM   gmd_material_header_gtmp
105       WHERE  formula_id = P_formula_id;
106 
107     CURSOR  Cur_get_dtl IS
108       SELECT formulaline_id, last_update_date
109        FROM  gmd_material_details_gtmp
110        WHERE line_type <> 3
111        ORDER BY line_type, line_no;
112     l_last_update_date	DATE;
113     l_return_status	VARCHAR2(10);
114     error_lock		EXCEPTION;
115   BEGIN
116     X_return_status := FND_API.g_ret_sts_success;
117     SAVEPOINT lock_formula_record;
118     OPEN Cur_get_hdr;
119     FETCH Cur_get_hdr INTO  l_last_update_date;
120     CLOSE Cur_get_hdr;
121     lock_formula_hdr(P_formula_id => P_formula_id
122                     ,P_last_update_date => l_last_update_date
123                     ,X_return_status => l_return_status);
124     IF l_return_status <> x_return_status THEN
125       RAISE error_lock;
126     END IF;
127     FOR l_rec IN Cur_get_dtl LOOP
128       IF l_rec.formulaline_id IS NOT NULL THEN
129         lock_formula_dtl (P_formulaline_id => l_rec.formulaline_id
130                          ,P_last_update_date => l_rec.last_update_date
131                          ,X_return_status => l_return_status);
132         IF l_return_status <> x_return_status THEN
133           RAISE error_lock;
134         END IF;
135       END IF;
136     END LOOP;
137   EXCEPTION
138     WHEN error_lock THEN
139       X_return_status := l_return_status;
140       ROLLBACK TO SAVEPOINT lock_formula_record;
141     WHEN OTHERS THEN
142       fnd_msg_pub.add_exc_msg ('GMD_SPREADSHEET_UPDATE', 'Lock_formula_Record');
143       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
144       ROLLBACK TO SAVEPOINT lock_formula_record;
145   END lock_formula_record;
146 
147   /*##############################################################
148   # NAME
149   #	lock_batch_hdr
150   # SYNOPSIS
151   #	proc   lock_batch_hdr
152   # DESCRIPTION
153   #      This procedure is used to lock the batch header.
154   ###############################################################*/
155 
156   PROCEDURE lock_batch_hdr (P_batch_id IN NUMBER, P_last_update_date IN DATE, X_return_status OUT NOCOPY VARCHAR2) IS
157     CURSOR Cur_lock_header IS
158       SELECT last_update_date
159       FROM   gme_batch_header
160       WHERE  batch_id = P_batch_id
161       FOR UPDATE OF LAST_UPDATE_DATE NOWAIT;
162     X_last_update_date  DATE;
163   BEGIN
164     X_return_status := FND_API.g_ret_sts_success;
165     OPEN Cur_lock_header;
166     FETCH Cur_lock_header INTO X_last_update_date;
167     CLOSE Cur_lock_header;
168     IF X_last_update_date <> P_last_update_date THEN
169       FND_MESSAGE.SET_NAME('GME', 'GME_RECORD_CHANGED');
170       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'GME_BATCH_HEADER');
171       FND_MSG_PUB.ADD;
172       X_return_status := FND_API.g_ret_sts_error;
173     END IF;
174   EXCEPTION
175     WHEN APP_EXCEPTION.RECORD_LOCK_EXCEPTION THEN
176       IF Cur_lock_header%ISOPEN THEN
177         CLOSE Cur_lock_header;
178       END IF;
179       FND_MESSAGE.SET_NAME('GME', 'GME_RECORD_LOCKED');
180       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'GME_BATCH_HEADER');
181       FND_MESSAGE.SET_TOKEN('RECORD', 'BATCH_ID');
182       FND_MESSAGE.SET_TOKEN('KEY', P_batch_id);
183       FND_MSG_PUB.ADD;
184       X_return_status := FND_API.g_ret_sts_error;
185     WHEN OTHERS THEN
186       fnd_msg_pub.add_exc_msg ('GMD_SPREADSHEET_UPDATE', 'Lock_Batch_Hdr');
187       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
188   END lock_batch_hdr;
189 
190   /*##############################################################
191   # NAME
192   #	lock_batch_dtl
193   # SYNOPSIS
194   #	proc   lock_batch_dtl
195   # DESCRIPTION
196   #      This procedure is used to lock the batch details.
197   ###############################################################*/
198 
199   PROCEDURE lock_batch_dtl (P_material_detail_id IN NUMBER, P_last_update_date IN DATE,
200                             X_return_status OUT NOCOPY VARCHAR2) IS
201     CURSOR Cur_lock_details IS
202       SELECT last_update_date
203       FROM   gme_material_details
204       WHERE  material_detail_id = P_material_detail_id
205       FOR UPDATE OF LAST_UPDATE_DATE NOWAIT;
206     X_last_update_date  DATE;
207   BEGIN
208     X_return_status := FND_API.g_ret_sts_success;
209     OPEN Cur_lock_details;
210     FETCH Cur_lock_details INTO X_last_update_date;
211     CLOSE Cur_lock_details;
212 
213     IF X_last_update_date <> P_last_update_date THEN
214       FND_MESSAGE.SET_NAME('GME', 'GME_RECORD_CHANGED');
215       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'GME_MATERIAL_DETAILS');
216       FND_MSG_PUB.ADD;
217       X_return_status := FND_API.g_ret_sts_error;
218     END IF;
219   EXCEPTION
220     WHEN APP_EXCEPTION.RECORD_LOCK_EXCEPTION THEN
221       IF Cur_lock_details%ISOPEN THEN
222         CLOSE Cur_lock_details;
223       END IF;
224       FND_MESSAGE.SET_NAME('GME', 'GME_RECORD_LOCKED');
225       FND_MESSAGE.SET_TOKEN('TABLE_NAME', 'GME_MATERIAL_DETAILS');
226       FND_MESSAGE.SET_TOKEN('RECORD', 'MATERIAL_DETAIL_ID');
227       FND_MESSAGE.SET_TOKEN('KEY', P_material_detail_id);
228       FND_MSG_PUB.ADD;
229       X_return_status := FND_API.g_ret_sts_error;
230     WHEN OTHERS THEN
231       fnd_msg_pub.add_exc_msg ('GMD_SPREADSHEET_UPDATE', 'Lock_Batch_Dtl');
232       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
233   END lock_batch_dtl;
234 
235   /*##############################################################
236   # NAME
237   #	lock_batch_record
238   # SYNOPSIS
239   #	proc   lock_batch_record
240   # DESCRIPTION
241   #      This procedure is used to lock the batch.
242   ###############################################################*/
243 
244   PROCEDURE lock_batch_record (P_batch_id IN NUMBER,
245                                X_return_status OUT NOCOPY VARCHAR2) IS
246     CURSOR Cur_get_hdr IS
247       SELECT last_update_date
248       FROM   gmd_material_header_gtmp
249       WHERE  batch_id = P_batch_id;
250 
251     CURSOR  Cur_get_dtl IS
252       SELECT material_detail_id, last_update_date
253        FROM  gmd_material_details_gtmp
254        WHERE line_type <> 3
255        ORDER BY line_type, line_no;
256     l_last_update_date	DATE;
257     l_return_status	VARCHAR2(10);
258     error_lock		EXCEPTION;
259   BEGIN
260     X_return_status := FND_API.g_ret_sts_success;
261     SAVEPOINT lock_batch_record;
262     OPEN Cur_get_hdr;
263     FETCH Cur_get_hdr INTO  l_last_update_date;
264     CLOSE Cur_get_hdr;
265     lock_batch_hdr(P_batch_id => P_batch_id
266                   ,P_last_update_date => l_last_update_date
267                   ,X_return_status => l_return_status);
268     IF l_return_status <> x_return_status THEN
269       RAISE error_lock;
270     END IF;
271     FOR l_rec IN Cur_get_dtl LOOP
272       IF l_rec.material_detail_id IS NOT NULL THEN
273         lock_batch_dtl (P_material_detail_id => l_rec.material_detail_id
274                        ,P_last_update_date => l_rec.last_update_date
275                        ,X_return_status => l_return_status);
276         IF l_return_status <> x_return_status THEN
277           RAISE error_lock;
278         END IF;
279       END IF;
280     END LOOP;
281   EXCEPTION
282     WHEN error_lock THEN
283       X_return_status := l_return_status;
284       ROLLBACK TO SAVEPOINT lock_batch_record;
285     WHEN OTHERS THEN
286       fnd_msg_pub.add_exc_msg ('GMD_SPREADSHEET_UPDATE', 'Lock_Batch_Record');
287       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
288       ROLLBACK TO SAVEPOINT lock_batch_record;
289   END lock_batch_record;
290 
291 
292   /*##############################################################
293   # NAME
294   #	update_batch
295   # SYNOPSIS
296   #	proc   update_batch
297   # DESCRIPTION
298   #      This procedure is used to update the batch.
299   # HISTORY
300   #      22-AUG-06 Kapil M Bug# 3927768
301   #      Changed the IF condition to update lot for the items.
302   #      19-SEP-06 Kapil M Bug# 3927768
303   #      Modified in deletion, updation and creation go product_pending_lots
304   ###############################################################*/
305 
306   PROCEDURE update_batch (P_batch_id IN NUMBER, X_return_status OUT NOCOPY VARCHAR2) IS
307 
308     CURSOR Cur_get_batch IS
309       SELECT *
310       FROM   gme_batch_header
311       WHERE  batch_id = P_batch_id;
312 
313     CURSOR Cur_get_del_material IS
314       SELECT material_detail_id
315       FROM   gme_material_details e
316       WHERE  batch_id = P_batch_id
317       AND    line_type <> 1
318       AND    NOT EXISTS (SELECT 1
319                          FROM   gmd_material_details_gtmp g
320                          WHERE  line_type <> 3
321                          AND    g.material_detail_id = e.material_detail_id);
322 
323     CURSOR Cur_get_material IS
324       SELECT *
325       FROM   gmd_material_details_gtmp
326       WHERE  line_type <> 3
327       ORDER BY line_type, line_no;
328 
329     CURSOR Cur_get_detail_id(V_material_detail_id NUMBER) IS
330       SELECT  1
331       FROM    gme_material_details
332       WHERE   batch_id = P_batch_id
333               AND material_detail_id = V_material_detail_id;
334 
335         -- Bug# 3927768 Kapil M
336         -- Changed the below three cursors
337     CURSOR Cur_get_lablot (V_material_detail_id NUMBER ) IS
338       SELECT *
339       FROM   gmd_material_details_gtmp
340       WHERE  line_type = 3
341       AND    material_detail_id = V_material_detail_id;
342 
343         -- Bug# 3927768 Kapil M
344     CURSOR Cur_get_lab_material (p_lot_id NUMBER) IS
345       SELECT quantity
346       FROM   gme_pending_product_lots
347       WHERE  batch_id = P_batch_id
348              AND pending_product_lot_id = p_lot_id;
349 
350         -- Bug# 3927768 Kapil M
351     CURSOR  Cur_get_del_lines (V_material_detail_id NUMBER) IS
352       SELECT material_detail_id, pending_product_lot_id
353       FROM   gme_pending_product_lots e
354       WHERE  batch_id = P_batch_id
355       AND    material_detail_id = V_material_detail_id
356       AND    NOT EXISTS (SELECT 1
357                          FROM   gmd_material_details_gtmp g
358                          WHERE  parent_line_id = V_material_detail_id
359                          AND    g.trans_id = e.pending_product_lot_id
360                          AND    line_type = 3);
361 
362     CURSOR  Cur_get_product_lot (V_material_detail_id NUMBER) IS
363       SELECT pending_product_lot_id
364       FROM   gme_pending_product_lots
365       WHERE  batch_id = P_batch_id
366       AND    material_detail_id = V_material_detail_id;
367 
368     CURSOR Cur_get_text IS
369       SELECT material_detail_id,text_code,orginal_text_code
370       FROM   gmd_material_details_gtmp
371       WHERE  text_code <> NVL(orginal_text_code,0);
372 
373     l_batch_row		GME_BATCH_HEADER%ROWTYPE;
374     l_batch_rec		GME_BATCH_HEADER%ROWTYPE;
375     l_batch_step        GME_BATCH_STEPS%ROWTYPE;
376     l_material_detail	GME_MATERIAL_DETAILS%ROWTYPE;
377     P_material		GME_MATERIAL_DETAILS%ROWTYPE;
378     X_material		GME_MATERIAL_DETAILS%ROWTYPE;
379     l_material_det	GME_MATERIAL_DETAILS%ROWTYPE;
380     l_material_out	GME_MATERIAL_DETAILS%ROWTYPE;
381     l_material_rec	GME_MATERIAL_DETAILS%ROWTYPE;
382     x_def_tran_row	GME_INVENTORY_TXNS_GTMP%ROWTYPE;
383     x_material_row	GME_MATERIAL_DETAILS%ROWTYPE;
384     l_pending_in_rec    GME_PENDING_PRODUCT_LOTS%ROWTYPE;
385     l_pending_out_rec   GME_PENDING_PRODUCT_LOTS%ROWTYPE;
386     l_labrec		Cur_get_lablot%ROWTYPE;
387     type text_table is table of NUMBER(10) index by binary_integer;
388     x_text_tab      text_table;
389     x_cnt           NUMBER default 0;
390 
391     l_material_count	   NUMBER(5);
392     l_resource_count	   NUMBER(5);
393     l_msg_index		   NUMBER(5);
394     l_default_release_type NUMBER(5);
395     l_text_code 	   NUMBER(5);
396     l_temp		   NUMBER;
397     l_transacted	   VARCHAR2(240);
398     l_message_count	   NUMBER;
399     l_message_list	   VARCHAR2(2000);
400 
401     l_return_status	VARCHAR2(10);
402 
403     lock_batch_err	EXCEPTION;
404     error_setup		EXCEPTION;
405     error_load_batch	EXCEPTION;
406     update_alloc_err	EXCEPTION;
407     insert_line_err	EXCEPTION;
408     update_line_err	EXCEPTION;
409     delete_line_err	EXCEPTION;
410   BEGIN
411     /* Initialize return status */
412     X_return_status := FND_API.g_ret_sts_success;
413     /* Establish the savepoint */
414     SAVEPOINT  update_batch;
415 
416     /*Let us first check if their are any changes in the batch */
417     lock_batch_record (p_batch_id => p_batch_id
418                       ,x_return_status => l_return_status);
419     IF l_return_status <> x_return_status THEN
420       RAISE lock_batch_err;
421     END IF;
422 
423     /* Let us load the batch transactions into the temporary table */
424     OPEN Cur_get_batch;
425     FETCH Cur_get_batch INTO l_batch_row;
426     CLOSE Cur_get_batch;
427 
428     /*Lets initialize the gme variables */
429     gme_common_pvt.set_timestamp;
430     IF NOT gme_common_pvt.setup(P_org_id => l_batch_row.organization_id) THEN
431       RAISE error_setup;
432     END IF; /* IF NOT gme_api_pub.setup_done */
433 
434     gmd_api_grp.fetch_parm_values(P_orgn_id       => l_batch_row.organization_id,
435                                   P_parm_name     => 'FM$DEFAULT_RELEASE_TYPE',
436                                   P_parm_value    => l_default_release_type,
437                                   X_return_status => X_return_status);
438 
439     /* First let us delete all the lines which existed in the batch */
440     /* but was deleted from the spreadsheet                         */
441     FOR l_del_matl_rec IN Cur_get_del_material LOOP
442       l_material_detail.material_detail_id := l_del_matl_rec.material_detail_id;
443       l_material_detail.batch_id := P_batch_id;
444       gme_material_detail_pvt.delete_material_line (p_batch_header_rec    => l_batch_row
445  						   ,p_material_detail_rec => l_material_detail
446                                                    ,p_batch_step_rec      => l_batch_step
447                                                    ,x_transacted          => l_transacted
448                                                    ,x_return_status       => l_return_status);
449       IF x_return_status <> l_return_status THEN
450         RAISE delete_line_err;
451       END IF;
452     END LOOP;
453 
454     /*Let us fetch all the material lines for the batch */
455     FOR l_matl_rec IN Cur_get_material LOOP
456       /*If the line is not an existing record in the batch material_details */
457       OPEN Cur_get_detail_id(l_matl_rec.material_detail_id);
458       FETCH Cur_get_detail_id INTO l_temp;
459       IF(Cur_get_detail_id%NOTFOUND) THEN
460         --Bug3680011 is fixed.
461         l_material_detail.material_detail_id := NULL;
462         /* This implies that this is a new line we need to first insert the material line */
463         l_material_detail.batch_id 		:= p_batch_id;
464         l_material_detail.line_no		:= l_matl_rec.line_no;
465         l_material_detail.line_type		:= l_matl_rec.line_type;
466         l_material_detail.inventory_item_id     := l_matl_rec.inventory_item_id;
467         l_material_detail.organization_id       := l_matl_rec.organization_id;
468         l_material_detail.dtl_um		:= l_matl_rec.detail_uom;
469         l_material_detail.revision		:= l_matl_rec.revision;
470         l_material_detail.text_code		:= l_matl_rec.text_code;
471         l_material_detail.phantom_type		:= 0;
472         l_material_detail.scale_type		:= 1;
473         l_material_detail.release_type		:= NVL(l_default_release_type,0);
474         l_material_detail.alloc_ind		:= 0;
475         l_material_detail.scrap_factor		:= 0;
476         l_material_detail.actual_qty		:= 0;
477         IF (l_batch_row.batch_status = 1) THEN
478           l_material_detail.plan_qty := l_matl_rec.qty;
479         ELSIF (l_batch_row.batch_status = 2) THEN
480           l_material_detail.wip_plan_qty := l_matl_rec.qty;
481         END IF;
482         gmd_debug.put_line(' Inserting line for batch:'||l_material_detail.batch_id||' Item:'||l_material_detail.inventory_item_id);
483         gme_material_detail_pvt.insert_material_line (p_batch_header_rec    => l_batch_row
484  						     ,p_material_detail_rec => l_material_detail
485                                                      ,p_batch_step_rec      => l_batch_step
486                                                      ,p_trans_id            => NULL
487                                                      ,x_transacted          => l_transacted
488                                                      ,x_return_status       => l_return_status
489                                                      ,x_material_detail_rec => l_material_out);
490         IF x_return_status <> l_return_status THEN
491           gmd_debug.put_line(' Insert material line error: Item:'||l_material_detail.inventory_item_id);
492           RAISE insert_line_err;
493         ELSE
494           l_matl_rec.material_detail_id := l_material_out.material_detail_id;
495           UPDATE gmd_material_details_gtmp
496           SET material_detail_id = l_matl_rec.material_detail_id,
497               parent_line_id = l_matl_rec.material_detail_id
498           WHERE parent_line_id = l_matl_rec.parent_line_id;
499         END IF;
500       ELSE
501         P_material.material_detail_id := l_matl_rec.material_detail_id;
502         IF (GME_MATERIAL_DETAILS_DBL.FETCH_ROW (P_material, X_material)) THEN
503           X_material.dtl_um := l_matl_rec.detail_uom;
504           IF (l_batch_row.batch_status = 1) THEN
505             X_material.plan_qty := l_matl_rec.qty;
506           ELSIF (l_batch_row.batch_status = 2) THEN
507             X_material.wip_plan_qty := l_matl_rec.qty;
508           END IF;
509           gme_material_detail_pvt.update_material_line (p_batch_header_rec    => l_batch_row
510  						       ,p_material_detail_rec => X_material
511  						       ,p_stored_material_detail_rec => NULL
512                                                        ,p_batch_step_rec      => l_batch_step
513                                                        ,p_scale_phantom       => fnd_api.g_false
514                                                        ,p_trans_id            => NULL
515                                                        ,x_transacted          => l_transacted
516                                                        ,x_return_status       => l_return_status
517                                                        ,x_material_detail_rec => l_material_out);
518           IF x_return_status <> l_return_status THEN
519             gmd_debug.put_line(' Insert material line error: Material id:'||l_material_detail.material_detail_id);
520             RAISE update_line_err;
521           END IF;
522         END IF;
523       END IF; /* IF(Cur_get_detail_id%NOTFOUND) THEN */
524       CLOSE Cur_get_detail_id;
525 
526       IF (l_batch_row.update_inventory_ind = 'Y') THEN
527         update_allocation (P_plant_Id	 	=> l_batch_row.organization_id
528                           ,P_batch_id 		=> l_batch_row.batch_id
529                           ,P_material_detail_id	=> l_matl_rec.material_detail_id
530                           ,P_line_type		=> l_matl_rec.line_type
531                           ,X_return_status	=> l_return_status);
532         IF l_return_status <> x_return_status THEN
533           RAISE update_alloc_err;
534         END IF;
535       ELSE
536         l_batch_rec.batch_id := P_batch_id;
537         l_material_rec.material_detail_id := l_matl_rec.material_detail_id;
538         FOR l_del_rec IN Cur_get_del_lines (l_matl_rec.material_detail_id) LOOP
539         -- Bug# 3927768 Kapil M
540         -- Those lots which are not found in gmd_material_details_gtmp should be deleted.
541         l_pending_in_rec.pending_product_lot_id := l_del_rec.pending_product_lot_id;
542 
543           gme_api_pub.delete_pending_product_lot (p_api_version              => 2.0,
544                                                   x_message_count            => l_message_count,
545                                                   x_message_list             => l_message_list,
546                                                   x_return_status 	     => l_return_status,
547                                                   p_batch_header_rec         => l_batch_rec,
548                                                   p_org_code 		     => NULL,
549                                                   p_material_detail_rec      => l_material_rec,
550                                                   p_pending_product_lots_rec => l_pending_in_rec);
551            IF x_return_status <> l_return_status THEN
552              gmd_debug.put_line(' Insert pending lot error: Material id:'||l_matl_rec.material_detail_id ||
553                                 'lot_number: '||l_pending_in_rec.lot_number);
554              RAISE update_line_err;
555            END IF;
556         END LOOP;
557 
558        /* Let us load the lab lots into the temporary table */
559         FOR l_labrec IN Cur_get_lablot (l_matl_rec.material_detail_id)LOOP
560         -- Bug# 3927768 Kapil M
561         -- Added the item_id condition to update LOTs for specified items only.
562         IF (l_labrec.line_type = 3 AND l_labrec.INVENTORY_ITEM_ID = l_matl_rec.inventory_item_id) THEN
563           l_batch_rec.batch_id := P_batch_id;
564           l_material_rec.material_detail_id := l_matl_rec.material_detail_id;
565           l_pending_in_rec.lot_number := l_labrec.lot_number;
566           l_pending_in_rec.quantity := l_labrec.qty;
567           l_pending_in_rec.secondary_quantity := l_labrec.secondary_qty;
568           l_pending_in_rec.created_by := l_labrec.created_by;
569           l_pending_in_rec.creation_date := l_labrec.creation_date;
570           l_pending_in_rec.last_updated_by := l_labrec.last_updated_by;
571           l_pending_in_rec.last_update_date := l_labrec.last_update_date;
572          /* Let us check the lab batch lot is already existing if yes update the line */
573         -- Bug# 3927768 Kapil M
574         -- Records fetched based on the pending_lot_id
575          OPEN Cur_get_lab_material(l_labrec.trans_id);
576          FETCH Cur_get_lab_material INTO l_temp;
577          IF (Cur_get_lab_material%FOUND) THEN
578         -- Bug# 3927768 Kapil M
579         -- If Quantity in a lot has been changed then, update is performed.
580            IF l_labrec.qty <> l_temp THEN
581             l_pending_in_rec.pending_product_lot_id := l_labrec.trans_id;
582            gme_api_pub.update_pending_product_lot (p_api_version              => 2.0,
583                                                    x_message_count            => l_message_count,
584                                                    x_message_list             => l_message_list,
585                                                    x_return_status 	      => l_return_status,
586                                                    p_batch_header_rec         => l_batch_rec,
587                                                    p_org_code 		      => NULL,
588                                                    p_material_detail_rec      => l_material_rec,
589                                                    p_pending_product_lots_rec => l_pending_in_rec,
590                                                    x_pending_product_lots_rec => l_pending_out_rec);
591               IF x_return_status <> l_return_status THEN
592                 gmd_debug.put_line(' Insert pending lot error: Material id:'||l_matl_rec.material_detail_id ||
593                                      'lot_number: '||l_pending_in_rec.lot_number);
594                 RAISE update_line_err;
595                END IF;
596             END IF;
597          ELSE
598            /* Let us check the lab batch lot is already existing if not insert the new line */
599            l_pending_in_rec.pending_product_lot_id := NULL;
600            gme_api_pub.create_pending_product_lot (p_api_version              => 2.0,
601                                                    x_message_count            => l_message_count,
602                                                    x_message_list             => l_message_list,
603                                                    x_return_status 	      => l_return_status,
604                                                    p_batch_header_rec         => l_batch_rec,
605                                                    p_org_code 		      => NULL,
606                                                    p_material_detail_rec      => l_material_rec,
607                                                    p_pending_product_lots_rec => l_pending_in_rec,
608                                                    x_pending_product_lots_rec => l_pending_out_rec);
609 
610           IF x_return_status <> l_return_status THEN
611             gmd_debug.put_line(' Insert pending lot error: Material id:'||l_matl_rec.material_detail_id ||
612                                'lot_number: '||l_pending_in_rec.lot_number);
613             RAISE update_line_err;
614           END IF;
615          END IF;
616          CLOSE Cur_get_lab_material;
617         END IF;
618        END LOOP;/*FOR l_labrec IN Cur_get_lablot*/
619       END IF;
620     END LOOP; /* FOR l_matl_rec IN Cur_get_material */
621 
622     FOR l_rec IN Cur_get_text LOOP
623       IF l_rec.material_detail_id IS NOT NULL THEN
624         IF l_rec.text_code IS NOT NULL THEN
625           l_text_code := GMA_EDITTEXT_PKG.Copy_Text(l_rec.text_code,'FM_TEXT_TBL_TL','GME_TEXT_TABLE_TL');
626 
627           UPDATE gme_material_details
628           SET    text_code = l_text_code
629           WHERE  material_detail_id = l_rec.material_detail_id;
630         END IF;
631       END IF;
632       IF l_rec.orginal_text_code IS NOT NULL AND
633          l_rec.text_code <> l_rec.orginal_text_code THEN
634         GMA_EDITTEXT_PKG.Delete_Text(l_rec.orginal_text_code,'GME_TEXT_TABLE_TL');
635       END IF;
636     END LOOP;
637 
638     update gmd_material_details_gtmp a
639     set last_update_date = (select last_update_date
640                             FROM gme_material_details
641                             WHERE material_detail_id = a.material_detail_id);
642   EXCEPTION
643     WHEN error_setup THEN
644       ROLLBACK TO SAVEPOINT update_batch;
645       X_return_status := FND_API.g_ret_sts_error;
646     WHEN error_load_batch OR update_alloc_err OR insert_line_err OR update_line_err
647          OR delete_line_err OR lock_batch_err THEN
648       ROLLBACK TO SAVEPOINT update_batch;
649       X_return_status := l_return_status;
650     WHEN OTHERS THEN
651       ROLLBACK TO SAVEPOINT update_batch;
652       fnd_msg_pub.add_exc_msg (gmd_spreadsheet_update.g_pkg_name, 'Update_Batch');
653       x_return_status := FND_API.g_ret_sts_unexp_error;
654   END update_batch;
655 
656   /*##############################################################
657   # NAME
658   #	update_allocation
659   # SYNOPSIS
660   #	proc   update_allocation
661   # DESCRIPTION
662   #      This procedure is used to update the allocations for the batch.
663   ###############################################################*/
664 
665   PROCEDURE update_allocation (P_plant_id		IN	NUMBER,
666   			       P_batch_id		IN	NUMBER,
667                                P_material_detail_id 	IN 	NUMBER,
668                                P_line_type		IN	NUMBER,
669                                X_return_status OUT NOCOPY VARCHAR2) IS
670 
671     CURSOR  Cur_get_del_lines (V_material_detail_id NUMBER) IS
672       SELECT *
673       FROM   mtl_reservations e
674       WHERE  demand_source_header_id = P_batch_id
675       AND    demand_source_line_id = V_material_detail_id
676       AND    demand_source_type_id = gme_common_pvt.g_txn_source_type
677       AND    NOT EXISTS (SELECT 1
678                          FROM   gmd_material_details_gtmp g
679                          WHERE  parent_line_id = V_material_detail_id
680                          AND    line_type = 3
681                          AND    g.reservation_id =  e.reservation_id);
682 
683     CURSOR  Cur_get_lines (V_material_detail_id NUMBER) IS
684       SELECT *
685        FROM  gmd_material_details_gtmp
686        WHERE parent_line_id = V_material_detail_id
687        AND   line_type = 3
688        AND   transaction_id IS NULL
689        ORDER BY line_no desc;
690 
691     CURSOR  Cur_get_line_revision (V_material_detail_id NUMBER) IS
692       SELECT revision,inventory_item_id
693        FROM  gmd_material_details_gtmp
694        WHERE material_detail_id = V_material_detail_id;
695 
696     CURSOR  Cur_get_rev_control (V_item_id NUMBER) IS
697       SELECT revision_qty_control_code
698        FROM  mtl_system_items_b
699        WHERE inventory_item_id = V_item_id
700              AND organization_id = P_plant_id;
701 
702     CURSOR  Cur_get_item_revision (V_item_id NUMBER) IS
703       SELECT revision
704        FROM  mtl_item_revisions
705        WHERE inventory_item_id = V_item_id
706              AND organization_id = P_plant_id
707        ORDER BY CREATION_DATE DESC;
708 
709     CURSOR Cur_get_qty (V_reservation_id NUMBER) IS
710       SELECT reservation_quantity
711       FROM   mtl_reservations
712       WHERE  reservation_id = V_reservation_id;
713 
714     CURSOR Cur_req_date IS
715       SELECT material_requirement_date
716       FROM   gme_material_details
717       WHERE  material_detail_id = P_material_detail_id;
718 
719     CURSOR Cur_get_new_qty IS
720       SELECT qty,transaction_id,lot_number
721       FROM   gmd_material_details_gtmp
722       WHERE  material_detail_id = P_material_detail_id
723       AND    lot_number IS NOT NULL;
724 
725     CURSOR Cur_get_old_qty (V_transaction_id NUMBER, V_lot_number VARCHAR2) IS
726       SELECT transaction_quantity
727       FROM   mtl_transaction_lot_numbers
728       WHERE  transaction_id = V_transaction_id
729       AND    lot_number = V_lot_number;
730 
731     l_material_out	GME_MATERIAL_DETAILS%ROWTYPE;
732 
733     l_return_status	VARCHAR2(10);
734     l_reservation_qty   NUMBER;
735     l_requirement_date  DATE;
736     l_trans_qty		NUMBER;
737     l_item_id		NUMBER;
738     l_revision		VARCHAR2(3);
739     l_rev_control	NUMBER;
740 
741     update_alloc_err	EXCEPTION;
742     insert_alloc_err	EXCEPTION;
743     delete_alloc_err	EXCEPTION;
744     trans_update	EXCEPTION;
745 
746   BEGIN
747     /* Initialize return status */
748     X_return_status := FND_API.g_ret_sts_success;
749 
750     /* Lets check wheter transaction qty is changed for any of the material lines */
751     /* if yes raise an error message */
752     FOR l_qty IN Cur_get_new_qty LOOP
753       OPEN Cur_get_old_qty(l_qty.transaction_id,l_qty.lot_number);
754       FETCH Cur_get_old_qty INTO l_trans_qty;
755       CLOSE Cur_get_old_qty;
756       IF l_qty.qty <> ABS(l_trans_qty) THEN
757         RAISE trans_update;
758       END IF;
759     END LOOP;
760 
761     /* First let us delete all the reservations which existed in the batch */
762     /* but was deleted from the spreadsheet.                               */
763     IF P_line_type <> 1 THEN
764       FOR l_del_rec IN Cur_get_del_lines (P_material_detail_id) LOOP
765         gmd_debug.put_line(' Material:'||P_material_detail_id||' trans:'||l_del_rec.reservation_id||' reserv qty:'||l_del_rec.reservation_quantity||' Lot:'||l_del_rec.lot_number);
766         gme_reservations_pvt.delete_reservation(p_reservation_id => l_del_rec.reservation_id
767                                                 ,x_return_status => l_return_status);
768         IF X_return_status <> l_return_status THEN
769           gmd_debug.put_line('Delete allocation error:'||l_del_rec.reservation_id);
770           RAISE delete_alloc_err;
771         END IF;
772       END LOOP;
773     END IF;
774 
775     /* Then let us update/insert the reservation lines associated with the material line */
776     FOR l_rec IN Cur_get_lines (P_material_detail_id) LOOP
777       OPEN Cur_req_date;
778       FETCH Cur_req_date INTO l_requirement_date;
779       CLOSE Cur_req_date;
780 
781       --Check if the item is revision control
782       OPEN Cur_get_rev_control (P_material_detail_id);
783       FETCH Cur_get_rev_control INTO l_rev_control;
784       CLOSE Cur_get_rev_control;
785 
786       IF (l_rev_control = 2) THEN
787         /*Get the item and revision from material detail line*/
788         OPEN Cur_get_line_revision (P_material_detail_id);
789         FETCH Cur_get_line_revision INTO l_revision,l_item_id;
790         CLOSE Cur_get_line_revision;
791 
792         /*If revision is not found for that material line then fetch the lastest revision
793           from the item revisions table */
794         IF (l_revision IS NULL) THEN
795           OPEN Cur_get_item_revision (l_item_id);
796           FETCH Cur_get_item_revision INTO l_revision;
797           CLOSE Cur_get_item_revision;
798         END IF;
799       ELSE
800         l_revision := NULL;
801       END IF;
802 
803       l_material_out.inventory_item_id         := l_rec.inventory_item_id;
804       l_material_out.organization_id 	       := P_plant_id;
805       l_material_out.revision    	       := l_revision;
806       l_material_out.batch_id                  := P_batch_id;
807       l_material_out.material_requirement_date := l_requirement_date;
808       l_material_out.material_detail_id        := P_material_detail_id;
809       gmd_debug.put_line('Line:'||l_rec.line_no||' Material:'||p_material_detail_id||
810                          ' Lot Number:'||l_rec.lot_number||' Qty:'||l_rec.qty||
811                          ' Secondary:'||l_rec.secondary_qty);
812 
813       /* Let us update the existing reservations */
814       IF l_rec.reservation_id IS NOT NULL THEN
815         OPEN Cur_get_qty (l_rec.reservation_id);
816         FETCH Cur_get_qty INTO l_reservation_qty;
817         CLOSE Cur_get_qty;
818         IF l_reservation_qty <> l_rec.qty THEN
819           gme_reservations_pvt.update_reservation (p_reservation_id => l_rec.reservation_id
820                                                   ,p_revision       => l_revision
821                                                   ,p_subinventory   => l_rec.subinventory_code
822                                                   ,p_locator_id     => l_rec.locator_id
823                                                   ,p_lot_number     => l_rec.lot_number
824                                                   ,p_new_qty        => l_rec.qty
825                                                   ,p_new_sec_qty    => ABS(l_rec.secondary_qty)
826                                                   ,p_new_uom        => l_rec.detail_uom
827                                                   ,p_new_date       => SYSDATE
828                                                   ,x_return_status  => l_return_status);
829           IF X_return_status <> l_return_status THEN
830             gmd_debug.put_line('Update allocation error:'||l_rec.reservation_id);
831             RAISE update_alloc_err;
832           END IF;
833         END IF;
834       ELSE
835         /* Let us create the new reservation material line */
836         gme_reservations_pvt.create_material_reservation (p_matl_dtl_rec  => l_material_out
837                                                          ,p_resv_qty      => l_rec.qty
838                                                          ,p_sec_resv_qty  => ABS(l_rec.secondary_qty)
839                                                          ,p_resv_um       => l_rec.detail_uom
840                                                          ,p_subinventory  => l_rec.subinventory_code
841                                                          ,p_locator_id    => l_rec.locator_id
842                                                          ,p_lot_number    => l_rec.lot_number
843                                                          ,x_return_status => l_return_status);
844         IF X_return_status <> l_return_status THEN
845           gmd_debug.put_line(' Insert alloc fail'||l_return_status);
846           RAISE insert_alloc_err;
847         END IF;
848       END IF; /* IF l_rec.reservation_id IS NOT NULL THEN */
849     END LOOP; /* FOR l_rec IN Cur_get_lines (l_matl_rec.material_detail_id) */
850 
851   EXCEPTION
852     WHEN update_alloc_err OR insert_alloc_err OR delete_alloc_err THEN
853       X_return_status := l_return_status;
854     WHEN trans_update THEN
855       gmd_api_grp.log_message('GMD_QTY_NO_UPDATE');
856       X_return_status := FND_API.g_ret_sts_error;
857     WHEN OTHERS THEN
858       fnd_msg_pub.add_exc_msg (gmd_spreadsheet_update.g_pkg_name, 'Update_Allocation');
859       x_return_status := FND_API.g_ret_sts_unexp_error;
860   END update_allocation;
861 
862 END GMD_SPREADSHEET_UPDATE;