DBA Data[Home] [Help]

PACKAGE BODY: APPS.GMF_LOT_COSTING_PUB

Source


1 PACKAGE BODY GMF_LOT_COSTING_PUB AS
2 /*  $Header: GMFPLCRB.pls 120.36.12010000.2 2008/10/21 20:54:46 rpatangy ship $ */
3 
4 --****************************************************************************************************
5 --*                                                                                                  *
6 --* Oracle Process Manufacturing                                                                     *
7 --* ============================                                                                     *
8 --*                                                                                                  *
9 --* Package GMF_LOT_COSTING_PUB                                                                      *
10 --* ---------------------------                                                                      *
11 --* This package contains a publically callable procedure ROLLUP_LOT_COSTS together with several     *
12 --* utility procedures that are called by it. For individual procedures' descriptions, see the       *
13 --* description in front of each one.                                                                *
14 --*                                                                                                  *
15 --* Author: Paul J Schofield, OPM Development EMEA                                                   *
16 --* Date:   September 2003                                                                           *
17 --*                                                                                                  *
18 --* HISTORY                                                                                          *
19 --* =======                                                                                          *
20 --* 12-Sep-2003     PJS     Removed p_debug_level parameter in favour of the GMF_CONC_DEBUG profile  *
21 --*                         option. Also created the audit trail in table GMF_LOT_COST_AUDIT and     *
22 --*                         removed all code that supported the GMF_RESOURCE_LOT_COST_TXNS table.    *
23 --*                                                                                                  *
24 --* 29-Sep-2003     PJS     Added code to support CREI/CRER, TRNI/TRNR, ADJI/ADJR, XFER, OMSO/OPSO   *
25 --*                         PIPH/PICY transactions                                                   *
26 --*                                                                                                  *
27 --* 09-Oct-2003     PJS     Change of direction on storing costs. Currently if a lot is replenished  *
28 --*                         the cost is updated by calculating an averaged cost of the new and old   *
29 --*                         quantities and amending the header and details as required. In the new   *
30 --*                         method we create a new set of costs that contain what the amended costs  *
31 --*                         would have had in them. The reason is so that the sub-ledger update can  *
32 --*                         post the cost of a consumption from a lot at the correct cost, based on  *
33 --*                         the transaction date.                                                    *
34 --*                                                                                                  *
35 --* 10-Oct-2003     PJS     More changes, to incorporate burdens on lot costs. If the new burdens    *
36 --*                         table (GMF_LOT_COST_BURDENS) has an entry for the whse/item/lot/cost     *
37 --*                         method code then the burden cost is incorporated into that specific lot's*
38 --*                         costs. If there is an entry against the whse/item/cost method code then  *
39 --*                         the costs are incorporated into all of the item's lots. A lot that has   *
40 --*                         specific burdens set up will thus have the item level burdens and the    *
41 --*                         lot-specific burdens against it in its resulting lot costs.              *
42 --*                                                                                                  *
43 --* 05-Nov-2003    umoogala Changes made to use cost_category_id instead of itemcost_class.	     *
44 --*                         Also, added lot_ctl = 1 condition to where clause while getting items for*
45 --*			    a passed itemcost_class.						     *
46 --*                                                                                                  *
47 --* 10-Nov-2003    PJS      If we encounter a consumption transaction (eg OMSO) but the lot has not  *
48 --*                         been costed, report an error and skip the transaction.                   *
49 --*                         Also fixed the cursors that retrieve uncosted transactions as a new      *
50 --*                         column has been added to the gmf_lot_costed_items table (co_code) and    *
51 --*                         this created a semi-cartesian join.                                      *
52 --*                                                                                                  *
53 --* 17-Nov-2003    PJS      Reinstate the code that handles acquisition costs as it somehow became   *
54 --*                         lost.                                                                    *
55 --*                                                                                                  *
56 --* 17-Nov-2003    umoogala Removed insert into gmf_lot_cost_audit table and replaced with procedure *
57 --*                         lot_cost_audit which prints to log file when debug profile is set to 3   *
58 --*			          or more.                                                                 *
59 --*			    Introduced and used debug level l_debug_level_none/low/medium/high       *
60 --*			    instead of using numbers.					             *
61 --*			    The reason for removing audit table is the issues with packaging.        *
62 --*			    (O/X)DF doesn't support nested table. XDF allows creation, but it doesn't*
63 --*			    support update or alterations to it. Also, Oracle db itself doesn't      *
64 --*			    support updates to  nested tables - we need to drop and recreate it.     *
65 --*                                                                                                  *
66 --* 21-Nov-2003    umoogala ic_item_mst.lot_costed_flag does not exist. To work around this loaded   *
67 --*		 	    all lot costed item from gmf_lot_costed_items_flag into lc_item_tab. If  *
68 --*			    item exists in this table then lot_costed_flag is set to 1 otherwise to 0*
69 --*			    Called new function is_item_lot_costed to do this in material_cursor.    *
70 --*                                                                                                  *
71 --* 30-Nov-2003    umoogala Now passing co_code to main routines ROLLUP_LOT_COSTS and removed        *
72 --*		 	    calendar_code and user params. Using co_code where ever cldr was used.   *
73 --*		 	    Also, using cm_mthd_mst.default_lot_cost_mthd for non-lot controlled items*
74 --*                                                                                                  *
75 --* 03-Dec-2003    PJS      Moved the code that sets the inventory transaction as 'costed' to after  *
76 --*                         the main CASE statement, and made it conditional on the return status of *
77 --*                         whatever procedure was called.                                           *
78 --*                                                                                                  *
79 --* 05-Dec-2003    umoogala Enabling process for trial runs. Added flag p_final_run_flag to args list*
80 --*                         Update lot_costed_ind when flag is set to Y.                             *
81 --*                                                                                                  *
82 --* 13-Jan-2004    PJS      Fixed the cursors to cater for the case where a recipe has no routing or *
83 --*                         no step dependencies set up.                                             *
84 --*                                                                                                  *
85 --* 21-Jan-2004    umoogala Bug 3388974: Fixed burdens cursor to pickup burdens.		     *
86 --*                         Skip global burden for item when lot specific burden is there.           *
87 --*                                                                                                  *
88 --* 27-Jan-2004    PJS      Bug 3388699: Amended cursor on cm_cmpt_mtl to retrieve analysis_code     *
89 --*                         and cost component class successfully when using company as the sole     *
90 --*                         criterion. Date ranging also added.                                      *
91 --*                                                                                                  *
92 --* 29-Jan-2004    PJS      Reworked burdens processing and acquisition cost processing to ensure    *
93 --*                         correct averaging is always performed. Rescinded some fixes from bug     *
94 --*                         3388974 as they were redundant and reinstated some code that was taken   *
95 --*                         out. Look for comments starting 3388974-2                                *
96 --*                                                                                                  *
97 --* 10-Feb-2004    PJS      Exchange rates catered for on TRNI/TRNR transactions if the movement is  *
98 --*                         between companies that use different currencies.                         *
99 --*                                                                                                  *
100 --* 11-Feb-2004    PJS      Set the actual_cost_ind in GME_BATCH_HEADER if the program is being run  *
101 --*                         in 'final' mode.                                                         *
102 --*                                                                                                  *
103 --* 12-Feb-2004    PJS      Various changes for bugs 3399618, 3401451, 3397388 and 3397408. These    *
104 --*                         reported different manifestations of the same problem of either adding   *
105 --*                         a duplicate row to the gmf_lot_cost_details table (the duplicate was a   *
106 --*                         burden row that shared the same keys) or a division by zero if there     *
107 --*                         was no onhand quantity.                                                  *
108 --*                                                                                                  *
109 --* 12-Feb-2004    PJS      Changes to prevent multiple updates to a cost header flagged as 'Final'. *
110 --*                         We now clone the row and the associated details so that the onhand_qty   *
111 --*                         can be maintained correctly. Also treat batch ingredient lines in the    *
112 --*                         same was ADJI/R transactions.                                            *
113 --*                                                                                                  *
114 --* 17-Feb-2004    PJS      Set the final flag in the cost heder if mode is not draft.               *
115 --*                                                                                                  *
116 --* 24-Feb-2004    PJS      Fixed indexing when writing burdens for a CREI                           *
117 --*                                                                                                  *
118 --* 25-Feb-2004    PJS      Added burden_ind to gmf_cost_type.                                       *
119 --*                                                                                                  *
120 --* 25-Feb-2004    PJS      Added handling for replenishing negative onhand quantities.              *
121 --*                                                                                                  *
122 --* 03-Mar-2004    umoogala Bug 3476508: setting status to show normal/warning/error on process req  *
123 --*			    screen.                                                                  *
124 --*			    Also, if any error is found in a trx (say, no rsrc cost), now we will    *
125 --*			    skip all trxns related to that item/lot/whse combination.                *
126 --*                                                                                                  *
127 --* 08-Mar-2004    PJS      Changes for bugs 3485915 (receipt uom conversion) and 3476427 (order of  *
128 --*                         parameters changed)                                                      *
129 --*                                                                                                  *
130 --* 09-Mar-2004    PJS      Ignore the orgn_code in the transaction when looking up resource costs   *
131 --*                         and use ic_whse_mst to find the correct one instead.                     *
132 --*                                                                                                  *
133 --* 11-Mar-2004    PJS      Changes to support lot cost adjustments (a pseudo transaction of type    *
134 --*                         'LADJ'). Also introduced logic to skip transactions for lots that have   *
135 --*                         failed costing attempts already.                                         *
136 --*                                                                                                  *
137 --* 15-Mar-2004    PJS      XFER txns do not use line types of +1 and -1. Use line id instead to     *
138 --*                         decide 1 => -1, 3 => +1                                                  *
139 --*                                                                                                  *
140 --* 17-Mar-2004    PJS      Various issues with cost adjustments. Altered cursors to respect delete  *
141 --*                         marks and retrieve the item's primary uom. Also avoided in/out clash in  *
142 --*                         call to create_header. No bug reference.                                 *
143 --*                                                                                                  *
144 --* 18-Mar-2004    umoogala Lot Cost Adjustment query fix. Removed ref to gmf_lot_cost_adjustment_dtls*
145 --*                                                                                                  *
146 --* 19-Mar-2004    PJS      Bug 3514108 - RMA fixes and Bug 3513668 - Requisitions                   *
147 --*                                                                                                  *
148 --* 22-Mar-2004    PJS      Reworked 3485915 and 3476427. Also tightened up error messaging for the  *
149 --*                         cases where clashing parameters are specified. 3486228 also fixed by     *
150 --*                         setting the transaction quantity to the residual quantity when a balance *
151 --*                         is flipped positive again.                                               *
152 --*                                                                                                  *
153 --* 24-Mar-2004    umoogala Lot Cost Adjustments. Updating onhand_qty in adjs table. Now trans_id in *
154 --*			    material txn table is -ve of cost_trans_id.				     *
155 --*			    Another change to clear old_cost record for each trx being processed.    *
156 --*                                                                                                  *
157 --* 25-Mar-2004    PJS      No bug reference. Do not use new_cost_tab elements as the target of an   *
158 --*                         OUT NOCOPY procedure parameter as a run time error results.              *
159 --*                                                                                                  *
160 --* 29-Mar-2004    PJS      BUG 3533452. Change process_batch procedure so that the same merge       *
161 --*                         procedure is called that other procedures call. Also gross up retrieved  *
162 --*                         cost by the yield quantity.                                              *
163 --*                                                                                                  *
164 --* 29-Mar-2004    umoogala Modified delete_lot_costs to first check item_id instead of category     *
165 --*                         since item overrides category.					     *
166 --*                                                                                                  *
167 --* 30-Mar-2004    PJS      Resolved an arry out of bounds error from 3533452.                       *
168 --*                                                                                                  *
169 --* 06-Apr-2004    PJS      Major changes to handle multiple yields from the same step and also to   *
170 --*                         handle to differing requirements of yields from terminal/non-terminal    *
171 --*                         steps. Also deleted procedure dump_batch_steps in favour of the lot_     *
172 --*                         cost_audit variant and tided up the debug lines. Batch changes cover     *
173 --*                         bug 3548217.                                                             *
174 --*                                                                                                  *
175 --* 06-Apr-2004    PJS      Fixed small problem with batches that possess a routing but no step      *
176 --*                         dependency chain. Now attach all inventory to final step.                *
177 --*                                                                                                  *
178 --* 07-Apr-2004    PJS      B3556291 - attach any unassociated ingredients to first step and any     *
179 --*                         unassociated products to final step                                      *
180 --*                                                                                                  *
181 --* 15-Apr-2004    PJS      Various issues with mixed mode accounting in the same batch. Anything    *
182 --*                         that is not a lot costed (co) product now has its costs subtracted from  *
183 --*                         the total costs accrued to date before the residual costs are shared     *
184 --*                         amongst the remaining lot costed products. Also tidied up a bit so that  *
185 --*                         presets no longer cause GSCC warnings.                                   *
186 --*                                                                                                  *
187 --* 16-Apr-2004    PJS      Sub Ledger Update has a problem with the costs generated for batch       *
188 --*                         yields if the cost(s) have been replenished. To get round this the       *
189 --*                         calculated costs are stored alongside the merged costs but with a        *
190 --*                         negated header ID. This is for bug 3578680 and now applies to all lots   *
191 --*                         that are replenished.                                                    *
192 --*                                                                                                  *
193 --* 22-Apr-2004    PJS      Rider to previous change. So as not to degrade the performance of the    *
194 --*                         SLU process a new column 'new_cost_ind' is being added to the gmf_       *
195 --*                         material_lot_cost_txns table. If a cost is updated then the indicator    *
196 --*                         will be set to 1. Null otherwise. This saves a select per transaction in *
197 --*                         the SLU as most of the time there will not be a new cost.                *
198 --*                                                                                                  *
199 --* 05-May-2004    PJS      Reworked the fix for bug 3578680 for TRNI etc.                           *
200 --*                                                                                                  *
201 --* 06-May-2004    umoogala Updating gmf_lot_cost_adjustments rows even in trial run for subledger to*
202 --*                         process. Only in final mode applied_ind is set to 'Y'. No bug was created*
203 --*                                                                                                  *
204 --* 25-May-2004    PJS      Bug 3643858. Include delete mark on LADJ cursor.  			     *
205 --*												     *
206 --* 19-Aug-2004    Dinesh   Bug# 3831782                                         	             *
207 --*        Added where clause in the queries in proc rollup_lot_costs to ignore the                  *
208 --*        Lot Cost Adjustment Records which has no Detail Records(i.e., NULL Adjustment Cost)       *
209 --*
210 --* 27-Nov-2004 Dinesh Vadivel Bug# 4004338
211 --*       Modified the basic INV_TRAN_CURSOR query to order the transactions from ic_tran_pnd table.
212 --*       Right now if we change a batch actual output qty from 100 to 150, the records in ic_tran_pnd table are
213 --*       in order as 100, 150 and -100 .
214 --*      Since our costing logic, needs them in 100,-100 and 150 order inv_tran_Cursor's order_by clause is modified
215 --*
216 --* 15-Dec-2004 Dinesh Vadivel Bug# 4053149
217 --*      Modified the process_batch to handle the various cases for the step dependencies
218 --*      and to create the virtual row appropriately. Also added new explosion_cursor_ss
219 --*
220 --*     Modified the process_reversals to populate the new_cost_ind. modified the call to the
221 --*     create_material_transaction to pass this new_cost_ind instead of NULL. This field is
222 --*     being used in SL update posting.
223 --*
224 --* 06-Jan-2004 Dinesh Vadivel Bug# 4095937
225 --*       The Lot Cost Process calculates the Exchg Rate as on the Receipt Header Date
226 --*        whereas the Subledger uses the "Exchg Rate Date". Modified the Lot Actual Cost Process
227 --*        to use the rcv_transactions.CURRENCY_CONVERSION_RATE as the Exchg Rate .
228 --*       This is how we are doing in Actual Costing and Subledger Update
229 --*
230 --*  20-Jan-2005 Girish Jha Bug 4094132
231 --*       We added a new filtering condition in the materials_cursor for handling reversals
232 --*
233 --* 28-Jan-2005 Dinesh Vadivel Bug 4057323 - Cost Allocation Factor Enhancement.
234 --*        Modified code especially in process_batch to use Cost Allocation Factor when the profile
235 --*        "GMF: Use Cost Alloc Factor in Lot Costing" is set to Yes. Also the cost Allocation factor will
236 --*         considered only under any of the following cases
237 --*       1. All the Products have to be yielded at one single step, not necessarily terminal step
238 --*       2. No Product should be associated to any step.
239 --*
240 --* 28-Jan-2005 Dinesh Vadivel - Bug 4149549 - Issue occurs only when debug_level is not 3.
241 --*      In rollup_lot_costs the initialization of old_cost.onhand_qty has been done inside the
242 --*      IF(l_debug_level >= debug_level_high)..... So the variable didn't get initialized when the
243 --*      debug level is not 3.
244 --*
245 --*   30-Jan-2005 Dinesh Vadivel Bug# 4152397
246 --*      Uncommented the code which fetches lot_id into l_lot_id for the lot_no
247 --*      entered on Lot ACP screen.
248 --*      Also, the inv_tran_cursor inside "ELSIF l_item_id IS NOT NULL .... "
249 --*      we have filter only those LADJ transactions for that particular Lot_id if any.
250 --*
251 --*   02-Feb-2005 Dinesh Vadivel Bug# 4130869
252 --*       Modified the Lot_Cost_Cursor to also filter by correct transaction_date
253 --*
254 --*  03-Feb-2005 - Bug 4144329 - Dinesh Vadivel - If there is no cost defined for Resource
255 --*            then don't stop by setting the cost as uncostable. Just give a warning and ignore
256 --*            the resources.
257 --*
258 --*  24-Feb-2005 Dinesh Vadivel Bug# 4177349
259 --*      When a batch is reversed to WIP, the Lot Cost process fails at process_reversals
260 --*      Now modified the code to handle the product yielding transactions.
261 --*      Added process_wip_batch for this purpose. More comments before the procedure
262 --*      definition
263 --*   24-Feb-2005 Dinesh Vadivel Bug# 4187891
264 --*      Cancellation of Inv Xfer has been modified such that it is considered
265 --*       as if it is an actual transfer where the source and destination warehouses are the same.
266 --*  24-Feb-2005 Dinesh Vadivel Bug# 4176690
267 --*      Added a new Date Field in the Lot Cost Process submission screen
268 --*      All the transactions only upto the Date entered will be considered for Lot Costing.
269 --*  13-Mar-2005 Dinesh Vadivel Bug# 4227784
270 --*    - Both these bugs have same code change of replacing l_total_item_qty to actual_line_qty
271 --*      in process_batch()
272 --*    - Added NVL clause in process_reversals to avoid "ORA error- Cannot insert NULL into
273 --*      into TOTAL_TRANS_COST".
274 --*    - Moved the old_cost.onhand_qty into ELSE part of lot_cost_cursor%FOUND in
275 --*      rollup_lot_costs(). This is to initialize if there is no record in gmf_lot_costs
276 --*  19-Apr-2005 Dinesh Bug# 4165614
277 --*     Passed correct shipped date to book the receive transaction in case of internal orders
278 --*     Modified argument passing date for process_movements in process_receipts()
279 --*  28-Apr-2005 WmJohn Harris Bug# 4307381  --  procedure process_batch :
280 --*     more detailed debug info for 2 msgs 'Unable to convert from ' ... correct subscript in 2nd msg
281 --*  23-May-2005 Dinesh Vadivel - Bug 4320765 - Modified item_cost_cursor to support warehouse association
282 --*     functionality for the Alternate Cost Method
283 --*  31-May-2005 Dinesh Vadivel - Bug 4320765(Part B)
284 --*     Modified "Explosion_Cursor" to avoid duplicate rows
285 --*  01-Jun-2005 Sukarna Reddy INCONV changes for release 12.
286 --*  07-Jun-2006 Anand Thiyagarajan Bug#5285726
287 --*     Modified Code to remove the references to trans_id in gmf_material_lot_cost_txns table
288 --*     which caused the lot cost process after a final run to calculate wrong costs
289 --*  07-Jun-2006 Anand Thiyagarajan Bug#5287514
290 --*     Modified code to call process_receipts procedure for Purchase Order Return to Vendors
291 --*     and for PO Receipt corrections, which are similar to the Purchase Order receipts with a +ve or -ve signs
292 --*  26-Jul-2006 Anand Thiyagarajan Bug#5412410
293 --*     Modified code in process_lot_split and process_lot_translate to correct the code pertaining to call of
294 --*     merge_costs procedure and also to correct the value of total trans cost and unit cost being passed to the
295 --*     create_material_transaction and create_lot_header procedures.
296 --*  14-Aug-2006 Anand Thiyagarajan Bug#5463200
297 --*     Modified Code in the Special Charges query to remove po_line_locations_all, changed the
298 --*     value for include_in_acquisition_cost to "I", used estimated_amount instead of actual
299 --*     and included MMT table join with RCV_TRANSACTION_ID instead of INV_TRANSACTION_ID
300 --*   2-Aug-2007 Venkat Ch. Bug 6320304/5953977 - Non-recoverable taxes ME, as part of this
301 --*     added unit of nonrecoverable tax to the unit cost in process_receipt().
302 --*   30-Jun-2008 Bug 7215069
303 --*      Changed ordering for Receipt transactions in inv_tran_cursor. If transactions exist for multiple
304 --*      document types with same transaction date then first process the receipt transactions.
305 --*   26-Aug-2008 Pramod B.H. Bug#7306720
306 --*      Modified the cursor component_class_cursor to handle the issue of LACP considering incorrect
307 --*      cost component class.
308 --****************************************************************************************************
309 
310 
311 
312 
313 
314 
315   --**********************************************************************************************
316   --*                                                                                            *
317   --* The procedures in this package share a common set of data structures. The most complex one *
318   --* being the l_step_tab table defined as being of type gmf_step_tab. This is a database type  *
319   --* that has nested tables in it. Once a batch has been exploded, its steps will be ordered    *
320   --* correctly in this table so that the costs of a step can be rolled forward into subsequent  *
321   --* steps until we fall off the end of the routing.                                            *
322   --*                                                                                            *
323   --**********************************************************************************************
324 
325 
326 
327     /* INVCONV sschinch Constants representing Transaction source type id */
328     PURCHASE_ORDER      CONSTANT PLS_INTEGER  := 1;
329     SALES_ORDER         CONSTANT PLS_INTEGER  := 2;
330     ACCOUNT             CONSTANT PLS_INTEGER  := 3;
331     MOVE_ORDER          CONSTANT PLS_INTEGER  := 4;  -- B 6859710
332     BATCH               CONSTANT PLS_INTEGER  := 5;
333     ACCOUNT_ALIAS       CONSTANT PLS_INTEGER  := 6;
334     INTERNAL_REQ        CONSTANT PLS_INTEGER  := 7;
335     INTERNAL_ORDER      CONSTANT PLS_INTEGER  := 8;
336     CYCLE_COUNT         CONSTANT PLS_INTEGER  := 9;
337     PHYSICAL_INVENTORY  CONSTANT PLS_INTEGER  :=10;
338     RMA                 CONSTANT PLS_INTEGER  :=12;
339     INVENTORY           CONSTANT PLS_INTEGER  :=13;
340 
341 
342     /* INVCONV sschinch Transaction Actions */
343 
344     LOT_COST_ADJUSTMENT         CONSTANT PLS_INTEGER :=0;
345     ISSUE_FROM_STORES           CONSTANT PLS_INTEGER := 1;
346     DIRECT_ORG_TRANSFER         CONSTANT PLS_INTEGER := 3;
347     CYCLE_COUNT_ADJUSTMENT      CONSTANT PLS_INTEGER := 4;
348     OWNERSHIP_TRANSFER          CONSTANT PLS_INTEGER := 6;
349     PHYSICAL_INVENTORY_ADJST    CONSTANT PLS_INTEGER := 8;
350     INTRANSIT_RECEIPT           CONSTANT PLS_INTEGER := 12;
351     LOGICAL_INTRANSIT_RECEIPT   CONSTANT PLS_INTEGER := 15;
352     INTRANSIT_SHIPMENT          CONSTANT PLS_INTEGER := 21;
353     LOGICAL_INTRANSIT_SHIPMENT  CONSTANT PLS_INTEGER := 22;
354     RECEIPT_INTO_STORES         CONSTANT PLS_INTEGER := 27;
355     DELIVERY_ADJUSTMENTS        CONSTANT PLS_INTEGER := 29; /* ANTHIYAG Bug#5287514 07-Jun-2006 */
356     LOT_SPLIT                   CONSTANT PLS_INTEGER := 40;
357     LOT_MERGE                   CONSTANT PLS_INTEGER := 41;
358     LOT_TRANSLATE               CONSTANT PLS_INTEGER := 42;
359 
360 
361     /* INVCONV sschinch FOB flags */
362     FOB_SHIPPING   CONSTANT PLS_INTEGER := 1;
363     FOB_RECEIVING  CONSTANT PLS_INTEGER := 2;
364 
365     l_calendar_code    cm_cldr_hdr.calendar_code%TYPE;
366     l_default_cost_type_id NUMBER; /* INVCONV sschinch */
367     l_le_id          NUMBER;
368     l_cost_type_id      NUMBER;
369 
370     --Use this to get the costof non-lot controlled items
371     l_default_lot_cstype_id  NUMBER;
372     l_cost_method_code  cm_mthd_mst.cost_mthd_code%TYPE;
373     l_trans_start_date  cm_mthd_mst.trans_start_date%TYPE;
374 
375     --l_cost_class       mtl_categories_v.category_concat_segs%TYPE;
376     l_cost_category_id  mtl_categories_v.category_id%TYPE;
377 
378 
379     --l_item_no            VARCHAR2(800);
380     l_lot_no             mtl_lot_numbers.LOT_NUMBER%TYPE; /* INVCONV sschinch */
381 
382     l_debug_level      PLS_INTEGER;
383     l_user             fnd_user.user_name%TYPE;
384     l_return_status    VARCHAR2(1) := 'S';
385 
386     l_final_run_date DATE; -- Bug 4176690
387 
388 
389     l_debug_level_none     PLS_INTEGER;
390     l_debug_level_low      PLS_INTEGER;
391     l_debug_level_medium   PLS_INTEGER;
392     l_debug_level_high     PLS_INTEGER;
393 
394     TYPE l_cost_tab_type IS TABLE OF SYSTEM.gmf_cost_type INDEX BY PLS_INTEGER;
395 
396     old_cost           gmf_lot_costs%ROWTYPE;
397     old_cost_tab       l_cost_tab_type; -- Existing lot costs of lot being rolled up
398 
399     new_cost           gmf_lot_costs%ROWTYPE;
400     new_cost_tab       l_cost_tab_type; -- New lot costs of lot being rolled up
401 
402     ing_cost           gmf_lot_costs%ROWTYPE;
403     ing_cost_tab       l_cost_tab_type; -- Batch ingredient cost
404 
405     prd_cost           gmf_lot_costs%ROWTYPE;
406     prd_cost_tab       l_cost_tab_type; -- Batch product cost
407 
408     cur_cost_tab       l_cost_tab_type; -- Current costs of batch step
409 
410     res_cost           NUMBER;
411     item_unit_cost     NUMBER;
412     lot_unit_cost      NUMBER;
413     lot_total_cost     NUMBER;
414 
415 
416     l_rate_type_code   VARCHAR2(4);
417     l_from_ccy_code    VARCHAR2(4);
418     l_to_ccy_code      VARCHAR2(4);
419     l_exchange_rate    NUMBER;
420     l_mul_div_sign     NUMBER;
421     l_error_status     NUMBER;
422 
423     l_lot_number  mtl_lot_numbers.lot_number%type; /* INVCONV sschinch */
424     l_source_lot_number mtl_lot_numbers.lot_number%type; /* INVCONV sschinch */
425     l_orgn_id NUMBER;
426 
427     l_base_ccy_code VARCHAR2(4);  /* Bug 4038722 Dinesh Vadivel */
428 
429 
430     l_tmp  BOOLEAN; -- Bug 3476508
431     i      PLS_INTEGER; -- Loop counter to sweep through uncosted inventory transactions
432     j      PLS_INTEGER;
433     k      PLS_INTEGER;
434     l      PLS_INTEGER;
435 
436     dummy  NUMBER;
437     l_item_id          mtl_item_flexfields.inventory_item_id%TYPE;
438     l_batchstep_id     NUMBER;
439     l_total_qty        NUMBER;
440     TYPE num_tab       IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
441     TYPE char_tab      IS TABLE OF VARCHAR2(80) INDEX BY VARCHAR2(80); /* INVCONV sschinch */
442 
443     TYPE org_tab       IS TABLE OF VARCHAR2(4) INDEX BY BINARY_INTEGER; /* INVCONV sschinch */
444     l_org_tab          org_tab;  /* INVCONV sschinch */
445     l_cost_mthd_code   cm_mthd_mst.cost_mthd_code%type;
446     l_default_cost_mthd cm_mthd_mst.cost_mthd_code%type;
447 
448     l_step_lev         num_tab;
449     l_step_tab         SYSTEM.gmf_step_tab;
450     l_skip_this_batch  BOOLEAN ;
451     l_skip_this_txn    BOOLEAN ;
452     l_cost_accrued     BOOLEAN ;
453     l_batch_status     NUMBER;
454     l_cost_factor      NUMBER;
455     l_step_index       NUMBER;
456 
457     receipt_qty         NUMBER;
458     receipt_unit_cost   NUMBER;
459     receipt_uom         VARCHAR2(3);
460     receipt_ccy         VARCHAR2(4);
461     l_residual_qty      NUMBER;
462     l_flg_ind           NUMBER;
463 
464     component_class_id  cm_cmpt_mst.cost_cmpntcls_id%TYPE;
465     cost_analysis_code  cm_alys_mst.cost_analysis_code%TYPE;
466 
467     /*l_uncostable_lots_tab num_tab; INVCONV sschinch*/
468       /*l_uncostable_lots_tab char_tab;  jboppana */
469 
470     TYPE lot_uncostable_lots_tab IS TABLE OF mtl_item_flexfields.inventory_item_id%TYPE INDEX BY VARCHAR2(150);
471     l_uncostable_lots_tab        lot_uncostable_lots_tab;
472 
473 
474     l_cost_alloc_profile NUMBER; -- Bug 4057323
475 
476     TYPE burdens_rec IS RECORD
477     (
478       LOT_BURDEN_LINE_ID              NUMBER(15)
479     , RESOURCES                       VARCHAR2(32)
480     , COST_CMPNTCLS_ID                NUMBER(10)
481     , COST_ANALYSIS_CODE              VARCHAR2(4)
482     , BURDEN_FACTOR                   NUMBER
483     , BURDEN_COST                     NUMBER
484     );
485 
486 
487     TYPE burdens_tab IS TABLE OF burdens_rec;
488     l_burdens_tab       burdens_tab;
489     l_burden_cost       NUMBER;
490     l_burden_costs_tab  l_cost_tab_type;
491     l_burdens_total     NUMBER;
492 
493     l_acqui_cost_tab    l_cost_tab_type;
494     l_acquisitions_total NUMBER;
495 
496     l_onhand_qty         NUMBER;
497     -- umoogala
498     TYPE lot_costed_items_tab IS TABLE OF mtl_item_flexfields.inventory_item_id%TYPE INDEX BY VARCHAR2(64);
499     lc_items_tab        lot_costed_items_tab;
500 
501     -- WHO columns -- umoogala 05-Dec-2003
502     l_user_id		fnd_user.user_id%TYPE;
503     l_login_id		NUMBER;
504     l_prog_appl_id  	NUMBER;
505     l_program_id	NUMBER;
506     l_request_id	NUMBER;
507 
508     l_routing           NUMBER;
509     l_dep_steps         NUMBER;
510    -- l_step_items        NUMBER;     /* No where used */
511     l_prior_step_id     NUMBER;
512 
513     l_final_run_flag	NUMBER(1);	 -- 1 for final run and 0 for trial run
514 
515 
516 /* FORWARD DECLARATIONS INVCONV sschinch */
517 
518 
519 
520 
521     --**********************************************************************************************
522     --*                                                                                            *
523     --* These next few declarations are for the main driving query. The rollup_lot_costs procedure *
524     --* is callable in several ways, and, for efficiency, each type of invocation has a dedicated  *
525     --* cursor. Each one returns rows of transaction_type (defined below). The rollup_lot_costs    *
526     --* procedure examines the parameters passed in and sets up a cursor appropriate to them.      *
527     --*                                                                                            *
528     --**********************************************************************************************
529 
530     TYPE transaction_type  IS RECORD
531     ( doc_id            NUMBER
532     , transaction_source_type_id  NUMBER(5)
533     , inventory_item_id           NUMBER
534     , line_id           NUMBER
535     , line_type         NUMBER
536     , lot_number         VARCHAR2(80)
537     , trans_date        DATE
538     , transaction_id          NUMBER
539     , trans_qty         NUMBER
540     , trans_um          VARCHAR2(4)
541     , orgn_id           NUMBER
542     , source            NUMBER(1)
543     , reverse_id        NUMBER
544     , transaction_action_id NUMBER(5)
545     , transfer_price     NUMBER
546     , transportation_cost NUMBER
547     , fob_point          NUMBER(1)
548     , transfer_transaction_id NUMBER
549     , transaction_cost     NUMBER
550     , transfer_orgn_id   NUMBER
551     );
552 
553     TYPE inv_tran_cursor_type IS REF CURSOR RETURN transaction_type;
554 
555     transaction_row transaction_type;
556 
557     /* INVCONV sschinch */
558     TYPE child_lots_rec  IS RECORD
559     ( lot_number VARCHAR2(80),
560       trans_qty  NUMBER,
561       trans_date DATE
562     );
563     child_lot_row  child_lots_rec;
564 
565     --**********************************************************************************************
566     --*                                                                                            *
567     --* This, rather complex, cursor explodes the batch routing and orders the steps in an order   *
568     --* suitable for the rollup. This is not necessarily the same as the ordering implied by the   *
569     --* step dependencies. The terminal step(s) of the routing are found and then a heirarchical   *
570     --* sub-query generates the base rows (that are added to by other parts of the query) ordered  *
571     --* by distance from the terminal step(s).                                                     *
572     --*                                                                                            *
573     --* The explosion handles linear, converging, diverging and parallel route sections and works  *
574     --* with any arbitrary routing step dependence topology, with the important exception of loops *
575     --* as this introduces a 'feedback' loop.                                                      *
576     --*                                                                                            *
577     --* Each row retrieved consists of a nested table of step-related data, which itself consists  *
578     --* of several nested tables so that we have a resulting structure as follows:                 *
579     --*                                                                                            *
580     --* Table of steps                                                                             *
581     --*   Each step consists of step_id, step_qty, step_uom, output_qty                            *
582     --*                         table of inherited costs,                                          *
583     --*                         table of current costs                                             *
584     --*                         table of step costs (= inherited + current)                        *
585     --*                         table of material txns                                             *
586     --*                         table of resource txns                                             *
587     --*                         table of steps that follow this step                               *
588     --*                                                                                            *
589     --*   Each inherited cost consists of cost component class, cost analysis code, level and cost *
590     --*                                                                                            *
591     --*   Each current cost has the same format as an inherited cost                               *
592     --*                                                                                            *
593     --*   Each material transaction consists of data from ic_tran_pnd and a cost table which is    *
594     --*   in the same format as the inherited costs                                                *
595     --*                                                                                            *
596     --*   Each resource transaction consists of data from gme_resource_txns and a cost table which *
597     --*   which is in the same format as the inherited costs                                       *
598     --*                                                                                            *
599     --*   Each step dependency consists of inherited step qty, step_qty_uom and the index of the   *
600     --*   dependent step in the structure.                                                         *
601     --*                                                                                            *
602     --*   This entire structure is dumped to the gmf_lot_cost_audit table when a lot's cost has    *
603     --*   been generated.                                                                          *
604     --**********************************************************************************************
605     --* NOTE: The columns in gmf_step_dependencies are a bit ambiguous. The dep_step_id is better  *
606     --* thought of as 'prior_step_id' as it is the one on which the (current) batchstep_id depends *
607     --**********************************************************************************************
608 
609 
610     CURSOR explosion_cursor
611     ( p_batch_id NUMBER )
612     IS
613       SELECT  max(grsd.seq)
614       , SYSTEM.gmf_step_type
615         ( grsd.dep_step_id, gbs.actual_step_qty, gbs.step_qty_um, 0
616         , CAST
617           ( MULTISET
618             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
619               FROM   DUAL
620             ) AS SYSTEM.gmf_cost_tab
621           )
622         , CAST
623           ( MULTISET
624             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
625               FROM   DUAL
626             ) AS SYSTEM.gmf_cost_tab
627           )
628         , CAST
629           ( MULTISET
630             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
631               FROM   DUAL
632             ) AS SYSTEM.gmf_cost_tab
633           )
634         , NULL, NULL
635         , CAST
636           ( MULTISET
637             (
638               SELECT SYSTEM.gmf_dependency_type(a.batchstep_id, b.actual_step_qty, b.step_qty_um, NULL)
639               FROM   gme_batch_step_dependencies a, gme_batch_steps b
640               WHERE  a.batch_id = p_batch_id and a.dep_step_id = grsd.dep_step_id
641               AND    a.batchstep_id = b.batchstep_id
642               AND    a.batch_id = b.batch_id
643             ) AS SYSTEM.gmf_dependency_tab
644           )
645         )
646       FROM
647       (
648         SELECT MAX(level) seq, dep_step_id, batchstep_id
649         FROM   gme_batch_step_dependencies
650         START WITH batch_id = p_batch_id
651         AND   batchstep_id NOT IN (SELECT dep_step_id FROM gme_batch_step_dependencies WHERE batch_id=p_batch_id)
652         CONNECT BY PRIOR dep_step_id = batchstep_id AND batch_id = PRIOR batch_id
653         GROUP BY dep_step_id, batchstep_id
654       ) grsd
655       , gme_batch_steps gbs
656       WHERE gbs.batch_id = p_batch_id
657       AND   gbs.batchstep_id = grsd.dep_step_id
658       GROUP BY  grsd.dep_step_id, gbs.actual_step_qty, gbs.step_qty_um
659       UNION ALL
660       SELECT 0
661       , SYSTEM.gmf_step_type
662         ( g.batchstep_id, g.actual_step_qty, g.step_qty_um, 0
663         , CAST
664           ( MULTISET
665             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
666               FROM   DUAL
667             ) AS SYSTEM.gmf_cost_tab
668           )
669         , CAST
670           ( MULTISET
671             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
672               FROM   DUAL
673             ) AS SYSTEM.gmf_cost_tab
674           )
675         , CAST
676           ( MULTISET
677             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
678               FROM   DUAL
679             ) AS SYSTEM.gmf_cost_tab
680           )
681         , NULL, NULL
682         , CAST
683           ( MULTISET
684             (
685               SELECT SYSTEM.gmf_dependency_type(NULL, NULL, NULL, NULL)
686               FROM   DUAL
687             ) AS SYSTEM.gmf_dependency_tab
688           )
689         )
690       FROM
691       ( SELECT DISTINCT/*Bug 4320765*/ gbsd.batchstep_id, gbs2.actual_step_qty, gbs2.step_qty_um
692         FROM gme_batch_step_dependencies gbsd
693       ,      gme_batch_steps gbs2
694       WHERE  gbsd.batch_id = p_batch_id
695       AND    gbs2.batch_id = p_batch_id
696       AND    gbsd.batchstep_id NOT IN
697              (SELECT dep_step_id from gme_batch_step_dependencies where batch_id = p_batch_id)
698       AND    gbsd.batchstep_id = gbs2.batchstep_id ) g
699       ORDER BY 1 desc;
700     --**********************************************************************************************
701     --                                                                                             *
702     -- This cursor does pretty much the same thing as above, but caters for the situation where    *
703     -- the recipe does not have a routing. We simply create a ficticious step (0) and attach all   *
704     -- materials and their transactions and costs to it. The _nr suffix means 'No Routing'         *
705     --                                                                                             *
706     --**********************************************************************************************
707 
708     CURSOR explosion_cursor_nr
709     IS
710       SELECT 0
711       , SYSTEM.gmf_step_type
712         ( 1, 0, NULL, 0
713         , CAST
714           ( MULTISET
715             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
716               FROM   DUAL
717             ) AS SYSTEM.gmf_cost_tab
718           )
719         , CAST
720           ( MULTISET
721             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
722               FROM   DUAL
723             ) AS SYSTEM.gmf_cost_tab
724           )
725         , CAST
726           ( MULTISET
727             ( SELECT SYSTEM.gmf_cost_type( 0, ' ', 0, 0, 0)
728               FROM   DUAL
729             ) AS SYSTEM.gmf_cost_tab
730           )
731         , NULL, NULL
732         , CAST
733           ( MULTISET
734             (
735               SELECT SYSTEM.gmf_dependency_type(NULL, NULL, NULL, NULL)
736               FROM   DUAL
737             ) AS SYSTEM.gmf_dependency_tab
738           )
739         )
740       FROM DUAL;
741 
742 
743    --**********************************************************************************************
744     --*                                                                                                                                                         *
745     --* Cursor to retrieve step from a SINGLE STEP BATCH which obviously                            *
746     --* will not have any dependency associated                                                                              *
747     --*                                                                                                                                                         *
748     --**********************************************************************************************
749       CURSOR explosion_cursor_ss(p_batch_id NUMBER)
750       IS
751          SELECT 0,
752           SYSTEM.gmf_step_type
753              (gbs.batchstep_id,
754               gbs.actual_step_qty,
755               gbs.step_qty_um,
756               0,
757               CAST (MULTISET (SELECT SYSTEM.gmf_cost_type (0, ' ', 0, 0, 0)
758                                 FROM DUAL) AS SYSTEM.gmf_cost_tab
759                    ),
760               CAST (MULTISET (SELECT SYSTEM.gmf_cost_type (0, ' ', 0, 0, 0)
761                                 FROM DUAL) AS SYSTEM.gmf_cost_tab
762                    ),
763               CAST (MULTISET (SELECT SYSTEM.gmf_cost_type (0, ' ', 0, 0, 0)
764                                 FROM DUAL) AS SYSTEM.gmf_cost_tab
765                    ),
766               NULL,
767               NULL,
768               CAST
769                  (MULTISET (SELECT SYSTEM.gmf_dependency_type (NULL, NULL, NULL, NULL)
770                               FROM DUAL) AS SYSTEM.gmf_dependency_tab
771                  )
772              )
773          FROM gme_batch_steps gbs
774          WHERE gbs.batch_id = p_batch_id  ;
775 
776 
777     --**********************************************************************************************
778     --*                                                                                            *
779     --* Cursor to retrieve steps that have not been set up in a dependency chain                   *
780     --*                                                                                            *
781     --**********************************************************************************************
782 
783     CURSOR steps_cursor (p_batch_id NUMBER)
784     IS
785      SELECT batchstep_no, batchstep_id
786      FROM   gme_batch_steps
787      WHERE  batch_id = p_batch_id
788      ORDER  by batchstep_no;
789 
790     --***************************************************************************************************************
791     --*                                                                                            *
792     --* Cursor to retrieve all material transactions for a given batch step.                       *
793     --*                                                                                            *
794     --* This cursor would ideally be nested inside the above cursor, but SQL syntax does not allow *
795     --* an order by clause in a subquery, and we need to have the transactions ordered by date     *
796     --*                                                                                            *
797     --* umoogala: ic_item_mst.lot_costed_flag does not exist. To work around this loaded all lot   *
798     --* costed item from gmf_lot_costed_items_flag into lc_item_tab. If item exists in this table  *
799     --* then lot_costed_flag is set to 1 otherwise to 0.                                           *
800     --*
801     --* Girish - Bug 4094132 Modified this materials cursor NOT IN clause to add  lot_id and reverse_id
802     --*  Since we are filtering the query using "NOT IN" the product yielded into multiple lots
803     --*  is not costed correctly. So added this condition.
804     --*
805     --* Dinesh Vadivel - Bug 4057323 - Added Cost Allocation Factor value in the select clause
806     --* prasad marada bug 7409599 getting distinct resource costs for the cost component class,
807     --*               analysis code combination, modified cursor resource_cost_cursor
808     --**************************************************************************************************************
809 
810 CURSOR materials_cursor
811     ( p_batch_id        NUMBER
812     , p_batchstep_id    NUMBER
813     )
814     IS
815       SELECT SYSTEM.gmf_matl_type
816              (mmt.transaction_id,
817               hoi.org_information2,
818               mmt.organization_id,
819               mmt.inventory_item_id,
820               mtln.lot_number,
821               gmd.line_type,
822               mmt.primary_quantity,
823               iimb.primary_uom_code,
824               mmt.transaction_date,
825 	            decode(is_item_lot_costed(iimb.organization_id,iimb.inventory_item_id), iimb.inventory_item_id, 1, NULL, 0, 0),
826               gmd.contribute_step_qty_ind,
827               0,
828               gmd.plan_qty,
829               gmd.actual_qty,
830               gmd.dtl_um,
831               NULL,
832               gmd.cost_alloc
833              )
834       FROM  mtl_system_items_b iimb,
835             mtl_material_transactions mmt,
836             gme_batch_step_items gbsi,
837             gme_material_details gmd,
838             mtl_transaction_lot_numbers mtln,
839             mtl_parameters mp,
840             hr_organization_information hoi,
841             gme_transaction_pairs gtp
842       WHERE gbsi.batch_id = p_batch_id
843       AND   gbsi.batchstep_id = p_batchstep_id
844       AND   mp.organization_id = mmt.organization_id
845       AND   hoi.organization_id = mmt.organization_id
846       AND   hoi.org_information_context = 'Accounting Information'
847       AND   gbsi.material_detail_id = mmt.trx_source_line_id
848       AND   mmt.transaction_id = mtln.transaction_id (+)
849       AND   mmt.transaction_source_type_id = 5  /* Production */
850       AND   mmt.transaction_quantity   <> 0
851       AND   mmt.inventory_item_id      = iimb.inventory_item_id
852       AND   mmt.organization_id        = iimb.organization_id
853       AND   mmt.transaction_date      <= l_final_run_date
854       AND   gmd.batch_id               = p_batch_id
855       AND   gmd.material_detail_id     = gbsi.material_detail_id
856       AND   mmt.transaction_id = gtp.transaction_id1 (+)
857       AND   NOT (mmt.inventory_item_id = transaction_row.inventory_item_id
858                  AND mmt.transaction_id  <> transaction_row.transaction_id
859                  AND mtln.lot_number = transaction_row.lot_number
860                  AND gtp.transaction_id2 IS NOT NULL )
861        ORDER BY mmt.transaction_date, gmd.line_type,
862                  DECODE (gmd.line_type,1, DECODE ((  ABS (DECODE (mmt.transaction_quantity, 0, 1, mmt.transaction_quantity))
863                              / DECODE (mmt.transaction_quantity, 0, 1, mmt.transaction_quantity)
864                             ),
865                             1, mmt.transaction_id,
866                             DECODE (gtp.transaction_id2,
867                                     NULL, mmt.transaction_id,
868                                     gtp.transaction_id2 + .5
869                                    )
870                            ),
871                    mmt.transaction_id
872                    );
873 
874 
875 
876     CURSOR unassociated_ings_cursor
877     ( p_batch_id       NUMBER
878     )
879     IS
880       SELECT SYSTEM.gmf_matl_type
881              ( mmt.transaction_id,
882                hoi.org_information2,
883                mmt.organization_id,
884                mmt.inventory_item_id,
885                mtln.lot_number,
886                gmd.line_type,
887                mmt.transaction_quantity,
888                mmt.transaction_uom,
889                mtln.transaction_date,
890 	             decode(is_item_lot_costed(iimb.organization_id,iimb.inventory_item_id), iimb.inventory_item_id, 1, NULL, 0, 0),
891                gmd.contribute_step_qty_ind,
892                0,
893                gmd.plan_qty,
894                gmd.actual_qty,
895                gmd.dtl_um,
896                NULL ,
897                gmd.cost_alloc
898              )
899       FROM  mtl_system_items_b iimb,
900             mtl_material_transactions mmt,
901             gme_material_details gmd,
902             mtl_transaction_lot_numbers mtln,
903             mtl_parameters mp,
904             hr_organization_information hoi
905       WHERE mmt.transaction_source_type_id = 5
906       AND   gmd.line_type IN (-1,2)
907       AND   mtln.transaction_quantity <> 0
908       AND   mmt.transaction_id = mtln.transaction_id
909       AND   mmt.organization_id = hoi.organization_id
910       AND   hoi.org_information_context = 'Accounting Information'
911       AND   mmt.organization_id = mp.organization_id
912       AND   iimb.inventory_item_id = mmt.inventory_item_id
913       AND   iimb.organization_id  = mmt.organization_id
914       AND   gmd.batch_id = p_batch_id
915       AND   mmt.trx_source_line_id = gmd.material_detail_id
916       AND   gmd.material_detail_id NOT IN
917             (SELECT material_detail_id FROM gme_batch_step_items
918              WHERE  batch_id = p_batch_id);
919 
920 
921 
922      CURSOR unassociated_prds_cursor
923     ( p_batch_id       NUMBER
924     )
925     IS
926       SELECT SYSTEM.gmf_matl_type
927              ( mmt.transaction_id,
928                hoi.org_information2,
929                mmt.organization_id,
930                mmt.inventory_item_id,
931                mtln.lot_number,
932                gmd.line_type,
933                mmt.transaction_quantity,
934                mmt.transaction_uom,
935                mtln.transaction_date,
936 	             decode(is_item_lot_costed(iimb.organization_id,iimb.inventory_item_id), iimb.inventory_item_id, 1, NULL, 0, 0),
937                gmd.contribute_step_qty_ind,
938                0,
939                gmd.plan_qty,
940                gmd.actual_qty,
941                gmd.dtl_um,
942                NULL ,
943                gmd.cost_alloc
944              )
945       FROM  mtl_system_items_b iimb,
946             mtl_material_transactions mmt,
947             gme_material_details gmd,
948             mtl_transaction_lot_numbers mtln,
949             hr_organization_information hoi
950       WHERE mmt.transaction_source_type_id = 5
951       AND   gmd.line_type = 1
952       AND   mtln.transaction_quantity <> 0
953       AND   mmt.transaction_id = mtln.transaction_id
954       AND   mmt.organization_id = hoi.organization_id
955       AND   hoi.org_information_context = 'Accounting Information'
956       AND   iimb.inventory_item_id = mmt.inventory_item_id
957       AND   iimb.organization_id  = mmt.organization_id
958       AND   gmd.batch_id = p_batch_id
959       AND   mmt.trx_source_line_id = gmd.material_detail_id
960       AND   gmd.material_detail_id NOT IN
961             (SELECT material_detail_id FROM gme_batch_step_items
962              WHERE  batch_id = p_batch_id);
963 
964 
965 CURSOR materials_cursor_nr
966     ( p_batch_id        NUMBER
967     )
968     IS
969       SELECT SYSTEM.gmf_matl_type
970              ( mmt.transaction_id,
971                l_le_id,
972                mmt.organization_id,
973                mmt.inventory_item_id,
974                mtln.lot_number,
975                gme.line_type,
976                mmt.primary_quantity,
977                iimb.primary_uom_code,
978                mmt.transaction_date,
979 	             decode(is_item_lot_costed(mmt.organization_id,iimb.inventory_item_id), iimb.inventory_item_id, 1, NULL, 0, 0),
980                gme.contribute_step_qty_ind,
981                0,
982                gme.plan_qty,
983                gme.actual_qty,
984                gme.dtl_um,
985                NULL  ,
986                gme.cost_alloc
987              )
988       FROM  mtl_system_items_b iimb,
989             mtl_material_transactions mmt,
990             gme_material_details gme,
991             mtl_transaction_lot_numbers mtln,
992             gme_transaction_pairs gtp
993       WHERE mmt.trx_source_line_id = gme.material_detail_id
994            AND gme.batch_id = p_batch_id
995            AND   mmt.transaction_quantity <> 0
996            AND   mmt.inventory_item_id = iimb.inventory_item_id
997            AND   mmt.organization_id = iimb.organization_id
998            AND   mmt.transaction_date <= l_final_run_date
999            AND   mmt.transaction_id = mtln.transaction_id (+)
1000            AND   mmt.transaction_id = gtp.transaction_id1 (+)
1001            AND   gtp.batch_id (+) = p_batch_id
1002            AND   NOT (mmt.inventory_item_id = transaction_row.inventory_item_id
1003                  AND gme.line_type = transaction_row.line_type
1004                  AND mmt.transaction_id  <> transaction_row.transaction_id
1005                  AND mtln.lot_number = transaction_row.lot_number
1006 		            AND gtp.transaction_id2 IS NOT NULL )
1007       ORDER BY mmt.transaction_date, gme.line_type,
1008                    DECODE (gme.line_type,
1009                    1, DECODE ((  ABS (DECODE (mmt.transaction_quantity, 0, 1, mmt.transaction_quantity))
1010                              / DECODE (mmt.transaction_quantity, 0, 1, mmt.transaction_quantity)
1011                             ),
1012                             1, mmt.transaction_id,
1013                             DECODE (gtp.transaction_id2,
1014                                     NULL, mmt.transaction_id,
1015                                     gtp.transaction_id2 + .5
1016                                    )
1017                            ),
1018                    mmt.transaction_id
1019                    );
1020 
1021 
1022     --**********************************************************************************************
1023     --*                                                                                            *
1024     --* Cursor to retrieve all resource transactions for a given batch step.                       *
1025     --*                                                                                            *
1026     --* This cursor should also be nested inside the above cursor, but SQL syntax does not allow   *
1027     --* an order by clause in a subquery, and we need to have the transactions ordered by date     *
1028     --*                                                                                            *
1029     --**********************************************************************************************
1030 
1031 
1032    CURSOR resources_cursor
1033     ( p_batch_id         NUMBER
1034     , p_batchstep_id     NUMBER
1035     )
1036     IS
1037       SELECT SYSTEM.gmf_rsrc_type
1038              ( grt.poc_trans_id,
1039                grt.organization_id,
1040                grt.resources,
1041                grt.resource_usage,
1042                grt.trans_qty_um,
1043                grt.trans_date,
1044                0,
1045                NULL
1046              )
1047       FROM   gme_resource_txns grt,
1048              gme_batch_step_resources gbsr
1049       WHERE  gbsr.batch_id = p_batch_id
1050       AND    gbsr.batchstep_id = p_batchstep_id
1051       AND    gbsr.batchstep_resource_id = grt.line_id
1052       AND    grt.doc_type = 'PROD'
1053       AND    grt.doc_id = p_batch_id
1054       AND    grt.completed_ind = 1
1055       AND    grt.resource_usage <> 0
1056       ORDER BY grt.trans_date;
1057 
1058     --**********************************************************************************************
1059     --*                                                                                            *
1060     --* Cursors to retrieve the cost of a lot in the organization specified.                          *
1061     --*                                                                                            *
1062     --**********************************************************************************************
1063 
1064 
1065  CURSOR lot_cost_cursor
1066     ( p_orgn_id     NUMBER
1067     , p_item_id     NUMBER
1068     , p_lot_number  VARCHAR2
1069     , p_trans_date DATE
1070     , p_cost_type_id NUMBER
1071     )
1072     IS
1073       SELECT *
1074       FROM  gmf_lot_costs glc
1075       WHERE glc.lot_number        = p_lot_number
1076       AND   glc.inventory_item_id = p_item_id
1077       AND   glc.organization_id   = p_orgn_id
1078       AND   glc.cost_type_id      = p_cost_type_id
1079       AND   glc.cost_date        <= NVL(p_trans_date, glc.cost_date)
1080       ORDER BY header_id desc
1081     ;
1082 
1083     CURSOR lot_cost_detail_cursor
1084     ( p_header_id  NUMBER )
1085     IS
1086       SELECT SYSTEM.gmf_cost_type
1087              ( glcd.cost_cmpntcls_id,
1088                glcd.cost_analysis_code,
1089                glcd.cost_level,
1090                glcd.component_cost,
1091                0
1092              )
1093       FROM  gmf_lot_cost_details glcd
1094       WHERE glcd.header_id = p_header_id;
1095 
1096     --**********************************************************************************************
1097     --*                                                                                            *
1098     --* Cursors to retrieve the standard cost of an item in the organization specified.               *
1099     --* umoogala: passing co_code instead of calendar_code. Also, joined with cldr_hdr.            *
1100     --* Dinesh Vadivel - Bug 4320765 - Modified item_cost_cursor to support warehouse association
1101     --*   functionality for the Alternate Cost Method                                                                                            *
1102     --**********************************************************************************************
1103 
1104  CURSOR item_cost_cursor
1105     ( p_le_id	    	 NUMBER
1106     , p_cost_type_id NUMBER
1107     , p_orgn_id      NUMBER
1108     , p_item_id      VARCHAR2
1109     , p_date         DATE
1110     )
1111     IS
1112       SELECT sum(cst.cmpnt_cost)
1113       FROM   cm_cmpt_dtl cst,
1114              gmf_period_statuses gps
1115       WHERE  gps.legal_entity_id  = p_le_id
1116       AND    gps.cost_type_id     = p_cost_type_id
1117       AND    gps.start_date      <= p_date
1118       AND    gps.end_date        >= p_date
1119       AND    gps.period_id        = cst.period_id
1120       AND    cst.organization_id  = (SELECT NVL (cstw.cost_organization_id, invw.organization_id)
1121                                                  FROM cm_whse_asc cstw, mtl_parameters invw
1122                                                  WHERE cstw.organization_id(+) = invw.organization_id
1123                                                     AND invw.organization_id = p_orgn_id
1124                                                     AND NVL(cstw.eff_start_date,p_date) <= p_date
1125                                                     AND NVL(cstw.eff_end_date,p_date) >= p_date
1126                                                     AND cstw.delete_mark (+) = 0)
1127       AND    cst.inventory_item_id = p_item_id
1128       AND    cst.delete_mark = 0
1129       AND    gps.delete_mark = 0;
1130 
1131 
1132 
1133 CURSOR item_cost_detail_cursor
1134     ( p_le_id		    NUMBER
1135     , p_cost_type_id NUMBER
1136     , p_orgn_id      NUMBER
1137     , p_item_id          VARCHAR2
1138     , p_date             DATE
1139     )
1140     IS
1141       SELECT SYSTEM.gmf_cost_type
1142              (cst.cost_cmpntcls_id,
1143               cst.cost_analysis_code,
1144               cst.cost_level,
1145               cst.cmpnt_cost,
1146               0
1147              )
1148       FROM   cm_cmpt_dtl cst,
1149              gmf_period_statuses gps
1150       WHERE  gps.legal_entity_id = p_le_id
1151        AND   gps.cost_type_id = p_cost_type_id
1152        AND   gps.start_date <= p_date
1153       AND    gps.end_date >= p_date
1154       AND    cst.cost_type_id = p_cost_type_id
1155       AND    gps.period_id = cst.period_id
1156       AND    cst.organization_id =
1157                         (SELECT NVL (cstw.cost_organization_id, invw.organization_id)
1158                                                 FROM cm_whse_asc cstw, mtl_parameters invw
1159                                                 WHERE cstw.organization_id(+) = invw.organization_id
1160                                                   AND invw.organization_id = p_orgn_id
1161                                                   AND NVL(cstw.eff_start_date,p_date) <= p_date
1162                                                   AND NVL(cstw.eff_end_date,p_date) >= p_date
1163                                                   AND cstw.delete_mark (+) = 0)
1164       AND    cst.inventory_item_id = p_item_id
1165       AND    cst.delete_mark = 0
1166       AND    gps.delete_mark = 0
1167     ;
1168     --**********************************************************************************************
1169     --*                                                                                            *
1170     --* Cursor to retrieve the cost of a resource.                                                 *
1171     --* umoogala: passing co_code instead of calendar_code. Also, joined with cldr_hdr.            *
1172     --*                                                                                            *
1173     --**********************************************************************************************
1174 
1175     -- Bug 7409599 added distinct below
1176 
1177    CURSOR resource_cost_cursor
1178     ( p_le_id         NUMBER
1179     , p_cost_type_id   NUMBER
1180     , p_resources      VARCHAR2
1181     , p_orgn_id        NUMBER
1182     , p_date             DATE
1183     , p_batch_id         NUMBER
1184     , p_batchstep_id     NUMBER
1185     )
1186     IS
1187     SELECT  SYSTEM.gmf_cost_type
1188                (gct.cost_cmpntcls_id,
1189                 gct.cost_analysis_code,
1190                 0,
1191                 gct.nominal_cost,
1192                 0)
1193     FROM (SELECT DISTINCT gbsr.cost_cmpntcls_id,  --used the distinct bug 7409599, pmarada
1194                 gbsr.cost_analysis_code,
1195                 0,
1196                 cst.nominal_cost,
1197                 0
1198           FROM  cm_rsrc_dtl cst
1199                ,gmf_period_statuses gps
1200                ,gme_batch_step_resources gbsr
1201          WHERE  gps.legal_entity_id = p_le_id
1202            AND    gps.cost_type_id = p_cost_type_id
1203            AND    gps.start_date <= p_date
1204            AND    gps.end_date >= p_date
1205            AND    cst.period_id = gps.period_id
1206            AND    cst.organization_id = p_orgn_id
1207            AND    cst.resources = p_resources
1208            AND    cst.delete_mark = 0
1209            AND    gps.delete_mark = 0
1210            AND    gbsr.batch_id = p_batch_id
1211            AND    gbsr.batchstep_id = p_batchstep_id
1212            AND    gbsr.resources = p_resources
1213          ) gct ;
1214 
1215     --**********************************************************************************************
1216     --*                                                                                            *
1217     --* Cursor to retrieve the default cost component class and analysis code for a received item  *
1218     --* umoogala: replaced itemcost_class with cost_category_id 				   *
1219     --*                                                                                            *
1220     --* Bug 3388699: Added the IS NULL and date clauses for retrieval using company                *
1221     --**********************************************************************************************
1222 
1223     CURSOR component_class_cursor
1224     ( p_le_id NUMBER
1225      ,p_item_id    NUMBER
1226      ,p_orgn_id     NUMBER
1227      ,p_date       DATE
1228     )
1229     IS
1230       SELECT a.mtl_cmpntcls_id,
1231              a.mtl_analysis_code, 1
1232         FROM cm_cmpt_mtl a
1233       WHERE (legal_entity_id = p_le_id OR legal_entity_id IS NULL)
1234         AND inventory_item_id = p_item_id
1235         AND (organization_id = p_orgn_id OR organization_id IS NULL)
1236         AND p_date BETWEEN eff_start_date AND eff_end_date
1237         AND a.delete_mark = 0
1238       UNION
1239       SELECT b.mtl_cmpntcls_id, b.mtl_analysis_code, 2
1240       FROM cm_cmpt_mtl b
1241       WHERE (legal_entity_id = p_le_id OR legal_entity_id IS NULL)
1242         AND (organization_id = p_orgn_id OR organization_id IS NULL)
1243         AND p_date BETWEEN eff_start_date AND eff_end_date
1244         AND delete_mark = 0
1245         AND cost_category_id IN
1246             ( SELECT category_id -- cost_category_id  Bug#7306720
1247                 FROM mtl_item_categories mic,
1248                      gmf_process_organizations_gt gpo
1249               WHERE  mic.inventory_item_id = p_item_id
1250                    AND mic.organization_id = gpo.organization_id
1251                    AND (mic.organization_id = p_orgn_id OR p_orgn_id IS NULL)
1252             )
1253       UNION
1254       SELECT d.mtl_cmpntcls_id, d.mtl_analysis_code, 3
1255       FROM gmf_fiscal_policies d
1256       WHERE d.legal_entity_id = p_le_id
1257       ORDER BY 3;
1258 
1259     -- Cursor to retrieve item-specific and lot-specific burdens. If burdens are defined at
1260     -- at both levels the lot-specific ones take priority. The cursor might need a bit of
1261     -- explaining. The first select (the first branch of the union) selects lot-specific
1262     -- burdens. The second branch of the union first finds all burdens that are item specific
1263     -- that do not have a matching one that is lot-specific. In this context 'matching' means
1264     -- that the two burdens have the same resource, cost analysis code and cost component class ID.
1265 
1266     -- The result is the set of burdens (which could easily be empty) that needs to be incorporated
1267     -- in the lot cost.
1268 
1269     -- Not that this partially repeals some changes made for bug 3388974
1270 
1271     -- Bug 3388974-2 This cursor reinstated.
1272 
1273      CURSOR burdens_cursor
1274     ( p_item_id      NUMBER
1275     , p_orgn_id      NUMBER
1276     , p_lot_number   VARCHAR2
1277     , p_cost_type_id NUMBER
1278     , p_trans_date   DATE
1279     )
1280     IS
1281         SELECT lot_burden_line_id,
1282                resources,
1283                cost_cmpntcls_id,
1284                cost_analysis_code,
1285                burden_factor,
1286                0
1287         FROM   gmf_lot_cost_burdens
1288         WHERE  inventory_item_id = p_item_id
1289         AND    organization_id = p_orgn_id
1290         AND    lot_number = p_lot_number
1291         AND    cost_type_id = p_cost_type_id
1292         AND    delete_mark = 0
1293         AND    start_date <= p_trans_date
1294         AND    nvl(end_date, p_trans_date) >= p_trans_date
1295       UNION
1296         SELECT lot_burden_line_id,
1297                resources,
1298                cost_cmpntcls_id,
1299                cost_analysis_code,
1300                burden_factor, 0
1301       	FROM   gmf_lot_cost_burdens
1302       	WHERE  inventory_item_id = p_item_id
1303       	AND    organization_id = p_orgn_id
1304       	AND    lot_number IS NULL
1305       	AND    cost_type_id = p_cost_type_id
1306       	AND    delete_mark = 0
1307       	AND    start_date <= p_trans_date
1308       	AND    nvl(end_date, p_trans_date) >= p_trans_date
1309       	AND    (resources, cost_cmpntcls_id, cost_analysis_code)
1310                NOT IN
1311                  (SELECT resources, cost_cmpntcls_id, cost_analysis_code
1312                   FROM   gmf_lot_cost_burdens
1313                   WHERE  inventory_item_id = p_item_id
1314                   AND    organization_id = p_orgn_id
1315                   AND    lot_number = p_lot_number
1316                   AND    cost_type_id = p_cost_type_id
1317                   AND    delete_mark = 0
1318       	          AND    start_date <= p_trans_date
1319       	          AND    nvl(end_date, p_trans_date) >= p_trans_date
1320                  )
1321      ORDER BY 3,4 ;
1322     -- End 3388974-2
1323 
1324     --**********************************************************************************************
1325     --*                                                                                            *
1326     --* Cursor to retrieve the cost of a resource.                                                 *
1327     --* umoogala: passing co_code instead of calendar_code. Also, joined with cldr_hdr.            *
1328     --*                                                                                            *
1329     --**********************************************************************************************
1330 
1331 
1332     CURSOR burden_cost_cursor
1333     ( p_le_id	             NUMBER
1334     , p_cost_type_id       NUMBER
1335     , p_resources          VARCHAR2
1336     , p_orgn_id            NUMBER
1337     , p_cost_cmpntcls_id   NUMBER
1338     , p_cost_analysis_code VARCHAR2
1339     , p_date               DATE
1340     )
1341     IS
1342       SELECT cst.nominal_cost
1343       FROM   cm_rsrc_dtl cst,
1344              gmf_period_statuses gps
1345       WHERE  gps.legal_entity_id = p_le_id
1346       AND    gps.cost_type_id = p_cost_type_id
1347       AND    gps.start_date <= p_date
1348       AND    gps.end_date >= p_date
1349       AND    cst.period_id = gps.period_id
1350       AND    cst.resources = p_resources
1351       AND    cst.organization_id = p_orgn_id
1352       AND    cst.delete_mark = 0
1353       AND    gps.delete_mark = 0;
1354 
1355 
1356     CURSOR lot_costed_items
1357       IS
1358       SELECT g.inventory_item_id,g.organization_id
1359       FROM  gmf_lot_costed_items_gt g
1360       ORDER BY organization_id,inventory_item_id
1361      ;
1362 
1363 
1364     --**********************************************************************************************
1365     --*      Cursor to get the Batch Step ID which has Step Material Associations
1366     --*
1367     --**********************************************************************************************
1368     CURSOR associated_batch_steps_cursor(p_batch_id NUMBER)
1369     IS
1370     SELECT DISTINCT gbsi.batchstep_id
1371        FROM gme_material_details gmd, gme_batch_step_items gbsi
1372      WHERE gmd.material_detail_id = gbsi.material_detail_id
1373            AND gmd.batch_id = gbsi.batch_id
1374            AND gmd.line_type = 1
1375            AND gmd.batch_id = p_batch_id;
1376 
1377     --**********************************************************************************************
1378     --*                                                                                            *
1379     --* Function to check whether item is lot costed or not. This fucntion is used in cursor       *
1380     --* materials_cursor.									   *
1381     --*                                                                                            *
1382     --**********************************************************************************************
1383 /* INVCONV sschinch modified to add orgn id as additional parameter*/
1384 FUNCTION is_item_lot_costed
1385 ( p_orgn_id IN NUMBER,
1386   p_item_id  IN NUMBER
1387 )
1388 RETURN NUMBER
1389 IS
1390 
1391 BEGIN
1392   RETURN lc_items_tab(p_item_id||'-'||p_orgn_id);
1393 END;
1394 
1395 
1396 
1397     --**********************************************************************************************
1398     --*                                                                                            *
1399     --* Procedures to merge a table of costs with the new_cost_tab. If mode = 'C' (= Combine) any  *
1400     --* matches between the costs_table and new_cost_tab are simply added together. If mode = 'A'  *
1401     --* (= Average) the cost_qty and new_qty are used to perform weighted averaging. The result is *
1402     --* placed in new_cost_tab in both modes, and new_cost.unit_cost is the sum its costs.         *
1403     --*                                                                                            *
1404     --* Combining costs is used for adding burdens or acquisition costs to a new cost before it is *
1405     --* either written to the database or used to update an existing cost. The update will use the *
1406     --* Averaging mode.                                                                            *
1407     --**********************************************************************************************
1408 
1409 PROCEDURE merge_costs
1410 ( costs_table     IN OUT NOCOPY l_cost_tab_type
1411 , cost_qty        IN NUMBER
1412 , new_qty         IN NUMBER
1413 , merge_mode      IN VARCHAR2
1414 )
1415 IS
1416   k              NUMBER;
1417   l              NUMBER;
1418   divisor        NUMBER;
1419   l_cost_accrued BOOLEAN := FALSE;
1420   procedure_name VARCHAR2(100);
1421 BEGIN
1422 
1423   procedure_name := 'Merge Costs';
1424 
1425   IF l_debug_level >= l_debug_level_medium
1426      THEN
1427        fnd_file.put_line
1428        (fnd_file.log,'Entered Procedure: '||procedure_name);
1429      END IF;
1430 
1431   IF l_debug_level >= l_debug_level_high
1432   THEN
1433     fnd_file.put_line(fnd_file.log,'Cost_qty = '||cost_qty||', new_qty = '||new_qty);
1434 
1435     fnd_file.put_line(fnd_file.log,'Before merge new_cost_tab is:');
1436 
1437     FOR k IN 1 .. new_cost_tab.COUNT
1438     LOOP
1439       fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
1440       fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
1441       fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||new_cost_tab(k).cost_level);
1442       fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
1443       fnd_file.put_line(fnd_file.log,'====================================');
1444     END LOOP;
1445 
1446     IF costs_table.EXISTS(1)
1447     THEN
1448       fnd_file.put_line(fnd_file.log,'Before merge costs_tab is:');
1449       FOR k IN 1 .. costs_table.COUNT
1450       LOOP
1451         fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||costs_table(k).cost_cmpntcls_id);
1452         fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||costs_table(k).cost_analysis_code);
1453         fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||costs_table(k).cost_level);
1454         fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||costs_table(k).component_cost);
1455         fnd_file.put_line(fnd_file.log,'====================================');
1456       END LOOP;
1457     ELSE
1458       fnd_file.put_line(fnd_file.log,'No costs to merge');
1459     END IF;
1460   END IF;
1461 
1462   IF costs_table.EXISTS(1)
1463   THEN
1464     -- If this is an averaging of costs we need to do his first before combining the results
1465     IF merge_mode = 'A'
1466     THEN
1467 
1468       divisor := new_qty + cost_qty;
1469       IF divisor = 0
1470       THEN
1471         divisor := 1;
1472       END IF;
1473 
1474       fnd_file.put_line(fnd_file.log,'Divisor is  '||divisor||'cost qty = '||cost_qty||' new qty= '||new_qty);
1475 
1476       FOR k in 1 .. costs_table.COUNT
1477       LOOP
1478         costs_table(k).component_cost := costs_table(k).component_cost * cost_qty / divisor;
1479       END LOOP;
1480 
1481       FOR k in 1 .. new_cost_tab.COUNT
1482       LOOP
1483         new_cost_tab(k).component_cost := new_cost_tab(k).component_cost * new_qty / divisor;
1484       END LOOP;
1485 
1486       IF l_debug_level >= l_debug_level_high
1487       THEN
1488         fnd_file.put_line(fnd_file.log,'Cost_qty = '||cost_qty||', new_qty = '||new_qty);
1489 
1490         fnd_file.put_line(fnd_file.log,'After averaging new_cost_tab is:');
1491 
1492         FOR k IN 1 .. new_cost_tab.COUNT
1493         LOOP
1494           fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
1495           fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
1496           fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||new_cost_tab(k).cost_level);
1497           fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
1498           fnd_file.put_line(fnd_file.log,'====================================');
1499         END LOOP;
1500 
1501         fnd_file.put_line(fnd_file.log,'After averaging costs_tab is:');
1502         FOR k IN 1 .. costs_table.COUNT
1503         LOOP
1504           fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||costs_table(k).cost_cmpntcls_id);
1505           fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||costs_table(k).cost_analysis_code);
1506           fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||costs_table(k).cost_level);
1507           fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||costs_table(k).component_cost);
1508           fnd_file.put_line(fnd_file.log,'====================================');
1509         END LOOP;
1510       END IF;
1511     END IF;
1512 
1513     FOR k IN 1 .. costs_table.COUNT
1514     LOOP
1515       FOR l in 1..new_cost_tab.COUNT
1516       LOOP
1517         l_cost_accrued := FALSE;
1518         IF  new_cost_tab(l).cost_cmpntcls_id = costs_table(k).cost_cmpntcls_id
1519         AND new_cost_tab(l).cost_analysis_code = costs_table(k).cost_analysis_code
1520         AND new_cost_tab(l).cost_level = costs_table(k).cost_level
1521         THEN
1522           new_cost_tab(l).component_cost :=  new_cost_tab(l).component_cost + costs_table(k).component_cost;
1523           l_cost_accrued := TRUE;
1524           EXIT;
1525         END IF;
1526       END LOOP;
1527 
1528       IF NOT l_cost_accrued
1529       THEN
1530 
1531         l := new_cost_tab.count+1;
1532         new_cost_tab(l) := SYSTEM.gmf_cost_type
1533                            ( costs_table(k).cost_cmpntcls_id
1534                            , costs_table(k).cost_analysis_code
1535                            , 0
1536                            , costs_table(k).component_cost
1537                            , 0
1538                            );
1539 
1540       END IF;
1541     END LOOP;
1542   END IF;
1543 
1544   new_cost.unit_cost := 0;
1545 
1546   FOR k IN 1 .. new_cost_tab.COUNT
1547   LOOP
1548     new_cost.unit_cost := new_cost.unit_cost + new_cost_tab(k).component_cost;
1549   END LOOP;
1550 
1551   IF l_debug_level >= l_debug_level_high
1552   THEN
1553     fnd_file.put_line(fnd_file.log,'After merge new_cost_tab is:');
1554     FOR k IN 1 .. new_cost_tab.COUNT
1555     LOOP
1556       fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
1557       fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
1558       fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||new_cost_tab(k).cost_level);
1559       fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
1560       fnd_file.put_line(fnd_file.log,'====================================');
1561     END LOOP;
1562     fnd_file.put_line(fnd_file.log,'After merging, new unit cost is: '||new_cost.unit_cost);
1563   END IF;
1564 
1565 
1566   IF l_debug_level >= l_debug_level_medium
1567      THEN
1568        fnd_file.put_line
1569        (fnd_file.log,'Leaving Procedure: '||procedure_name);
1570      END IF;
1571 END;
1572 
1573 
1574 
1575     --**********************************************************************************************
1576     --*                                                                                            *
1577     --* Procedure load and cost burdens. If any burdens are located, they are costed and the       *
1578     --* l_burdens_tab and l_burdens_costs_tab tables are populated                                 *
1579     --*                                                                                            *
1580     --**********************************************************************************************
1581 
1582 -- 3388974-2 This procedure reinstated and its replacement deleted.
1583 
1584 PROCEDURE process_burdens
1585 IS
1586   i         NUMBER;
1587   j         NUMBER;
1588   factor    NUMBER;
1589   cost      NUMBER;
1590   procedure_name VARCHAR2(100);
1591 BEGIN
1592 
1593   procedure_name := 'Process Burdens';
1594 
1595   IF l_debug_level >= l_debug_level_medium
1596      THEN
1597        fnd_file.put_line
1598        (fnd_file.log,'Entered Procedure: '||procedure_name);
1599      END IF;
1600 
1601   l_return_status := 'S';
1602   l_burdens_total := 0;
1603   l_burden_costs_tab.delete;
1604 
1605 
1606 
1607   OPEN  burdens_cursor ( transaction_row.inventory_item_id
1608                        , transaction_row.orgn_id
1609                        , transaction_row.lot_number
1610                        , l_cost_type_id
1611                        , transaction_row.trans_date
1612                        );
1613 
1614 
1615   FETCH burdens_cursor BULK COLLECT into l_burdens_tab;
1616 
1617   CLOSE burdens_cursor;
1618 
1619   IF  l_burdens_tab.EXISTS(1)
1620   THEN
1621     IF l_debug_level >= l_debug_level_high
1622     THEN
1623       fnd_file.put_line(fnd_file.log,
1624                         'Burdens found for item: ' || transaction_row.inventory_item_id ||
1625 	  	        ' orgn: ' || l_org_tab(transaction_row.orgn_id) || ' cost type: ' || l_cost_method_code ||
1626 		        ' lot: ' || transaction_row.lot_number ||
1627 		        ' trans_date: ' || to_char(transaction_row.trans_date));
1628 
1629       fnd_file.put_line
1630       ( fnd_file.log
1631       , 'Burdens Table is:');
1632       FOR i IN 1.. l_burdens_tab.COUNT
1633       LOOP
1634         fnd_file.put_line( fnd_file.log, 'Resources['||i||']:'||l_burdens_tab(i).resources);
1635         fnd_file.put_line( fnd_file.log, 'CCC ID   ['||i||']:'||l_burdens_tab(i).cost_cmpntcls_id);
1636         fnd_file.put_line( fnd_file.log, 'C/A Code ['||i||']:'||l_burdens_tab(i).cost_analysis_code);
1637         fnd_file.put_line( fnd_file.log, 'B/Factor ['||i||']:'||l_burdens_tab(i).burden_factor);
1638       END LOOP;
1639     END IF;
1640 
1641     -- Retrieve the cost for each resource. If we can't find a cost for this cost method
1642     -- then we cannot carry on.
1643 
1644     FOR i IN 1..l_burdens_tab.COUNT
1645     LOOP
1646       l_burden_cost := 0;
1647 
1648       -- umoogala: using co_code and default_cost_mthd to get costs for non-lot controlled items.
1649       -- was calendar_code and cost_mthd_code
1650 
1651       IF l_debug_level >= l_debug_level_high
1652       THEN
1653         fnd_file.put_line
1654         ( fnd_file.log
1655         , 'Searching for resource cost using LE: ' || l_le_id ||
1656           ' mthd: ' || l_default_cost_type_id ||
1657 	  ' rsrc: ' || l_burdens_tab(i).resources ||
1658           ' orgn: ' || l_org_tab(transaction_row.orgn_id) ||
1659           ' CCC/ID: ' || l_burdens_tab(i).cost_cmpntcls_id ||
1660           ' A/Code: ' ||l_burdens_tab(i).cost_analysis_code ||
1661           ' date: '   || transaction_row.trans_date);
1662       END IF;
1663 /* INVCONV sschinch */
1664       OPEN burden_cost_cursor
1665            ( l_le_id
1666            , l_default_cost_type_id
1667            , l_burdens_tab(i).resources
1668            , transaction_row.orgn_id
1669            , l_burdens_tab(i).cost_cmpntcls_id
1670            , l_burdens_tab(i).cost_analysis_code
1671            , transaction_row.trans_date
1672            );
1673 
1674       l_burden_cost := NULL;
1675 
1676       FETCH burden_cost_cursor INTO l_burden_cost;
1677 
1678       CLOSE burden_cost_cursor;
1679 
1680       IF l_burden_cost IS NOT NULL
1681       THEN
1682 
1683         IF l_debug_level >= l_debug_level_high
1684         THEN
1685           fnd_file.put_line
1686           (fnd_file.log, 'Found cost: '|| l_burden_cost);
1687         END IF;
1688 
1689         l_burdens_tab(i).burden_cost := l_burdens_tab(i).burden_factor * l_burden_cost;
1690 
1691       ELSE
1692 
1693         fnd_file.put_line
1694         (  fnd_file.log
1695         ,  'ERROR: Unable to locate a burden cost. Resource: '
1696         || l_burdens_tab(i).resources
1697         || ', analysis code: '
1698         || l_burdens_tab(i).cost_analysis_code
1699         || ', component class ID: '
1700         || to_char(l_burdens_tab(i).cost_cmpntcls_id)
1701         );
1702 
1703         l_return_status := 'E';
1704         RETURN;
1705       END IF;
1706 
1707       l_burden_costs_tab(i) := SYSTEM.gmf_cost_type
1708                              ( l_burdens_tab(i).cost_cmpntcls_id
1709                              , l_burdens_tab(i).cost_analysis_code
1710                              , 0
1711                              , l_burdens_tab(i).burden_cost
1712                              , 1
1713                              );
1714 
1715 
1716       l_burdens_total := l_burdens_total + l_burden_costs_tab(i).component_cost;
1717     END LOOP;
1718   END IF;
1719 
1720   IF l_debug_level >= l_debug_level_high
1721   THEN
1722     fnd_file.put_line(fnd_file.log,'At end of process_burdens, the burden costs are:');
1723     FOR i IN 1 .. l_burden_costs_tab.COUNT
1724     LOOP
1725       fnd_file.put_line(fnd_file.log,'CCC/ID['||i||']: '||l_burden_costs_tab(i).cost_cmpntcls_id);
1726       fnd_file.put_line(fnd_file.log,'A/Code['||i||']: '||l_burden_costs_tab(i).cost_analysis_code);
1727       fnd_file.put_line(fnd_file.log,'Level ['||i||']: '||l_burden_costs_tab(i).cost_level);
1728       fnd_file.put_line(fnd_file.log,'C/Cost['||i||']: '||l_burden_costs_tab(i).component_cost);
1729       fnd_file.put_line(fnd_file.log,'====================================');
1730     END LOOP;
1731   END IF;
1732 
1733 
1734 
1735   IF l_debug_level >= l_debug_level_medium
1736      THEN
1737        fnd_file.put_line
1738        (fnd_file.log,'Leaving Procedure: '||procedure_name);
1739      END IF;
1740 
1741 EXCEPTION
1742   WHEN OTHERS
1743   THEN
1744 
1745     fnd_file.put_line(fnd_file.log,'ERROR: '||substr(sqlerrm,1,100) || ' in ' || procedure_name);
1746     l_return_status := 'E';
1747 
1748 END process_burdens;
1749 
1750     --**********************************************************************************************
1751     --*                                                                                            *
1752     --* Procedure to create a cost header for a new lot in gmf_lot_costs                           *
1753     --*                                                                                            *
1754     --**********************************************************************************************
1755 
1756 
1757 PROCEDURE create_cost_header
1758 ( p_item_id          IN NUMBER
1759 , p_lot_number       IN VARCHAR2
1760 , p_orgn_id          IN NUMBER
1761 , p_cost_type_id     IN NUMBER
1762 , p_unit_cost        IN NUMBER
1763 , p_cost_date        IN DATE
1764 , p_onhand_qty       IN NUMBER
1765 , p_doc_id           IN NUMBER
1766 , p_trx_src_type_id  IN NUMBER
1767 , p_txn_act_id       IN NUMBER
1768 , x_header_id       OUT NOCOPY NUMBER
1769 , x_unit_cost       OUT NOCOPY NUMBER
1770 , x_onhand_qty      OUT NOCOPY NUMBER
1771 , x_return_status   OUT NOCOPY VARCHAR2
1772 )
1773 IS
1774   loop_count NUMBER;
1775   procedure_name VARCHAR2(100);
1776 BEGIN
1777   procedure_name := 'Create Cost Header';
1778   IF l_debug_level >= l_debug_level_medium
1779      THEN
1780        fnd_file.put_line
1781        (fnd_file.log,'Entered Procedure: '||procedure_name);
1782      END IF;
1783 
1784   IF l_debug_level >= l_debug_level_medium
1785   THEN
1786     fnd_file.put_line(fnd_file.log, 'p_unit_cost  = '||p_unit_cost);
1787   END IF;
1788 
1789   IF p_unit_cost IS NULL
1790   THEN
1791     fnd_file.put_line
1792     (fnd_file.log,'ERROR: Could not create cost header for Lot Number '||to_char(transaction_row.lot_number)||' as no cost was available');
1793     fnd_file.put_line
1794     (fnd_file.log,'      Transaction type/ID was '||transaction_row.transaction_source_type_id||'/'||to_char(transaction_row.transaction_id));
1795     x_return_status := 'E';
1796     RETURN;
1797   END IF;
1798 
1799   IF l_debug_level >= l_debug_level_medium
1800   THEN
1801     fnd_file.put_line(fnd_file.log,'Inside INSERT HEADER');
1802     fnd_file.put_line(fnd_file.log,'Item ID      = '||p_item_id);
1803     fnd_file.put_line(fnd_file.log,'Lot Number       = '||p_lot_number);
1804     fnd_file.put_line(fnd_file.log,'Unit Cost    = '||p_unit_cost);
1805     fnd_file.put_line(fnd_file.log,'Cost Date    = '||p_cost_date);
1806     fnd_file.put_line(fnd_file.log,'Whse Code    = '||p_orgn_id);
1807     fnd_file.put_line(fnd_file.log,'Cost Method  = '||p_cost_type_id);
1808     fnd_file.put_line(fnd_file.log,'Onhand Qty   = '||p_onhand_qty);
1809     fnd_file.put_line(fnd_file.log,'Doc Type     = '||p_trx_src_type_id||','||p_txn_act_id);
1810     fnd_file.put_line(fnd_file.log,'Doc ID       = '||p_doc_id);
1811   END IF;
1812 
1813   INSERT INTO gmf_lot_costs
1814   ( header_id
1815   , inventory_item_id
1816   , lot_number
1817   , organization_id
1818   , cost_type_id
1819   , unit_cost
1820   , cost_date
1821   , onhand_qty
1822   , last_trx_source_type_id
1823   , last_trx_action_id
1824   , last_costing_doc_id
1825   , creation_date
1826   , created_by
1827   , last_update_date
1828   , last_updated_by
1829   , delete_mark
1830   , request_id
1831   , program_application_id
1832   , program_id
1833   , program_update_date
1834   , final_cost_flag
1835   )
1836   VALUES
1837   (
1838     gmf_cost_header_id_s.nextval
1839   , p_item_id
1840   , p_lot_number
1841   , p_orgn_id
1842   , p_cost_type_id
1843   , p_unit_cost
1844   , p_cost_date
1845   , p_onhand_qty
1846   , p_trx_src_type_id
1847   , p_txn_act_id
1848   , p_doc_id
1849   , SYSDATE
1850   , l_user_id
1851   , SYSDATE
1852   , l_user_id
1853   , 0
1854   , l_request_id
1855   , l_prog_appl_id
1856   , l_program_id
1857   , SYSDATE
1858   , l_final_run_flag
1859   )
1860   RETURNING header_id, unit_cost, onhand_qty
1861   INTO      x_header_id, x_unit_cost, x_onhand_qty;
1862 
1863   x_return_status := 'S';
1864 
1865   IF l_debug_level >= l_debug_level_medium
1866      THEN
1867        fnd_file.put_line
1868        (fnd_file.log,'Leaving Procedure: '||procedure_name);
1869      END IF;
1870 
1871 
1872 EXCEPTION
1873 
1874   WHEN OTHERS
1875   THEN
1876     fnd_file.put_line
1877     (fnd_file.log,'ERROR: Unable to create cost header');
1878     fnd_file.put_line
1879     (fnd_file.log,SQLERRM || ' in ' || procedure_name);
1880 
1881     x_return_status := 'E';
1882 
1883 END create_cost_header;
1884 
1885 
1886     --**********************************************************************************************
1887     --*                                                                                            *
1888     --* Procedure to create a new lot cost detail row in gmf_lot_cost_details                      *
1889     --*                                                                                            *
1890     --**********************************************************************************************
1891 
1892 
1893 PROCEDURE create_cost_detail
1894 ( p_header_id          IN NUMBER
1895 , p_component_class_id IN NUMBER
1896 , p_cost_analysis_code IN VARCHAR2
1897 , p_cost_level         IN VARCHAR2
1898 , p_component_cost     IN NUMBER
1899 , p_burden_ind         IN NUMBER
1900 , x_return_status     OUT NOCOPY VARCHAR2
1901 )
1902 IS
1903 
1904   loop_count NUMBER;
1905   procedure_name VARCHAR2(100);
1906 BEGIN
1907   procedure_name := 'Create Cost Detail';
1908   IF l_debug_level >= l_debug_level_medium
1909      THEN
1910        fnd_file.put_line
1911        (fnd_file.log,'Entered Procedure: '||procedure_name);
1912      END IF;
1913   IF l_debug_level >= l_debug_level_medium
1914   THEN
1915     fnd_file.put_line(fnd_file.log,'Inside INSERT DETAIL');
1916     fnd_file.put_line(fnd_file.log,'Header ID           = '||p_header_id);
1917     fnd_file.put_line(fnd_file.log,'Component Class ID  = '||p_component_class_id);
1918     fnd_file.put_line(fnd_file.log,'Analysis Code       = '||p_cost_analysis_code);
1919     fnd_file.put_line(fnd_file.log,'Cost Level          = '||p_cost_level);
1920     fnd_file.put_line(fnd_file.log,'Burden Ind          = '||p_burden_ind);
1921     fnd_file.put_line(fnd_file.log,'Cost                = '||p_component_cost);
1922   END IF;
1923 
1924 
1925     INSERT INTO gmf_lot_cost_details
1926     ( header_id
1927     , detail_id
1928     , cost_cmpntcls_id
1929     , cost_analysis_code
1930     , cost_level
1931     , component_cost
1932     , burden_ind
1933     , creation_date
1934     , created_by
1935     , last_update_date
1936     , last_updated_by
1937     , delete_mark
1938     , request_id
1939     , program_application_id
1940     , program_id
1941     , program_update_date
1942     , final_cost_flag
1943     )
1944     VALUES
1945     ( p_header_id
1946     , gmf_cost_detail_id_s.nextval
1947     , p_component_class_id
1948     , p_cost_analysis_code
1949     , p_cost_level
1950     , p_component_cost
1951     , p_burden_ind
1952     , sysdate
1953     , l_user_id
1954     , sysdate
1955     , l_user_id
1956     , 0
1957     , l_request_id
1958     , l_prog_appl_id
1959     , l_program_id
1960     , SYSDATE
1961     , l_final_run_flag
1962     );
1963   x_return_status := 'S';
1964   IF l_debug_level >= l_debug_level_medium
1965      THEN
1966        fnd_file.put_line
1967        (fnd_file.log,'Leaving Procedure: '||procedure_name);
1968      END IF;
1969 
1970 EXCEPTION
1971 
1972   WHEN OTHERS
1973   THEN
1974     fnd_file.put_line
1975     (fnd_file.log,'ERROR: Unable to create cost detail');
1976     fnd_file.put_line
1977     (fnd_file.log,SQLERRM || ' in ' || procedure_name);
1978 
1979     x_return_status := 'E';
1980 
1981 END create_cost_detail;
1982 
1983     --**********************************************************************************************
1984     --*                                                                                            *
1985     --* Procedure to clone the costs for a lot/organization                                           *
1986     --*                                                                                            *
1987     --**********************************************************************************************
1988 
1989 PROCEDURE clone_costs
1990 IS
1991   old_header_id  NUMBER;
1992   new_header_id  NUMBER;
1993   i              NUMBER;
1994   discard        NUMBER;
1995   procedure_name VARCHAR2(100);
1996 BEGIN
1997 
1998   procedure_name := 'Clone Costs';
1999   IF l_debug_level >= l_debug_level_medium
2000      THEN
2001        fnd_file.put_line
2002        (fnd_file.log,'Entered Procedure: '||procedure_name);
2003      END IF;
2004 
2005   create_cost_header
2006   ( old_cost.inventory_item_id /*bug 5309434*/
2007   , old_cost.lot_number
2008   , old_cost.organization_id
2009   , old_cost.cost_type_id
2010   , old_cost.unit_cost
2011   , old_cost.cost_date
2012   , old_cost.onhand_qty
2013   ,old_cost.last_trx_source_type_id
2014   ,old_cost.last_trx_action_id
2015   , old_cost.last_costing_doc_id
2016   , new_header_id
2017   , discard
2018   , discard
2019   , l_return_status
2020   );
2021 
2022   old_cost.header_id := new_header_id;
2023 
2024   IF l_return_status = 'S'
2025   THEN
2026     FOR i in 1 .. old_cost_tab.COUNT
2027     LOOP
2028       create_cost_detail
2029       ( new_header_id
2030       , old_cost_tab(i).cost_cmpntcls_id
2031       , old_cost_tab(i).cost_analysis_code
2032       , 0
2033       , old_cost_tab(i).component_cost
2034       , 0
2035       , l_return_status
2036       );
2037     END LOOP;
2038   END IF;
2039   IF l_debug_level >= l_debug_level_medium
2040      THEN
2041        fnd_file.put_line
2042        (fnd_file.log,'Leaving Procedure: '||procedure_name);
2043      END IF;
2044 
2045 EXCEPTION
2046 
2047   WHEN OTHERS
2048   THEN
2049   fnd_file.put_line
2050   ( fnd_file.log
2051   , 'ERROR: Could not clone costs '||SQLERRM
2052   );
2053 
2054   l_return_status := 'U';
2055 END clone_costs;
2056 
2057 
2058     --**********************************************************************************************
2059     --*                                                                                            *
2060     --* Procedure to create a new linking transaction in gmf_material_lot_cost_txns                *
2061     --*                                                                                            *
2062     --**********************************************************************************************
2063 PROCEDURE create_material_transaction
2064 ( p_header_id        IN NUMBER
2065 , p_cost_type_id     IN NUMBER
2066 , p_trans_date       IN DATE
2067 , p_trans_qty        IN NUMBER
2068 , p_trans_um         IN VARCHAR2
2069 , p_total_cost       IN NUMBER
2070 , p_trans_id         IN NUMBER
2071 , p_unit_cost        IN NUMBER
2072 , p_onhand_qty       IN NUMBER
2073 , p_old_unit_cost    IN NUMBER
2074 , p_old_onhand_qty   IN NUMBER
2075 , p_new_cost_ind     IN NUMBER
2076 , p_lot_number       IN VARCHAR2
2077 , x_return_status   OUT NOCOPY VARCHAR2
2078 )
2079 IS
2080   loop_count NUMBER;
2081   procedure_name VARCHAR2(100);
2082 BEGIN
2083   procedure_name := 'Create Material Transaction';
2084   IF l_debug_level >= l_debug_level_medium
2085      THEN
2086        fnd_file.put_line
2087        (fnd_file.log,'Entered Procedure: '||procedure_name);
2088      END IF;
2089 
2090   IF l_debug_level >= l_debug_level_medium
2091   THEN
2092     fnd_file.put_line(fnd_file.log,'Creating material transaction with these values:');
2093     fnd_file.put_line(fnd_file.log,'Header ID      :'||p_header_id);
2094     fnd_file.put_line(fnd_file.log,'Cost Method    :'||p_cost_type_id);
2095     fnd_file.put_line(fnd_file.log,'Date           :'||p_trans_date);
2096     fnd_file.put_line(fnd_file.log,'Trans Qty      :'||p_trans_qty);
2097     fnd_file.put_line(fnd_file.log,'UoM            :'||p_trans_um);
2098     fnd_file.put_line(fnd_file.log,'Total Cost     :'||p_total_cost);
2099     fnd_file.put_line(fnd_file.log,'Trans ID       :'||p_trans_id);
2100     fnd_file.put_line(fnd_file.log,'Unit Cost      :'||p_unit_cost);
2101     fnd_file.put_line(fnd_file.log,'Onhand Qty     :'||p_onhand_qty);
2102     fnd_file.put_line(fnd_file.log,'Old Unit Cost  :'||p_old_unit_cost);
2103     fnd_file.put_line(fnd_file.log,'Old Onhand Qty :'||p_old_onhand_qty);
2104     fnd_file.put_line(fnd_file.log,'New Cost Ind   :'||p_new_cost_ind);
2105     fnd_file.put_line(fnd_file.log,'Lot Number   :'||p_lot_number);
2106   END IF;
2107 
2108   INSERT INTO gmf_material_lot_cost_txns
2109   ( cost_trans_id
2110   , cost_header_id
2111   , cost_type_id
2112   , cost_trans_date
2113   , cost_trans_qty
2114   , cost_trans_um
2115   , total_trans_cost
2116   , transaction_id
2117   , new_unit_cost
2118   , new_onhand_qty
2119   , old_unit_cost
2120   , old_onhand_qty
2121   , creation_date
2122   , created_by
2123   , last_update_date
2124   , last_updated_by
2125   , request_id
2126   , program_application_id
2127   , program_id
2128   , program_update_date
2129   , final_cost_flag
2130   , new_cost_ind
2131   , lot_number
2132   )
2133   VALUES
2134   ( gmf_cost_trans_id_s.nextval
2135   , p_header_id
2136   , p_cost_type_id
2137   , p_trans_date
2138   , p_trans_qty
2139   , p_trans_um
2140   , p_total_cost
2141   , decode(p_trans_id, -9, (-1*gmf_cost_trans_id_s.currval),p_trans_id)
2142   , p_unit_cost
2143   , p_onhand_qty
2144   , p_old_unit_cost
2145   , p_old_onhand_qty
2146   , sysdate
2147   , l_user_id
2148   , sysdate
2149   , l_user_id
2150   , l_request_id
2151   , l_prog_appl_id
2152   , l_program_id
2153   , SYSDATE
2154   , l_final_run_flag
2155   , p_new_cost_ind
2156   , p_lot_number
2157   );
2158   x_return_status := 'S';
2159   IF l_debug_level >= l_debug_level_medium
2160      THEN
2161        fnd_file.put_line
2162        (fnd_file.log,'Leaving Procedure: '||procedure_name);
2163      END IF;
2164 
2165 
2166 EXCEPTION
2167 
2168   WHEN OTHERS
2169   THEN
2170     fnd_file.put_line
2171     (fnd_file.log,'ERROR: Unable to create material cost transaction');
2172     fnd_file.put_line
2173     (fnd_file.log,SQLERRM || ' in ' || procedure_name);
2174 
2175     x_return_status := 'E';
2176 
2177 END create_material_transaction;
2178 
2179 
2180     --**********************************************************************************************
2181     --*                                                                                            *
2182     --* Procedures to handle received lots.                                                        *
2183     --*                                                                                            *
2184     --* The costs come from the PO together with any associated Special Charges and burdens.       *
2185     --* If this is the first receipt for this lot in this warehouse the costs will be set up.      *
2186     --*                                                                                            *
2187     --* If there is already a cost for this lot and warehouse then the costs will be revised       *
2188     --* by averaging the new cost with the old cost by using the original and revised quantities.  *
2189     --*                                                                                            *
2190     --* Returns update the cost using an identical formula                                         *
2191     --*                                                                                            *
2192     --* HISTORY                                                                                    *
2193     --*                                                                                            *
2194     --*   Bug#5463200 Anand Thiyagarajan  14-Aug-2006                                              *
2195     --*     Modified Code in the Special Charges query to remove po_line_locations_all, changed the*
2196     --*     value for include_in_acquisition_cost to "I", used estimated_amount instead of actual  *
2197     --*     and included MMT table join with RCV_TRANSACTION_ID instead of INV_TRANSACTION_ID      *
2198     --**********************************************************************************************
2199 
2200 PROCEDURE get_special_charges IS
2201 
2202     /* Begin 3824810 sschinch */
2203     TYPE acquistion_rec IS RECORD
2204     ( COST_CMPNTCLS_ID               NUMBER(15)
2205     , COST_ANALYSIS_CODE              VARCHAR2(4)
2206     , COMPONENT_COST                  NUMBER
2207     , RECEIPT_UOM                     VARCHAR2(3)
2208      );
2209 
2210    TYPE acq_tab_type IS TABLE OF acquistion_rec	 INDEX BY PLS_INTEGER;
2211 
2212         CURSOR acquisition_cursor IS
2213         SELECT  rc.cost_component_class_id
2214                 ,rc.cost_analysis_code
2215                 ,nvl(rca.estimated_amount, rca.actual_amount)/mmt.transaction_quantity /* ANTHIYAG Bug#5463200 14-Aug-2006 */
2216                 ,uom.uom_code
2217          FROM   rcv_transactions t,
2218                 po_rcv_charges rc,
2219                  po_rcv_charge_allocations rca,
2220                 mtl_units_of_measure uom,
2221                 mtl_material_transactions mmt /* ANTHIYAG Bug#5463200 14-Aug-2006 */
2222          WHERE  mmt.transaction_id = transaction_row.transaction_id /* ANTHIYAG Bug#5463200 14-Aug-2006 */
2223          AND    t.transaction_id = mmt.rcv_transaction_id
2224          AND    t.shipment_header_id = rc.shipment_header_id
2225          AND    t.shipment_line_id  = rca.shipment_line_id
2226          AND    rc.charge_id = rca.charge_id
2227          AND    t.unit_of_measure = uom.unit_of_measure
2228          AND    rc.include_in_acquisition_cost = 'I'; /* ANTHIYAG Bug#5463200 14-Aug-2006 */
2229 
2230          l_acq_tab            acq_tab_type;
2231          l_from_uom           VARCHAR2(25); --(This variable stores po or receipt unit of measure)
2232          l_cmpntcls_id        NUMBER;
2233          l_cost_analysis_code VARCHAR2(5);
2234          l_component_cost     NUMBER;
2235          l_acquisition_cost NUMBER;
2236          procedure_name VARCHAR2(100);
2237 
2238         /* End 3824810 sschinch */
2239 BEGIN
2240 
2241   procedure_name := 'Process Special Charges';
2242   IF l_debug_level >= l_debug_level_medium
2243      THEN
2244        fnd_file.put_line
2245        (fnd_file.log,'Entered Procedure: '||procedure_name);
2246      END IF;
2247 
2248   l_acquisitions_total := 0;
2249 
2250   OPEN acquisition_cursor;
2251   FETCH acquisition_cursor BULK COLLECT INTO l_acq_tab;
2252   CLOSE acquisition_cursor;
2253 
2254 
2255     IF l_acq_tab.EXISTS(1)
2256      THEN
2257     FOR i IN 1 .. l_acq_tab.COUNT
2258     LOOP
2259 
2260       l_from_uom := l_acq_tab(i).receipt_uom;
2261       IF transaction_row.trans_um <> l_from_uom
2262        THEN
2263          l_acquisition_cost :=
2264                INV_CONVERT.INV_UM_CONVERT(ITEM_ID       => transaction_row.inventory_item_id
2265                                          ,PRECISION     => 5
2266                                          ,ORGANIZATION_ID => transaction_row.orgn_id
2267                                          ,LOT_NUMBER     => transaction_row.lot_number
2268                                          ,FROM_QUANTITY => l_acq_tab(i).component_cost
2269                                          ,FROM_UNIT     => transaction_row.trans_um
2270                                          ,TO_UNIT       => l_from_uom
2271                                          ,FROM_NAME     => NULL
2272                                          ,TO_NAME       => NULL
2273                                            );
2274         l_acq_tab(i).component_cost := l_acquisition_cost;
2275 
2276       	IF (l_acquisition_cost < 0)
2277       	THEN
2278            fnd_file.put_line
2279                  (fnd_file.log,'ERROR: Unable to convert from '
2280                  ||transaction_row.trans_um
2281                  ||' to '||l_from_uom||' for transaction ID '
2282                  ||transaction_row.transaction_id
2283                  );
2284                  l_return_status := 'E';
2285                  RETURN;
2286 
2287         END IF;
2288       END IF;
2289 
2290       /******** Bug  4038722 - Dinesh Vadivel - Start **********/
2291 
2292       /*   Convert to Base Currency, if Acquisition Cost(i.e., Receipt )
2293        **  currency is different.
2294        **  receipt_ccy and l_exchange_rate would have been calculated
2295        **  in process_receipts itself. So we can just use it as they are global variables.
2296        */
2297       IF ( l_base_ccy_code <>  receipt_ccy)  THEN /* Check if the receipt currency is the same as the base currency */
2298 
2299          IF l_debug_level >= l_debug_level_medium
2300            THEN
2301               fnd_file.put_line   (fnd_file.log,'
2302                  In Acquisition Costs() : Converting component_cost : '||
2303                  NVL(l_acq_tab(i).component_cost,0)||' Receipt Currency : '||receipt_ccy||
2304                  ' to Base Currency : '||l_base_ccy_code||'. New component_cost : '||
2305                  NVL(l_acq_tab(i).component_cost,0) * l_exchange_rate||'. Exchange Rate is : '||l_exchange_rate);
2306           END IF;
2307 
2308           l_acq_tab(i).component_cost :=  NVL(l_acq_tab(i).component_cost,0) * l_exchange_rate;
2309 
2310         END IF;
2311 
2312       /******** Bug  4038722 - Dinesh Vadivel - End **********/
2313 
2314       l_acquisitions_total := l_acquisitions_total + NVL(l_acq_tab(i).component_cost,0);
2315 
2316       l_cmpntcls_id := l_acq_tab(i).cost_cmpntcls_id;
2317       l_cost_analysis_Code := l_acq_tab(i).cost_analysis_code;
2318       l_component_cost := NVL(l_acq_tab(i).component_cost,0);
2319 
2320 
2321 
2322       l_acqui_cost_tab(i) := SYSTEM.gmf_cost_type(l_cmpntcls_id,
2323       			                   l_cost_analysis_code,
2324      			                   0,
2325      			                   l_component_cost,
2326      			                   0);
2327 
2328        /*End Bug 3824810 sschinch */
2329 
2330     END LOOP;
2331   END IF;
2332 
2333     IF l_debug_level >= l_debug_level_medium
2334     THEN
2335       fnd_file.put_line(fnd_file.log,'At end of get_special_charges, the costs are:');
2336       FOR i IN 1 .. l_acqui_cost_tab.COUNT
2337       LOOP
2338         fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||l_acqui_cost_tab(i).cost_cmpntcls_id);
2339         fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||l_acqui_cost_tab(i).cost_analysis_code);
2340         fnd_file.put_line(fnd_file.log,'Level ['||k||']: '||l_acqui_cost_tab(i).cost_level);
2341         fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||l_acqui_cost_tab(i).component_cost);
2342         fnd_file.put_line(fnd_file.log,'====================================');
2343 
2344       END LOOP;
2345     END IF;
2346 
2347     IF l_debug_level >= l_debug_level_medium
2348      THEN
2349        fnd_file.put_line
2350        (fnd_file.log,'Leaving Procedure: '||procedure_name);
2351      END IF;
2352     EXCEPTION
2353     WHEN OTHERS THEN
2354       fnd_file.put_line(fnd_file.log,procedure_name||':'||SQLERRM);
2355 END get_special_charges;
2356 
2357 --*************************************************************************************
2358 --*    Procedure Name : PROCESS_ADJUSTMENT
2359 --*
2360 --*     Description :
2361 --*                Procedure to handle adjusted lots (ADJI/ADJR)
2362 --*
2363 --* HISTORY
2364 --*
2365 --*   27-Nov-2004 Dinesh Vadivel Bug# 4004338
2366 --*        Added cost_type_code in where clause of the select query which returns the header_id
2367 --*        from the gmf_material_lot_cost_txns. The issue arises if we have the same item in two different lot cost methods
2368 --*        and try to run the Lot Actual Cost Process
2369 --*************************************************************************************
2370 
2371  PROCEDURE process_adjustment
2372 IS
2373   loop_count NUMBER;
2374   l_header_id gmf_lot_costs.header_id%type;
2375   procedure_name VARCHAR2(100);
2376 BEGIN
2377 
2378   procedure_name := 'Process Adjustment';
2379   IF l_debug_level >= l_debug_level_medium
2380      THEN
2381        fnd_file.put_line
2382        (fnd_file.log,'Entered Procedure: '||procedure_name);
2383      END IF;
2384 
2385   -- This procedure is used if the lot being adjusted has a lot cost. Lots being created
2386   -- via ADJx transactions are handled by the process_creation procedure (above).
2387 
2388   -- Adjustments to lots are handled at the prevailing lot costs. They only affect the quantities
2389   -- not the costs themselves.
2390 
2391   IF l_debug_level >= l_debug_level_medium
2392   THEN
2393     fnd_file.put_line
2394     (fnd_file.log,'Updating lot cost header with trans_qty of '||transaction_row.trans_qty);
2395   END IF;
2396 
2397   -- If the existing cost is marked as 'Final' and we are running in test mode we need
2398   -- to clone the header and its details to prevent multiple decrements from the same transaction.
2399 
2400   IF     old_cost.final_cost_flag = 1
2401   AND    l_final_run_flag = 0
2402   THEN
2403     clone_costs;
2404   END IF;
2405 
2406 
2407 
2408   UPDATE gmf_lot_costs
2409   SET    onhand_qty = onhand_qty + transaction_row.trans_qty
2410   ,      last_update_date = sysdate
2411   WHERE  header_id = old_cost.header_id;
2412 
2413   IF SQL%ROWCOUNT = 1
2414   THEN
2415     IF l_debug_level >= l_debug_level_medium
2416     THEN
2417       fnd_file.put_line
2418       (fnd_file.log,'Creating new cost transaction');
2419     END IF;
2420 
2421     l_header_id := old_cost.header_id;
2422 
2423     create_material_transaction
2424     ( l_header_id
2425     , l_cost_type_id /* INVCONV sschinch */
2426     , transaction_row.trans_date
2427     , transaction_row.trans_qty
2428     , transaction_row.trans_um
2429     , transaction_row.trans_qty * old_cost.unit_cost
2430     , transaction_row.transaction_id
2431     , old_cost.unit_cost
2432     , old_cost.onhand_qty + transaction_row.trans_qty
2433     , old_cost.unit_cost
2434     , old_cost.onhand_qty
2435     , NULL
2436     ,transaction_row.lot_number
2437     , l_return_status
2438     );
2439 
2440     IF l_return_status <> 'S'
2441     THEN
2442       RETURN;
2443     END IF;
2444   ELSE
2445     l_return_status := 'E';
2446     RETURN;
2447   END IF;
2448   IF l_debug_level >= l_debug_level_medium
2449      THEN
2450        fnd_file.put_line
2451        (fnd_file.log,'Leaving Procedure: '||procedure_name);
2452      END IF;
2453 
2454 EXCEPTION
2455   WHEN OTHERS
2456   THEN fnd_file.put_line
2457        (fnd_file.log,'Failed in procedure process_adjustment with error');
2458        fnd_file.put_line
2459        (fnd_file.log,SQLERRM);
2460        l_return_status := 'U';
2461 
2462 END process_adjustment;
2463 
2464 
2465 
2466 --********************************************************************************************************
2467     --*    Procedure Name : PROCESS_REVERSALS
2468     --*
2469     --*     Description :
2470     --*               Procedure to reversals for products  - Uday Moogala - Bug 4004338
2471     --*
2472     --*   Description :   Assume three records returned by inv_tran_cursor with trans_qty as 100,-100 and 75.
2473     --*    When we encounter -100 record we have to reverse the transaction and set the unit_cost of this record to
2474     --*           Zero  -  if there is no cost prior to 100 record
2475     --*           X$     - where X$ is the cost of the record that is prior to 100 if any exists.
2476     --*          This X$ will be set one and only if we get 100 and -100 adjacent.
2477     --*
2478     --*   Dinesh -No Bug# - Earlier new_cost_ind was not set up properly.Now corrected along with 4053149
2479     --*          NEW_COST_IND in gmf_material_lot_cost_txns is used in the Subledger Posting.
2480     --*          If this indicator is set to 1 then that means whatever cost pointed by
2481     --*          header_id in gmf_lot_cost_details is the AVERAGE COST and not the actual
2482     --*          TRANSACTION COST. The Actual Transaction cost is under the negative of header_id.
2483     --*          So, depending on this NEW_COST_IND, the SL will decide on posting at the cost of
2484     --*          header_id or negative of header_id (i.e., -header_id)
2485     --*
2486     --*  Dinesh 4227784 - Issue due to the above changes. Since we have added gmf_material_lot_cost_txns
2487     --*          to the get_previous_costs_cur CURSOR, while querying for the prev-prev transaction
2488     --*          it will ignore the reversal transactions if any, because the reversal transaction will
2489     --*          not have the exact header_id as in gmf_lot_costs. Rather it will have the same header_id
2490     --*          as that of its original transaction.
2491     --*          So removed this table and added seperately to get new_cost_ind
2492     --*
2493     --**********************************************************************************************
2494 
2495 
2496 PROCEDURE process_reversals
2497 IS
2498 /* INVCONV sschinch modifications */
2499 
2500   CURSOR get_previous_costs_cur(
2501            p_item_id   NUMBER,
2502            p_lot_number VARCHAR2,
2503            p_orgn_id      NUMBER,
2504            p_cost_type_id NUMBER,
2505            p_cost_date DATE
2506            )
2507   IS
2508    SELECT *
2509      FROM (
2510            SELECT last_trx_source_type_id,  --last_costing_doc_type prev_doc_type INVCONV sschinch,
2511                   last_trx_action_id,     --last_costing_doc_id   prev_doc_id INVCONV sschinch,
2512                   header_id             prev_header_id,
2513                   unit_cost             prev_unit_cost,
2514                   RANK () OVER (PARTITION BY glc.inventory_item_id, glc.organization_id, glc.cost_type_id, glc.lot_number
2515                                     ORDER BY glc.cost_date DESC, glc.header_id DESC) lot_cost_rank
2516              FROM gmf_lot_costs glc
2517             WHERE glc.inventory_item_id     = p_item_id
2518               AND glc.lot_number  = p_lot_number
2519               AND glc.organization_id = p_orgn_id
2520               AND glc.cost_type_id = p_cost_type_id
2521               AND glc.cost_date <= p_cost_date
2522           )
2523      WHERE lot_cost_rank < 3
2524      ORDER BY lot_cost_rank
2525     ;
2526 
2527   CURSOR get_cost_details_cur(p_header_id NUMBER)
2528   IS
2529     SELECT cost_cmpntcls_id,
2530            cost_analysis_code,
2531            cost_level,
2532            component_cost,
2533            burden_ind,
2534            cost_origin,
2535            frozen_ind
2536       FROM gmf_lot_cost_details
2537      WHERE header_id = p_header_id
2538   ;
2539 
2540 /* Bug 4227784 - Dinesh Added this as we removed txns table from above query */
2541   CURSOR get_material_lot_cost_txns(p_header_id NUMBER)
2542   IS
2543     SELECT   gmlct.new_cost_ind
2544        FROM  gmf_material_lot_cost_txns gmlct
2545      WHERE   gmlct.cost_header_id = p_header_id
2546     ORDER BY cost_trans_id DESC
2547   ;
2548 
2549   l_prev_cost_cnt    NUMBER := 0;
2550   l_prev_header_id   gmf_lot_costs.header_id%TYPE;
2551   l_prev_prev_header_id   gmf_lot_costs.header_id%TYPE := NULL;
2552   l_prev_unit_cost   gmf_lot_costs.unit_cost%TYPE;
2553   l_cost_header_id   gmf_material_lot_cost_txns.cost_header_id%TYPE;
2554 
2555   l_onhand_qty       gmf_lot_costs.onhand_qty%TYPE;
2556   l_header_id        gmf_lot_costs.header_id%TYPE;
2557   l_unit_cost        gmf_lot_costs.unit_cost%TYPE;
2558   l_prev_trans_unit_cost  gmf_lot_cost_details.component_cost%TYPE;
2559   l_cmpnt_cost       gmf_lot_cost_details.component_cost%TYPE;
2560   l_prev_new_cost_ind   gmf_material_lot_cost_txns.new_cost_ind%TYPE;          /* Dinesh No Bug# */
2561   procedure_name VARCHAR2(100);
2562 
2563 BEGIN
2564 
2565   procedure_name := 'Process Reversals';
2566   IF l_debug_level >= l_debug_level_medium
2567      THEN
2568        fnd_file.put_line
2569        (fnd_file.log,'Entered Procedure: '||procedure_name);
2570      END IF;
2571 
2572     --
2573   -- Running this loop only twice to see two previous cost rows.
2574   -- Cursor will return more than 2 rows in some cases, so had to put EXIT
2575   -- after 2nd iteration
2576   --
2577   /* INVCONV sschich modifications */
2578   FOR i in get_previous_costs_cur(transaction_row.inventory_item_id,
2579                                   transaction_row.lot_number,
2580                                   transaction_row.orgn_id,
2581                                   l_cost_type_id,
2582                                   transaction_row.trans_date
2583                                  )
2584   LOOP
2585       -- if following variable has count > 1 then there are previous costs before
2586       -- original yield.
2587       l_prev_cost_cnt := l_prev_cost_cnt + 1;
2588 
2589 
2590       IF l_prev_cost_cnt = 1
2591       AND (i.last_trx_source_type_id  <> 5 --transaction_row.transaction_source_type_id
2592            OR i.last_trx_action_id <> transaction_row.transaction_action_id)
2593       THEN
2594         -- Other types of txns after original yield. So, process this reversal
2595         -- as regular adjustment. This will result in incorrect avg costs. known issue
2596         IF l_debug_level >= l_debug_level_medium
2597         THEN
2598           fnd_file.put_line
2599           (fnd_file.log,'Reversals: Processing reversal as regular adjustment');
2600         END IF;
2601 
2602         process_adjustment;
2603         RETURN;
2604 
2605 
2606       ELSIF l_prev_cost_cnt = 1         -- 1st iteration
2607       AND   i.last_trx_source_type_id = 5
2608       AND   i.last_trx_action_id = transaction_row.transaction_action_id
2609       THEN
2610         -- set cost and onhand qty to zero assuming no previous costs.
2611         -- if prev costs exists, then we'll use those costs and qty, but will
2612         -- get set in the else block below in the 2nd iteration.
2613         IF l_debug_level >= l_debug_level_low
2614         THEN
2615           fnd_file.put_line
2616           (fnd_file.log, 'Reversals: This txn is (pure) reversal of previous txn');
2617         END IF;
2618 
2619         l_prev_header_id      := i.prev_header_id;
2620         l_cost_header_id      := i.prev_header_id; /* will be used to insert in material txns table */
2621         l_prev_unit_cost      := 0;
2622         --
2623         -- new_cost_ind is needed as Subledger depends on this flag to get the
2624         -- correct transaction costs.
2625         --
2626         -- l_prev_new_cost_ind   := i.prev_new_cost_ind;   /* Dinesh - No Bug #  Removed for 4227784*/
2627         /* Bug 4227784 Added instead of above line*/
2628         OPEN get_material_lot_cost_txns(l_prev_header_id);
2629         FETCH get_material_lot_cost_txns INTO l_prev_new_cost_ind;
2630         CLOSE get_material_lot_cost_txns;
2631       ELSE         -- 2nd iteration
2632         --
2633         -- Will come here if there any old costs before original yield.
2634         --
2635         IF l_debug_level >= l_debug_level_low
2636         THEN
2637           fnd_file.put_line
2638           (fnd_file.log,'Reversals: costs exists prior to original yield');
2639         END IF;
2640         l_prev_header_id      := i.prev_header_id;
2641         l_prev_prev_header_id := i.prev_header_id;
2642         l_prev_unit_cost      := i.prev_unit_cost;
2643         --
2644         -- new_cost_ind is needed as Subledger depends on this flag to get the
2645         -- correct transaction costs.
2646         --
2647         --l_prev_new_cost_ind   := i.prev_new_cost_ind; /*Dinesh - No Bug # - Removed for 4227784*/
2648         /* Bug 4227784 Added instead of above line*/
2649         OPEN get_material_lot_cost_txns(l_prev_header_id);
2650         FETCH get_material_lot_cost_txns INTO l_prev_new_cost_ind;
2651         CLOSE get_material_lot_cost_txns;
2652 
2653         EXIT;
2654       END IF;
2655   END LOOP;
2656 
2657 
2658   IF l_debug_level >= l_debug_level_low
2659   THEN
2660     fnd_file.put_line
2661      (fnd_file.log,'Reversals: setting unit cost to ' || l_prev_unit_cost ||
2662                    ' and qty to ' || (old_cost.onhand_qty + transaction_row.trans_qty));
2663   END IF;
2664 
2665   IF l_prev_cost_cnt = 0
2666       THEN
2667         fnd_file.put_line
2668               (fnd_file.log,'ERROR: Failed to retrieve previous costs in Process Reversals');
2669         RETURN;
2670   END IF;
2671 
2672   create_cost_header
2673   ( p_item_id         => transaction_row.inventory_item_id
2674   , p_lot_number      => transaction_row.lot_number
2675   , p_orgn_id         => transaction_row.orgn_id
2676   , p_cost_type_id    => l_cost_type_id
2677   , p_unit_cost       => l_prev_unit_cost
2678   , p_cost_date       => transaction_row.trans_date
2679   , p_onhand_qty      => old_cost.onhand_qty + transaction_row.trans_qty
2680   , p_trx_src_type_id => transaction_row.transaction_source_type_id
2681   , p_doc_id          => transaction_row.doc_id
2682   , p_txn_act_id      => transaction_row.transaction_action_id
2683   , x_header_id      => l_header_id
2684   , x_unit_cost      => l_unit_cost
2685   , x_onhand_qty     => l_onhand_qty
2686   , x_return_status  => l_return_status
2687   );
2688 
2689 
2690   IF l_return_status = 'S'
2691   THEN
2692 
2693         IF l_debug_level >= l_debug_level_low
2694         THEN
2695           fnd_file.put_line
2696           (fnd_file.log,'Reversals: Creating new cost detail row');
2697         END IF;
2698 
2699     FOR j in get_cost_details_cur(l_prev_header_id)
2700     LOOP
2701 
2702         IF l_prev_cost_cnt = 1
2703         THEN
2704           l_cmpnt_cost := 0;
2705         ELSIF l_prev_cost_cnt > 1
2706         THEN
2707           -- carrying forward costs before original yield
2708           l_cmpnt_cost := NVL(j.component_cost,0);
2709         END IF;
2710 
2711         create_cost_detail
2712         ( p_header_id          => l_header_id
2713         , p_component_class_id => j.cost_cmpntcls_id
2714         , p_cost_analysis_code => j.cost_analysis_code
2715         , p_cost_level         => j.cost_level
2716         , p_component_cost     => l_cmpnt_cost
2717         , p_burden_ind         => j.burden_ind
2718         , x_return_status      => l_return_status
2719         );
2720 
2721     END LOOP;
2722 
2723     IF l_return_status = 'S'
2724     THEN
2725 
2726       IF l_debug_level >= l_debug_level_medium
2727       THEN
2728         fnd_file.put_line
2729         (fnd_file.log,'Reversals: Creating new material cost transaction. the l_prev_prev_header_id is  '||l_prev_prev_header_id||' and l_cost_header_id '||l_cost_header_id);
2730       END IF;
2731 
2732 
2733 
2734       SELECT NVL(SUM(component_cost),0)
2735         INTO l_prev_trans_unit_cost
2736         FROM gmf_lot_cost_details
2737        WHERE header_id = DECODE(NVL(l_prev_prev_header_id, 0), 0, l_cost_header_id, -l_cost_header_id);
2738 
2739 
2740 
2741       create_material_transaction
2742       ( l_cost_header_id
2743       , l_cost_type_id    /*INVCONV sschinch */
2744       , transaction_row.trans_date
2745       , transaction_row.trans_qty
2746       , transaction_row.trans_um
2747       , transaction_row.trans_qty * l_prev_trans_unit_cost --old_cost.unit_cost
2748       , transaction_row.transaction_id
2749       , l_unit_cost
2750       , old_cost.onhand_qty + transaction_row.trans_qty
2751       , old_cost.unit_cost
2752       , old_cost.onhand_qty
2753       ,  l_prev_new_cost_ind
2754       ,  transaction_row.lot_number
2755       , l_return_status
2756       );
2757 
2758       IF l_return_status <> 'S'
2759       THEN
2760         RETURN;
2761       END IF;
2762 
2763     ELSE
2764       RETURN;
2765     END IF;
2766   END IF;
2767 
2768 EXCEPTION
2769   WHEN OTHERS
2770   THEN fnd_file.put_line
2771        (fnd_file.log,'Failed in procedure process_reversals with error');
2772        fnd_file.put_line
2773        (fnd_file.log,SQLERRM);
2774        l_return_status := 'U';
2775 END process_reversals;
2776 
2777 
2778 
2779 --************************************************************************************************
2780 --*  Procedure Name : PROCESS_REVERSALS2
2781 --*
2782 --*  Desc: New Procedure for handling batch product reversal transactions
2783 --*   In process_reversals procedure we check whether the cost record in gmf_lot_costs
2784 --*   just prior to reversal transaction is its Original transaction.
2785 --*   If so, we will leap frog that record so as to reverse the effect of original transaction
2786 --*   in the average cost of the lot. gmf_material_lot_cost_txns will be pointed to the original
2787 --*   transaction record, so that subledger posts the entry accordingly. BUT we are not handling
2788 --*   the case if original transactions and reversal transactions don't come next to each other.
2789 --*   we process it as adjustment and it is a known issue.
2790 --*
2791 --*   To handle this issue, changed the complete logic of process_reversals.
2792 --*   No more leap frogging. We directly get the original transaction header_id and get the orig
2793 --*   transaction cost. With this we average it with the latest average cost available in order t
2794 --*   reverse the orig trx from the average cost.
2795 --*   If the current onhand_qty(before reversal) is less than or equal to the reversal trx qty
2796 --*   then we consider it as adjustment.
2797 --*
2798 --* Handled in 11.5.10 as part of Bug 4769118
2799 --*
2800 --*/
2801 
2802 PROCEDURE process_reversals2
2803 IS
2804   CURSOR get_orig_trx(p_orig_trans_id NUMBER)
2805   IS
2806   SELECT DECODE(NVL(txns.new_cost_ind,0), 0, txns.cost_header_id, -txns.cost_header_id), txns.new_cost_ind
2807   FROM gmf_material_lot_cost_txns txns
2808   WHERE txns.transaction_id = p_orig_trans_id;
2809 
2810   l_orig_trx_header_id gmf_lot_costs.header_id%TYPE;
2811   l_orig_trx_new_cost_ind NUMBER;
2812   l_orig_trx_trans_cost NUMBER;
2813   orig_trx_cost_tab l_cost_tab_type;
2814 
2815   l_onhand_qty       gmf_lot_costs.onhand_qty%TYPE;
2816   l_header_id        gmf_lot_costs.header_id%TYPE;
2817   l_unit_cost        gmf_lot_costs.unit_cost%TYPE;
2818   l_cmpnt_cost       gmf_lot_cost_details.component_cost%TYPE;
2819   i NUMBER;
2820   procedure_name VARCHAR2(100);
2821 
2822 
2823 BEGIN
2824    procedure_name := 'Process Reversals2';
2825    IF l_debug_level >= l_debug_level_medium
2826      THEN
2827        fnd_file.put_line
2828        (fnd_file.log,'Entered Procedure: '||procedure_name);
2829      END IF;
2830 
2831     OPEN get_orig_trx(transaction_row.reverse_id);
2832     FETCH get_orig_trx INTO l_orig_trx_header_id, l_orig_trx_new_cost_ind;
2833 
2834     IF(get_orig_trx%NOTFOUND) THEN
2835       CLOSE get_orig_trx;
2836       fnd_file.put_line(fnd_file.log,'Reversals2: Error in locating the original trx '||transaction_row.reverse_id||' of transaction'||transaction_row.transaction_id);
2837       l_return_status := 'E';
2838       RETURN;
2839     END IF;
2840     CLOSE get_orig_trx;
2841 
2842     /* l_orig_trx_header_id directly points to trx cost. and it can be negative */
2843     OPEN  lot_cost_detail_cursor(l_orig_trx_header_id);
2844     FETCH lot_cost_detail_cursor BULK COLLECT INTO orig_trx_cost_tab;
2845 
2846     IF(orig_trx_cost_tab.COUNT = 0) THEN
2847       CLOSE lot_cost_detail_cursor;
2848       fnd_file.put_line(fnd_file.log,'Reversals2: Error in locating the cost detail for orig_trx '||transaction_row.reverse_id);
2849       l_return_status := 'E';
2850       RETURN;
2851     END IF;
2852     CLOSE lot_cost_detail_cursor;
2853 
2854     new_cost := old_cost;
2855     new_cost_tab := old_cost_tab;
2856 
2857     IF (old_cost.onhand_qty + transaction_row.trans_qty <= 0) THEN
2858         /* Replicate process_adjustments without create_material_transactions */
2859         IF     old_cost.final_cost_flag = 1
2860         AND    l_final_run_flag = 0
2861         THEN
2862           clone_costs;
2863         END IF;
2864 
2865         UPDATE gmf_lot_costs
2866         SET    onhand_qty = onhand_qty + transaction_row.trans_qty,
2867         last_update_date = sysdate
2868         WHERE  header_id = old_cost.header_id;
2869 
2870         IF(SQL%ROWCOUNT = 1) THEN
2871           l_return_status := 'S';
2872         ELSE
2873           fnd_file.put_line(fnd_file.log,'Reversals2: Error in updating gmf_lot_costs for transaction_id: '||to_char(transaction_row.transaction_id));
2874           l_return_status := 'E';
2875           RETURN;
2876         END IF;
2877 
2878     ELSE
2879 
2880       merge_costs(orig_trx_cost_tab, transaction_row.trans_qty, new_cost.onhand_qty, 'A');
2881       create_cost_header
2882       ( p_item_id         => transaction_row.inventory_item_id
2883       , p_lot_number      => transaction_row.lot_number
2884       , p_orgn_id         => transaction_row.orgn_id
2885       , p_cost_type_id    => l_cost_type_id
2886       , p_unit_cost      => new_cost.unit_cost
2887       , p_cost_date      => transaction_row.trans_date
2888       , p_onhand_qty     => old_cost.onhand_qty + transaction_row.trans_qty
2889       , p_trx_src_type_id => transaction_row.transaction_source_type_id
2890       , p_txn_act_id       => transaction_row.transaction_action_id
2891       , p_doc_id          => transaction_row.doc_id
2892       , x_header_id      => l_header_id
2893       , x_unit_cost      => l_unit_cost
2894       , x_onhand_qty     => l_onhand_qty
2895       , x_return_status  => l_return_status
2896       );
2897 
2898 
2899       IF l_return_status = 'S'
2900       THEN
2901         IF l_debug_level >= l_debug_level_medium
2902         THEN
2903           fnd_file.put_line(fnd_file.log,'Reversals2: Creating new cost detail row');
2904         END IF;
2905 
2906         FOR i in 1..new_cost_tab.COUNT
2907         LOOP
2908           create_cost_detail
2909           ( p_header_id          => l_header_id
2910           , p_component_class_id => new_cost_tab(i).cost_cmpntcls_id
2911           , p_cost_analysis_code => new_cost_tab(i).cost_analysis_code
2912           , p_cost_level         => new_cost_tab(i).cost_level
2913           , p_component_cost     => new_cost_tab(i).component_cost
2914           , p_burden_ind         => new_cost_tab(i).burden_ind
2915           , x_return_status      => l_return_status
2916           );
2917         END LOOP;
2918 
2919       END IF;
2920     END IF; /* End of if old_cost.onhand + trans_qty <= 0 */
2921 
2922     IF l_return_status = 'S'
2923     THEN
2924 
2925       l_orig_trx_trans_cost := 0;
2926 
2927       FOR i in 1..orig_trx_cost_tab.COUNT
2928       LOOP
2929         l_orig_trx_trans_cost := l_orig_trx_trans_cost + orig_trx_cost_tab(i).component_cost;
2930       END LOOP;
2931 
2932       IF l_debug_level >= l_debug_level_medium
2933       THEN
2934         fnd_file.put_line
2935         (fnd_file.log,'Reversals2: Creating new material cost transaction. The orig_header_id is '||l_orig_trx_header_id||' and l_header_id '||l_header_id);
2936       END IF;
2937 
2938       create_material_transaction
2939       ( l_orig_trx_header_id
2940       , l_cost_type_id
2941       , transaction_row.trans_date
2942       , transaction_row.trans_qty
2943       , transaction_row.trans_um
2944       , transaction_row.trans_qty * l_orig_trx_trans_cost
2945       , transaction_row.transaction_id
2946       , new_cost.unit_cost
2947       , old_cost.onhand_qty + transaction_row.trans_qty
2948       , old_cost.unit_cost
2949       , old_cost.onhand_qty
2950       , l_orig_trx_new_cost_ind
2951       , transaction_row.lot_number
2952       , l_return_status
2953       );
2954 
2955 
2956       IF l_return_status <> 'S'
2957       THEN
2958         fnd_file.put_line(fnd_file.log,'Reversals2: Error in creating material_transaction for '||to_char(transaction_row.transaction_id));
2959         RETURN;
2960       END IF;
2961 
2962     ELSE
2963       fnd_file.put_line(fnd_file.log,'Reversals2: Error in creating Cost Header/Detail for transaction '||to_char(transaction_row.transaction_id));
2964       RETURN;
2965     END IF;
2966    IF l_debug_level >= l_debug_level_medium
2967      THEN
2968        fnd_file.put_line
2969        (fnd_file.log,'Leaving Procedure: '||procedure_name);
2970      END IF;
2971 
2972  EXCEPTION
2973  WHEN OTHERS THEN fnd_file.put_line
2974    (fnd_file.log,'Failed in procedure process_reversals2 with error');
2975     fnd_file.put_line(fnd_file.log,SQLERRM);
2976     l_return_status := 'U';
2977  END PROCESS_REVERSALS2;
2978 
2979 
2980 
2981 
2982 
2983     --**********************************************************************************************
2984     --*                                                                                            *
2985     --* Procedure to handle movements (TRNI/TRNR)                                                  *
2986     --*                                                                                            *
2987     --**********************************************************************************************
2988 
2989 
2990 
2991 
2992 PROCEDURE process_movement
2993 ( p_line_type   NUMBER
2994 , p_source_orgn NUMBER
2995 , p_target_orgn NUMBER
2996 , p_source_le   NUMBER
2997 , p_target_le   NUMBER
2998 , p_trans_date DATE
2999 )
3000 IS
3001   l_orgn_code    VARCHAR2(4);
3002   l_header_id    NUMBER;
3003   l_unit_cost    NUMBER;
3004   l_onhand_qty   NUMBER;
3005   l_method       VARCHAR2(10);
3006   l_ccc_id       NUMBER;
3007   l_a_code       VARCHAR2(4);
3008   l_no_of_rows   NUMBER;
3009   i              NUMBER;
3010   retval         NUMBER;
3011   l_msg_data     VARCHAR2(100);
3012   l_msg_count    NUMBER;
3013   l_var_return_status VARCHAR2(2);
3014   l_total_cost    NUMBER;
3015 
3016   l_src_qty       NUMBER;
3017   l_src_uom       VARCHAR2(3);
3018   l_cost_ratio    NUMBER;
3019   procedure_name VARCHAR2(100);
3020 
3021 
3022 
3023   CURSOR get_src_qty_uom IS
3024      select mtln.primary_quantity,
3025             lcig.primary_uom_code
3026      from   mtl_material_transactions mmt,
3027             mtl_transaction_lot_numbers mtln,
3028             gmf_lot_costed_items_gt lcig
3029      where  mmt.transaction_id = transaction_row.transfer_transaction_id
3030        AND  mmt.transaction_id = mtln.transaction_id
3031        AND  mmt.inventory_item_id = lcig.inventory_item_id
3032        AND  mmt.organization_id   = lcig.organization_id;
3033 
3034 BEGIN
3035    procedure_name := 'Process Movement';
3036    IF l_debug_level >= l_debug_level_medium
3037      THEN
3038        fnd_file.put_line
3039        (fnd_file.log,'Entered Procedure: '||procedure_name);
3040      END IF;
3041      -- This procedure is only called when the source and target organizations differ.
3042 
3043   -- If this is a debit on the source organization (line type = -1) this is equivalent to an adjustment
3044   -- and we must assume that there is a cost there already (in old_cost and old_cost_tab).
3045 
3046   -- If it is the credit on a target organization then we have to locate the costs in the source organization
3047   -- and create or modify the cost in the target organization with them.
3048 
3049   -- A complication here is that TRNI/TRNR transaction pairs can be for different companies, and this means
3050   -- the the company in the sending transaction might not use the same currency as the company in the
3051   -- receiving transaction.
3052 
3053   IF p_line_type = -1
3054   THEN
3055     -- This is the debit on the source organization.
3056     process_adjustment;
3057 
3058   ELSE
3059     -- This is the credit on the target organization. Retrieve the costs from the source organization.
3060     -- This section also caters for line type 0 (used in PORC transactions for internal orders)
3061 
3062     IF l_debug_level >= l_debug_level_medium
3063     THEN
3064       fnd_file.put_line(fnd_file.log,'At start of Process Movement, new_cost_tab is:');
3065       IF new_cost_tab.EXISTS(1)
3066       THEN
3067         FOR k IN 1 .. new_cost_tab.COUNT
3068         LOOP
3069           fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
3070           fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
3071           fnd_file.put_line(fnd_file.log,'Level ['||k||']: '||new_cost_tab(k).cost_level);
3072           fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
3073           fnd_file.put_line(fnd_file.log,'====================================');
3074         END LOOP;
3075       ELSE
3076         fnd_file.put_line(fnd_file.log,'EMPTY');
3077       END IF;
3078     END IF;
3079     -- As there is a chance that the two organizations could be in separate companies we need to do something
3080     -- to ensure we can locate a cost for the sending transaction. If the two companies involved are the same
3081     -- we can simply query the gmf_lot_costs table. If not we have to do dig around for costs.
3082 
3083 
3084 
3085       IF (p_source_le <> p_target_le)
3086       THEN
3087         IF (1 = gmf_cmcommon.Get_Process_Item_Cost(p_api_version               => 1.0
3088                                                    ,p_init_msg_list             => 'T'
3089                                                    ,x_return_status             => l_var_return_status
3090                                                    ,x_msg_count                 => l_msg_count
3091                                                   ,x_msg_data                  => l_msg_data
3092                                                   ,p_inventory_item_id         => transaction_row.inventory_item_id
3093                                                   ,p_organization_id           =>  p_source_orgn
3094                                                   ,p_transaction_date          => p_trans_date
3095                                                   ,p_detail_flag               => 4
3096                                                   ,p_cost_method               => l_method
3097                                                   ,p_cost_component_class_id   =>l_ccc_id
3098                                                   ,p_cost_analysis_code        =>  l_a_code
3099                                                   ,x_total_cost                => l_total_cost
3100                                                   ,x_no_of_rows                => l_no_of_rows
3101                                                   ,p_lot_number                => transaction_row.lot_number
3102                                                  ,p_transaction_id            => NULL
3103                                                 ) ) THEN
3104           IF new_cost_tab.EXISTS(1)
3105           THEN
3106             new_cost_tab.delete;
3107           END IF;
3108 
3109           FOR i IN 1..l_no_of_rows
3110           LOOP
3111             gmf_cmcommon.get_multiple_cmpts_cost
3112                              (v_index             => i
3113                              ,v_cost_cmpntcls_id  => l_ccc_id
3114                              ,v_cost_analysis_code=> l_a_code
3115                              ,v_cmpnt_amt         => l_unit_cost
3116                              ,v_retrieve_ind      => 4
3117                              ,v_status            => retval
3118                              );
3119             IF retval <> 0
3120             THEN
3121               l_return_status := 'E';
3122               fnd_file.put_line
3123               (fnd_file.log,'ERROR: Failed to retrieve single cost component in source organization '||l_org_tab(p_source_orgn));
3124               RETURN;
3125             ELSE
3126               -- Procedure doesn't return burden ind so coerce it to zero.
3127               new_cost_tab(i) := SYSTEM.gmf_cost_type ( l_ccc_id, l_a_code, 0, l_unit_cost, 0);
3128             END IF;
3129           END LOOP;
3130         ELSE
3131           IF new_cost_tab.EXISTS(1)
3132           THEN
3133             new_cost_tab.delete;
3134           END IF;
3135           OPEN  component_class_cursor( p_target_le,transaction_row.inventory_item_id,p_target_orgn,p_trans_date);
3136           FETCH component_class_cursor INTO l_ccc_id,l_a_code,dummy;
3137           IF (component_class_cursor%NOTFOUND) THEN
3138             l_return_status := 'E';
3139             fnd_file.put_line
3140             (fnd_file.log,'ERROR: Failed to retrieve cost multiple components in source organization '||l_org_tab(p_source_orgn));
3141             CLOSE component_class_cursor;
3142             RETURN;
3143           END IF;
3144         END IF;
3145        ELSE
3146             new_cost.header_id := NULL;
3147             OPEN  lot_cost_cursor(p_source_orgn, transaction_row.inventory_item_id, transaction_row.lot_number, p_trans_date,l_cost_type_id );
3148             FETCH lot_cost_cursor INTO new_cost;
3149             CLOSE lot_cost_cursor;
3150 
3151             IF new_cost.header_id IS NULL
3152             THEN
3153               fnd_file.put_line
3154               ( fnd_file.log,'ERROR: Unable to locate cost header for organization: '||l_org_tab(p_source_orgn)
3155               ||  ', item ID: '||transaction_row.inventory_item_id
3156               ||', lot Number: '||transaction_row.lot_number
3157               );
3158               l_return_status := 'E';
3159               RETURN;
3160             END IF;
3161 
3162             OPEN  lot_cost_detail_cursor ( new_cost.header_id );
3163             FETCH lot_cost_detail_cursor BULK COLLECT INTO new_cost_tab;
3164             CLOSE lot_cost_detail_cursor;
3165           END IF;
3166 
3167           IF l_debug_level >= l_debug_level_medium
3168           THEN
3169             fnd_file.put_line(fnd_file.log,'After reading costs from source organization, new_cost_tab is:');
3170             FOR k IN 1 .. new_cost_tab.COUNT
3171             LOOP
3172               fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
3173               fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
3174               fnd_file.put_line(fnd_file.log,'Level ['||k||']: '||new_cost_tab(k).cost_level);
3175               fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
3176               fnd_file.put_line(fnd_file.log,'====================================');
3177             END LOOP;
3178           END IF;
3179 
3180 
3181           IF NOT new_cost_tab.EXISTS(1)
3182           THEN
3183             fnd_file.put_line
3184             ( fnd_file.log,'ERROR: Unable to locate source cost details for organization: '||l_org_tab(p_source_orgn)
3185             ||', inventory item ID: '||transaction_row.inventory_item_id
3186             ||', lot number: '||transaction_row.lot_number /* INVCONV sschinch */
3187             );
3188             l_return_status := 'E';
3189             RETURN;
3190           END IF;
3191 
3192           OPEN get_src_qty_uom;
3193           FETCH get_src_qty_uom INTO l_src_qty, l_src_uom;
3194           IF get_src_qty_uom%NOTFOUND THEN
3195               fnd_file.put_line( fnd_file.log,'ERROR: Unable to locate source primary quantity and primary uom for the transfer transaction id: '||
3196                  transaction_row.transfer_transaction_id);
3197                 l_return_status := 'E';
3198              CLOSE get_src_qty_uom;
3199              RETURN;
3200           END IF;
3201           CLOSE get_src_qty_uom;
3202 
3203           IF l_src_uom <> transaction_row.trans_um THEN
3204               fnd_file.put_line( fnd_file.log,'Source primary uom: '||l_src_uom||' and Receiving primary uom: '||transaction_row.trans_um||
3205                  ' are different');
3206               IF transaction_row.trans_qty <> 0 THEN
3207                  l_cost_ratio := (l_src_qty * -1)/transaction_row.trans_qty;
3208                  fnd_file.put_line(fnd_file.log,'Source primary qty: '||l_src_qty||', Receiving primary qty: '||transaction_row.trans_qty||
3209                  ', cost ratio: '||l_cost_ratio);
3210               ELSE
3211                  l_cost_ratio := 0;
3212                  fnd_file.put_line(fnd_file.log,'Transaction qty is zero, so making cost ratio as zero');
3213               END IF;
3214 
3215               FOR i IN 1 .. new_cost_tab.COUNT
3216               LOOP
3217                 new_cost_tab(i).component_cost := new_cost_tab(i).component_cost * l_cost_ratio;
3218               END LOOP;
3219 
3220           ELSE
3221               fnd_file.put_line( fnd_file.log,'Source primary uom: '||l_src_uom||' and Receiving primary uom: '||transaction_row.trans_um||
3222                  ' are same');
3223               l_cost_ratio := 1;
3224           END IF;
3225 
3226 
3227 
3228           process_burdens;
3229 
3230           IF l_return_status <> 'S'
3231           THEN
3232             RETURN;
3233           END IF;
3234 
3235           -- At this point old_cost_tab holds the costs of the lot in the target whse (if any exist),
3236           -- new_cost_tab holds the costs of the lot in the source whse (these must exist) and
3237           -- l_burdens_cost_tab holds the costs of any burdens set up against the target whse (if any exist).
3238           -- We now need to see if the two organizations belong to companies that share a common
3239           -- currency. If we find that they don't then we have to convert the source costs to the currency
3240           -- used in the target before we start the merging them.
3241 
3242           IF p_source_le <> p_target_le
3243           THEN
3244             SELECT s.base_currency_code,t.base_currency_code
3245             INTO   l_from_ccy_code, l_to_ccy_code
3246             FROM   gmf_fiscal_policies s,
3247                    gmf_fiscal_policies t
3248             WHERE  s.legal_entity_id = p_source_le
3249             AND    t.legal_entity_id  = p_target_le;
3250 
3251             IF l_from_ccy_code <> l_to_ccy_code
3252             THEN
3253 
3254 
3255               l_exchange_rate := gl_currency_api.get_closest_rate(x_from_currency => l_from_ccy_code,
3256                                                                x_to_currency   => l_to_ccy_code,
3257                                                                x_conversion_date => transaction_row.trans_date,
3258                                                                x_max_roll_days   => 0);
3259 
3260 
3261 
3262               IF l_error_status <> 0
3263               THEN
3264                 fnd_file.put_line
3265                 ( fnd_file.log
3266                  , 'ERROR: Unable to find exchange rate from '||l_from_ccy_code
3267                  ||' to '||l_to_ccy_code
3268                  ||' on '||transaction_row.trans_date
3269                 );
3270                 l_return_status := 'E';
3271                 RETURN;
3272               END IF;
3273 
3274              FOR i IN 1 .. new_cost_tab.COUNT
3275               LOOP
3276                 new_cost_tab(i).component_cost := new_cost_tab(i).component_cost * l_exchange_rate;
3277               END LOOP;
3278             END IF;
3279           END IF;
3280 
3281           IF l_burdens_total <> 0
3282           THEN
3283             IF l_debug_level >= l_debug_level_medium
3284             THEN
3285               fnd_file.put_line
3286                 (fnd_file.log,'Combining burden costs');
3287             END IF;
3288 
3289             merge_costs( l_burden_costs_tab
3290                        , 1
3291                        , 1
3292                       , 'C'
3293                        );
3294             new_cost.unit_cost := new_cost.unit_cost + l_burdens_total;
3295           END IF;
3296 
3297           -- We need to preserve the 'new' cost so that we can write its details separately to the
3298           -- merged costs. This preserved cost is also what is used when we write the new material
3299           -- lot cost transaction. Bug 3578680
3300 
3301           prd_cost := new_cost;
3302           prd_cost_tab := new_cost_tab;
3303 
3304           IF l_debug_level >= l_debug_level_medium
3305           THEN
3306             fnd_file.put_line
3307              (fnd_file.log,'Aggregating old costs with new costs');
3308           END IF;
3309 
3310           merge_costs( old_cost_tab
3311                , old_cost.onhand_qty
3312                , transaction_row.trans_qty
3313                , 'A'
3314                );
3315           create_cost_header
3316            ( p_item_id         => transaction_row.inventory_item_id
3317             , p_lot_number      => transaction_row.lot_number
3318             , p_orgn_id         => transaction_row.orgn_id
3319             , p_cost_type_id    =>  l_cost_type_id
3320             , p_unit_cost       => new_cost.unit_cost
3321             , p_cost_date       => transaction_row.trans_date
3322             , p_onhand_qty      => transaction_row.trans_qty + old_cost.onhand_qty
3323             , p_trx_src_type_id => transaction_row.transaction_source_type_id
3324             , p_txn_act_id       => transaction_row.transaction_action_id
3325             , p_doc_id          => transaction_row.doc_id
3326             , x_header_id       => l_header_id
3327             , x_unit_cost       => l_unit_cost
3328             , x_onhand_qty      => l_onhand_qty
3329             , x_return_status   => l_return_status
3330           );
3331 
3332           IF l_return_status = 'S'
3333           THEN
3334             IF l_debug_level >= l_debug_level_medium
3335             THEN
3336               fnd_file.put_line
3337                 (fnd_file.log,'Creating new cost detail rows');
3338             END IF;
3339 
3340             -- Bug 3388974
3341             new_cost.header_id := l_header_id;
3342             new_cost.unit_cost := l_unit_cost;
3343             new_cost.onhand_qty := l_onhand_qty;
3344 
3345             FOR i IN 1..new_cost_tab.COUNT
3346             LOOP
3347               create_cost_detail
3348                ( l_header_id
3349                 , new_cost_tab(i).cost_cmpntcls_id
3350                 , new_cost_tab(i).cost_analysis_code
3351                 , 0
3352                 , new_cost_tab(i).component_cost
3353                 , 0
3354                 , l_return_status
3355                );
3356 
3357              IF l_return_status <> 'S'
3358              THEN
3359                RETURN;
3360              END IF;
3361            END LOOP;
3362 
3363            IF l_debug_level >= l_debug_level_medium
3364            THEN
3365              fnd_file.put_line
3366                (fnd_file.log,'Creating new material cost transaction');
3367            END IF;
3368 
3369 
3370            IF NOT old_cost_tab.EXISTS(1)
3371            THEN
3372              IF l_debug_level >= l_debug_level_high
3373              THEN
3374                fnd_file.put_line (fnd_file.log,'AAAAA');
3375              END IF;
3376 
3377              create_material_transaction
3378              ( new_cost.header_id
3379                , l_cost_type_id
3380                , transaction_row.trans_date
3381                , transaction_row.trans_qty
3382                , transaction_row.trans_um
3383                , new_cost.onhand_qty * new_cost.unit_cost
3384                , transaction_row.transaction_id
3385                , new_cost.unit_cost
3386                , transaction_row.trans_qty
3387                , NULL
3388                , NULL
3389                , NULL
3390                ,transaction_row.lot_number
3391                , l_return_status
3392              );
3393 
3394            ELSE
3395              IF l_debug_level >= l_debug_level_high
3396              THEN
3397                fnd_file.put_line (fnd_file.log,'BBBBB');
3398              END IF;
3399              create_material_transaction
3400              ( new_cost.header_id
3401                , l_cost_type_id
3402                , transaction_row.trans_date
3403                , transaction_row.trans_qty
3404                , transaction_row.trans_um
3405                , transaction_row.trans_qty * prd_cost.unit_cost -- Bug 3578680
3406                , transaction_row.transaction_id
3407                , new_cost.unit_cost
3408                , old_cost.onhand_qty + transaction_row.trans_qty
3409                , old_cost.unit_cost
3410                , old_cost.onhand_qty
3411                , 1
3412                ,transaction_row.lot_number
3413                , l_return_status
3414              );
3415 
3416              -- Bug 3578680
3417              FOR i IN 1..prd_cost_tab.COUNT
3418              LOOP
3419                create_cost_detail
3420                ( -l_header_id
3421                , prd_cost_tab(i).cost_cmpntcls_id
3422                , prd_cost_tab(i).cost_analysis_code
3423                , 0
3424                , prd_cost_tab(i).component_cost
3425                , 0
3426                , l_return_status
3427               );
3428 
3429               IF l_return_status <> 'S'
3430               THEN
3431                 RETURN;
3432               END IF;
3433             END LOOP;
3434           END IF;
3435           IF l_return_status <> 'S'
3436           THEN
3437             RETURN;
3438           END IF;
3439          END IF; /* get cost */
3440      END IF; /* Line type */
3441    IF l_debug_level >= l_debug_level_medium
3442      THEN
3443        fnd_file.put_line
3444        (fnd_file.log,'Leaving Procedure: '||procedure_name);
3445      END IF;
3446   EXCEPTION
3447   WHEN OTHERS THEN
3448   fnd_file.put_line
3449        (fnd_file.log,'Failed in procedure Process Movement with error');
3450        fnd_file.put_line
3451        (fnd_file.log,SQLERRM);
3452        l_return_status := 'U';
3453 
3454 END process_movement;
3455 
3456 --********************************************************************************************************
3457 --*    Procedure Name : PROCESS_RECEIPT
3458 --*
3459 --*     Description :
3460 --*               Procedure to handle Purchase Order Receipt.
3461 --*
3462 --* HISTORY
3463 --*
3464 --*   06-Jan-2004 Dinesh Vadivel Bug# 4095937
3465 --*       The Lot Cost Process calculates the Exchg Rate as on the Receipt Header Date
3466 --*        whereas the Subledger uses the "Exchg Rate Date". Modified the Lot Actual Cost Process
3467 --*        to use the rcv_transactions.CURRENCY_CONVERSION_RATE as the Exchg Rate .
3468 --*   2-Aug-2007 Bug 6320304/5953977 - Non-recoverable taxes ME, as part of this added unit of
3469 --*        nonrecoverable tax to the unit cost.
3470 --*
3471 --********************************************************************************************************
3472 
3473 PROCEDURE process_receipt
3474 IS
3475   document_code   rcv_transactions.source_document_code%TYPE;
3476   source_orgn_id    NUMBER;
3477   target_orgn_id    NUMBER;
3478   source_le_id      NUMBER;
3479   target_le_id      NUMBER;
3480   l_shipped_date DATE;
3481   procedure_name VARCHAR2(100);
3482 BEGIN
3483       procedure_name := 'Process Receipt';
3484      IF l_debug_level >= l_debug_level_medium
3485      THEN
3486        fnd_file.put_line
3487        (fnd_file.log,'Entered Procedure: '||procedure_name);
3488      END IF;
3489 
3490       IF l_debug_level >= l_debug_level_medium
3491       THEN
3492         fnd_file.put_line
3493         (fnd_file.log,'PO Receipt found: transaction ID = '||to_char(transaction_row.transaction_id));
3494       END IF;
3495 
3496       -- The pointers in the inventory transaction link to the receipt as follows:
3497       -- DOC_ID is the SHIPMENT_HEADER_ID in rcv_shipment_headers
3498       -- LINE_ID is the TRANSACTION_ID in rcv_transactions
3499 
3500       -- From the row in rcv_transactions the po_unit_price (expressed in price_um so
3501       -- we need to convert it to item_um) is the source of the cost. There is also the
3502       -- received qty (expressed in recv_um so it might need converting too, although the
3503       -- OPM inventory transaction should have the number we need already). There are
3504       -- pointers in the receiving transaction to the po_header, po_line and the receipt
3505       -- line too.
3506 
3507       -- The cost component class for the lot cost details is found in table cm_cmpt_mtl
3508       -- with a default from the fiscal policy if there isn't an entry in the table.
3509 
3510       -- Finally we have to keep in mind that a PORC transaction could be for a -ve quantity
3511       -- if goods are being returned to a vendor. In this respect, we shouldn't ever encounter
3512       -- the situation where uncosted goods are being sent back as we must have received them
3513       -- beforehand.
3514 
3515 
3516       IF l_debug_level >= l_debug_level_medium
3517       THEN
3518         fnd_file.put_line
3519         (fnd_file.log,' Retrieving receipt details');
3520       END IF;
3521 
3522       -- Now using source_doc_unit_of_measure instead of unit_of_measure
3523 
3524       -- B3514108, added source_document_code to select statement so we can see if this PORC is
3525       -- actually an RMA. Note that source_doc_unit_of_measure is NULL for an RMA so we have to
3526       -- perform an outer join.
3527 
3528 
3529 	/* Bug 6320304/5953977        SELECT t.po_unit_price, */
3530       SELECT  t.po_unit_price + DECODE(nvl(pda.quantity_ordered,0),0,0, (nvl(pda.nonrecoverable_tax,0)/pda.quantity_ordered)),
3531                t.currency_code,
3532                t.quantity,
3533                u.uom_code,
3534                t.source_document_code,
3535                NVL(t.currency_conversion_rate,1)
3536       INTO    receipt_unit_cost,
3537               receipt_ccy,
3538               receipt_qty,
3539               receipt_uom,
3540               document_code,
3541               l_exchange_rate
3542       FROM    rcv_transactions t, mtl_units_of_measure u, mtl_material_transactions mmt -- jboppana
3543       		, po_distributions_all pda
3544       WHERE   t.source_doc_unit_of_measure = u.unit_of_measure(+)
3545       AND     t.transaction_id = mmt.rcv_transaction_id
3546     --  AND     mmt.transaction_source_id = transaction_row.doc_id
3547       AND    t.po_distribution_id = pda.po_distribution_id (+)  /* Bug 6320304/5953977 */
3548       AND     mmt.transaction_id = transaction_row.transaction_id     ;
3549 
3550       -- If we're processing an RMA treat it as an adjustment
3551       -- and make a swift exit.
3552       /******** Bug  4038722 - Dinesh Vadivel - Convert to Base Currency, if Receipt currency is different **********/
3553       /*     Added the query to pick up the base currency in the main lot_cost_rollup procedure  */
3554 
3555       IF ( l_base_ccy_code <>  receipt_ccy)  THEN /* Check if the receipt currency is the same as the base currency */
3556         IF l_debug_level >= l_debug_level_medium
3557         THEN
3558           fnd_file.put_line   (fnd_file.log,' Converting Receipt_unit_cost : '||receipt_unit_cost||' Receipt Currency : '||receipt_ccy||
3559                                ' to Base Currency : '||l_base_ccy_code||'. New_receipt_unit_cost : '||receipt_unit_cost * l_exchange_rate||'. Exchange Rate is : '||l_exchange_rate);
3560         END IF;
3561 
3562         receipt_unit_cost := receipt_unit_cost * l_exchange_rate;
3563 
3564 
3565      END IF;
3566 
3567       /******** Bug  4038722 - Dinesh Vadivel - Convert to Base Currency, if Receipt currency is different - End **********/
3568 
3569 
3570       IF document_code = 'RMA'
3571       THEN
3572         IF l_debug_level >= l_debug_level_medium
3573         THEN
3574           fnd_file.put_line
3575           (fnd_file.log,' Processing PORC txn as an RMA');
3576         END IF;
3577         process_adjustment;
3578         RETURN;
3579       END IF;
3580 
3581       -- End of B3514108 changes
3582 
3583       -- B3513668 If this is an internal order treat it as a transfer or movement
3584 
3585       IF document_code = 'REQ'
3586       THEN
3587         SELECT
3588           mmt.organization_id,
3589           mmt.transfer_organization_id,
3590           hoi1.org_information2,
3591           hoi2.org_information2,
3592           r.shipped_date
3593         INTO
3594           target_orgn_id,source_orgn_id, source_le_id, target_le_id, l_shipped_date
3595         FROM
3596           rcv_transactions t,
3597           mtl_material_transactions mmt,
3598           rcv_shipment_headers r,
3599           rcv_shipment_lines rsl,
3600           po_headers_all poh,
3601           hr_organization_information hoi1,
3602           hr_organization_information hoi2
3603         WHERE
3604                 t.source_document_code = 'REQ'
3605         AND     t.transaction_id = mmt.rcv_transaction_id
3606         AND     mmt.transaction_id = transaction_row.transaction_id
3607         AND     mmt.organization_id = hoi2.organization_id
3608         AND     mmt.transfer_organization_id = hoi1.organization_id
3609         AND     hoi1.org_information_context = 'Accounting Information'
3610         AND     hoi2.org_information_context = 'Accounting Information'
3611         AND     t.shipment_header_id = r.shipment_header_id
3612         AND     r.receipt_source_code in ('INTERNAL ORDER')
3613         AND     t.shipment_line_id = rsl.shipment_line_id
3614         AND     t.po_header_id = poh.po_header_id (+);
3615 
3616 
3617          /* INVCONV sschinch */
3618          -- process_movement (1, source_whse, target_whse, source_co, target_co,l_shipped_date);
3619             process_movement (1, source_orgn_id, target_orgn_id, source_le_id, target_le_id,l_shipped_date);
3620 
3621         RETURN;
3622       END IF;
3623 
3624       /* Inter org transfers -- Intransit*/
3625       IF document_code = 'INVENTORY'
3626       THEN
3627         SELECT
3628           mmt.organization_id,
3629           mmt.transfer_organization_id,
3630           hoi1.org_information2,
3631           hoi2.org_information2,
3632           r.shipped_date
3633         INTO
3634           target_orgn_id,source_orgn_id, source_le_id, target_le_id, l_shipped_date
3635         FROM
3636           rcv_transactions t,
3637           mtl_material_transactions mmt,
3638           rcv_shipment_headers r,
3639           rcv_shipment_lines rsl,
3640           po_headers_all poh,
3641           hr_organization_information hoi1,
3642           hr_organization_information hoi2
3643         WHERE
3644                 t.source_document_code = 'INVENTORY'
3645         AND     t.transaction_id = mmt.rcv_transaction_id
3646         AND     mmt.transaction_id = transaction_row.transaction_id
3647         AND     mmt.organization_id = hoi2.organization_id
3648         AND     mmt.transfer_organization_id = hoi1.organization_id
3649         AND     hoi1.org_information_context = 'Accounting Information'
3650         AND     hoi2.org_information_context = 'Accounting Information'
3651         AND     t.shipment_header_id = r.shipment_header_id
3652         AND     r.receipt_source_code in ('INVENTORY')
3653         AND     t.shipment_line_id = rsl.shipment_line_id
3654         AND     t.po_header_id = poh.po_header_id (+);
3655 
3656 
3657          /* INVCONV sschinch */
3658          -- process_movement (1, source_whse, target_whse, source_co, target_co,l_shipped_date);
3659             process_movement (1, source_orgn_id, target_orgn_id, source_le_id, target_le_id,l_shipped_date);
3660 
3661         RETURN;
3662       END IF;
3663 
3664       -- If we reach here the PORC transaction is for a true PO Receipt
3665 
3666       IF receipt_unit_cost IS NULL
3667       THEN
3668         fnd_file.put_line
3669         (fnd_file.log,'ERROR: Could not retrieve PO unit price for transaction ID '||to_char(transaction_row.transaction_id));
3670         l_return_status := 'E';
3671         RETURN;
3672       END IF;
3673 
3674       IF l_debug_level >= l_debug_level_medium
3675       THEN
3676         fnd_file.put_line
3677         (fnd_file.log,'Received '||transaction_row.trans_qty ||' '||transaction_row.trans_um
3678          ||' at a unit price of '||l_base_ccy_code||' '||to_char(receipt_unit_cost)); /* Bug 4038722 - Changed the receipt_ccy to l_base_ccy_code. */
3679       END IF;
3680 
3681       IF transaction_row.trans_um <> receipt_uom
3682       THEN
3683          -- convert unit cost of receipt to a unit cost that is in the OPM transaction uom
3684          -- BUG 3485915 Reversed the uom parameters in the call
3685         lot_unit_cost :=
3686                INV_CONVERT.INV_UM_CONVERT(ITEM_ID       => transaction_row.inventory_item_id
3687                                           ,LOT_NUMBER    => transaction_row.lot_number
3688                                           ,ORGANIZATION_ID => transaction_row.orgn_id
3689                                           ,PRECISION     => 5
3690                                           ,FROM_QUANTITY => receipt_unit_cost
3691                                           ,FROM_UNIT     => transaction_row.trans_um
3692                                           ,TO_UNIT       => receipt_uom
3693                                           ,FROM_NAME     => NULL
3694                                           ,TO_NAME       => NULL
3695                                          );
3696         IF lot_unit_cost < 0
3697         THEN
3698           fnd_file.put_line
3699           (fnd_file.log,'ERROR: Could not convert PO receipt uom for transaction ID '||to_char(transaction_row.transaction_id));
3700           l_return_status := 'E';
3701           RETURN;
3702         END IF;
3703 
3704       ELSE
3705         lot_unit_cost := receipt_unit_cost;
3706       END IF;
3707 
3708       IF l_debug_level >= l_debug_level_medium
3709       THEN
3710         fnd_file.put_line(fnd_file.log,'Retrieving burdens for receipt');
3711       END IF;
3712 
3713       process_burdens;
3714 
3715       IF   l_return_status <> 'S'
3716       THEN
3717         RETURN;
3718       END IF;
3719 
3720       IF l_debug_level >= l_debug_level_medium
3721       THEN
3722         fnd_file.put_line(fnd_file.log,'Retrieving Freight and special charges for receipt');
3723       END IF;
3724 
3725       get_special_charges;
3726 
3727       IF l_return_status <> 'S'
3728       THEN
3729         RETURN;
3730       END IF;
3731 
3732       IF l_debug_level >= l_debug_level_medium
3733       THEN
3734         fnd_file.put_line
3735         (fnd_file.log,'Retrieving component class and analysis code for cost details');
3736       END IF;
3737 
3738       OPEN component_class_cursor
3739            (l_le_id, transaction_row.inventory_item_id, transaction_row.orgn_id,transaction_row.trans_date);
3740       FETCH component_class_cursor INTO component_class_id, cost_analysis_code, dummy;
3741       CLOSE component_class_cursor;
3742 
3743       IF l_debug_level >= l_debug_level_medium
3744       THEN
3745         fnd_file.put_line
3746         (fnd_file.log,'Setting up lot cost of PO receipt');
3747       END IF;
3748 
3749       IF l_debug_level >= l_debug_level_medium
3750       THEN
3751         fnd_file.put_line
3752         (fnd_file.log,'Lot cost of PO Receipt is: ' || to_char(lot_unit_cost));
3753       END IF;
3754 
3755 
3756       IF l_debug_level >= l_debug_level_medium
3757       THEN
3758         fnd_file.put_line
3759         (fnd_file.log,'Initialising new_cost_tab(1)' || to_char(lot_unit_cost));
3760       END IF;
3761 
3762       new_cost_tab(1) :=  SYSTEM.gmf_cost_type
3763                           ( component_class_id
3764                           , cost_analysis_code
3765                           , 0
3766                           , lot_unit_cost
3767                           , 0
3768                           );
3769 
3770       new_cost.unit_cost := lot_unit_cost;
3771 
3772       IF NOT old_cost_tab.EXISTS(1)
3773       THEN
3774         -- No costing data for this lot/organization exists
3775 
3776         IF l_burdens_total <> 0
3777         THEN
3778 
3779           IF l_debug_level >= l_debug_level_medium
3780           THEN
3781             fnd_file.put_line
3782             (fnd_file.log,'Merging burden costs');
3783           END IF;
3784 
3785           merge_costs( l_burden_costs_tab
3786                      , 0
3787                      , transaction_row.trans_qty
3788                      , 'C'
3789                      );
3790 
3791        END IF;
3792 
3793        IF l_acquisitions_total <> 0
3794        THEN
3795 
3796          IF l_debug_level >= l_debug_level_medium
3797          THEN
3798             fnd_file.put_line
3799             (fnd_file.log,'Merging acquisition costs');
3800          END IF;
3801 
3802          merge_costs( l_acqui_cost_tab
3803                      , 0
3804                      , transaction_row.trans_qty
3805                      , 'C'
3806                      );
3807 
3808       END IF;
3809 
3810       lot_unit_cost := lot_unit_cost + l_burdens_total + l_acquisitions_total;
3811 
3812       l_onhand_qty := transaction_row.trans_qty;
3813 
3814       IF l_debug_level >= l_debug_level_medium
3815       THEN
3816           fnd_file.put_line
3817           (fnd_file.log,'Finished setting up costs for PO Receipt. Lot unit cost is:'||to_char(lot_unit_cost));
3818       END IF;
3819     ELSE
3820       IF l_debug_level >= l_debug_level_medium
3821       THEN
3822         fnd_file.put_line
3823           (fnd_file.log,'Merging old costs with new cost');
3824       END IF;
3825 
3826       IF l_burdens_total <> 0
3827       THEN
3828         IF l_debug_level >= l_debug_level_medium
3829         THEN
3830             fnd_file.put_line
3831             (fnd_file.log,'Merging burden costs');
3832         END IF;
3833 
3834         merge_costs( l_burden_costs_tab
3835                     , transaction_row.trans_qty
3836                     , old_cost.onhand_qty
3837                     , 'C'
3838                     );
3839 
3840       END IF;
3841 
3842       IF l_acquisitions_total <> 0
3843       THEN
3844 
3845         IF l_debug_level >= l_debug_level_medium
3846         THEN
3847            fnd_file.put_line (fnd_file.log,'Merging Special Charges');
3848           END IF;
3849 
3850           merge_costs( l_acqui_cost_tab
3851                      , transaction_row.trans_qty
3852                      , old_cost.onhand_qty
3853                      , 'C'
3854                      );
3855 
3856         END IF;
3857 
3858         -- Bug 3578680
3859         prd_cost := new_cost;
3860         prd_cost_tab := new_cost_tab;
3861 
3862         merge_costs( old_cost_tab
3863                    , old_cost.onhand_qty
3864                    , transaction_row.trans_qty
3865                    , 'A'
3866                    );
3867 
3868         IF l_debug_level >= l_debug_level_medium
3869         THEN
3870           fnd_file.put_line(fnd_file.log,'Lot_unit_cost        = '||lot_unit_cost);
3871           fnd_file.put_line(fnd_file.log,'l_burdens_total      = '||l_burdens_total);
3872           fnd_file.put_line(fnd_file.log,'l_acquisitions_total = '||l_acquisitions_total);
3873           fnd_file.put_line(fnd_file.log,'old_onhand           = '||old_cost.onhand_qty);
3874           fnd_file.put_line(fnd_file.log,'old_unit_cost        = '||old_cost.unit_cost);
3875           fnd_file.put_line(fnd_file.log,'trans_qty            = '||transaction_row.trans_qty);
3876         END IF;
3877 
3878         lot_unit_cost := new_cost.unit_cost;
3879 
3880         IF l_debug_level >= l_debug_level_medium
3881         THEN
3882           fnd_file.put_line
3883           (fnd_file.log,'Finished setting up revised costs for PO Receipt. Lot unit cost is:'||to_char(lot_unit_cost));
3884         END IF;
3885 
3886          l_onhand_qty := transaction_row.trans_qty + old_cost.onhand_qty;
3887 
3888       END IF;
3889 
3890       IF l_debug_level >= l_debug_level_low
3891       THEN
3892         fnd_file.put_line
3893         (fnd_file.log,'Creating cost header row');
3894       END IF;
3895 
3896       create_cost_header
3897       ( transaction_row.inventory_item_id
3898       , transaction_row.lot_number
3899       , transaction_row.orgn_id
3900       , l_cost_type_id
3901       , lot_unit_cost
3902       , transaction_row.trans_date
3903       , l_onhand_qty
3904       , transaction_row.doc_id
3905       , transaction_row.transaction_source_type_id
3906       , transaction_row.transaction_action_id
3907       , new_cost.header_id
3908       , new_cost.unit_cost
3909       , new_cost.onhand_qty
3910       , l_return_status
3911       );
3912 
3913       IF l_return_status = 'S'
3914       THEN
3915         IF l_debug_level >= l_debug_level_medium
3916         THEN
3917           fnd_file.put_line
3918             (fnd_file.log,'Creating cost detail rows');
3919         END IF;
3920 
3921         FOR i in 1 .. new_cost_tab.COUNT
3922         LOOP
3923           create_cost_detail
3924           ( new_cost.header_id
3925           , new_cost_tab(i).cost_cmpntcls_id
3926           , new_cost_tab(i).cost_analysis_code
3927           , 0
3928           , new_cost_tab(i).component_cost
3929           , 0
3930           , l_return_status
3931           );
3932 
3933           IF l_return_status <> 'S'
3934           THEN
3935             RETURN;
3936           END IF;
3937 
3938         END LOOP;
3939 
3940         IF l_return_status = 'S'
3941         THEN
3942           IF l_debug_level >= l_debug_level_medium
3943           THEN
3944             fnd_file.put_line
3945             (fnd_file.log,'Creating cost transaction');
3946           END IF;
3947 
3948           IF NOT old_cost_tab.EXISTS(1)
3949           THEN
3950             create_material_transaction
3951             ( new_cost.header_id
3952             , l_cost_type_id
3953             , transaction_row.trans_date
3954             , transaction_row.trans_qty
3955             , transaction_row.trans_um
3956             , new_cost.onhand_qty * new_cost.unit_cost
3957             , transaction_row.transaction_id
3958             , new_cost.unit_cost
3959             , transaction_row.trans_qty
3960             , NULL
3961             , NULL
3962             , NULL
3963             , transaction_row.lot_number
3964             , l_return_status
3965             );
3966           ELSE
3967             -- Bug 3578680 Write the cost details with a negated header
3968             FOR i in 1 .. prd_cost_tab.COUNT
3969             LOOP
3970               create_cost_detail
3971               ( -new_cost.header_id
3972               , prd_cost_tab(i).cost_cmpntcls_id
3973               , prd_cost_tab(i).cost_analysis_code
3974               , 0
3975               , prd_cost_tab(i).component_cost
3976               , 0
3977               , l_return_status
3978               );
3979 
3980               IF l_return_status <> 'S'
3981               THEN
3982                 RETURN;
3983               END IF;
3984 
3985             END LOOP;
3986 
3987             create_material_transaction
3988             ( new_cost.header_id
3989             , l_cost_type_id
3990             , transaction_row.trans_date
3991             , transaction_row.trans_qty
3992             , transaction_row.trans_um
3993             , prd_cost.unit_cost*transaction_row.trans_qty
3994             , transaction_row.transaction_id
3995             , new_cost.unit_cost
3996             , new_cost.onhand_qty
3997             , old_cost.unit_cost
3998             , old_cost.onhand_qty
3999             , 1
4000             ,transaction_row.lot_number
4001             , l_return_status
4002             );
4003 
4004           END IF;
4005 
4006         END IF;
4007       END IF;
4008      IF l_debug_level >= l_debug_level_medium
4009      THEN
4010        fnd_file.put_line
4011        (fnd_file.log,'Leaving Procedure: '||procedure_name);
4012      END IF;
4013 END process_receipt;
4014 
4015 
4016     --**********************************************************************************************
4017     --*                                                                                            *
4018     --* Lot Cost audit- printing to log file.                                                      *
4019     --*                                                                                            *
4020     --**********************************************************************************************
4021 
4022 
4023 PROCEDURE lot_cost_audit
4024      ( p_item_id	NUMBER
4025      , p_lot_number  	VARCHAR2
4026      , p_orgn_id	NUMBER
4027      , p_batch_id	NUMBER
4028      , p_date_costed	DATE
4029      , p_steps		SYSTEM.GMF_STEP_TAB
4030      )
4031 IS
4032 
4033   l_item_id       NUMBER;
4034   l_lot_number      VARCHAR2(80);
4035   l_batch_id      NUMBER;
4036   l_date_costed   DATE;
4037   i               NUMBER;
4038   j               NUMBER;
4039   k               NUMBER;
4040   l               NUMBER;
4041   l_item_no       VARCHAR2(2000);
4042   l_batch_no      VARCHAR2(32);
4043   l_plant_code    VARCHAR2(4);
4044   l_resources     VARCHAR2(32);
4045   l_cost_analysis_code          VARCHAR2(4);
4046   l_cost_component_class_code   VARCHAR2(16);
4047   procedure_name VARCHAR2(100);
4048 
4049 
4050 BEGIN
4051    procedure_name := 'Lot Cost Audit';
4052    IF l_debug_level >= l_debug_level_medium
4053      THEN
4054        fnd_file.put_line
4055        (fnd_file.log,'Entered Procedure: '||procedure_name);
4056      END IF;
4057 
4058     -- Retrieve data in a form that the user will understand
4059 
4060 
4061     SELECT item_number INTO l_item_no FROM mtl_item_flexfields
4062     WHERE inventory_item_id = p_item_id AND organization_id = p_orgn_id;
4063 
4064 
4065 
4066     fnd_file.put_line
4067     (fnd_file.log, 'Lot cost breakdown for item '
4068     ||l_item_no
4069     ||' lot '
4070     ||l_lot_number
4071     ||' created by batch '
4072     ||l_plant_code
4073     ||' '
4074     ||l_batch_no
4075     ||' in organization '
4076     ||p_orgn_id
4077     ||' on '
4078     ||to_char(p_date_costed)
4079     );
4080 
4081     fnd_file.put_line
4082     (fnd_file.log, '==============================================================================================');
4083 
4084       --
4085       -- umoogala 26-dec-03: program is failing with ORA error when there are no batch steps
4086       --
4087        IF NOT l_step_tab.EXISTS(1)
4088        THEN
4089          fnd_file.put_line
4090          (fnd_file.log,'No batch steps to print.');
4091          RETURN;
4092        END IF;
4093 
4094       fnd_file.put_line
4095       (fnd_file.log,' ');
4096 
4097       FOR i IN 1..l_step_tab.count
4098       LOOP
4099         fnd_file.put_line
4100         (fnd_file.log,'Dump of step index '||to_char(i));
4101         fnd_file.put_line
4102         (fnd_file.log,'---------------------');
4103         fnd_file.put_line
4104         (fnd_file.log,'Step ID         = '||to_char(l_step_tab(i).current_step_id));
4105         fnd_file.put_line
4106         (fnd_file.log,'Step qty        = '
4107         ||to_char(ROUND(l_step_tab(i).step_qty,2))||' '||l_step_tab(i).step_qty_uom);
4108         fnd_file.put_line
4109         (fnd_file.log,'Output qty      = '
4110         ||to_char(ROUND(l_step_tab(i).output_qty,2))||' '||l_step_tab(i).step_qty_uom);
4111         fnd_file.put_line
4112         (fnd_file.log,'  ');
4113 
4114         fnd_file.put_line
4115         (fnd_file.log,'  Current Costs');
4116         fnd_file.put_line
4117         (fnd_file.log,'  -------------');
4118 
4119         IF l_step_tab(i).current_costs.EXISTS(1)
4120         THEN
4121           FOR j IN 1..l_step_tab(i).current_costs.count
4122           LOOP
4123             fnd_file.put_line
4124             (fnd_file.log,'  Component Class ID     = '
4125             ||to_char(l_step_tab(i).current_costs(j).cost_cmpntcls_id));
4126             fnd_file.put_line
4127             (fnd_file.log,'  Cost Analysis Code     = '
4128             ||l_step_tab(i).current_costs(j).cost_analysis_code);
4129             fnd_file.put_line
4130             (fnd_file.log,'  Cost Level             = '
4131             ||to_char(l_step_tab(i).current_costs(j).cost_level));
4132             fnd_file.put_line
4133             (fnd_file.log,'  Component Cost         = '
4134             ||to_char(ROUND(l_step_tab(i).current_costs(j).component_cost,2)));
4135             fnd_file.put_line(fnd_file.log,' ');
4136           END LOOP;
4137         ELSE
4138           fnd_file.put_line(fnd_file.log,'  This step has no current costs');
4139         END IF;
4140 
4141         fnd_file.put_line
4142         (fnd_file.log,'  Inherited Costs');
4143         fnd_file.put_line
4144         (fnd_file.log,'  ---------------');
4145         IF l_step_tab(i).inherited_costs.EXISTS(1)
4146         THEN
4147           FOR j IN 1..l_step_tab(i).inherited_costs.count
4148           LOOP
4149             fnd_file.put_line
4150             (fnd_file.log,'  Component Class ID     = '
4151             ||to_char(l_step_tab(i).inherited_costs(j).cost_cmpntcls_id));
4152             fnd_file.put_line
4153             (fnd_file.log,'  Cost Analysis Code     = '
4154             ||l_step_tab(i).inherited_costs(j).cost_analysis_code);
4155             fnd_file.put_line
4156             (fnd_file.log,'  Cost Level             = '
4157             ||to_char(l_step_tab(i).inherited_costs(j).cost_level));
4158             fnd_file.put_line
4159             (fnd_file.log,'  Component Cost         = '
4160             ||to_char(ROUND(l_step_tab(i).inherited_costs(j).component_cost,2)));
4161             fnd_file.put_line(fnd_file.log,' ');
4162           END LOOP;
4163         ELSE
4164           fnd_file.put_line(fnd_file.log,'  This step has no inherited costs');
4165         END IF;
4166 
4167         fnd_file.put_line
4168         (fnd_file.log,'  Step Costs');
4169         fnd_file.put_line
4170         (fnd_file.log,'  ---------------');
4171         IF l_step_tab(i).step_costs.EXISTS(1)
4172         THEN
4173           FOR j IN 1..l_step_tab(i).step_costs.count
4174           LOOP
4175             fnd_file.put_line
4176             (fnd_file.log,'  Component Class ID     = '
4177             ||to_char(l_step_tab(i).step_costs(j).cost_cmpntcls_id));
4178             fnd_file.put_line
4179             (fnd_file.log,'  Cost Analysis Code     = '
4180             ||l_step_tab(i).step_costs(j).cost_analysis_code);
4181             fnd_file.put_line
4182             (fnd_file.log,'  Cost Level             = '
4183             ||to_char(l_step_tab(i).step_costs(j).cost_level));
4184             fnd_file.put_line
4185             (fnd_file.log,'  Component Cost         = '
4186             ||to_char(ROUND(l_step_tab(i).step_costs(j).component_cost,2)));
4187             fnd_file.put_line(fnd_file.log,' ');
4188           END LOOP;
4189         ELSE
4190           fnd_file.put_line(fnd_file.log,'  This step has no step costs - THIS SHOULD NEVER HAPPEN');
4191         END IF;
4192 
4193 
4194         fnd_file.put_line(fnd_file.log,' ');
4195         fnd_file.put_line
4196         (fnd_file.log,'  Subsequent steps');
4197         fnd_file.put_line
4198         (fnd_file.log,'  ----------------');
4199         IF l_step_tab(i).dependencies(1).step_index IS NULL
4200         THEN
4201           fnd_file.put_line(fnd_file.log,'  This is a terminal step');
4202         ELSE
4203           FOR j IN 1..l_step_tab(i).dependencies.count
4204           LOOP
4205             fnd_file.put_line
4206             (fnd_file.log,'  Step index      = '||to_char(l_step_tab(i).dependencies(j).step_index));
4207             fnd_file.put_line
4208             (fnd_file.log,'  Step ID         = '||to_char(l_step_tab(i).dependencies(j).batchstep_id));
4209             fnd_file.put_line
4210             (fnd_file.log,'  Step qty        = '
4211             ||to_char(ROUND(l_step_tab(i).dependencies(j).step_qty,2))
4212             ||l_step_tab(i).dependencies(j).step_qty_uom);
4213             fnd_file.put_line(fnd_file.log,' ');
4214           END LOOP;
4215         END IF;
4216 
4217         fnd_file.put_line(fnd_file.log,' ');
4218         fnd_file.put_line
4219         (fnd_file.log,'  Materials');
4220         fnd_file.put_line
4221         (fnd_file.log,'  ---------');
4222 
4223         IF l_step_tab(i).materials.EXISTS(1)
4224         THEN
4225           FOR j in 1..l_step_tab(i).materials.count
4226           LOOP
4227             fnd_file.put_line
4228             (fnd_file.log,'  Trans ID      = '||to_char(l_step_tab(i).materials(j).trans_id));
4229             fnd_file.put_line
4230             (fnd_file.log,'  Legal Entity       = '||l_step_tab(i).materials(j).legal_entity_id);
4231             fnd_file.put_line
4232             (fnd_file.log,'  Organization      = '||l_org_tab(l_step_tab(i).materials(j).organization_id));
4233             fnd_file.put_line
4234             (fnd_file.log,'  Item ID       = '||to_char(l_step_tab(i).materials(j).item_id));
4235             fnd_file.put_line
4236             (fnd_file.log,'  Lot Number        = '||to_char(l_step_tab(i).materials(j).lot_number));
4237             fnd_file.put_line
4238             (fnd_file.log,'  Line type     = '||to_char(l_step_tab(i).materials(j).line_type));
4239             fnd_file.put_line
4240             (fnd_file.log,'  Trans Qty     = '||to_char(l_step_tab(i).materials(j).trans_qty)
4241             ||l_step_tab(i).materials(j).trans_um);
4242             fnd_file.put_line
4243             (fnd_file.log,'  Trans Date    = '
4244             ||to_char(l_step_tab(i).materials(j).trans_date,'DD-Mon-YYYY HH24:MI:SS'));
4245             fnd_file.put_line
4246             (fnd_file.log,'  Lot Cost Flag = '||to_char(l_step_tab(i).materials(j).lot_costed_flag));
4247             fnd_file.put_line
4248             (fnd_file.log,'  Contribution  = '||to_char(l_step_tab(i).materials(j).step_contribution));
4249             fnd_file.put_line
4250             (fnd_file.log,'  Trans Cost    = '||to_char(ROUND(l_step_tab(i).materials(j).trans_cost,2)));
4251             fnd_file.put_line
4252             (fnd_file.log,' ');
4253             fnd_file.put_line
4254             (fnd_file.log,'    Cost Details for material transaction '
4255             ||to_char(l_step_tab(i).materials(j).trans_id));
4256             fnd_file.put_line
4257             (fnd_file.log,'    ----------------------------------------------');
4258 
4259             IF l_step_tab(i).materials(j).cost_details.EXISTS(1)
4260             THEN
4261               FOR k IN 1..l_step_tab(i).materials(j).cost_details.count
4262               LOOP
4263                 fnd_file.put_line
4264                 (fnd_file.log,'    Component Class ID     = '
4265                 ||to_char(l_step_tab(i).materials(j).cost_details(k).cost_cmpntcls_id));
4266                 fnd_file.put_line
4267                 (fnd_file.log,'    Cost Analysis Code     = '
4268                 ||l_step_tab(i).materials(j).cost_details(k).cost_analysis_code);
4269                 fnd_file.put_line
4270                 (fnd_file.log,'    Cost Level             = '
4271                 ||to_char(l_step_tab(i).materials(j).cost_details(k).cost_level));
4272                 fnd_file.put_line
4273                 (fnd_file.log,'    Component Cost         = '
4274                 ||to_char(ROUND(l_step_tab(i).materials(j).cost_details(k).component_cost,2)));
4275                 fnd_file.put_line(fnd_file.log,' ');
4276               END LOOP;
4277             ELSE
4278               fnd_file.put_line(fnd_file.log,'    No costs exist for this material');
4279             END IF;
4280           END LOOP;
4281         ELSE
4282           fnd_file.put_line(fnd_file.log,'  This step has no associated materials');
4283         END IF;
4284 
4285         fnd_file.put_line(fnd_file.log,' ');
4286         fnd_file.put_line
4287         (fnd_file.log,'  Resources');
4288         fnd_file.put_line
4289         (fnd_file.log,'  ---------');
4290 
4291         IF l_step_tab(i).resources.EXISTS(1)
4292         THEN
4293           FOR j in 1..l_step_tab(i).resources.count
4294           LOOP
4295             fnd_file.put_line
4296             (fnd_file.log,'  Trans ID      = '||to_char(l_step_tab(i).resources(j).trans_id));
4297             fnd_file.put_line
4298             (fnd_file.log,'  Orgn Id     = '||l_org_tab(l_step_tab(i).resources(j).organization_id));
4299             fnd_file.put_line
4300             (fnd_file.log,'  Resource      = '||l_step_tab(i).resources(j).resources);
4301             fnd_file.put_line
4302             (fnd_file.log,'  Resource Usage= '||to_char(l_step_tab(i).resources(j).resource_usage)
4303             ||l_step_tab(i).resources(j).trans_um);
4304             fnd_file.put_line
4305             (fnd_file.log,'  Trans Date    = '
4306             ||to_char(l_step_tab(i).resources(j).trans_date,'DD-Mon-YYYY HH24:MI:SS'));
4307             fnd_file.put_line
4308             (fnd_file.log,'  Trans Cost    = '||to_char(ROUND(l_step_tab(i).resources(j).trans_cost,2)));
4309             fnd_file.put_line
4310             (fnd_file.log,' ');
4311             fnd_file.put_line
4312             (fnd_file.log,'    Cost Details for resource transaction '
4313             ||to_char(l_step_tab(i).resources(j).trans_id));
4314             fnd_file.put_line
4315             (fnd_file.log,'    ---------------------------------------------');
4316 
4317             IF l_step_tab(i).resources(j).cost_details.EXISTS(1)
4318             THEN
4319               FOR k IN 1..l_step_tab(i).resources(j).cost_details.count
4320               LOOP
4321                 fnd_file.put_line
4322                 (fnd_file.log,'    Component Class ID     = '
4323                 ||to_char(l_step_tab(i).resources(j).cost_details(k).cost_cmpntcls_id));
4324                 fnd_file.put_line
4325                 (fnd_file.log,'    Cost Analysis Code     = '
4326                 ||l_step_tab(i).resources(j).cost_details(k).cost_analysis_code);
4327                 fnd_file.put_line
4328                 (fnd_file.log,'    Cost Level             = '
4329                 ||to_char(l_step_tab(i).resources(j).cost_details(k).cost_level));
4330                 fnd_file.put_line
4331                 (fnd_file.log,'    Component Cost         = '
4332                 ||to_char(ROUND(l_step_tab(i).resources(j).cost_details(k).component_cost,2)));
4333                 fnd_file.put_line(fnd_file.log,' ');
4334               END LOOP;
4335             ELSE
4336               fnd_file.put_line(fnd_file.log,'    This resource has no costs');
4337             END IF;
4338           END LOOP;
4339         ELSE
4340           fnd_file.put_line(fnd_file.log,'  This step has no associated resources');
4341         END IF;
4342       END LOOP;
4343    IF l_debug_level >= l_debug_level_medium
4344      THEN
4345        fnd_file.put_line
4346        (fnd_file.log,'Leaving Procedure: '||procedure_name);
4347      END IF;
4348 
4349 END lot_cost_audit;
4350 
4351 
4352 
4353 
4354 
4355 
4356 --********************************************************************************************************
4357     --*    Procedure Name : PROCESS_BATCH
4358     --*
4359     --*     Description :
4360     --*               Procedure to handle manufactured lots.
4361     --*
4362     --* HISTORY
4363     --*
4364     --*  15-Dec-2004 Dinesh Vadivel Bug# 4053149
4365     --*    Earlier we were handling only two cases in the step dependency chain
4366     --*     1. if no routing call the explosion_cursor_nr.
4367     --*     2. if there is routing and dependent_steps == 0 then we will create n-1
4368     --*          virtual rows in gme_batch_step_dependencies
4369     --*    Now changed the code to handle the following cases if there is routing present
4370     --*     1. All the steps have Dependency defined - Directly call the explosion_cursor
4371     --*     2. Single Step Batch. Obviously No Dependency - So call explosion_cursor_ss
4372     --*     3. All steps are Independent. Here create n-1 virtual rows in dependency table
4373     --*         and then call the explosion_cursor
4374     --*     4. Few steps have dependency defined by user and Few are independent
4375     --*           Here, we have to add virtual rows in dependency table only for those
4376     --*           independent rows. For this we use a query and find the Min(batchstep_id)
4377     --*           and insert these independent rows above it.
4378     --*
4379     --*  Bug 4094132 - 20-Jan-2005 - Girish Jha Added a condition to set the new local variable
4380     --*                               l_step_output_qty to 0 or Null.
4381     --*
4382     --* 03-Feb-2005 - Bug 4144329 - Dinesh Vadivel - If there is no cost defined for Resource
4383     --*            then don't stop by setting the cost as uncostable. Just give a warning and ignore
4384     --*            the resources.
4385 
4386 --********************************************************************************************************
4387 
4388 PROCEDURE process_batch
4389 IS
4390   l_cost_factor   NUMBER;
4391   l_tran_qty      NUMBER;
4392   l_um_type       VARCHAR2(25);
4393   ing_tab         SYSTEM.gmf_matl_tab;
4394   prd_tab         SYSTEM.gmf_matl_tab;
4395   l_new_cost  NUMBER;
4396     l_step_output_qty NUMBER;         -- Bug 4094132 Added
4397     l_count NUMBER;                            -- Bug 4057323
4398     l_unassociated_prds NUMBER;   -- Bug 4057323
4399 
4400 
4401     /***** Bug 4227784 - Dinesh - The Below explanation is correct. But
4402      if we use the total_item_qty obtained from the below cursor, then the
4403      case in which the same product is allocated in multiple lines may give
4404      wrong cost. So we have to use actual_line_qty instead of
4405      total_item_qty *****/
4406 
4407     /***** Bug 4057323 - Dinesh - Added the below cursor *****/
4408     -- Eg: Consider we have two products P1 and P2 having cost allocation factor
4409     -- of 0.7 and 0.3 respectively.  P1 has 10LB which is yielded into two lots L1(8LB)
4410     -- L2(2LB) . P2 has 20LB yielded into one single Lot. Let us assume Total Ingredient
4411     -- Cost is 300$
4412     -- In the above case when we use the Cost Allocation Factor, the product P1 gets 210$ (300 * 0.7)
4413     -- and P2 gets 90$ (300 * 0.3). Now we need to approtion the cost of P1 into its Lots L1 and L2.
4414     -- It is done as L1 gets 210$ * 8/(8+2) = 168$ and L2 gets 210$ * 2/(2+8) = 42$ . This is total cost the
4415     -- lots L1 and L2 gets. So unit price of these lots will become as 21$ each.
4416     -- Here the denominator (8+2) is obtained using the following newly added query.
4417 
4418 
4419 
4420   /***** Bug 4053149  Dinesh Vadivel - Start *****/
4421   l_min_dep_step_id       NUMBER;
4422   l_cur_step_id           NUMBER;
4423   l_independent_steps_cnt NUMBER;
4424   procedure_name VARCHAR2(100);
4425 
4426 
4427   TYPE l_independent_steps_type IS TABLE OF
4428         gme_batch_steps.batchstep_id%TYPE INDEX BY BINARY_INTEGER;
4429   l_independent_steps  l_independent_steps_type;
4430 
4431   -- we'll add order by...doesn't harm. since data is not setup properly, we'll assume
4432   -- steps are in order, at least.
4433 
4434   /* Cursor to get the details of Independent Steps.
4435   ** i.e., Steps without any dependency defined */
4436   CURSOR independent_steps_cursor(p_batch_id NUMBER)
4437   IS
4438      SELECT batchstep_id
4439        FROM gme_batch_steps
4440       WHERE batch_id = p_batch_id
4441         AND batchstep_id NOT IN
4442              (
4443                SELECT batchstep_id
4444                  FROM gme_batch_step_dependencies
4445                 WHERE batch_id = p_batch_id
4446                 UNION ALL
4447                SELECT dep_step_id
4448                  FROM gme_batch_step_dependencies
4449                 WHERE batch_id = p_batch_id
4450              )
4451       ORDER BY batchstep_id
4452   ;
4453 
4454    /***** Bug 4053149  Dinesh Vadivel - End *****/
4455 
4456 BEGIN
4457 
4458    procedure_name := 'Process Batch';
4459    IF l_debug_level >= l_debug_level_medium
4460      THEN
4461        fnd_file.put_line
4462        (fnd_file.log,'Entered Procedure: '||procedure_name);
4463      END IF;
4464 
4465    l_skip_this_batch  := FALSE;
4466    l_skip_this_txn    := FALSE;
4467    l_cost_accrued     := FALSE;
4468 
4469 
4470 
4471       -- We're in business  . Will reach here only if batch_status is in (3,4)
4472 
4473       IF l_debug_level >= l_debug_level_medium
4474       THEN
4475         fnd_file.put_line
4476         (fnd_file.log,'Batch is eligible for lot costing');
4477       END IF;
4478 
4479      l_skip_this_batch := FALSE;
4480 
4481       -- If this is a product line then we need to perform a complete explosion of the batch
4482       -- steps. This will retrieve the steps in the correct sequence dependencies together
4483       -- with all associated material and resource transactions.
4484 
4485      IF transaction_row.line_type = 1 -- Don't explode for byproducts
4486      THEN
4487        IF l_debug_level >= l_debug_level_medium
4488        THEN
4489          fnd_file.put_line
4490          (fnd_file.log,'About to explode batch');
4491        END IF;
4492 
4493        -- Explode the batch
4494 
4495        SELECT nvl(routing_id,0) INTO l_routing
4496        FROM   gme_batch_header
4497        WHERE  batch_type = 0
4498        AND    batch_id = transaction_row.doc_id;
4499 
4500        IF l_routing = 0
4501        THEN
4502         fnd_file.put_line(fnd_file.log,' Opening nr cursor');
4503          OPEN  explosion_cursor_nr;
4504          FETCH explosion_cursor_nr BULK COLLECT INTO l_step_lev, l_step_tab;
4505          CLOSE explosion_cursor_nr;
4506 
4507           GMD_API_GRP.FETCH_PARM_VALUES (P_orgn_id => l_orgn_id,
4508                              P_parm_name => 'FM_YIELD_TYPE',
4509                              P_parm_value  => l_um_type,
4510                              X_return_status => l_return_status);
4511           IF l_return_status = 'E' THEN
4512            fnd_file.put_line(fnd_file.log,'Error Cannot find the value for the FM_YIELD_TYPE' );
4513            RETURN;
4514         END IF;
4515 
4516 
4517          SELECT uom_code INTO l_step_tab(1).step_qty_uom
4518          FROM   mtl_units_of_measure
4519          WHERE  uom_class = l_um_type AND base_uom_flag = 'Y';
4520 
4521        ELSE
4522          fnd_file.put_line(fnd_file.log,' Entering else part of l_routing=0');
4523 
4524          SELECT count(*) INTO l_dep_steps
4525          FROM   gme_batch_step_dependencies
4526          WHERE  batch_id = transaction_row.doc_id;
4527 
4528          /******* Dinesh Vadivel - Bug 4053149 - Start ********/
4529 
4530          OPEN independent_steps_cursor(transaction_row.doc_id);
4531          FETCH independent_steps_cursor BULK COLLECT INTO l_independent_steps;
4532          CLOSE independent_steps_cursor;
4533 
4534          l_independent_steps_cnt :=  NVL(l_independent_steps.COUNT,0)  ;
4535 
4536          IF l_debug_level >= l_debug_level_medium
4537          THEN
4538              fnd_file.put_line(fnd_file.log,
4539                 '  Before all the CASES...' ||
4540                 '# of dep steps : '|| l_dep_steps || '...' ||
4541                 '# of independent steps : '|| l_independent_steps_cnt );
4542               fnd_file.put_line(fnd_file.log,
4543                 ' Independent steps(ids), if any, are: ' );
4544               FOR i in 1.. l_independent_steps_cnt LOOP
4545                  fnd_file.put_line(fnd_file.log, ' i = '||i||'. step_id --> '||l_independent_steps(i));
4546               END LOOP;
4547          END IF;
4548 
4549 
4550          /*************  CASE 1 ******************/
4551          --  All the steps have Dependency defined
4552          IF (l_independent_steps_cnt = 0 AND  l_dep_steps > 0) THEN
4553 
4554            IF l_debug_level >= l_debug_level_medium
4555            THEN
4556               fnd_file.put_line(fnd_file.log,'  Opening the Normal Explosion Cursor at CASE 1. All dependency already defined ');
4557             END IF;
4558 
4559             OPEN  explosion_cursor (transaction_row.doc_id);
4560             FETCH explosion_cursor BULK COLLECT INTO l_step_lev, l_step_tab;
4561             CLOSE explosion_cursor;
4562 
4563            /*************  CASE 2 ******************/
4564           --  Single Step Batch. No Dependency
4565          ELSIF (l_independent_steps_cnt = 1  AND l_dep_steps = 0) THEN
4566 
4567              IF l_debug_level >= l_debug_level_medium
4568              THEN
4569                 fnd_file.put_line(fnd_file.log,'  Opening the Single Step Explosion Cursor at CASE 2');
4570              END IF;
4571 
4572               OPEN  explosion_cursor_ss (transaction_row.doc_id);
4573               FETCH explosion_cursor_ss BULK COLLECT INTO l_step_lev, l_step_tab;
4574               CLOSE explosion_cursor_ss;
4575 
4576          /*************  CASE 3 ******************/
4577          --  All steps are Independent
4578          ELSIF ( l_independent_steps_cnt > 1 AND l_dep_steps = 0) THEN
4579 
4580              IF l_debug_level >= l_debug_level_medium
4581              THEN
4582                 fnd_file.put_line(fnd_file.log,
4583                    ' Inside CASE 3 : All steps are independent. So we are
4584                      building virtual dependency chain. ');
4585              END IF;
4586 
4587               i:= 0;
4588               l_prior_step_id := NULL;
4589 
4590               FOR step_row IN steps_cursor(transaction_row.doc_id)
4591               LOOP
4592                    IF i > 0
4593                    THEN
4594                      INSERT INTO gme_batch_step_dependencies
4595                      ( batch_id
4596                      , batchstep_id
4597                      , dep_step_id
4598                      , standard_delay
4599                      , dep_type
4600                      , created_by
4601                      , creation_date
4602                      , last_updated_by
4603                      , last_update_date
4604                      )
4605                      VALUES
4606                      ( transaction_row.doc_id
4607                      , step_row.batchstep_id
4608                      , l_prior_step_id
4609                      , 0
4610                      , 0
4611                      , -1
4612                      , SYSDATE
4613                      , -1
4614                      , SYSDATE
4615                      );
4616                    END IF;
4617 
4618                    i := i+1;
4619                    l_prior_step_id := step_row.batchstep_id;
4620              END LOOP;
4621 
4622              OPEN  explosion_cursor (transaction_row.doc_id);
4623              FETCH explosion_cursor BULK COLLECT INTO l_step_lev, l_step_tab;
4624              CLOSE explosion_cursor;
4625 
4626              DELETE FROM gme_batch_step_dependencies
4627              WHERE  batch_id = transaction_row.doc_id;
4628          -- END OF CASE 3
4629 
4630 
4631          /*************  CASE 4 ******************/
4632          -- Few steps have dependency defined and Few are independent.
4633          ELSIF(l_independent_steps_cnt > 0 AND  l_dep_steps > 0) THEN
4634 
4635              IF l_debug_level >= l_debug_level_medium
4636              THEN
4637                  fnd_file.put_line(fnd_file.log,
4638                    ' Inside CASE 4 : Few steps are independent. So we are
4639                      building virtual dependency chain only for those
4640                      independent rows. ');
4641              END IF;
4642 
4643              SELECT MIN(dep_step_id)
4644                INTO l_min_dep_step_id
4645                FROM gme_batch_step_dependencies
4646               START WITH batch_id =  transaction_row.doc_id
4647                 AND batchstep_id NOT IN (SELECT dep_step_id
4648                                            FROM gme_batch_step_dependencies
4649                                           WHERE batch_id =  transaction_row.doc_id)
4650              CONNECT BY PRIOR dep_step_id = batchstep_id
4651                 AND batch_id = PRIOR batch_id;
4652 
4653              IF l_debug_level >= l_debug_level_medium
4654              THEN
4655                 fnd_file.put_line(fnd_file.log,'  CASE 4 : The minimum step id is '||l_min_dep_step_id);
4656              END IF;
4657 
4658              i:= 0;
4659              l_cur_step_id := l_min_dep_step_id;
4660 
4661              /*  Eg:  We have records 10,20,30,40,50 and 30,40,50 have dependency existing.
4662              **       There will be two records in the gme_batch_step_Dependency table
4663              **       as   batchstep_id : 40  (dep_step_id : 30)
4664              **       and batchstep_id : 50  (dep_step_id : 40)
4665              **
4666              **       In the below insert, we will add two new records as
4667              **       batchstep_id : 30      (dep_step_id : 20)
4668              **       batchstep_id : 20 (dep_step_id : 10).
4669              */
4670 
4671 
4672              FOR i IN 1..l_independent_steps_cnt
4673              LOOP
4674                INSERT INTO gme_batch_step_dependencies
4675                      ( batch_id
4676                      , batchstep_id
4677                      , dep_step_id
4678                      , standard_delay
4679                      , dep_type
4680                      , created_by
4681                      , creation_date
4682                      , last_updated_by
4683                      , last_update_date
4684                      )
4685                VALUES
4686                      ( transaction_row.doc_id
4687                      , l_cur_step_id
4688                      , l_independent_steps(i)
4689                      , 0
4690                      , 0
4691                      , -1
4692                      , SYSDATE
4693                      , -1
4694                      , SYSDATE
4695                      );
4696                l_cur_step_id :=  l_independent_steps(i);
4697              END LOOP;
4698 
4699              OPEN  explosion_cursor (transaction_row.doc_id);
4700              FETCH explosion_cursor BULK COLLECT INTO l_step_lev, l_step_tab;
4701              CLOSE explosion_cursor;
4702 
4703              /* Delete only those records which were inserted above.
4704              **  Eg:  We have records 10,20,30,40,50 and 30,40,50 have dependency existing.
4705              **       There will be two records in the gme_batch_step_Dependency table
4706              **       as   40  (dep_step_id : 30)
4707              **       and 50  (dep_step_id : 40)
4708              **
4709              **       In the above insert, we have added two new records as
4710              **       30 (dep_step_id : 20)
4711              **       20 (dep_step_id : 10).
4712              **Now we need to delete these two newly inserted records.
4713              */
4714 
4715              FOR i IN 1 .. l_independent_steps_cnt
4716              LOOP
4717                 DELETE FROM gme_batch_step_dependencies
4718                 WHERE batch_id = transaction_row.doc_id
4719                   AND dep_step_id = l_independent_steps(i);
4720              END LOOP;
4721 
4722           /* ELSE is not used, because code will not reach ELSE. */
4723 
4724          END IF; /* Ending all the Cases */
4725 
4726       /******* Dinesh Vadivel - Bug 4053149 - End ********/
4727 
4728      END IF;  /* End if of l_routing = 0 */
4729 
4730        IF NOT l_step_tab.EXISTS(1)
4731        THEN
4732          fnd_file.put_line
4733          (fnd_file.log,'ERROR: Could not explode steps of batch ID '||to_char(transaction_row.doc_id));
4734          l_tmp := FALSE;
4735          RETURN;
4736        END IF;
4737 
4738        IF l_debug_level >= l_debug_level_medium
4739        THEN
4740          fnd_file.put_line
4741          (fnd_file.log,'After explosion, '||to_char(l_step_tab.count)||' steps loaded');
4742        END IF;
4743 
4744        -- Load the transactions and cost them individually
4745 
4746        FOR i in 1..l_step_tab.count
4747        LOOP
4748 
4749           /**** Bug 5368082 Skip the Batch and set the Lot as uncostable if any of the step_qty is zero ****/
4750          /* Added l_routing <> 0. When there is no routing, still l_step_tab will
4751           * have one record. In that case we should not check for step_qty = 0 check */
4752          IF (l_routing <> 0 AND l_step_tab(i).step_qty = 0)
4753          THEN
4754 	        l_skip_this_batch := TRUE;
4755 
4756            fnd_file.put_line /* Bug 4297815 - Debug Msg Tuning */
4757            ( fnd_file.log,'ERROR: The Actual Step Qty of one of the steps in Batch_Id '||transaction_row.doc_id||' is zero. The Batch will be skipped from being costed.');
4758 
4759            l_return_status := 'E';
4760            l_uncostable_lots_tab(transaction_row.orgn_id||'-'||transaction_row.inventory_item_id||'-'||transaction_row.lot_number) := transaction_row.inventory_item_id;
4761            l_tmp := FALSE;
4762 
4763            RETURN;
4764          END IF;
4765          /**** Bug 5368082 Skip the Lot if any of the step_qty is zero ****/
4766 
4767          IF l_routing <> 0
4768          THEN
4769             -- Load all resource transactions for each step and calculate the cost of each
4770 
4771            IF l_debug_level >= l_debug_level_medium
4772            THEN
4773             fnd_file.put_line
4774             (fnd_file.log,'Loading resource transactions for step ID '
4775             ||to_char(l_step_tab(i).current_step_id)
4776             );
4777            END IF;
4778 
4779            OPEN  resources_cursor (transaction_row.doc_id, l_step_tab(i).current_step_id);
4780            FETCH resources_cursor BULK COLLECT INTO l_step_tab(i).resources;
4781            CLOSE resources_cursor;
4782 
4783            IF l_debug_level >= l_debug_level_medium
4784            THEN
4785              fnd_file.put_line
4786              (fnd_file.log,'Loaded '
4787              ||to_char(l_step_tab(i).resources.count)||' resource txns'
4788              );
4789            END IF;
4790 
4791            FOR j in 1..l_step_tab(i).resources.count
4792            LOOP
4793 
4794              res_cost := NULL;
4795 	         OPEN resource_cost_cursor ( l_le_id
4796                , l_default_cost_type_id
4797                , l_step_tab(i).resources(j).resources
4798                , l_step_tab(i).resources(j).organization_id
4799                , l_step_tab(i).resources(j).trans_date
4800                , transaction_row.doc_id
4801                , l_step_tab(i).current_step_id
4802                );
4803              FETCH resource_cost_cursor BULK COLLECT INTO l_step_tab(i).resources(j).cost_details;
4804              CLOSE resource_cost_cursor;
4805 
4806              IF NOT l_step_tab(i).resources(j).cost_details.EXISTS(1)
4807              THEN
4808 
4809              fnd_file.put_line
4810                (fnd_file.log, 'Warning: The resource '
4811                   ||l_step_tab(i).resources(j).resources
4812                   ||' transaction is ignored as the resource has no cost'
4813                );
4814 
4815              ELSE
4816 
4817                FOR k IN 1..l_step_tab(i).resources(j).cost_details.count
4818                LOOP
4819 
4820                  l_step_tab(i).resources(j).trans_cost := l_step_tab(i).resources(j).trans_cost
4821                   + l_step_tab(i).resources(j).resource_usage
4822                    *l_step_tab(i).resources(j).cost_details(k).component_cost;
4823 
4824                  l_cost_accrued := FALSE;
4825 
4826                  FOR l IN 1..l_step_tab(i).current_costs.count
4827                  LOOP
4828                    IF   l_step_tab(i).resources(j).cost_details(k).cost_cmpntcls_id
4829                        =l_step_tab(i).current_costs(l).cost_cmpntcls_id
4830                    AND  l_step_tab(i).resources(j).cost_details(k).cost_analysis_code
4831                        =l_step_tab(i).current_costs(l).cost_analysis_code
4832                    AND  l_step_tab(i).resources(j).cost_details(k).cost_level
4833                        =l_step_tab(i).current_costs(l).cost_level
4834                    THEN
4835                      l_step_tab(i).current_costs(l).component_cost :=
4836                        l_step_tab(i).current_costs(l).component_cost
4837                      + l_step_tab(i).resources(j).resource_usage
4838                       *l_step_tab(i).resources(j).cost_details(k).component_cost;
4839                      l_cost_accrued := TRUE;
4840                      EXIT;
4841                    END IF;
4842                  END LOOP;
4843 
4844                  IF NOT l_cost_accrued
4845                  THEN
4846                    IF l_step_tab(i).current_costs(1).cost_analysis_code = ' '
4847                    THEN
4848                      l_step_tab(i).current_costs(1) :=
4849                        l_step_tab(i).resources(j).cost_details(k);
4850                      l_step_tab(i).current_costs(1).component_cost :=
4851                        l_step_tab(i).resources(j).resource_usage
4852                       *l_step_tab(i).resources(j).cost_details(k).component_cost;
4853                    ELSE
4854                      l_step_tab(i).current_costs.EXTEND;
4855                      l := l_step_tab(i).current_costs.count;
4856                      l_step_tab(i).current_costs(l) :=
4857                        l_step_tab(i).resources(j).cost_details(k);
4858                      l_step_tab(i).current_costs(l).component_cost :=
4859                        l_step_tab(i).resources(j).resource_usage
4860                       *l_step_tab(i).resources(j).cost_details(k).component_cost;
4861                    END IF;
4862                  END IF;
4863                END LOOP;
4864              END IF;
4865            END LOOP;
4866          END IF;
4867 
4868          -- Now load the inventory transactions. If the batch didn't have a routing, or the
4869          -- routing it possessed only had a single step, all inventory is attached to the
4870          -- first (only) step in the steps table.
4871 
4872          -- If there was a routing but no associations were set up, we attach all inventory
4873          -- to the last step of the chain, so that the products absorb all of the costs.
4874 
4875          -- If we have a routing and dependencies we attach the inventory to the
4876          -- correct step.
4877 
4878 
4879          IF l_step_tab.COUNT = 1
4880          THEN
4881            -- Only come in here for single step routings
4882            OPEN  materials_cursor_nr (transaction_row.doc_id);
4883            FETCH materials_cursor_nr BULK COLLECT INTO l_step_tab(i).materials;
4884            CLOSE materials_cursor_nr;
4885          ELSE
4886            -- Get here if dependenies exist, so attach inventory to the correct step.
4887            OPEN  materials_cursor (transaction_row.doc_id, l_step_tab(i).current_step_id);
4888            FETCH materials_cursor BULK COLLECT INTO l_step_tab(i).materials;
4889            CLOSE materials_cursor;
4890 
4891            -- B3556291
4892            -- Now need to see if there were any lines that were not associated to a step. If so,
4893            -- associate the ingredients with the first step and the products with the last step
4894 
4895            IF i = 1
4896            THEN
4897              OPEN unassociated_ings_cursor (transaction_row.doc_id);
4898              FETCH unassociated_ings_cursor BULK COLLECT INTO ing_tab;
4899              CLOSE unassociated_ings_cursor;
4900 
4901              FOR j IN 1..ing_tab.COUNT
4902              LOOP
4903                l_step_tab(i).materials.EXTEND;
4904                l_step_tab(i).materials(l_step_tab(i).materials.COUNT) := ing_tab(j);
4905              END LOOP;
4906            END IF;
4907 
4908            IF i = l_step_tab.COUNT
4909            THEN
4910              OPEN unassociated_prds_cursor (transaction_row.doc_id);
4911              FETCH unassociated_prds_cursor BULK COLLECT INTO prd_tab;
4912              CLOSE unassociated_prds_cursor;
4913 
4914              FOR j IN 1..prd_tab.COUNT
4915              LOOP
4916                l_step_tab(i).materials.EXTEND;
4917                l_step_tab(i).materials(l_step_tab(i).materials.COUNT) := prd_tab(j);
4918              END LOOP;
4919            END IF;
4920            -- B3556291 end
4921          END IF;
4922 
4923 
4924          -- If transactions have been reversed then don't attempt to cost them. Simply set both transactions'
4925          -- quantities to zero, so that they'll be ignored.
4926 
4927          FOR j IN 1..l_step_tab(i).materials.COUNT-1
4928          LOOP
4929            FOR k IN j+1..l_step_tab(i).materials.COUNT
4930            LOOP
4931              IF l_step_tab(i).materials(j).organization_id = l_step_tab(i).materials(k).organization_id
4932              AND l_step_tab(i).materials(j).line_type = l_step_tab(i).materials(k).line_type
4933              AND l_step_tab(i).materials(j).lot_number = l_step_tab(i).materials(k).lot_number
4934              AND l_step_tab(i).materials(j).trans_qty + l_step_tab(i).materials(k).trans_qty = 0
4935              THEN
4936                l_step_tab(i).materials(j).trans_qty := 0;
4937                l_step_tab(i).materials(k).trans_qty := 0;
4938                EXIT;
4939              END IF;
4940            END LOOP;
4941          END LOOP;
4942 
4943          IF l_routing = 0
4944          THEN
4945 
4946            l_step_tab(1).step_qty := 0;
4947 
4948            FOR j IN 1..l_step_tab(1).materials.COUNT
4949            LOOP
4950              IF l_step_tab(1).materials(j).step_contribution = 'Y'
4951              AND l_step_tab(1).materials(j).line_type = -1
4952              AND l_step_tab(1).materials(j).trans_qty <> 0
4953              THEN
4954                l_tran_qty :=
4955                INV_CONVERT.INV_UM_CONVERT(ITEM_ID       => l_step_tab(1).materials(j).item_id
4956                                          ,LOT_NUMBER    => l_step_tab(1).materials(j).lot_number
4957                                          ,PRECISION     => 5
4958                                          ,ORGANIZATION_ID => transaction_row.orgn_id
4959                                          ,FROM_QUANTITY => -l_step_tab(1).materials(j).trans_qty
4960                                          ,FROM_UNIT     => l_step_tab(1).materials(j).trans_um
4961                                          ,TO_UNIT       => l_step_tab(1).step_qty_uom
4962                                          ,FROM_NAME     => NULL
4963                                          ,TO_NAME       => NULL
4964                                            );
4965 
4966                IF l_tran_qty < 0
4967                THEN
4968 
4969 		IF l_debug_level < l_debug_level_high
4970 		THEN
4971 			 fnd_file.put_line
4972 			 (fnd_file.log,'ERROR: Unable to convert from '
4973 			 ||l_step_tab(1).materials(j).trans_um
4974 			 ||' to '||l_step_tab(1).step_qty_uom||' for transaction ID '
4975 			 ||l_step_tab(1).materials(j).trans_id
4976 			 );
4977 		ELSE
4978 			 fnd_file.put_line
4979 			 (fnd_file.log,'ERROR: Unable to convert from '
4980 			 ||l_step_tab(1).materials(j).trans_um
4981 			 ||' to '||l_step_tab(1).step_qty_uom||' for transaction ID '
4982 			 ||l_step_tab(1).materials(j).trans_id
4983 		       ||' for item ID '
4984 		       ||l_step_tab(1).materials(j).item_id
4985 		       ||' for lot Number '
4986 		       ||l_step_tab(1).materials(j).lot_number
4987 		       ||' qty '
4988 		       ||l_step_tab(1).materials(j).trans_qty
4989 			 );
4990 		END IF;
4991                  l_return_status := 'E';
4992                  l_tmp := FALSE;
4993                  RETURN;
4994                END IF;
4995 
4996                l_step_tab(1).step_qty := l_step_tab(1).step_qty + l_tran_qty;
4997              END IF;
4998            END LOOP;
4999          END IF;
5000 
5001        /***** Bug 4057323 - To check whether all the Products are yielded in one single step - Start *****/
5002         IF l_debug_level >= l_debug_level_high
5003         THEN
5004             fnd_file.put_line (fnd_file.log, 'Cost Allocation Factor : Just before entering the cost allocation factor code , l_cost_alloc_profile value is '||l_cost_alloc_profile);
5005         END IF;
5006          IF (l_cost_alloc_profile = 1)
5007            THEN
5008               IF l_debug_level >= l_debug_level_high
5009               THEN
5010                    fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor :  l_Step_tab.COUNT is '||l_step_tab.COUNT);
5011                END IF;
5012               IF (l_step_tab.COUNT = 1)
5013               THEN
5014                 IF l_debug_level >= l_debug_level_high
5015                 THEN
5016                    fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor : Go ahead as there is only one total step ');
5017                  END IF;
5018                  -- Go ahead... There is only one step available. So all products should be attached to this step only.
5019                  l_cost_alloc_profile := 1;
5020               ELSIF (l_step_tab.COUNT > 1)
5021               THEN
5022                   IF l_debug_level >= l_debug_level_high
5023                   THEN
5024                       fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor :  Wait, there are many steps. So have to process others. Before the distinct batchstep_id area');
5025                    END IF;
5026 
5027                  /* Check whether the number of Distinct steps having step material association is 1.
5028                      If not don't use Cost Allocation Factor */
5029                  SELECT COUNT (DISTINCT batchstep_id)
5030                    INTO l_count
5031                    FROM gme_material_details gmd, gme_batch_step_items gbsi
5032                   WHERE gmd.material_detail_id = gbsi.material_detail_id
5033                     AND gmd.batch_id = gbsi.batch_id
5034                     AND gmd.line_type = 1
5035                     AND gmd.batch_id = transaction_row.doc_id;
5036 
5037                      IF l_debug_level >= l_debug_level_high
5038                      THEN
5039                         fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor : After the distinct batchstep_id area. the l_count is '||l_count);
5040                       END IF;
5041 
5042                  IF (NVL (l_count, 0) = 1)
5043                  THEN
5044                      IF l_debug_level >= l_debug_level_high
5045                      THEN
5046                         fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor : There are some Step Matl Association. So check any unassociated products ');
5047                       END IF;
5048 
5049                     -- If l_count is 1 then there is only one step having step material association
5050                     /* Get Unassociated Products */
5051                     /* Check whether there is/are any unassociated products */
5052 
5053 
5054                       SELECT COUNT (DISTINCT mmt.inventory_item_id)
5055                       INTO l_unassociated_prds
5056                       FROM mtl_material_transactions mmt, gme_material_details gmd
5057                      WHERE mmt.transaction_source_type_id = 5
5058                        AND mmt.transaction_source_id = gmd.batch_id
5059                        AND gmd.line_type = 1
5060                        AND mmt.transaction_quantity <> 0
5061                        AND gmd.batch_id =transaction_row.doc_id
5062                        AND mmt.trx_source_line_id = gmd.material_detail_id
5063                        AND gmd.material_detail_id NOT IN (
5064                                 SELECT material_detail_id
5065                                   FROM gme_batch_step_items
5066                                  WHERE batch_id = transaction_row.doc_id);
5067 
5068                        IF l_debug_level >= l_debug_level_high
5069                        THEN
5070                            fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor : The number of unassociated products are '||l_unassociated_prds);
5071                        END IF;
5072 
5073                     IF (l_unassociated_prds = 0)
5074                     THEN
5075 
5076                      IF l_debug_level >= l_debug_level_high
5077                      THEN
5078                         fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor : unassociated prds are zero. so Go Ahead');
5079                       END IF;
5080 
5081                        -- Go ahead and use the profile
5082                        l_cost_alloc_profile := 1;
5083                     ELSE
5084 
5085                        /***** Important Case *****/
5086                        -- At this place we have some products attached to a step,
5087                        -- and some unassociated products.
5088                        -- Although there is a chance that all the products which have explicit step association
5089                        -- is on terminal step  and our logic considers the unassociated products
5090                        -- to be attached with the terminal step, BUT WE DONOT SUPPORT THIS CASE
5091                          fnd_file.put_line
5092                              ( fnd_file.log, ' NOTE : The profile GMF: Use Cost Alloc Factor in Lot Costing has been set to ''Yes''.
5093                                   Since few products have step association defined and few does not, this profile will NOT be used.');
5094                          l_cost_alloc_profile := 0;
5095                      END IF;
5096 
5097                  ELSIF (NVL (l_count, 0) = 0)  THEN
5098                      IF l_debug_level >= l_debug_level_high
5099                      THEN
5100                          fnd_file.put_line (fnd_file.log, ' Cost Allocation Factor : No Step material Associations. So Go Ahead ');
5101                       END IF;
5102 
5103                     -- Go Ahead.. The Number of steps having step material Association is zero.
5104                     -- So all steps should have been attached to a single step by default which is the terminal step
5105                     l_cost_alloc_profile := 1;
5106 
5107                  ELSE    -- The Products are associated with multiple steps. So don't use the profile
5108                     fnd_file.put_line
5109                          ( fnd_file.log, ' NOTE : The profile GMF: Use Cost Alloc Factor in Lot Costing has been set to ''Yes''.
5110                                 Since all the products are not yielded in a single step this profile will NOT be used.');
5111                     l_cost_alloc_profile := 0;
5112                  END IF;                     /* End if of   IF( NVL(l_count,0) = 1) */
5113               END IF;                           /* End of IF (l_step_tab.COUNT = 1) */
5114            END IF;  /* End if of l_cost_alloc_profile =1 */
5115 
5116         /***** Bug 4057323 - To check whether all the Products are yielded in one single step  - End *****/
5117 
5118 
5119          -- Now set up total output qty
5120 
5121          l_step_tab(i).output_qty := 0;
5122 
5123          FOR j IN 1..l_step_tab(i).materials.COUNT
5124          LOOP
5125            IF l_step_tab(i).materials(j).line_type = 1
5126            AND l_step_tab(i).materials(j).lot_costed_flag = 1 -- Only consider lot costed products for output_qty
5127            THEN
5128 
5129              /***** Bug 4094132 - Girish Jha - Begin *****/
5130     	      IF (l_step_tab(i).materials(j).trans_id = transaction_row.transaction_id AND transaction_row.reverse_id IS NOT NULL) THEN
5131                 l_step_output_qty := 0;
5132   	      ELSE
5133 	        l_step_output_qty := NULL;
5134  	      END IF;
5135               /***** Bug 4094132 - Girish Jha - End *****/
5136 
5137 
5138 
5139                l_tran_qty :=
5140                INV_CONVERT.INV_UM_CONVERT(ITEM_ID       => l_step_tab(i).materials(j).item_id
5141                                          ,LOT_NUMBER    => l_step_tab(i).materials(j).lot_number
5142                                          ,PRECISION     => 5
5143                                          ,ORGANIZATION_ID => transaction_row.orgn_id
5144                                          ,FROM_QUANTITY => nvl(l_step_output_qty, l_step_tab(i).materials(j).trans_qty)
5145                                          ,FROM_UNIT     => l_step_tab(i).materials(j).trans_um
5146                                          ,TO_UNIT       => l_step_tab(i).step_qty_uom
5147                                          ,FROM_NAME     => NULL
5148                                          ,TO_NAME       => NULL
5149                                            );
5150 
5151      IF l_tran_qty < 0
5152              THEN
5153 
5154 		IF l_debug_level < l_debug_level_high
5155 		THEN
5156 		       fnd_file.put_line
5157 		       (fnd_file.log,'ERROR: Unable to convert from '
5158 		       ||l_step_tab(i).materials(j).trans_um
5159 		       ||' to '||l_step_tab(i).step_qty_uom||' for transaction ID '
5160 		       ||l_step_tab(i).materials(j).trans_id
5161 		       );
5162 		ELSE
5163 		       fnd_file.put_line
5164 		       (fnd_file.log,'ERROR: Unable to convert from '
5165 		       ||l_step_tab(i).materials(j).trans_um
5166 		       ||' to '||l_step_tab(i).step_qty_uom||' for transaction ID '
5167 		       ||l_step_tab(i).materials(j).trans_id
5168 		       ||' for item ID '
5169 		       ||l_step_tab(i).materials(j).item_id
5170 		       ||' for Lot Number '
5171 		       ||l_step_tab(i).materials(j).lot_number
5172 		       ||' qty (nvl) '
5173 		       ||l_step_output_qty||' nvl part2 '||l_step_tab(i).materials(j).trans_qty
5174 		       );
5175 		END IF;
5176                l_return_status := 'E';
5177                l_tmp := FALSE;
5178                RETURN;
5179              END IF;
5180 
5181              l_step_tab(i).output_qty := l_step_tab(i).output_qty + l_tran_qty;
5182            END IF;
5183          END LOOP;
5184 
5185          IF l_debug_level >= l_debug_level_medium
5186          THEN
5187            fnd_file.put_line
5188            (fnd_file.log,'Loaded '||to_char(l_step_tab(i).materials.count)||' material txns');
5189          END IF;
5190 
5191          FOR j in 1..l_step_tab(i).materials.count
5192          LOOP
5193            IF l_step_tab(i).materials(j).trans_qty <> 0
5194            THEN
5195              -- Calculate the cost of ingredients from the cost of the lot consumed.
5196              -- If the lot being consumed has not been costed, perhaps because the
5197              -- batch that produced it has not yet been certified, we skip this batch.
5198 
5199              -- The transactions are sorted by date and then by line type. This should
5200              -- give the correct ordering of transactions for the rollup.
5201 
5202              -- If item is not lot controlled or is not lot costed
5203              -- use the standard (period-based) cost from cm_cmpt_dtl,
5204              -- otherwise use the lot cost
5205 
5206              IF l_step_tab(i).materials(j).line_type IN (-1,2) -- Treat byproducts as negative ingredients
5207              OR l_step_tab(i).materials(j).line_type = 1 AND l_step_tab(i).materials(j).lot_costed_flag = 0
5208              THEN
5209                -- This is an ingredient attached to this step
5210 
5211                ing_cost.unit_cost := NULL;
5212 
5213                IF l_step_tab(i).materials(j).lot_costed_flag = 0
5214                THEN
5215 	         -- umoogala: using co_code and default_cost_mthd to get costs for non-lot controlled items.
5216 	         -- was calendar_code and cost_mthd_code
5217 
5218                  OPEN item_cost_detail_cursor
5219                        ( l_le_id
5220                        , l_default_cost_type_id
5221                        , l_step_tab(i).materials(j).organization_id
5222                        , l_step_tab(i).materials(j).item_id
5223                        , l_step_tab(i).materials(j).trans_date
5224                        );
5225                  FETCH item_cost_detail_cursor BULK COLLECT INTO l_step_tab(i).materials(j).cost_details;
5226                  CLOSE item_cost_detail_cursor;
5227 
5228 	         -- umoogala: using co_code and default_cost_mthd to get costs for non-lot controlled items.
5229 	         -- was calendar_code and cost_mthd_code
5230 
5231                  ing_cost.unit_cost := NULL;
5232                  OPEN item_cost_cursor
5233                        ( l_le_id
5234                        , l_default_cost_type_id
5235                        , l_step_tab(i).materials(j).organization_id
5236                        , l_step_tab(i).materials(j).item_id
5237                        , l_step_tab(i).materials(j).trans_date
5238                        );
5239                  FETCH item_cost_cursor INTO ing_cost.unit_cost;
5240                  CLOSE item_cost_cursor;
5241 
5242                  IF ing_cost.unit_cost IS NULL
5243                  THEN
5244                    l_skip_this_batch := TRUE;
5245                  END IF;
5246 
5247                ELSE
5248 
5249                  ing_cost.header_id := NULL;
5250 
5251                  OPEN  lot_cost_cursor ( l_step_tab(i).materials(j).organization_id
5252                                        , l_step_tab(i).materials(j).item_id
5253                                        , l_step_tab(i).materials(j).lot_number
5254                                        , l_step_tab(i).materials(j).trans_date      -- Bug 4130869 Added Date field
5255                                        , l_cost_type_id
5256                                        );
5257                  FETCH lot_cost_cursor INTO ing_cost;
5258                  CLOSE lot_cost_cursor;
5259 
5260 
5261 
5262                  IF ing_cost.header_id IS NOT NULL
5263                  THEN
5264                    OPEN  lot_cost_detail_cursor
5265                          ( ing_cost.header_id );
5266                    FETCH lot_cost_detail_cursor BULK COLLECT INTO l_step_tab(i).materials(j).cost_details;
5267                    CLOSE lot_cost_detail_cursor;
5268                  ELSE
5269                    l_skip_this_batch := TRUE;
5270                  END IF;
5271 
5272                END IF;
5273 
5274                IF l_skip_this_batch
5275                THEN
5276                  fnd_file.put_line
5277                  (fnd_file.log, 'ERROR: Cannot calculate cost of lot '
5278                   ||to_char(transaction_row.lot_number)
5279                   ||' because material transaction '
5280                   ||to_char(l_step_tab(i).materials(j).trans_id)
5281                   ||' cannot be costed'
5282                  );
5283                ELSE
5284                  FOR k IN 1..l_step_tab(i).materials(j).cost_details.count
5285                  LOOP
5286                    l_step_tab(i).materials(j).trans_cost := l_step_tab(i).materials(j).trans_cost
5287                      + -1*l_step_tab(i).materials(j).trans_qty * l_step_tab(i).materials(j).cost_details(k).component_cost;
5288                    l_cost_accrued := FALSE;
5289 
5290                    FOR l IN 1..l_step_tab(i).current_costs.count
5291                    LOOP
5292                      IF   l_step_tab(i).materials(j).cost_details(k).cost_cmpntcls_id
5293                          =l_step_tab(i).current_costs(l).cost_cmpntcls_id
5294                      AND  l_step_tab(i).materials(j).cost_details(k).cost_analysis_code
5295                          =l_step_tab(i).current_costs(l).cost_analysis_code
5296                      AND  l_step_tab(i).materials(j).cost_details(k).cost_level
5297                          =l_step_tab(i).current_costs(l).cost_level
5298                      THEN
5299                        l_step_tab(i).current_costs(l).component_cost :=
5300                           l_step_tab(i).current_costs(l).component_cost
5301                         + -1*l_step_tab(i).materials(j).trans_qty
5302                             *l_step_tab(i).materials(j).cost_details(k).component_cost;
5303                        l_cost_accrued := TRUE;
5304                        EXIT;
5305                      END IF;
5306                    END LOOP;
5307 
5308                    IF NOT l_cost_accrued
5309                    THEN
5310                      IF l_step_tab(i).current_costs(1).cost_analysis_code = ' '
5311                      THEN
5312 
5313                        l_step_tab(i).current_costs(1) := l_step_tab(i).materials(j).cost_details(k);
5314                        l_step_tab(i).current_costs(1).component_cost :=
5315                          -l_step_tab(i).materials(j).trans_qty * l_step_tab(i).materials(j).cost_details(k).component_cost;
5316                      ELSE
5317                        l_step_tab(i).current_costs.EXTEND;
5318                        l := l_step_tab(i).current_costs.count;
5319                        l_step_tab(i).current_costs(l) :=
5320                          l_step_tab(i).materials(j).cost_details(k);
5321                        l_step_tab(i).current_costs(l).component_cost :=
5322                          -1*l_step_tab(i).materials(j).trans_qty
5323                            *l_step_tab(i).materials(j).cost_details(k).component_cost;
5324                      END IF;
5325                    END IF;
5326                  END LOOP;
5327                END IF;
5328              ELSE
5329                -- This is a product/coproduct that is yielded at this step. If the item
5330                -- being yielded uses standard costing we extract the cost so that we can
5331                -- work out the cost of this transaction and then include it in the total
5332                -- for this step. Any items that use lot costing have these costs calculated
5333                -- after we've rolled up the costs into the step from where the lot is yielded
5334 
5335                IF l_step_tab(i).materials(j).lot_number IS NULL /* INVCONV sshchinch */
5336                OR l_step_tab(i).materials(j).lot_costed_flag = 0
5337                THEN
5338 	               -- umoogala: using co_code and default_cost_mthd to get costs for non-lot controlled items.
5339 	               -- was calendar_code and cost_mthd_code
5340                  OPEN item_cost_detail_cursor
5341                  ( l_le_id
5342                  , l_default_cost_type_id
5343                  , l_step_tab(i).materials(j).organization_id
5344                  , l_step_tab(i).materials(j).item_id
5345                  , l_step_tab(i).materials(j).trans_date
5346                  );
5347                  FETCH item_cost_detail_cursor BULK COLLECT INTO l_step_tab(i).materials(j).cost_details;
5348                  CLOSE item_cost_detail_cursor;
5349 
5350 
5351 	               -- umoogala: using co_code and default_cost_mthd to get costs for non-lot controlled items.
5352 	               -- was calendar_code and cost_mthd_code
5353                  OPEN item_cost_cursor
5354                  ( l_le_id
5355                  , l_default_cost_type_id
5356                  , l_step_tab(i).materials(j).organization_id
5357                  , l_step_tab(i).materials(j).item_id
5358                  , l_step_tab(i).materials(j).trans_date
5359                  );
5360                  FETCH item_cost_cursor INTO prd_cost.unit_cost;
5361                  CLOSE item_cost_cursor;
5362 
5363                  IF NOT l_step_tab(i).materials(j).cost_details.EXISTS(1)
5364                  THEN
5365                    fnd_file.put_line
5366                    (fnd_file.log, 'ERROR: Cannot calculate cost of Lot Number '
5367                     ||to_char(transaction_row.lot_number)
5368                     ||' because item ID / Lot Number '
5369                     ||to_char(l_step_tab(i).materials(j).item_id)
5370                     ||'/'
5371                     ||to_char(l_step_tab(i).materials(j).lot_number)
5372                     ||' cannot be costed'
5373                    );
5374                    l_skip_this_batch := TRUE;
5375                  ELSE
5376                    FOR k IN 1..l_step_tab(i).materials(j).cost_details.count
5377                    LOOP
5378                      l_step_tab(i).materials(j).trans_cost := l_step_tab(i).materials(j).trans_cost
5379                      + -1*l_step_tab(i).materials(j).trans_qty * l_step_tab(i).materials(j).cost_details(k).component_cost;
5380 
5381                      l_cost_accrued := FALSE;
5382 
5383                      FOR l IN 1..l_step_tab(i).current_costs.count
5384                      LOOP
5385                        IF   l_step_tab(i).materials(j).cost_details(k).cost_cmpntcls_id
5386                            =l_step_tab(i).current_costs(l).cost_cmpntcls_id
5387                        AND  l_step_tab(i).materials(j).cost_details(k).cost_analysis_code
5388                            =l_step_tab(i).current_costs(l).cost_analysis_code
5389                        AND  l_step_tab(i).materials(j).cost_details(k).cost_level
5390                            =l_step_tab(i).current_costs(l).cost_level
5391                        THEN
5392                          l_step_tab(i).current_costs(l).component_cost :=
5393                            l_step_tab(i).current_costs(l).component_cost
5394                          + -1*l_step_tab(i).materials(j).trans_qty * l_step_tab(i).materials(j).cost_details(k).component_cost;
5395                          l_cost_accrued := TRUE;
5396                          EXIT;
5397                        END IF;
5398                      END LOOP;
5399 
5400                      IF NOT l_cost_accrued
5401                      THEN
5402                        IF l_step_tab(i).current_costs(1).cost_analysis_code = ' '
5403                        THEN
5404                          l_step_tab(i).current_costs(1) :=
5405                            l_step_tab(i).materials(j).cost_details(k);
5406                          l_step_tab(i).current_costs(1).component_cost :=
5407                            l_step_tab(i).materials(j).trans_qty * l_step_tab(i).materials(j).cost_details(k).component_cost;
5408                        ELSE
5409                          l_step_tab(i).current_costs.EXTEND;
5410                          l := l_step_tab(i).current_costs.count;
5411                          l_step_tab(i).current_costs(l) :=
5412                            l_step_tab(i).materials(j).cost_details(k);
5413                          l_step_tab(i).current_costs(l).component_cost :=
5414                           -1*l_step_tab(i).materials(j).trans_qty * l_step_tab(i).materials(j).cost_details(k).component_cost;
5415                        END IF;
5416                      END IF;
5417                    END LOOP;
5418                  END IF;
5419                END IF;
5420              END IF;
5421            END IF; -- If trans_qty <> 0
5422         END LOOP;
5423 
5424         IF l_debug_level >= l_debug_level_medium
5425         THEN
5426           fnd_file.put_line
5427           (fnd_file.log,'Setting up step dependency index and quantities');
5428         END IF;
5429 
5430         -- Set up the step_index field in the 'next steps' nested tables
5431 
5432         FOR j IN 1..l_step_tab(i).dependencies.count
5433         LOOP
5434           FOR k IN 1..l_step_tab.count
5435           LOOP
5436             IF l_step_tab(k).current_step_id = l_step_tab(i).dependencies(j).batchstep_id
5437             THEN
5438 
5439               IF l_debug_level >= l_debug_level_medium
5440               THEN
5441                 fnd_file.put_line
5442                 (fnd_file.log,'Setting ('||to_char(i)||','||to_char(j)||') to '||to_char(k));
5443               END IF;
5444 
5445                l_step_tab(i).dependencies(j).step_index := k;
5446 
5447               EXIT;
5448             END IF;
5449           END LOOP;
5450         END LOOP;
5451 
5452         IF l_debug_level >= l_debug_level_medium
5453         THEN
5454           fnd_file.put_line
5455           (fnd_file.log,'End of transaction load/costing loop for iteration '||to_char(i));
5456         END IF;
5457 
5458       END LOOP; -- End of loop that retrieves and costs the transactions
5459 
5460       -- Start of the actual rollup
5461 
5462       IF l_skip_this_batch
5463       THEN
5464         -- For one reason or another we cannot cost this lot.
5465         fnd_file.put_line
5466         ( fnd_file.log,'ERROR: Batch ID '
5467         ||to_char(transaction_row.doc_id)
5468         ||' was skipped because of missing cost(s)');
5469         l_return_status := 'E';
5470         l_uncostable_lots_tab(transaction_row.orgn_id||'-'||transaction_row.inventory_item_id||'-'||transaction_row.lot_number) := transaction_row.inventory_item_id;
5471         l_tmp := FALSE;
5472 
5473         RETURN;
5474       ELSE
5475 
5476 
5477         -- At this stage we have a complete explosion of the batch in terms of materials
5478         -- consumed and yielded, and also resources expended, together with all costs for
5479         -- each consumption and expenditure. We now need to traverse the routing
5480         -- to roll up the costs from the starting step(s) to the step where the lot is yielded.
5481 
5482         -- The explosion of the routing honours the fact that steps can converge and also
5483         -- diverge into any arbitrary topology. The only thing that is not allowed is a feedback
5484         -- loop.
5485 
5486         -- Traversing the routing is simplified by the explosion method, which orders the steps
5487         -- in the correct sequence. We can start at the first node (step) and examine the
5488         -- nested table in it to see what the next step/steps is/are. If there is only one 'next'
5489         -- step the costs accumulated in the current step are passed on. If there is more than
5490         -- one next step the costs accumulated so far are passed on in direct proportion to
5491         -- their actual step quantities. If there are no next steps we have reached a terminal
5492         -- step in the routing.
5493 
5494         -- Note that if anything is yielded at the current step, the cost of it is subtracted
5495         -- and only the residual costs are rolled into the next steps.
5496 
5497         -- We have the following values for each step, stored in table l_step_tab:
5498 
5499         -- current_step_id (ie the batchstep_id of the current step)
5500         -- current_costs   (ie all costs incurred at this step)
5501         -- inherited_costs (ie all of the costs from prior steps)
5502         -- dependencies    (ie a list of steps that directly follow on from this step)
5503 
5504         -- Each element of the dependencies list has the following components
5505 
5506         -- batchstep_id       (the ID of the step)
5507         -- step_qty (the material quantity inherited from prior steps)
5508         -- step_qty_uom       (the unit of measure of the above)
5509         -- step_index         (this is the index of the step in l_step_tab)
5510 
5511         IF l_debug_level >= l_debug_level_low
5512         THEN
5513           fnd_file.put_line
5514           (fnd_file.log,'Transaction costs complete. Starting rollup for batch ID '
5515           ||to_char(transaction_row.doc_id)
5516           );
5517         END IF;
5518 
5519 
5520         FOR i in 1..l_step_tab.count
5521         LOOP
5522           IF l_debug_level >= l_debug_level_medium
5523           THEN
5524             fnd_file.put_line
5525             (fnd_file.log,'Inside rollup loop for step index '||to_char(i));
5526           END IF;
5527 
5528           -- We need to set up the step_costs table. This holds the combined inherited costs (that is
5529           -- those that have come from prior steps) and the current costs (ie those that have been
5530           -- introduced at this step. This is done so that any yields from this step can be calculated
5531           -- a bit more easily.
5532 
5533           new_cost_tab.delete;
5534           cur_cost_tab.delete;
5535 
5536           FOR j IN 1.. l_step_tab(i).inherited_costs.COUNT
5537           LOOP
5538             new_cost_tab(j) := l_step_tab(i).inherited_costs(j);
5539           END LOOP;
5540 
5541           FOR j IN 1..l_step_tab(i).current_costs.COUNT
5542           LOOP
5543             cur_cost_tab(j) := l_step_tab(i).current_costs(j);
5544           END LOOP;
5545 
5546           merge_costs ( cur_cost_tab
5547                       , 1
5548                       , 1
5549                       , 'C'
5550                       );
5551 
5552           FOR j IN 1..new_cost_tab.COUNT
5553           LOOP
5554             l_step_tab(i).step_costs(j) := new_cost_tab(j);
5555             l_step_tab(i).step_costs.EXTEND;
5556           END LOOP;
5557 
5558           -- Get rid of the unused last entry
5559 
5560           l_step_tab(i).step_costs.DELETE(l_step_tab(i).step_costs.COUNT);
5561 
5562           -- See if we've yielded anything that is lot_costed in this step.
5563 
5564           FOR j IN 1..l_step_tab(i).materials.count
5565           LOOP
5566 
5567             IF  l_step_tab(i).materials(j).line_type = 1 -- Ignore byproducts
5568             AND l_step_tab(i).materials(j).lot_costed_flag = 1
5569             THEN
5570               -- We've yielded something. Find its cost and, if needed,  update the
5571               -- lot costing tables. If there isn't an existing cost then we have to
5572               -- create a new one.
5573 
5574               new_cost.onhand_qty := l_step_tab(i).materials(j).trans_qty;
5575               new_cost.unit_cost := 0;
5576               new_cost_tab.delete;
5577               old_cost.onhand_qty := 0;
5578               old_cost_tab.delete;
5579               cur_cost_tab.delete; /* Bug 3533452 */
5580 
5581               IF l_debug_level >= l_debug_level_medium
5582               THEN
5583                 fnd_file.put_line
5584                 (fnd_file.log,'Setting up new_cost_tab');
5585               END IF;
5586 
5587               -- Bug 3548217
5588               IF l_step_tab(i).step_qty_uom <> l_step_tab(i).materials(j).trans_um
5589               THEN
5590 
5591               l_tran_qty :=
5592                INV_CONVERT.INV_UM_CONVERT(ITEM_ID       => l_step_tab(i).materials(j).item_id
5593                                          ,LOT_NUMBER    => l_step_tab(i).materials(j).lot_number
5594                                          ,PRECISION     => 5
5595                                          ,ORGANIZATION_ID => transaction_row.orgn_id
5596                                          ,FROM_QUANTITY => l_step_tab(i).materials(j).trans_qty
5597                                          ,FROM_UNIT     => l_step_tab(i).materials(j).trans_um
5598                                          ,TO_UNIT       => l_step_tab(i).step_qty_uom
5599                                          ,FROM_NAME     => NULL
5600                                          ,TO_NAME       => NULL
5601                                            );
5602 
5603                 IF l_tran_qty < 0
5604                 THEN
5605                   fnd_file.put_line
5606                   (fnd_file.log,'ERROR: Unable to convert to step qty uom for transaction ID '
5607                   ||l_step_tab(i).materials(j).trans_id
5608                   );
5609                   l_return_status := 'E';
5610                   l_tmp := FALSE;
5611                   RETURN;
5612                 END IF;
5613               ELSE
5614                 l_tran_qty := l_step_tab(i).materials(j).trans_qty;
5615               END IF;
5616 
5617               -- Bug 3548217
5618               -- If we're on a terminal step we have to set up the cost factor
5619               -- so that all costs will be absorbed by the products yielded. If
5620               -- the step is higher up the chain the we use the step qty instead so that all
5621               -- residual costs are passed on to the next steps.
5622 
5623               IF l_step_tab(i).dependencies(1).step_index IS NULL
5624               THEN
5625 
5626                  /***** Bug 4094132 - Girish Jha - Begin *****/
5627                   IF (l_step_tab(i).materials(j).trans_id = transaction_row.transaction_id AND transaction_row.reverse_id IS NOT NULL) THEN
5628                     l_step_output_qty := 0;
5629                   ELSE
5630                     l_step_output_qty := NULL;
5631                   END IF;
5632                   /***** Bug 4094132 - Girish Jha - End *****/
5633 
5634                 -- We're on a terminal step
5635 
5636                 /***** Bug 4057323 - Use Cost Allocation Factor Depending on Profile value - Start *****/
5637                 IF ( l_cost_alloc_profile = 1) THEN
5638                   l_cost_factor := l_step_tab(i).materials(j).cost_alloc;
5639                 ELSE  /* Else approtion the cost by using the quantities as the ratio */
5640                     /* Quantity in the batch step is not zero then */
5641                   IF l_step_tab(i).output_qty<>0 THEN   /*Condition Added - Bug 5985680, pmarada  */
5642                     l_cost_factor := l_tran_qty /l_step_tab(i).output_qty;
5643                   ELSE
5644                     l_cost_factor := 0;
5645                     fnd_file.put_line (fnd_file.log,' Setting Cost Allocation Factor to zero as output_qty is zero.');
5646                   END IF;
5647                 END IF;
5648                 /***** Bug 4057323 - Use Cost Allocation Factor Depending on Profile value - End *****/
5649 
5650                 IF l_debug_level >= l_debug_level_high
5651                 THEN
5652                    fnd_file.put_line (fnd_file.log,' Cost Allocation Factor :  For the transaction of '||l_step_tab(i).materials(j).trans_id
5653                                                 || ' the new cost_factor is '|| l_cost_factor);
5654                  END IF;
5655 
5656                 -- Reduce remaining output_qty for next time around
5657 
5658                 -- Bug 4094132 Added NVL(l_step_output_qty, .....
5659                 -- l_step_tab(i).output_qty := l_step_tab(i).output_qty - l_tran_qty;
5660                 l_step_tab(i).output_qty := l_step_tab(i).output_qty - NVL(l_step_output_qty,l_tran_qty);
5661 
5662               ELSE  /* If not terminal step */
5663                   /***** Bug 4057323 - Use Cost Allocation Factor Depending on Profile value - Start *****/
5664                   IF ( l_cost_alloc_profile = 1) THEN
5665                     l_cost_factor := l_step_tab(i).materials(j).cost_alloc;
5666                   ELSE  /* Else approtion the cost by using the quantities as the ratio of step quantities*/
5667                     IF l_step_tab(i).step_qty <> 0 THEN  /*Condition Added - Bug 5985680, pmarada  */
5668                       l_cost_factor := l_tran_qty / l_step_tab(i).step_qty;
5669                     ELSE
5670                       l_cost_factor := 0;
5671                       fnd_file.put_line (fnd_file.log,' Setting Cost Allocation Factor to zero as step_qty is zero.');
5672                     END IF;
5673                   END IF;
5674                   /***** Bug 4057323 - Use Cost Allocation Factor Depending on Profile value - End *****/
5675               END IF;
5676 
5677               IF l_debug_level >= l_debug_level_low
5678               THEN
5679                 fnd_file.put_line
5680                 (fnd_file.log,'Cost factor for yield costs calculation is '||l_cost_factor);
5681 
5682                 fnd_file.put_line(fnd_file.log,'Step costs before are');
5683                 FOR jj IN 1..l_step_tab(i).step_costs.COUNT
5684                 LOOP
5685                   fnd_file.put_line
5686                   (fnd_file.log,l_step_tab(i).step_costs(jj).component_cost);
5687                 END LOOP;
5688               END IF;
5689 
5690               -- Now calculate the costs of the yielded lot and reduce the step costs by the same amounts
5691 
5692               FOR l IN 1 ..l_step_tab(i).step_costs.COUNT
5693               LOOP
5694                 new_cost_tab(l) := l_step_tab(i).step_costs(l);
5695 
5696                 /***** Bug 4057323 - Use Cost Allocation Factor Depending on Profile value - Start *****/
5697                 IF ( l_cost_alloc_profile = 0 ) THEN
5698                   new_cost_tab(l).component_cost := l_step_tab(i).step_costs(l).component_cost * l_cost_factor;              -- Bug 4057323
5699                   new_cost.unit_cost := new_cost.unit_cost + new_cost_tab(l).component_cost;
5700                   l_step_tab(i).step_costs(l).component_cost := l_step_tab(i).step_costs(l).component_cost * (1-l_cost_factor);
5701 
5702                 ELSE
5703                  /* B 4057323 - The following change is to apportion the cost into multiple lots depending on LOT QUANTITIES
5704                      if the product is yielded into Multiple Lots */
5705                      /* Bug 4227784 - Replaced l_total_item_qty by the line_actual_qty. This is fail if there are mulitple lines for same product */
5706 
5707                   IF(l_step_tab(i).materials(j).actual_line_qty = 0) THEN /* Bug 4227784. To avoid Divide by zero error */
5708                     new_cost_tab(l).component_cost := 0;
5709                   ELSE
5710                     new_cost_tab(l).component_cost := l_step_tab(i).step_costs(l).component_cost * l_cost_factor * l_step_tab(i).materials(j).trans_qty / l_step_tab(i).materials(j).actual_line_qty; --l_total_item_qty;
5711                   END IF;
5712 
5713                   new_cost.unit_cost := new_cost.unit_cost + new_cost_tab(l).component_cost;
5714                 END IF;
5715 
5716                 /***** Bug 4057323 - Use Cost Allocation Factor Depending on Profile value - End *****/
5717 
5718               END LOOP;
5719               -- End 3548217
5720 
5721               IF l_debug_level >= l_debug_level_low
5722               THEN
5723                 fnd_file.put_line(fnd_file.log,'Step costs after are');
5724                 FOR jj IN 1..l_step_tab(i).step_costs.COUNT
5725                 LOOP
5726                   fnd_file.put_line
5727                   (fnd_file.log,l_step_tab(i).step_costs(jj).component_cost);
5728                 END LOOP;
5729                 fnd_file.put_line(fnd_file.log,'New costs after are');
5730                 FOR jj IN 1..new_cost_tab.COUNT
5731                 LOOP
5732                   fnd_file.put_line
5733                   (fnd_file.log,new_cost_tab(jj).component_cost);
5734                 END LOOP;
5735               END IF;
5736 
5737               -- See if this transaction is the transaction that has yielded the lot being costed
5738               -- Reworked the following loops for bug 3548217
5739               IF transaction_row.transaction_id = l_step_tab(i).materials(j).trans_id
5740               THEN
5741                 -- It was. -- See if any burdens should apply to this yield
5742 
5743                 process_burdens;
5744 
5745                 IF l_return_status <> 'S'
5746                 THEN
5747                   RETURN;
5748                 END IF;
5749 
5750                 -- If we retrieved any, incorporate ('c' = Combine) their costs into the cost accumulated so far
5751 
5752                 IF l_burdens_total <> 0
5753                 THEN
5754                   -- Burdens are held per unit, we need to gross them up to the product output quantity
5755 
5756                   FOR l IN 1..l_burden_costs_tab.count
5757                   LOOP
5758                     l_burden_costs_tab(l).component_cost := l_burden_costs_tab(l).component_cost * transaction_row.trans_qty;
5759                     IF l_debug_level >= l_debug_level_medium
5760                     THEN
5761                       fnd_file.put_line
5762                       (fnd_file.log,'l_burden_costs_tab['||l||'] is '||l_burden_costs_tab(l).component_cost);
5763                     END IF;
5764                   END LOOP;
5765 
5766 
5767                   merge_costs ( l_burden_costs_tab
5768                               , 1
5769                               , 1
5770                               , 'C'
5771                               );
5772 
5773                 END IF;
5774 
5775 
5776                 old_cost.header_id := NULL;
5777 
5778                 OPEN lot_cost_cursor
5779                    ( l_step_tab(i).materials(j).organization_id
5780                    , l_step_tab(i).materials(j).item_id
5781                    , l_step_tab(i).materials(j).lot_number
5782                    , l_step_tab(i).materials(j).trans_date      -- Bug 4130869 Added Date field
5783                    ,l_cost_type_id
5784                    );
5785                 FETCH lot_cost_cursor INTO old_cost;
5786                 CLOSE lot_cost_cursor;
5787 
5788                 IF old_cost.header_id IS NOT NULL
5789                 THEN
5790                   -- A cost already exists, retrieve it together with the details,
5791 
5792 
5793                   OPEN lot_cost_detail_cursor
5794                        ( old_cost.header_id );
5795                   FETCH lot_cost_detail_cursor BULK COLLECT INTO old_cost_tab;
5796                   CLOSE lot_cost_detail_cursor;
5797 
5798                   FOR k IN 1 .. old_cost_tab.COUNT
5799                   LOOP
5800                     old_cost_tab(k).component_cost := old_cost_tab(k).component_cost * old_cost.onhand_qty;
5801                   END LOOP;
5802 
5803                   -- Before merging, we need to preserve the 'new' cost so that sub-ledger has access to the
5804                   -- details. Bug 3578680
5805 
5806                   prd_cost_tab := new_cost_tab;
5807                   prd_cost := new_cost;
5808 
5809                   -- Now merge the old and new costs
5810 
5811                   --new_cost.unit_cost := 0;
5812 
5813                   merge_costs ( old_cost_tab
5814                               , 1
5815                               , 1
5816                               , 'C'
5817                               );
5818 
5819                   l_new_cost := new_cost.unit_cost;
5820                   IF l_debug_level >= l_debug_level_low
5821                   THEN
5822                      fnd_file.put_line   (fnd_file.log, 'Before create_cost_header in process_batch ');
5823                      fnd_file.put_line   (fnd_file.log, 'new unit cost: '||new_cost.unit_cost);
5824                      fnd_file.put_line   (fnd_file.log, 'l_new unit cost: '||l_new_cost);
5825                      fnd_file.put_line   (fnd_file.log, 'trans qty: '||transaction_row.trans_qty);
5826                      fnd_file.put_line   (fnd_file.log, 'onhand qty: '||old_cost.onhand_qty);
5827                   END IF;
5828 
5829                   -- At this stage we have all the header and cost component information we need
5830                   -- to store the costs in the database.
5831 
5832                    create_cost_header
5833                   ( l_step_tab(i).materials(j).item_id
5834                   , l_step_tab(i).materials(j).lot_number
5835                   , l_step_tab(i).materials(j).organization_id
5836                   , l_cost_type_id
5837                   , l_new_cost/(transaction_row.trans_qty+old_cost.onhand_qty)
5838                   , l_step_tab(i).materials(j).trans_date
5839                   , old_cost.onhand_qty + l_step_tab(i).materials(j).trans_qty
5840                   , transaction_row.doc_id
5841                   , transaction_row.transaction_source_type_id
5842                   , transaction_row.transaction_action_id
5843                   , new_cost.header_id
5844                   , dummy
5845                   , new_cost.onhand_qty
5846                   , l_return_status
5847                   );
5848 
5849 
5850                   IF l_return_status ='S'
5851                   THEN
5852 
5853                     FOR k IN 1.. new_cost_tab.count
5854                     LOOP
5855                       IF new_cost_tab(k).component_cost <> 0
5856                       THEN
5857                         create_cost_detail
5858                         ( new_cost.header_id
5859                         , new_cost_tab(k).cost_cmpntcls_id
5860                         , new_cost_tab(k).cost_analysis_code
5861                         , new_cost_tab(k).cost_level
5862                         , new_cost_tab(k).component_cost/(transaction_row.trans_qty+old_cost.onhand_qty)
5863                         , 0
5864                         , l_return_status
5865                         );
5866 
5867                         IF l_return_status <> 'S'
5868                         THEN
5869                           RETURN;
5870                         END IF;
5871                       END IF;
5872                     END LOOP;
5873 
5874                     FOR k IN 1 .. prd_cost_tab.COUNT
5875                     LOOP
5876                       -- Write the 'new' costs with a -ve header ID Bug 3578680
5877 
5878                       IF prd_cost_tab(k).component_cost <> 0
5879                       THEN
5880                         create_cost_detail
5881                         ( -new_cost.header_id
5882                         , prd_cost_tab(k).cost_cmpntcls_id
5883                         , prd_cost_tab(k).cost_analysis_code
5884                         , prd_cost_tab(k).cost_level
5885                         , prd_cost_tab(k).component_cost/transaction_row.trans_qty
5886                         , 0
5887                         , l_return_status
5888                         );
5889 
5890                         IF l_return_status <> 'S'
5891                         THEN
5892                           RETURN;
5893                         END IF;
5894                       END IF;
5895                     END LOOP;
5896 
5897                     create_material_transaction
5898                     ( new_cost.header_id
5899                     , l_cost_type_id
5900                     , l_step_tab(i).materials(j).trans_date
5901                     , l_step_tab(i).materials(j).trans_qty
5902                     , l_step_tab(i).materials(j).trans_um
5903                     , prd_cost.unit_cost
5904                     , l_step_tab(i).materials(j).trans_id
5905                     , new_cost.unit_cost/(transaction_row.trans_qty+old_cost.onhand_qty)
5906                     , new_cost.onhand_qty
5907                     , old_cost.unit_cost
5908                     , old_cost.onhand_qty
5909                     , 1
5910                     ,transaction_row.lot_number
5911                     , l_return_status
5912                     );
5913 
5914                     IF l_debug_level >= l_debug_level_low
5915                     THEN
5916                        fnd_file.put_line (fnd_file.log, 'Completed inserts into tables in process_batch ');
5917                     END IF;
5918 
5919                     IF l_return_status <> 'S'
5920                     THEN
5921                       RETURN;
5922                     END IF;
5923                   ELSE
5924                     RETURN;
5925                   END IF;
5926                 ELSE
5927                   -- No cost currently exists, create one and all associated details
5928                   -- and transactions. Again, this is only for the invoking transaction
5929 
5930                   IF l_debug_level >= l_debug_level_medium
5931                   THEN
5932 
5933                     fnd_file.put_line
5934                     ( fnd_file.log,'New cost tab has '||to_char(new_cost_tab.count)||' entries:');
5935 
5936                     FOR k IN 1 .. new_cost_tab.COUNT
5937                     LOOP
5938                       fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
5939                       fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
5940                       fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||new_cost_tab(k).cost_level);
5941                       fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
5942                       fnd_file.put_line(fnd_file.log,'====================================');
5943                     END LOOP;
5944 
5945                     fnd_file.put_line(fnd_file.log,' New total cost is : '||new_cost.unit_cost);
5946                     fnd_file.put_line(fnd_file.log,' New unit cost is  : '||new_cost.unit_cost/transaction_row.trans_qty);
5947 
5948                   END IF;
5949 
5950                   create_cost_header
5951                   ( l_step_tab(i).materials(j).item_id
5952                   , l_step_tab(i).materials(j).lot_number   /* INCONV SSCHINCH */
5953                   , l_step_tab(i).materials(j).organization_id
5954                   , l_cost_type_id
5955                   , new_cost.unit_cost/transaction_row.trans_qty
5956                   , l_step_tab(i).materials(j).trans_date
5957                   , l_step_tab(i).materials(j).trans_qty
5958                   , transaction_row.doc_id
5959                   , transaction_row.transaction_source_type_id
5960                   , transaction_row.transaction_action_id
5961                   , new_cost.header_id
5962                   , dummy
5963                   , new_cost.onhand_qty
5964                   , l_return_status
5965                   );
5966 
5967                   IF l_return_status = 'S'
5968                   THEN
5969 
5970                     FOR k IN 1..new_cost_tab.count
5971                     LOOP
5972                       IF new_cost_tab(k).component_cost <> 0
5973                       THEN
5974                         create_cost_detail
5975                         ( new_cost.header_id
5976                         , new_cost_tab(k).cost_cmpntcls_id
5977                         , new_cost_tab(k).cost_analysis_code
5978                         , 0
5979                         , new_cost_tab(k).component_cost/transaction_row.trans_qty
5980                         , 0
5981                         , l_return_status
5982                         );
5983 
5984                       END IF;
5985 
5986                       IF l_return_status <> 'S'
5987                       THEN
5988                         RETURN;
5989                       END IF;
5990                     END LOOP;
5991                   END IF;
5992 
5993                   create_material_transaction
5994                   ( new_cost.header_id
5995                   , l_cost_type_id
5996                   , l_step_tab(i).materials(j).trans_date
5997                   , l_step_tab(i).materials(j).trans_qty
5998                   , l_step_tab(i).materials(j).trans_um
5999                   , new_cost.unit_cost
6000                   , l_step_tab(i).materials(j).trans_id
6001                   , new_cost.unit_cost/transaction_row.trans_qty
6002                   , l_step_tab(i).materials(j).trans_qty
6003                   , NULL
6004                   , NULL
6005                   , NULL
6006                   ,transaction_row.lot_number
6007                   , l_return_status
6008                   );
6009 
6010                   IF l_return_status <> 'S'
6011                   THEN
6012                     RETURN;
6013                   END IF;
6014                 END IF;
6015 
6016               END IF;
6017 
6018             END IF;
6019 
6020           END LOOP;
6021 
6022           IF l_debug_level >= l_debug_level_medium
6023           THEN
6024             fnd_file.put_line
6025             (fnd_file.log,'After yield check');
6026           END IF;
6027 
6028           -- If we are not on a terminal step, we have to roll the costs into
6029           -- the next step(s) in the dependency chain. Also, if the route divides
6030           -- at this point we need to aportion the costs held in this step between
6031           -- all subsequent steps.
6032 
6033           IF l_step_tab(i).dependencies(1).step_index IS NOT NULL
6034           THEN
6035 
6036             IF l_debug_level >= l_debug_level_medium
6037             THEN
6038               fnd_file.put_line
6039               (fnd_file.log,'Before quantity accumulation');
6040             END IF;
6041 
6042             l_total_qty := 0;
6043 
6044             FOR j in 1..l_step_tab(i).dependencies.count
6045             LOOP
6046               l_total_qty := l_total_qty + l_step_tab(i).dependencies(j).step_qty;
6047             END LOOP;
6048 
6049             IF l_debug_level >= l_debug_level_medium
6050             THEN
6051               fnd_file.put_line
6052               (fnd_file.log,'After quantity accumulation, total_qty is'
6053               ||to_char(l_total_qty,'999999999.99')
6054               );
6055             END IF;
6056 
6057 
6058             FOR j IN 1..l_step_tab(i).dependencies.count
6059             LOOP
6060               l_cost_factor := l_step_tab(i).dependencies(j).step_qty / l_total_qty;
6061 
6062               IF l_debug_level >= l_debug_level_medium
6063               THEN
6064                 fnd_file.put_line
6065                 (fnd_file.log,'Cost factor is '||to_char(l_cost_factor,'9999.99'));
6066               END IF;
6067 
6068               -- Roll current costs into next step(s). We loop through all costs accumulated
6069               -- and apply the above factor to each cost when rolling them forward
6070 
6071               -- Find index of step to roll costs into
6072 
6073               l_step_index := l_step_tab(i).dependencies(j).step_index;
6074 
6075               FOR k IN 1..l_step_tab(i).step_costs.count
6076               LOOP
6077                 IF l_step_tab(i).step_costs(k).cost_analysis_code <> ' '
6078                 THEN
6079 
6080                   IF l_debug_level >= l_debug_level_medium
6081                   THEN
6082                     fnd_file.put_line
6083                     (fnd_file.log,'Rolling costs of step '
6084                     ||to_char(i)||' into step '||to_char(l_step_index));
6085                    END IF;
6086 
6087                    -- Now roll current costs into the next step
6088 
6089                    l_cost_accrued := FALSE;
6090 
6091                    FOR l IN 1..l_step_tab(l_step_index).inherited_costs.count
6092                    LOOP
6093                      IF   l_step_tab(i).step_costs(k).cost_cmpntcls_id
6094                          =l_step_tab(l_step_index).inherited_costs(l).cost_cmpntcls_id
6095                      AND  l_step_tab(i).step_costs(k).cost_analysis_code
6096                          =l_step_tab(l_step_index).inherited_costs(l).cost_analysis_code
6097                      AND  l_step_tab(i).step_costs(k).cost_level
6098                          =l_step_tab(l_step_index).inherited_costs(l).cost_level
6099                      THEN
6100                        l_step_tab(l_step_index).inherited_costs(l).component_cost :=
6101                          l_step_tab(l_step_index).inherited_costs(l).component_cost
6102                         +l_step_tab(i).step_costs(k).component_cost * l_cost_factor;
6103 
6104                        l_cost_accrued := TRUE;
6105                        EXIT;
6106                      END IF;
6107                    END LOOP;
6108 
6109                    -- If we didn't find a match, create a new cost in the target steps
6110                    -- inherited costs
6111 
6112                    IF NOT l_cost_accrued
6113                    THEN
6114                      IF l_step_tab(l_step_index).inherited_costs(1).cost_analysis_code = ' '
6115                      THEN
6116                        l_step_tab(l_step_index).inherited_costs(1) :=
6117                          l_step_tab(i).step_costs(k);
6118                        l_step_tab(l_step_index).inherited_costs(1).component_cost :=
6119                          l_step_tab(i).step_costs(k).component_cost * l_cost_factor;
6120                      ELSE
6121                        l_step_tab(l_step_index).inherited_costs.EXTEND;
6122                        l := l_step_tab(l_step_index).inherited_costs.count;
6123                        l_step_tab(l_step_index).inherited_costs(l) := l_step_tab(i).step_costs(k);
6124                        l_step_tab(l_step_index).inherited_costs(l).component_cost :=
6125                        l_step_tab(i).step_costs(k).component_cost * l_cost_factor;
6126                      END IF;
6127                    END IF;
6128                  END IF;
6129                END LOOP;
6130              END LOOP;
6131            END IF;                     -- If we are not in terminal step
6132          END LOOP; -- End of outer rollup loop
6133        END IF;-- End of conditional skip
6134      END IF;-- End of if this is an output
6135 
6136      IF l_debug_level >= l_debug_level_high
6137      THEN
6138        lot_cost_audit
6139 	     ( transaction_row.inventory_item_id
6140 	     , transaction_row.lot_number
6141 	     , transaction_row.orgn_id
6142 	     , transaction_row.doc_id
6143 	     , transaction_row.trans_date
6144 	     , l_step_tab
6145 	     );
6146      END IF;
6147 
6148      -- Finally, mark the invoking transaction as costed
6149      -- Also, mark the batch as having participated in actual costing - PJS 11Feb04
6150 
6151     IF l_final_run_flag = 1  -- umoogala 05-Dec-2003
6152      THEN
6153        /*UPDATE mtl_transaction_lot_numbers
6154        SET    lot_cost_ind 	      = 1,
6155 	      --request_id              = l_request_id,
6156 	      --program_application_id  = l_prog_appl_id,
6157 	      --program_id              = l_program_id,
6158 	      last_update_date     = sysdate
6159        WHERE  transaction_id = transaction_row.transaction_id;*/
6160 
6161        UPDATE gme_batch_header
6162        SET    actual_cost_ind = 1
6163        WHERE  batch_id = transaction_row.doc_id;
6164 
6165      END IF;
6166     IF l_debug_level >= l_debug_level_medium
6167      THEN
6168        fnd_file.put_line
6169        (fnd_file.log,'Entered Procedure: '||procedure_name);
6170      END IF;
6171 
6172 END process_batch;
6173 
6174 
6175 
6176     --**********************************************************************************************
6177     --*                                                                                            *
6178     --* Procedure to handle created lots (CREI/CRER)                                               *
6179     --*                                                                                            *
6180     --**********************************************************************************************
6181 
6182 
6183 
6184 PROCEDURE process_creation
6185 IS
6186   l_header_id    NUMBER;
6187   l_unit_cost    NUMBER;
6188   l_onhand_qty   NUMBER;
6189   procedure_name VARCHAR2(100);
6190 BEGIN
6191 
6192   procedure_name := 'Process Creation';
6193   IF l_debug_level >= l_debug_level_medium
6194      THEN
6195        fnd_file.put_line
6196        (fnd_file.log,'Entered Procedure: '||procedure_name);
6197      END IF;
6198 
6199   -- We assume that no lot cost exists, as the lot is being created by this transaction.
6200   -- The only costs we can determine come from burdens.
6201 
6202   process_burdens;
6203 
6204   IF l_return_status = 'S'
6205   THEN
6206     create_cost_header
6207     ( p_item_id              => transaction_row.inventory_item_id
6208     , p_lot_number           => transaction_row.lot_number  /* INVCONV sschinch */
6209     , p_orgn_id              => transaction_row.orgn_id         /* INVCONV sschinch */
6210     , p_cost_type_id         => l_cost_type_id
6211     , p_unit_cost            => NVL(l_burdens_total,0)
6212     , p_cost_date            => transaction_row.trans_date
6213     , p_onhand_qty           => transaction_row.trans_qty
6214     , p_trx_src_type_id      => transaction_row.transaction_source_type_id  /* INVCONV sschinch */
6215     , p_txn_act_id           => transaction_row.transaction_action_id   /* INVCONV sschinch */
6216     , p_doc_id               => transaction_row.doc_id
6217     , x_header_id            => l_header_id
6218     , x_unit_cost            => l_unit_cost
6219     , x_onhand_qty           => l_onhand_qty
6220     , x_return_status        => l_return_status
6221     );
6222 
6223     -- Bug 3388974-2
6224     new_cost.header_id := l_header_id;
6225     new_cost.unit_cost := l_unit_cost;
6226     new_cost.onhand_qty:= l_onhand_qty;
6227 
6228     IF l_return_status = 'S'
6229     THEN
6230 
6231       IF l_burdens_total <> 0
6232       THEN
6233         IF l_debug_level >= l_debug_level_medium
6234         THEN
6235           fnd_file.put_line
6236           (fnd_file.log,'Processing' || l_burden_costs_tab.count ||' burdens for CREI transaction ID '||transaction_row.transaction_id);
6237         END IF;
6238 
6239         FOR i IN 1..l_burden_costs_tab.COUNT
6240         LOOP
6241           create_cost_detail
6242           ( l_header_id
6243           , l_burden_costs_tab(i).cost_cmpntcls_id
6244           , l_burden_costs_tab(i).cost_analysis_code
6245           , 0
6246           , l_burden_costs_tab(i).component_cost
6247           , 1
6248           , l_return_status
6249           );
6250 
6251           IF l_return_status <> 'S'
6252           THEN EXIT;
6253           END IF;
6254         END LOOP;
6255 
6256       ELSE
6257 
6258         IF l_debug_level >= l_debug_level_medium
6259         THEN
6260           fnd_file.put_line
6261           (fnd_file.log,'No burdens found, retrieving default component class and analysis code for cost details');
6262         END IF;
6263 
6264 
6265         OPEN component_class_cursor
6266              (l_le_id, transaction_row.inventory_item_id, transaction_row.orgn_id,transaction_row.trans_date); /* INVCONV sschinch */
6267         FETCH component_class_cursor INTO component_class_id, cost_analysis_code, dummy;
6268         CLOSE component_class_cursor;
6269 
6270         IF l_debug_level >= l_debug_level_medium
6271         THEN
6272           fnd_file.put_line
6273           (fnd_file.log,'Creating new cost detail row');
6274         END IF;
6275 
6276         create_cost_detail
6277         ( l_header_id
6278         , component_class_id
6279         , cost_analysis_code
6280         , 0
6281         , 0.00
6282         , 0
6283         , l_return_status
6284         );
6285 
6286       END IF; -- end of cost details creation
6287     ELSE
6288       RETURN; --BUG 3476508  Some kind of problem with burdens
6289     END IF; -- end of header creation
6290 
6291     IF l_return_status = 'S'
6292     THEN
6293 
6294       IF l_debug_level >= l_debug_level_medium
6295       THEN
6296         fnd_file.put_line
6297         (fnd_file.log,'Creating new material cost transaction');
6298       END IF;
6299 
6300       create_material_transaction
6301       ( l_header_id
6302       , l_cost_type_id
6303       , transaction_row.trans_date
6304       , transaction_row.trans_qty
6305       , transaction_row.trans_um
6306       , transaction_row.trans_qty * l_burdens_total
6307       , transaction_row.transaction_id
6308       , l_burdens_total
6309       , transaction_row.trans_qty
6310       , NULL
6311       , NULL
6312       , NULL
6313       ,transaction_row.lot_number
6314       , l_return_status
6315       );
6316 
6317       IF l_return_status <> 'S'
6318       THEN
6319         RETURN;
6320       END IF;
6321 
6322     ELSE
6323       RETURN;
6324     END IF;
6325   END IF;
6326   IF l_debug_level >= l_debug_level_medium
6327      THEN
6328        fnd_file.put_line
6329        (fnd_file.log,'Leaving Procedure: '||procedure_name);
6330      END IF;
6331 
6332 EXCEPTION
6333   WHEN OTHERS
6334   THEN fnd_file.put_line
6335        (fnd_file.log,'Failed in procedure process_creation with error');
6336        fnd_file.put_line
6337        (fnd_file.log,SQLERRM);
6338        l_return_status := 'U';
6339 END process_creation;
6340 
6341 
6342 
6343 
6344 
6345     --**********************************************************************************************
6346     --*                                                                                            *
6347     --* Procedure to handle sales orders (OMSO/OPSO)                                               *
6348     --*                                                                                            *
6349     --**********************************************************************************************
6350 
6351 
6352 PROCEDURE process_sales_order
6353 IS
6354   loop_count NUMBER;
6355   procedure_name VARCHAR2(100);
6356 BEGIN
6357 
6358   procedure_name := 'Process Sales Order';
6359   IF l_debug_level >= l_debug_level_medium
6360      THEN
6361        fnd_file.put_line
6362        (fnd_file.log,'Entered Procedure: '||procedure_name);
6363      END IF;
6364   -- This is a debit on the source organization so treat this as an adjustment. Returns are handled
6365   -- as PORC transactions.
6366 
6367   process_adjustment;
6368 
6369   IF l_debug_level >= l_debug_level_medium
6370      THEN
6371        fnd_file.put_line
6372        (fnd_file.log,'Leaving Procedure: '||procedure_name);
6373      END IF;
6374 
6375 END process_sales_order;
6376 
6377 
6378 
6379     --**********************************************************************************************
6380     --*                                                                                            *
6381     --* Procedure to handle cycle counts (PIPH/PICY)                                               *
6382     --*                                                                                            *
6383     --**********************************************************************************************
6384 
6385 
6386 PROCEDURE process_cycle_count
6387 IS
6388   loop_count NUMBER;
6389   procedure_name VARCHAR2(100);
6390 BEGIN
6391 
6392   procedure_name := 'Process cycle count';
6393   IF l_debug_level >= l_debug_level_medium
6394      THEN
6395        fnd_file.put_line
6396        (fnd_file.log,'Entered Procedure: '||procedure_name);
6397      END IF;
6398 
6399   -- For costing purposes this is equivalent to an adjustment
6400 
6401   process_adjustment;
6402   IF l_debug_level >= l_debug_level_medium
6403      THEN
6404        fnd_file.put_line
6405        (fnd_file.log,'Leaving Procedure: '||procedure_name);
6406      END IF;
6407 
6408 END process_cycle_count;
6409 
6410 
6411 
6412     --**********************************************************************************************
6413     --*                                                                                            *
6414     --* Procedure to delete previously costed rows in the trail run.                               *
6415     --*                                                                                            *
6416     --**********************************************************************************************
6417 
6418 
6419 PROCEDURE delete_lot_costs
6420 IS
6421 
6422     TYPE lot_cost_cursor_type IS REF CURSOR;
6423     Cur_lc_header lot_cost_cursor_type;
6424 
6425     TYPE header_ids_tab IS TABLE OF gmf_lot_costs.header_id%TYPE
6426     	INDEX BY BINARY_INTEGER;
6427     l_header_ids_tab       header_ids_tab;
6428     l_empty_header_ids_tab header_ids_tab;
6429 
6430 
6431     TYPE rowids_tab IS TABLE OF rowid INDEX BY BINARY_INTEGER;
6432     l_rowids_tab       rowids_tab;
6433     l_empty_rowids_tab rowids_tab;
6434 
6435 
6436     l_rows_to_delete	PLS_INTEGER;
6437     l_indx_from		PLS_INTEGER;
6438     l_indx_to		PLS_INTEGER;
6439     l_max_loop_cnt	PLS_INTEGER;
6440     l_remaining_rows	PLS_INTEGER;
6441 
6442     l_matl_rows_deleted PLS_INTEGER;
6443     l_cdtl_rows_deleted PLS_INTEGER;
6444     procedure_name VARCHAR2(100);
6445 
6446 BEGIN
6447   procedure_name := 'Delete Lot Costs';
6448   IF l_debug_level >= l_debug_level_medium
6449      THEN
6450        fnd_file.put_line
6451        (fnd_file.log,'Entered Procedure: '||procedure_name);
6452      END IF;
6453 
6454   l_rows_to_delete	:= 1000;
6455   l_matl_rows_deleted   := 0;
6456   l_cdtl_rows_deleted   := 0;
6457 
6458   /* umoogala 29-Mar-2004
6459   ** Since item_id overrides itemcost_class check for item_id first
6460   */
6461 
6462 
6463     -- Open a cursor that retrieves only the item/lot/sublot specified
6464     OPEN Cur_lc_header FOR
6465     	SELECT glc.header_id, glc.rowid
6466 	      FROM  gmf_lot_costs glc,
6467 	            gmf_lot_costed_items_gt gpo
6468        WHERE  glc.organization_id   = gpo.organization_id
6469          AND  glc.inventory_item_id = gpo.inventory_item_id
6470 	       AND  glc.cost_type_id      = l_cost_type_id
6471 	       AND  glc.final_cost_flag 	= 0
6472 	       --AND  glc.inventory_item_id = l_item_id  /*jboppana*/
6473 	       AND  glc.lot_number 		    = DECODE(l_lot_no, NULL, glc.lot_number, l_lot_no)
6474 	       ;
6475 
6476   FETCH Cur_lc_header BULK COLLECT INTO l_header_ids_tab, l_rowids_tab;
6477   CLOSE Cur_lc_header;
6478 
6479   IF l_header_ids_tab.EXISTS(1)
6480   THEN
6481 
6482     --
6483     -- umoogala: delete and commit for every 10000 rows
6484     -- All the logic here is to avoid 'ORA-22160: element at index [n] does not exist'
6485     -- error when trying to delete non-existent elememnt.
6486     --
6487 
6488     l_indx_from      := l_header_ids_tab.FIRST;
6489     l_remaining_rows := l_header_ids_tab.count;
6490 
6491     IF l_header_ids_tab.count <= l_rows_to_delete
6492     THEN
6493       l_indx_to      := l_header_ids_tab.count;
6494       l_max_loop_cnt := 1;
6495 
6496     ELSE
6497       l_indx_to      := l_rows_to_delete;
6498       l_max_loop_cnt := ceil(l_header_ids_tab.count/l_rows_to_delete);
6499     END IF;
6500 
6501 
6502     fnd_file.put_line(fnd_File.LOG, '#of rows to delete in cost header: ' || l_header_ids_tab.count);
6503     fnd_file.put_line(fnd_File.LOG, 'l_max_loop_cnt: ' || l_max_loop_cnt);
6504 
6505     FOR i in 1..l_max_loop_cnt
6506     LOOP
6507 
6508 
6509 	--
6510         -- Delete all material trx info
6511 	--
6512         FORALL indx IN l_indx_from..l_indx_to
6513           DELETE FROM gmf_material_lot_cost_txns
6514           WHERE cost_header_id in l_header_ids_tab(indx);
6515 
6516   	l_matl_rows_deleted := l_matl_rows_deleted + SQL%ROWCOUNT;
6517 
6518 	--
6519         -- Delete all cost details
6520 	--
6521         FORALL indx IN l_indx_from..l_indx_to
6522           DELETE FROM gmf_lot_cost_details
6523           WHERE abs(header_id) in l_header_ids_tab(indx);
6524 
6525   	l_cdtl_rows_deleted := l_cdtl_rows_deleted + SQL%ROWCOUNT;
6526 
6527 
6528         COMMIT;
6529 
6530 
6531         l_remaining_rows := l_header_ids_tab.COUNT - (i * l_rows_to_delete);
6532 
6533         EXIT WHEN (l_header_ids_tab.count <= l_rows_to_delete) OR
6534                   (l_remaining_rows < 0);
6535 
6536 
6537         IF l_remaining_rows <= l_rows_to_delete
6538 	THEN
6539           l_indx_from := l_indx_to + 1;
6540           l_indx_to   := l_header_ids_tab.COUNT;
6541 
6542         ELSE
6543           l_indx_from := l_indx_to + 1;
6544           l_indx_to   := l_indx_to + l_rows_to_delete;
6545         END IF;
6546 
6547     END LOOP;
6548 
6549 
6550     --
6551     -- Now delete all rows from main lot costs table
6552     --
6553     FORALL indx IN l_rowids_tab.FIRST..l_rowids_tab.LAST
6554       DELETE FROM gmf_lot_costs
6555       WHERE rowid in l_rowids_tab(indx);
6556 
6557 
6558     fnd_file.put_line(fnd_File.LOG, '  ' || l_matl_rows_deleted || ' rows deleted from gmf_material_lot_cost_txns.');
6559     fnd_file.put_line(fnd_File.LOG, '  ' || l_cdtl_rows_deleted || ' rows deleted from gmf_lot_cost_details.');
6560     fnd_file.put_line(fnd_File.LOG, '  ' || SQL%ROWCOUNT || ' rows deleted from gmf_lot_costs.');
6561 
6562 
6563     COMMIT;
6564 
6565 
6566     -- remove old rows and release memory.
6567     l_header_ids_tab	:= l_empty_header_ids_tab;
6568     l_rowids_tab	:= l_empty_rowids_tab;
6569 
6570   END IF;
6571 
6572 /***** Bug 4094132 -  Added the following Delete - Start  *****/
6573 -- Delete the residual transactions for which header is final costed
6574 -- but because of reversal, one more transaction got created for the same header.
6575 
6576 
6577 
6578 DELETE
6579   FROM gmf_material_lot_cost_txns t
6580  WHERE cost_type_id = l_cost_type_id
6581    AND EXISTS (
6582           SELECT 1
6583             FROM gmf_lot_costs glc,
6584                  gmf_process_organizations_gt gpo
6585            WHERE glc.organization_id = gpo.organization_id
6586              AND glc.header_id = t.cost_header_id
6587              AND glc.cost_type_id = t.cost_type_id
6588              AND glc.final_cost_flag = 1
6589              AND t.final_cost_flag = 0);
6590 
6591 
6592   l_matl_rows_deleted := l_matl_rows_deleted + SQL%ROWCOUNT;
6593 
6594 
6595  IF l_matl_rows_deleted = 0 THEN
6596     fnd_file.put_line(fnd_File.LOG, '  No rows found to delete.');
6597  END IF;
6598 
6599  COMMIT;
6600  /***** Bug 4094132 -  Added the above Delete  - End *****/
6601   IF l_debug_level >= l_debug_level_medium
6602      THEN
6603        fnd_file.put_line
6604        (fnd_file.log,'Leaving Procedure: '||procedure_name);
6605      END IF;
6606 
6607 END delete_lot_costs;
6608 
6609 
6610 
6611 PROCEDURE process_lot_cost_adjustments
6612 IS
6613   CURSOR adjustments_cursor IS
6614   SELECT SYSTEM.gmf_cost_type
6615 	 ( lcad.cost_cmpntcls_id
6616          , lcad.cost_analysis_code
6617          , 0
6618          , lcad.adjustment_cost
6619          , 0
6620 	 )
6621   FROM  gmf_lot_cost_adjustment_dtls lcad
6622   WHERE lcad.adjustment_id = transaction_row.doc_id
6623   AND   lcad.delete_mark = 0;
6624 
6625   new_unit_cost   NUMBER;
6626   procedure_name VARCHAR2(100);
6627 
6628 BEGIN
6629   procedure_name := 'Process Lot Cost Adjustments';
6630   IF l_debug_level >= l_debug_level_medium
6631      THEN
6632        fnd_file.put_line
6633        (fnd_file.log,'Entered Procedure: '||procedure_name);
6634      END IF;
6635 
6636   IF l_debug_level >= l_debug_level_medium
6637   THEN
6638     fnd_file.put_line
6639     (fnd_file.log,'INSIDE lot_cost_adjustments for transaction ID '||transaction_row.transaction_id);
6640   END IF;
6641 
6642   -- Load adjustment cost details
6643 
6644 
6645   OPEN  adjustments_cursor;
6646   FETCH adjustments_cursor BULK COLLECT INTO new_cost_tab;
6647   CLOSE adjustments_cursor;
6648 
6649   -- Now merge the costs adjustments just loaded with the existing costs loaded in the rollup_lot_costs
6650   -- procedure.
6651 
6652    merge_costs ( old_cost_tab
6653   , 0
6654   , old_cost.onhand_qty
6655   , 'C'
6656   );
6657   -- Write the adjusted costs to the database
6658 /* INVCONV sschinch changes done to parameter*/
6659   create_cost_header
6660   ( transaction_row.inventory_item_id
6661   , transaction_row.lot_number
6662   , transaction_row.orgn_id
6663   , l_cost_type_id
6664   , new_cost.unit_cost
6665   , transaction_row.trans_date
6666   , old_cost.onhand_qty
6667   , transaction_row.doc_id
6668   , transaction_row.transaction_source_type_id
6669   ,transaction_row.transaction_action_id
6670   , new_cost.header_id
6671   , new_unit_cost
6672   , new_cost.onhand_qty
6673   , l_return_status
6674   ); -- PJS 17-Mar-2004 no bug reference
6675 
6676   -- If that worked OK, create the new cost details
6677 
6678   IF l_return_status = 'S'
6679   THEN
6680     FOR i IN 1..new_cost_tab.COUNT
6681     LOOP
6682       create_cost_detail
6683       ( new_cost.header_id
6684       , new_cost_tab(i).cost_cmpntcls_id
6685       , new_cost_tab(i).cost_analysis_code
6686       , 0
6687       , new_cost_tab(i).component_cost
6688       , 0
6689       , l_return_status
6690       );
6691 
6692       IF l_return_status <> 'S'
6693       THEN
6694         RETURN;
6695       END IF;
6696     END LOOP;
6697 
6698     -- Finally create a transaction for the adjustment
6699 
6700     new_cost.unit_cost := new_unit_cost;
6701 
6702     IF NOT old_cost_tab.EXISTS(1)
6703     THEN
6704       create_material_transaction
6705       ( new_cost.header_id
6706       , l_cost_type_id
6707       , transaction_row.trans_date
6708       , transaction_row.trans_qty
6709       , transaction_row.trans_um
6710       , new_cost.onhand_qty * new_cost.unit_cost
6711       , -9	-- trans_id
6712       , new_cost.unit_cost
6713       , transaction_row.trans_qty
6714       , NULL
6715       , NULL
6716       , NULL
6717       ,transaction_row.lot_number
6718       , l_return_status
6719       );
6720 
6721     ELSE
6722       create_material_transaction
6723       ( new_cost.header_id
6724       , l_cost_type_id /* INVCONV sschinch*/
6725       , transaction_row.trans_date
6726       , transaction_row.trans_qty
6727       , transaction_row.trans_um
6728       , new_cost.onhand_qty * new_cost.unit_cost - old_cost.onhand_qty * old_cost.unit_cost
6729       , -9	-- trans_id
6730       , new_cost.unit_cost
6731       , new_cost.onhand_qty
6732       , old_cost.unit_cost
6733       , old_cost.onhand_qty
6734       , NULL
6735       ,transaction_row.lot_number
6736       , l_return_status
6737       );
6738     END IF;
6739   END IF;
6740   IF l_debug_level >= l_debug_level_medium
6741      THEN
6742        fnd_file.put_line
6743        (fnd_file.log,'Leaving Procedure: '||procedure_name);
6744      END IF;
6745 
6746 END process_lot_cost_adjustments;
6747 
6748 
6749 
6750 
6751 --********************************************************************************************************
6752 --*    Procedure Name : PROCESS_WIP_BATCH
6753 --*
6754 --*     Description :
6755 --*               Procedure to Process the PROD transaction records, whose current
6756 --*       status is not Completed or Closed. Basically if we complete a batch and then
6757 --*       for example we yield 20LB product. Now we reverted the batch to WIP State
6758 --*       introducing a new -20 LB record. At this point, If we run the Lot Actual Cost Process
6759 --*       we don't cost these two transactions. Rather we copy the previous cost of the Lot if any
6760 --*       or 0$ to both these +20LB and -20LB transaction.
6761 --*
6762 --********************************************************************************************************
6763 
6764 PROCEDURE process_wip_batch
6765 IS
6766  procedure_name VARCHAR2(100);
6767 BEGIN
6768   procedure_name := 'Process WIP Batch';
6769   IF l_debug_level >= l_debug_level_medium
6770   THEN
6771      fnd_file.put_line (fnd_file.log,' Entering process_wip_batch');
6772    END IF;
6773 
6774   old_cost_tab.delete;
6775 
6776   OPEN  lot_cost_cursor (transaction_row.orgn_id,
6777                          transaction_row.inventory_item_id,
6778                          transaction_row.lot_number,
6779                          transaction_row.trans_date,
6780                          l_cost_type_id);
6781   FETCH lot_cost_cursor INTO old_cost;
6782 
6783   IF lot_cost_cursor%FOUND
6784   THEN
6785      IF   l_debug_level >= l_debug_level_high
6786      THEN
6787        fnd_file.put_line
6788        (fnd_file.log,'Reading existing costs for header ID '||old_cost.header_id);
6789      END IF;
6790 
6791       OPEN  lot_cost_detail_cursor (old_cost.header_id);
6792       FETCH lot_cost_detail_cursor BULK COLLECT INTO old_cost_tab;
6793       CLOSE lot_cost_detail_cursor;
6794 
6795      END IF;
6796      CLOSE lot_cost_cursor;
6797 
6798      IF old_cost_tab.EXISTS(1)
6799      THEN
6800        IF   l_debug_level >= l_debug_level_high
6801        THEN
6802          fnd_file.put_line
6803          (fnd_file.log,'Lot Cost before this transaction is '||to_char(old_cost.unit_cost,'999999999.99'));
6804        END IF;
6805 
6806 
6807        -- At this stage we have all the header and cost component information we need
6808        -- to store the costs in the database.
6809 
6810        create_cost_header
6811        ( transaction_row.inventory_item_id
6812        , transaction_row.lot_number /* INVCONV sschinch */
6813        , transaction_row.orgn_id    /* INVCONV sschinch */
6814        , l_cost_type_id             /*INVCONV sschinch */
6815        , old_cost.unit_cost     -- Carry Forward the Cost
6816        , transaction_row.trans_date
6817        , old_cost.onhand_qty + transaction_row.trans_qty
6818        , transaction_row.doc_id
6819        , transaction_row.transaction_source_type_id
6820        ,transaction_row.transaction_action_id
6821        , new_cost.header_id
6822        , dummy
6823        , new_cost.onhand_qty
6824        , l_return_status
6825        );
6826 
6827        IF l_return_status ='S'
6828        THEN
6829          FOR k IN 1.. old_cost_tab.count
6830          LOOP
6831            IF old_cost_tab(k).component_cost <> 0
6832            THEN
6833              create_cost_detail
6834              ( new_cost.header_id
6835              , old_cost_tab(k).cost_cmpntcls_id
6836              , old_cost_tab(k).cost_analysis_code
6837              , old_cost_tab(k).cost_level
6838              , old_cost_tab(k).component_cost
6839              , 0
6840              , l_return_status
6841              );
6842 
6843            IF l_return_status <> 'S'
6844            THEN
6845              RETURN;
6846            END IF;
6847          END IF;
6848        END LOOP;
6849 
6850        FOR k IN 1 .. old_cost_tab.COUNT
6851        LOOP
6852        -- Write the 'new' costs with a -ve header ID . This is because, there is some cost
6853        -- before this transaction. So this transaction must have ideally resulted in the change of
6854        -- cost. So we may need to store the transaction cost under the -header_id
6855        -- Although this looks like duplicate entry, process_reversals may expect this record.
6856 
6857        IF old_cost_tab(k).component_cost <> 0
6858        THEN
6859          create_cost_detail
6860          ( -new_cost.header_id
6861          , old_cost_tab(k).cost_cmpntcls_id
6862          , old_cost_tab(k).cost_analysis_code
6863          , old_cost_tab(k).cost_level
6864          , old_cost_tab(k).component_cost
6865          , 0
6866          , l_return_status
6867          );
6868 
6869          IF l_return_status <> 'S'
6870          THEN
6871            RETURN;
6872          END IF;
6873        END IF;
6874      END LOOP;
6875 
6876      create_material_transaction
6877      ( new_cost.header_id
6878       , l_cost_type_id     /*INVCONV sschinch */
6879       , transaction_row.trans_date
6880       , transaction_row.trans_qty
6881       , transaction_row.trans_um
6882       , old_cost.unit_cost  * transaction_row.trans_qty
6883       , transaction_row.transaction_id
6884       , old_cost.unit_cost
6885       ,  new_cost.onhand_qty -- Same as old_cost.onhand_qty+transaction_row.trans_qty
6886       , old_cost.unit_cost
6887       , old_cost.onhand_qty
6888       , 1
6889       ,transaction_row.lot_number
6890       , l_return_status
6891       );
6892 
6893         IF l_return_status <> 'S'
6894         THEN
6895           RETURN;
6896         END IF;
6897       ELSE
6898         RETURN;
6899       END IF;
6900     ELSE
6901       -- No cost currently exists, create one and all associated details
6902       -- and transactions. Again, this is only for the invoking transaction
6903       IF   l_debug_level >= l_debug_level_high
6904       THEN
6905         fnd_file.put_line( fnd_file.log,' Previous Cost is NULL');
6906       END IF;
6907 
6908        create_cost_header
6909        ( transaction_row.inventory_item_id
6910        , transaction_row.lot_number  /* INVCONV sschinch */
6911        , transaction_row.orgn_id     /* INVCONV sschinch */
6912        , l_cost_type_id             /*INVCONV sschinch */
6913        , 0     -- No Cost to Carry Forward. So Set to 0$
6914        , transaction_row.trans_date
6915        , transaction_row.trans_qty
6916        , transaction_row.doc_id
6917        , transaction_row.transaction_source_type_id
6918        ,transaction_row.transaction_action_id
6919        , new_cost.header_id
6920        , dummy
6921        , new_cost.onhand_qty
6922        , l_return_status
6923        );
6924 
6925        IF l_return_status <> 'S'
6926        THEN
6927           RETURN;
6928        END IF;
6929 
6930         OPEN component_class_cursor
6931              (l_le_id, transaction_row.inventory_item_id,transaction_row.orgn_id, transaction_row.trans_date);
6932         FETCH component_class_cursor INTO component_class_id, cost_analysis_code, dummy;
6933         CLOSE component_class_cursor;
6934 
6935         IF l_debug_level >= l_debug_level_medium
6936         THEN
6937           fnd_file.put_line
6938           (fnd_file.log,'Creating new cost detail row');
6939         END IF;
6940 
6941         create_cost_detail
6942         ( new_cost.header_id
6943         , component_class_id
6944         , cost_analysis_code
6945         , 0
6946         , 0.00
6947         , 0
6948         , l_return_status
6949         );
6950 
6951        IF l_return_status <> 'S'
6952         THEN
6953           RETURN;
6954        END IF;
6955 
6956        create_material_transaction
6957       ( new_cost.header_id
6958        , l_cost_type_id  /* INVCONV sschinch */
6959        , transaction_row.trans_date
6960        , transaction_row.trans_qty
6961        , transaction_row.trans_um
6962        , 0 -- Total Cost is also 0$
6963        , transaction_row.transaction_id
6964        , 0 -- Carrying Forward 0$
6965        ,  new_cost.onhand_qty -- Same as old_cost.onhand_qty+transaction_row.trans_qty
6966        , 0 -- No Old Cost
6967        , 0  -- No Old Qty
6968        , NULL
6969        ,transaction_row.lot_number
6970        , l_return_status
6971        );
6972 
6973       IF l_return_status <> 'S'
6974         THEN
6975           RETURN;
6976        END IF;
6977 
6978     END IF;
6979     IF l_debug_level >= l_debug_level_medium
6980      THEN
6981       fnd_file.put_line (fnd_file.log,' Entering process_wip_batch');
6982      END IF;
6983 
6984 END process_wip_batch;
6985 
6986 
6987 
6988 
6989 /*=========================================================
6990   PROCEDURE : perform_weighted_average
6991 
6992   DESCRIPTION  This procedure performs weighted avererage of
6993                individual lots
6994   AUTHOR : Sukarna Reddy  INVCONV June 2005
6995  ==========================================================*/
6996 
6997 PROCEDURE perform_weighted_average
6998 ( costs_table      IN OUT NOCOPY l_cost_tab_type
6999  ,trans_qty        IN NUMBER
7000  ,total_qty        IN NUMBER
7001  )
7002 IS
7003   k              NUMBER;
7004   l              NUMBER;
7005   divisor        NUMBER;
7006   l_new_row   NUMBER;
7007   procedure_name VARCHAR2(100);
7008 BEGIN
7009 
7010   procedure_name := 'Weighted Average';
7011 
7012   IF l_debug_level >= l_debug_level_medium
7013      THEN
7014        fnd_file.put_line
7015        (fnd_file.log,'Entered Procedure: '||procedure_name);
7016      END IF;
7017 
7018   IF l_debug_level >= l_debug_level_high
7019   THEN
7020     fnd_file.put_line(fnd_file.log,'trans_qty = '||trans_qty);
7021 
7022     fnd_file.put_line(fnd_file.log,'Previous Copy of new_cost_tab is:');
7023 
7024     FOR k IN 1 .. new_cost_tab.COUNT
7025     LOOP
7026       fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
7027       fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
7028       fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||new_cost_tab(k).cost_level);
7029       fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
7030       fnd_file.put_line(fnd_file.log,'====================================');
7031     END LOOP;
7032 
7033     IF costs_table.EXISTS(1)
7034     THEN
7035       fnd_file.put_line(fnd_file.log,'Before Average costs_tab is:');
7036       FOR k IN 1 .. costs_table.COUNT
7037       LOOP
7038         fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||costs_table(k).cost_cmpntcls_id);
7039         fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||costs_table(k).cost_analysis_code);
7040         fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||costs_table(k).cost_level);
7041         fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||costs_table(k).component_cost);
7042         fnd_file.put_line(fnd_file.log,'====================================');
7043       END LOOP;
7044     ELSE
7045       fnd_file.put_line(fnd_file.log,'No costs to merge');
7046     END IF;
7047   END IF;
7048 
7049   IF costs_table.EXISTS(1)
7050   THEN
7051 
7052       divisor := total_qty;
7053       IF divisor = 0
7054       THEN
7055         divisor := 1;
7056       END IF;
7057 
7058       fnd_file.put_line(fnd_file.log,'Divisor is  '||divisor);
7059 
7060       FOR k in 1 .. costs_table.COUNT
7061       LOOP
7062         costs_table(k).component_cost := costs_table(k).component_cost * trans_qty / divisor;
7063       END LOOP;
7064 
7065       IF l_debug_level >= l_debug_level_high
7066       THEN
7067         fnd_file.put_line(fnd_file.log,' new_qty = '||trans_qty);
7068 
7069        -- fnd_file.put_line(fnd_file.log,'After averaging new_cost_tab is:');
7070 
7071         fnd_file.put_line(fnd_file.log,'After averaging costs_tab is:');
7072         FOR k IN 1 .. costs_table.COUNT
7073         LOOP
7074           fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||costs_table(k).cost_cmpntcls_id);
7075           fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||costs_table(k).cost_analysis_code);
7076           fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||costs_table(k).cost_level);
7077           fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||costs_table(k).component_cost);
7078           fnd_file.put_line(fnd_file.log,'====================================');
7079         END LOOP;
7080       END IF;
7081 
7082    IF (new_cost_tab.COUNT = 0) THEN
7083          l_new_row := 1;
7084          FOR k IN 1..costs_table.COUNT
7085            LOOP
7086             new_cost_tab(l_new_row) := SYSTEM.gmf_cost_type(costs_table(k).cost_cmpntcls_id,costs_table(k).cost_analysis_code,costs_table(k).cost_level,costs_table(k).component_cost,0);
7087             l_new_row := l_new_row + 1;
7088           END LOOP;
7089      ELSE
7090        merge_costs(costs_table,
7091                       0,
7092                       0,
7093                      'C'
7094                      );
7095    END IF;
7096 
7097 
7098 
7099 
7100       fnd_file.put_line(fnd_file.log,'After averaging new_cost_tab is:');
7101       FOR k IN 1 .. new_cost_tab.COUNT
7102       LOOP
7103           fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||new_cost_tab(k).cost_cmpntcls_id);
7104           fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||new_cost_tab(k).cost_analysis_code);
7105           fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||new_cost_tab(k).cost_level);
7106           fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||new_cost_tab(k).component_cost);
7107           fnd_file.put_line(fnd_file.log,'====================================');
7108       END LOOP;
7109       END IF;
7110 
7111   IF l_debug_level >= l_debug_level_medium
7112      THEN
7113        fnd_file.put_line
7114        (fnd_file.log,'Leaving Procedure: '||procedure_name);
7115      END IF;
7116 END;
7117 
7118 
7119 /*=====================================================================
7120   PROCEDURE : get_new_cost
7121 
7122   DESCRIPTION This procedure sums up all the component costs by grouping
7123               component class and analysis code
7124   AUTHOR : Sukarna Reddy  INVCONV
7125 ======================================================================*/
7126 
7127   PROCEDURE get_new_cost (p_cost_tab IN OUT NOCOPY  l_cost_tab_type,
7128                           x_new_cost_tab OUT NOCOPY l_cost_tab_type,
7129                           x_total_cost   OUT NOCOPY NUMBER
7130                           )
7131   IS
7132     l_cost_table SYSTEM.gmf_cost_tab := new SYSTEM.gmf_cost_tab();
7133     CURSOR final_cmpnt_cur IS
7134      SELECT SYSTEM.gmf_cost_type(nct.cost_cmpntcls_id,
7135             nct.cost_analysis_code,
7136             nct.cost_level,
7137             sum(nct.component_cost),
7138             nct.burden_ind)
7139      FROM TABLE ( cast(l_cost_Table AS SYSTEM.gmf_cost_tab) ) nct
7140      GROUP BY nct.cost_cmpntcls_id,nct.cost_analysis_code,nct.cost_level,nct.burden_ind;
7141 
7142     procedure_name VARCHAR2(100);
7143 
7144   BEGIN
7145    procedure_name := 'Get New Cost';
7146    IF l_debug_level >= l_debug_level_medium
7147      THEN
7148        fnd_file.put_line
7149        (fnd_file.log,'Entered Procedure: '||procedure_name);
7150      END IF;
7151 
7152    IF (p_cost_tab.COUNT > 0) THEN
7153     FOR i IN 1..p_cost_tab.COUNT LOOP
7154       l_cost_table.extend;
7155       l_cost_table(i) := SYSTEM.gmf_cost_type(p_cost_tab(i).cost_cmpntcls_id,
7156                                       p_cost_tab(i).cost_analysis_code,
7157                                       p_cost_tab(i).cost_level,
7158                                       p_cost_tab(i).component_cost,
7159                                       p_cost_tab(i).burden_ind);
7160     END LOOP;
7161      OPEN final_cmpnt_cur;
7162      FETCH final_cmpnt_cur BULK COLLECT INTO x_new_cost_tab;
7163      CLOSE final_cmpnt_cur;
7164    END IF;
7165 
7166 
7167    SELECT SUM(nct.component_cost)
7168    INTO x_total_cost
7169    FROM TABLE ( CAST(l_cost_table AS SYSTEM.gmf_cost_tab) ) nct;
7170 
7171    IF l_debug_level >= l_debug_level_high
7172    THEN
7173      fnd_file.put_line(fnd_file.log,'After weighted average new_cost_tab is:');
7174      FOR k IN 1 .. new_cost_tab.COUNT
7175      LOOP
7176        fnd_file.put_line(fnd_file.log,'CCC/ID['||k||']: '||x_new_cost_tab(k).cost_cmpntcls_id);
7177        fnd_file.put_line(fnd_file.log,'A/Code['||k||']: '||x_new_cost_tab(k).cost_analysis_code);
7178        fnd_file.put_line(fnd_file.log,'Level['||k||'] : '||x_new_cost_tab(k).cost_level);
7179        fnd_file.put_line(fnd_file.log,'C/Cost['||k||']: '||x_new_cost_tab(k).component_cost);
7180        fnd_file.put_line(fnd_file.log,'====================================');
7181      END LOOP;
7182      fnd_file.put_line(fnd_file.log,'After merging, new unit cost is: '||x_total_cost);
7183    END IF;
7184    IF l_debug_level >= l_debug_level_medium
7185      THEN
7186        fnd_file.put_line
7187        (fnd_file.log,'Leaving Procedure: '||procedure_name);
7188      END IF;
7189 END;
7190 
7191 /*=========================================================
7192   PROCEDURE : Load_lot_costed_items_gt
7193 
7194   DESCRIPTION
7195     This procedure loads global temporary tables with process
7196     organizations and lot costed items.
7197   AUTHOR : Sukarna Reddy  INVCONV June 2005
7198 
7199   HISTORY
7200     jboppana bug 5241052
7201       added inventory_asset_flag and process_costing_enabled_flag to the insert query
7202     ANTHIYAG Bug#5279681
7203       Modified Query to correct the Query which fetches item codes based on Category
7204       Codes and also to add delete_mark check for the first query
7205  ==========================================================*/
7206 
7207  PROCEDURE Load_Lot_Costed_Items_gt(p_le_id        IN NUMBER,
7208                                    p_orgn_id      IN NUMBER,
7209                                    p_item_id      IN NUMBER,
7210                                    p_category_id  IN NUMBER,
7211                                    x_return_status OUT NOCOPY NUMBER
7212                                    ) IS
7213    l_from_orgn_code VARCHAR2(4) := NULL;
7214    l_row_count NUMBER;
7215    ll_return_status NUMBER;
7216 
7217 
7218    CURSOR get_process_org IS
7219    SELECT organization_code,
7220           organization_id
7221     FROM  gmf_process_organizations_gt
7222    ORDER BY organization_code;
7223    l_le_id NUMBER;
7224    procedure_name VARCHAR2(100);
7225  BEGIN
7226    procedure_name := 'load Lot Costed Items GT';
7227    IF l_debug_level >= l_debug_level_medium
7228      THEN
7229        fnd_file.put_line
7230        (fnd_file.log,'Entered Procedure: '||procedure_name);
7231      END IF;
7232    IF (p_le_id IS NOT NULL) THEN
7233      -- Always load all organizations. There may be transfers across orgs
7234      /*
7235      IF (p_orgn_id IS NOT NULL) THEN
7236        SELECT mp.organization_code
7237          INTO l_from_orgn_code
7238          FROM mtl_parameters mp
7239        WHERE mp.organization_id = p_orgn_id;
7240      END IF;
7241      */
7242     l_le_id := p_le_id;
7243  /*   gmf_organizations_pkg.get_process_organizations(p_legal_entity_id => l_le_id
7244                                                    ,p_From_Orgn_Code => l_from_orgn_code
7245                                                    ,p_To_Orgn_Code  => l_from_orgn_code
7246                                                    ,x_Row_Count     => l_row_count
7247                                                    ,x_Return_Status => ll_return_status
7248                                                    ); */
7249     -- B6822310 replace code to load all process orgs.
7250 
7251     Begin
7252        INSERT
7253         INTO GMF_PROCESS_ORGANIZATIONS_GT
7254         (
7255            organization_id,
7256            organization_code,
7257            base_currency_code,
7258            std_uom,
7259            legal_entity_id,
7260            operating_unit_id
7261         )
7262        SELECT  mp.organization_id, mp.organization_code, gfp.base_currency_code,
7263                NULL,  gfp.legal_entity_id, ood.operating_unit
7264         FROM  mtl_parameters mp,
7265                 gmf_fiscal_policies gfp,
7266                 org_organization_definitions ood
7267        WHERE  mp.process_enabled_flag = 'Y'
7268          AND  gfp.legal_entity_id = ood.legal_entity
7269 	 AND  mp.organization_id = ood.organization_id;
7270        l_Row_Count := sql%rowcount;
7271 
7272        IF l_Row_Count = 0
7273          THEN
7274          ll_return_status := -1; --No Rows returned by the API
7275        END IF;
7276 
7277        UPDATE gmf_process_organizations_gt gpo
7278           SET std_uom = (SELECT u.uom_code
7279                       FROM mtl_units_of_measure u,
7280                            gmd_parameters_hdr h,
7281                            gmd_parameters_dtl d
7282                     WHERE u.base_uom_flag = 'Y'
7283                     AND gpo.organization_id = h.organization_id
7284                     AND h.parameter_id = d.parameter_id
7285                     AND d.parameter_name = 'FM_YIELD_TYPE'
7286                     AND d.parameter_value = u.uom_class)
7287       WHERE gpo.std_uom IS NULL;
7288 
7289       UPDATE gmf_process_organizations_gt gpo
7290          SET std_uom = (SELECT u.uom_code
7291                       FROM mtl_units_of_measure u,
7292                            gmd_parameters_hdr h,
7293                            gmd_parameters_dtl d
7294                     WHERE u.base_uom_flag = 'Y'
7295                     AND  h.organization_id IS NULL
7296                     AND h.parameter_id = d.parameter_id
7297                     AND d.parameter_name = 'FM_YIELD_TYPE'
7298                     AND d.parameter_value = u.uom_class)
7299       WHERE gpo.std_uom IS NULL;
7300 
7301       ll_return_status := 0;
7302 
7303     EXCEPTION
7304       WHEN OTHERS
7305       THEN
7306       ll_return_status := -1;
7307 
7308     END;
7309 
7310 
7311    -- B 6822310 replaced commented code as above.
7312 
7313     IF (ll_return_status <> 0) THEN
7314       x_return_status := ll_return_status;
7315       RETURN;
7316     END IF;
7317     /* Build index for organization id */
7318     FOR cur_rec IN get_process_org LOOP
7319       l_org_tab(cur_rec.organization_id) := cur_rec.organization_code;
7320     END LOOP;
7321 
7322    INSERT
7323       INTO GMF_LOT_COSTED_ITEMS_GT
7324       (
7325           organization_id,
7326           inventory_item_id,
7327           primary_uom_code
7328       )
7329       SELECT
7330            msi.organization_id,
7331            msi.inventory_item_id,
7332            msi.primary_uom_code
7333       FROM gmf_lot_costed_items lci,
7334            mtl_system_items_b msi,
7335            gmf_process_organizations_gt gpo
7336       WHERE lci.legal_entity_id = p_le_id
7337         AND lci.delete_mark = 0 /* ANTHIYAG Bug#5279681 06-Jun-2006 */
7338         AND gpo.organization_id = msi.organization_id
7339         AND msi.lot_control_code = 2
7340         AND lci.inventory_item_id = msi.inventory_item_id
7341         AND msi.inventory_asset_flag = 'Y'
7342         AND msi.process_costing_enabled_flag = 'Y'
7343         AND lci.inventory_item_id = NVL(p_item_id,lci.inventory_item_id)
7344         AND lci.cost_type_id = l_cost_type_id
7345         AND
7346          (
7347            (
7348               p_item_id IS NULL
7349               AND p_category_id IS NULL
7350            )
7351           OR
7352           (
7353               p_item_id IS NOT NULL
7354           )
7355          )
7356     UNION
7357       SELECT
7358         mic.organization_id,    /*ANTHIYAG Bug#5279681 06-Jun-2006 */
7359         mic.inventory_item_id,  /*ANTHIYAG Bug#5279681 06-Jun-2006 */
7360         i.primary_uom_code
7361       FROM mtl_item_categories mic,
7362            gmf_lot_costed_items g,
7363            mtl_system_items_b i,
7364            gmf_process_organizations_gt gpo
7365      WHERE g.cost_category_id = mic.category_id
7366           AND g.legal_entity_id = l_le_id
7367           AND g.delete_mark = 0
7368           AND i.lot_control_code = 2
7369           AND gpo.organization_id = i.organization_id
7370           AND i.organization_id = mic.organization_id
7371           AND mic.inventory_item_id = i.inventory_item_id
7372           AND i.inventory_asset_flag = 'Y'
7373           AND i.process_costing_enabled_flag = 'Y'
7374           AND g.cost_type_id = l_cost_type_id
7375           AND g.cost_category_id = NVL(p_category_id,g.cost_category_id)
7376           AND
7377            (
7378             (
7379                p_item_id IS NULL
7380                AND p_category_id IS NULL
7381             )
7382             OR
7383             (
7384                p_category_id IS NOT NULL
7385             )
7386            ) ;
7387    END IF;
7388     x_return_status := 0;
7389     IF l_debug_level >= l_debug_level_medium
7390      THEN
7391        fnd_file.put_line
7392        (fnd_file.log,'Leaving Procedure: '||procedure_name);
7393      END IF;
7394   EXCEPTION
7395     WHEN OTHERS THEN
7396       x_return_status := -1;
7397 END;
7398 
7399 
7400 
7401   /*=========================================================
7402     PROCEDURE : Process_lot_split
7403 
7404     DESCRIPTION
7405       This procedure process lot split transactions.
7406     AUTHOR : Sukarna Reddy  INVCONV
7407    ==========================================================*/
7408 
7409   PROCEDURE process_lot_split IS
7410     l_old_cost gmf_lot_costs%ROWTYPE;
7411     l_old_cost_tab l_cost_tab_type;
7412     l_parent_lot_number VARCHAR2(80);
7413     i NUMBER;
7414     l_new_cost  NUMBER;
7415     procedure_name VARCHAR2(100);
7416   BEGIN
7417     procedure_name := 'Process Lot Split';
7418     IF l_debug_level >= l_debug_level_medium
7419      THEN
7420        fnd_file.put_line
7421        (fnd_file.log,'Entered Procedure: '||procedure_name);
7422      END IF;
7423 
7424     IF (transaction_row.transaction_id = transaction_row.transfer_transaction_id)
7425     THEN    /* This is a parent lot from which split happened */
7426     -- Check if cost for this Lot exist
7427       IF old_cost_tab.EXISTS(1)
7428       THEN
7429         process_adjustment;
7430       ELSE
7431         process_creation;
7432       END IF;
7433     ELSE  /* This is a new lot created from the parent lot */
7434       --check if there is cost from parent lot At this point
7435       SELECT  mln.lot_number
7436         INTO  l_parent_lot_number
7437         FROM  mtl_transaction_lot_numbers mln,
7438               mtl_material_transactions mmt
7439        WHERE  mmt.transaction_id = transaction_row.transfer_transaction_id
7440             AND mmt.transaction_id = mln.transaction_id;
7441 
7442        OPEN lot_cost_cursor(transaction_row.orgn_id,
7443                             transaction_row.inventory_item_id,
7444                             l_parent_lot_number,
7445                             transaction_row.trans_date,
7446                             l_cost_type_id);
7447        FETCH lot_cost_cursor INTO l_old_cost;
7448 
7449        IF lot_cost_cursor%FOUND
7450        THEN
7451          IF   l_debug_level >= l_debug_level_high
7452          THEN
7453             fnd_file.put_line
7454             (fnd_file.log,'Reading existing costs for header ID '||l_old_cost.header_id);
7455          END IF;
7456 
7457          OPEN  lot_cost_detail_cursor (l_old_cost.header_id);
7458          FETCH lot_cost_detail_cursor BULK COLLECT INTO l_old_cost_tab;
7459          CLOSE lot_cost_detail_cursor;
7460 
7461          IF (l_old_cost_tab.EXISTS(1)) THEN
7462            merge_costs(l_old_cost_tab,
7463                        old_cost.onhand_qty,
7464                        transaction_row.trans_qty,
7465                        'C'
7466                       );
7467             merge_costs(old_cost_tab,
7468                         transaction_row.trans_qty, /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7469                         old_cost.onhand_qty, /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7470                        'A'
7471                        );
7472           END IF;
7473           CLOSE lot_cost_cursor;
7474        ELSE
7475          CLOSE lot_cost_cursor;
7476          -- if we are here that means there is no incomming cost from the parent lot
7477          -- check if current child lot has prior cost
7478          IF (old_cost_tab.EXISTS(1)) THEN
7479            merge_costs(old_cost_tab,
7480                        transaction_row.trans_qty, /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7481                        old_cost.onhand_qty, /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7482                        'A'
7483                       );
7484          ELSE
7485            -- If we are hear then this is a new transaction
7486            process_creation;
7487            RETURN;
7488          END IF;
7489        END IF;
7490         --
7491        IF (new_cost_tab.EXISTS(1)) THEN   -- jboppana
7492          l_new_cost := new_cost.unit_cost;
7493          create_cost_header
7494           (p_item_id               => transaction_row.inventory_item_id
7495            ,p_lot_number           => transaction_row.lot_number
7496            ,p_orgn_id              => transaction_row.orgn_id
7497            ,p_cost_type_id         => l_cost_type_id
7498            ,p_unit_cost            => l_new_cost
7499            ,p_cost_date            => transaction_row.trans_date
7500            ,p_onhand_qty           => transaction_row.trans_qty + NVL(old_cost.onhand_qty,0) /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7501            ,p_trx_src_type_id      => transaction_row.transaction_source_type_id
7502            ,p_txn_act_id           => transaction_row.transaction_action_id
7503            ,p_doc_id               => transaction_row.doc_id
7504            ,x_header_id            => new_cost.header_id
7505            ,x_unit_cost            => new_cost.unit_cost
7506            ,x_onhand_qty           => new_cost.onhand_qty
7507            ,x_return_status        => l_return_status
7508           );
7509 
7510 
7511           IF l_debug_level >= l_debug_level_medium
7512           THEN
7513             fnd_file.put_line
7514              (fnd_file.log,'Creating new cost detail row');
7515           END IF;
7516 
7517           FOR i IN 1..new_cost_tab.COUNT
7518           LOOP
7519             create_cost_detail
7520                  ( new_cost.header_id
7521                   ,new_cost_tab(i).cost_cmpntcls_id
7522                   , new_cost_tab(i).cost_analysis_code
7523                   ,0
7524                   , new_cost_tab(i).component_cost
7525                   ,0
7526                   , l_return_status
7527                  );
7528           END LOOP;
7529           IF l_return_status = 'S'
7530           THEN
7531             IF l_debug_level >= l_debug_level_medium
7532             THEN
7533               fnd_file.put_line
7534                 (fnd_file.log,'Creating new material cost transaction');
7535             END IF;
7536              create_material_transaction
7537             ( new_cost.header_id
7538              ,l_cost_type_id
7539              ,transaction_row.trans_date
7540               ,transaction_row.trans_qty
7541               ,transaction_row.trans_um
7542               ,transaction_row.trans_qty * nvl(new_cost.unit_cost,0) /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7543               ,transaction_row.transaction_id
7544               ,nvl(new_cost.unit_cost,0) /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7545               ,transaction_row.trans_qty
7546               ,NULL
7547               ,NULL
7548               ,NULL
7549               ,transaction_row.lot_number
7550               , l_return_status
7551              );
7552           END IF;
7553         END IF;
7554       END IF;
7555     IF l_debug_level >= l_debug_level_medium
7556      THEN
7557        fnd_file.put_line
7558        (fnd_file.log,'Leaving Procedure: '||procedure_name);
7559      END IF;
7560   END;
7561 
7562   /* INVCONV sschinch New procedure*/
7563 
7564   /*=========================================================
7565     PROCEDURE : Process_lot_merge
7566     DESCRIPTION
7567       This procedure processes lot merge transactions for costing.
7568     AUTHOR : Sukarna Reddy Jun 2005 INVCONV
7569    ==========================================================*/
7570 
7571   PROCEDURE process_lot_merge IS
7572 
7573   CURSOR child_lots_cursor IS
7574   SELECT mtln.lot_number,
7575          ABS(mtln.primary_quantity),
7576          mtln.transaction_date
7577     FROM mtl_transaction_lot_numbers mtln, mtl_material_transactions mmt
7578    WHERE mmt.transfer_transaction_id = transaction_row.transfer_transaction_id
7579         AND  mmt.transaction_id <> transaction_row.transfer_transaction_id
7580         AND  mmt.transaction_id = mtln.transaction_id  ;
7581 
7582 
7583   l_unit_cost  NUMBER;
7584   l_total_cost NUMBER;
7585   l_cost_tab   l_cost_tab_type;
7586   l_old_cost   gmf_lot_costs%rowtype;
7587   l_new_cost_tab l_cost_tab_type;
7588   procedure_name VARCHAR2(100);
7589 
7590 
7591 
7592   BEGIN
7593     procedure_name := 'Process Merged Lot';
7594     IF l_debug_level >= l_debug_level_medium
7595      THEN
7596        fnd_file.put_line
7597        (fnd_file.log,'Entered Procedure: '||procedure_name);
7598      END IF;
7599 
7600     IF (transaction_row.transaction_id = transaction_row.transfer_transaction_id)
7601     THEN
7602       -- This is a merged lot and there may be or may not be any prior cost for this lot
7603       -- Get the cost from child lots which are the sources of costs for this transaction
7604       -- and perform weighted average. We need to get the child lots first.
7605         OPEN child_lots_cursor;
7606         FETCH child_lots_cursor INTO child_lot_row;
7607         WHILE child_lots_cursor%FOUND
7608         LOOP
7609          OPEN lot_cost_cursor(transaction_row.orgn_id,
7610                               transaction_row.inventory_item_id,
7611                               child_lot_row.lot_number,
7612                               child_lot_row.trans_date,
7613                               l_cost_type_id);
7614          FETCH lot_cost_cursor INTO l_old_cost;
7615 
7616          OPEN  lot_cost_detail_cursor ( l_old_cost.header_id );
7617          FETCH lot_cost_detail_cursor BULK COLLECT INTO l_cost_tab;
7618          CLOSE lot_cost_detail_cursor;
7619 
7620          IF (l_cost_tab.EXISTS(1)) THEN
7621            perform_weighted_average(l_cost_tab,
7622                                     child_lot_row.trans_qty,
7623                                     transaction_row.trans_qty
7624                                     );
7625          ELSE
7626             fnd_file.put_line
7627                 (fnd_File.LOG,'PROCEDURE Process_Lot_Merge '||'Warning : Child Lot :'||child_lot_row.lot_number||' has no cost will be using 0 cost ');
7628          END IF;
7629 
7630          CLOSE lot_cost_cursor;
7631          FETCH child_lots_cursor INTO child_lot_row;
7632        END LOOP;
7633        CLOSE child_lots_cursor;
7634 
7635        IF (old_cost_tab.EXISTS(1)) THEN
7636           perform_weighted_average(old_cost_tab,
7637                                    old_cost.onhand_qty,
7638                                    transaction_row.trans_qty
7639                                    );
7640           merge_costs(old_cost_tab,
7641                       0,
7642                       0,
7643                      'C'
7644                      );
7645       END IF;
7646 
7647        get_new_cost(p_cost_tab => new_cost_tab,
7648                     x_new_cost_tab => l_new_cost_tab,
7649                     x_total_cost   => l_unit_cost
7650                    );
7651        new_cost_tab := l_new_cost_tab;
7652        lot_unit_cost := l_unit_cost;
7653 
7654       IF (new_cost_tab.EXISTS(1)) THEN
7655         create_cost_header
7656           ( transaction_row.inventory_item_id
7657           , transaction_row.lot_number
7658           , transaction_row.orgn_id
7659           , l_cost_type_id
7660           , lot_unit_cost
7661           , transaction_row.trans_date
7662           , transaction_row.trans_qty
7663           , transaction_row.doc_id
7664           ,transaction_row.transaction_source_type_id
7665           ,transaction_row.transaction_action_id
7666           , new_cost.header_id
7667           , new_cost.unit_cost
7668           , new_cost.onhand_qty
7669           , l_return_status
7670          );
7671 
7672       IF l_return_status = 'S'
7673       THEN
7674         IF l_debug_level >= l_debug_level_medium
7675         THEN
7676           fnd_file.put_line
7677             (fnd_file.log,'Creating cost detail rows');
7678         END IF;
7679 
7680         FOR i in 1 .. new_cost_tab.COUNT
7681         LOOP
7682           create_cost_detail
7683           ( new_cost.header_id
7684           , new_cost_tab(i).cost_cmpntcls_id
7685           , new_cost_tab(i).cost_analysis_code
7686           , 0
7687           , new_cost_tab(i).component_cost
7688           , 0
7689           , l_return_status
7690           );
7691 
7692           IF l_return_status <> 'S'
7693           THEN
7694             RETURN;
7695           END IF;
7696         END LOOP;
7697 
7698 
7699         IF l_debug_level >= l_debug_level_medium
7700         THEN
7701           fnd_file.put_line
7702             (fnd_file.log,'Procedure : '||procedure_name||' Creating cost transaction');
7703         END IF;
7704 
7705         create_material_transaction
7706             ( new_cost.header_id
7707             , l_cost_type_id
7708             , transaction_row.trans_date
7709             , transaction_row.trans_qty
7710             , transaction_row.trans_um
7711             , new_cost.onhand_qty * new_cost.unit_cost
7712             , transaction_row.transaction_id
7713             , new_cost.unit_cost
7714             , new_cost.onhand_qty
7715             , NULL
7716             , NULL
7717             , NULL
7718             ,transaction_row.lot_number
7719             , l_return_status
7720             );
7721       END IF; /* l_return_status = 'S' */
7722      END IF;
7723     ELSE
7724       -- This is a child lot and consumed lot. Consider this as an adjustment.
7725       process_adjustment;
7726     END IF;
7727     IF l_debug_level >= l_debug_level_medium
7728      THEN
7729        fnd_file.put_line
7730        (fnd_file.log,'Leaving Procedure: '||procedure_name);
7731      END IF;
7732 
7733   END process_lot_merge;
7734   /*=========================================================
7735     PROCEDURE : Process_lot_translate
7736     DESCRIPTION
7737       This procedure processes lot translate transaction.
7738     AUTHOR : Sukarna Reddy june 2005
7739    ==========================================================*/
7740 
7741 
7742   PROCEDURE process_lot_translate IS
7743     l_old_cost  gmf_lot_costs%rowtype;
7744     l_cost_tab  l_cost_tab_type;
7745     l_lot_number  VARCHAR2(80);
7746     l_trans_date  DATE;
7747     i PLS_INTEGER;
7748     l_new_cost NUMBER;
7749     procedure_name VARCHAR2(100);
7750   BEGIN
7751     procedure_name := 'Process Lot Translate';
7752     IF l_debug_level >= l_debug_level_medium
7753      THEN
7754        fnd_file.put_line
7755        (fnd_file.log,'Entered Procedure: '||procedure_name);
7756      END IF;
7757 
7758     IF (transaction_row.transaction_id = transaction_row.transfer_transaction_id) THEN
7759       process_adjustment;
7760     ELSE
7761       SELECT    lot_number,
7762                 transaction_date
7763                INTO l_lot_number,
7764                     l_trans_date
7765       FROM   mtl_transaction_lot_numbers
7766       WHERE transaction_id = transaction_row.transfer_transaction_id;
7767 
7768       IF (old_cost_tab.EXISTS(1)) THEN
7769         merge_costs(old_cost_tab,
7770               old_cost.onhand_qty,
7771               transaction_row.trans_qty,
7772               'C'
7773              );
7774       END IF;
7775 
7776        -- Get the parent lot info to retrive cost
7777 
7778       OPEN lot_cost_cursor(transaction_row.orgn_id,
7779                            transaction_row.inventory_item_id,
7780                            l_lot_number,
7781                            l_trans_date,
7782                            l_cost_type_id);
7783       FETCH lot_cost_cursor INTO l_old_cost;
7784       CLOSE lot_cost_cursor;
7785       IF (l_old_cost.header_id > 0) THEN
7786         OPEN  lot_cost_detail_cursor ( l_old_cost.header_id);
7787         FETCH lot_cost_detail_cursor BULK COLLECT INTO l_cost_tab;
7788         CLOSE lot_cost_detail_cursor;
7789       END IF;
7790 
7791       IF (l_cost_tab.EXISTS(1)) THEN
7792         IF (old_cost_tab.EXISTS(1)) THEN
7793           merge_costs(l_cost_tab,
7794                 transaction_row.trans_qty, /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7795                 old_cost.onhand_qty, /* ANTHIYAG Bug#5412410 26-Jul-2006 */
7796                'A'
7797                );
7798         ELSE
7799           merge_costs(l_cost_tab,
7800                 transaction_row.trans_qty,
7801                 0,
7802                'A'
7803                );
7804         END IF;
7805       ELSE
7806         IF (NOT new_cost_tab.EXISTS(1)) THEN
7807           -- There is not cost for this lot
7808           --Treat this as creation of inventory
7809           process_creation;
7810           RETURN;
7811         END IF;
7812       END IF;
7813 
7814       l_new_cost := new_cost.unit_cost;
7815 
7816       IF (new_cost_tab.EXISTS(1)) THEN
7817         create_cost_header
7818           ( transaction_row.inventory_item_id
7819           , transaction_row.lot_number
7820           , transaction_row.orgn_id
7821           , l_cost_type_id
7822           , l_new_cost
7823           , transaction_row.trans_date
7824           , transaction_row.trans_qty + NVL(old_cost.onhand_qty,0)
7825           , transaction_row.doc_id
7826           ,transaction_row.transaction_source_type_id
7827           ,transaction_row.transaction_action_id
7828           , new_cost.header_id
7829           , new_cost.unit_cost
7830           , new_cost.onhand_qty
7831           , l_return_status
7832          );
7833 
7834        IF (l_return_status = 'S') THEN
7835          FOR i in 1 .. new_cost_tab.COUNT
7836          LOOP
7837            create_cost_detail
7838                ( new_cost.header_id
7839                , new_cost_tab(i).cost_cmpntcls_id
7840                , new_cost_tab(i).cost_analysis_code
7841                , 0
7842                , new_cost_tab(i).component_cost
7843                , 0
7844                , l_return_status
7845               );
7846 
7847            IF l_return_status <> 'S'
7848            THEN
7849                 RETURN;
7850            END IF;
7851            create_material_transaction
7852               ( new_cost.header_id
7853               , l_cost_type_id
7854               , transaction_row.trans_date
7855               , transaction_row.trans_qty
7856               , transaction_row.trans_um
7857               , new_cost.onhand_qty * new_cost.unit_cost
7858               , transaction_row.transaction_id
7859               , new_cost.unit_cost
7860               , new_cost.onhand_qty
7861               , NULL
7862               , NULL
7863               , NULL
7864               ,transaction_row.lot_number
7865               , l_return_status
7866               );
7867         END LOOP;
7868       END IF;
7869     END IF;
7870     END IF;
7871     IF l_debug_level >= l_debug_level_medium
7872      THEN
7873        fnd_file.put_line
7874        (fnd_file.log,'Leaving Procedure: '||procedure_name);
7875      END IF;
7876   END process_lot_translate;
7877 
7878 
7879   /*=========================================================
7880   PROCEDURE : process_consigned_inventory
7881 
7882   DESCRIPTION
7883     This procedure will process consigned inventory transactions
7884   AUTHOR : Sukarna Reddy  INVCONV June 2005
7885  ==========================================================*/
7886 
7887  PROCEDURE process_consigned_inventory IS
7888    l_ccc_id NUMBER;
7889    l_a_code VARCHAR2(4);
7890    l_new_cost   NUMBER;
7891    procedure_name VARCHAR2(100);
7892  BEGIN
7893      procedure_name := 'Process Consigned Inventory';
7894 
7895      IF l_debug_level >= l_debug_level_medium
7896      THEN
7897        fnd_file.put_line
7898        (fnd_file.log,'Entered Procedure: '||procedure_name);
7899      END IF;
7900 
7901      OPEN component_class_cursor
7902     ( l_le_id
7903      ,transaction_row.inventory_item_id
7904      ,transaction_row.orgn_id
7905      ,transaction_row.trans_date
7906     );
7907     FETCH component_class_cursor INTO l_ccc_id,l_a_code,dummy;
7908     CLOSE component_class_cursor;
7909 
7910      IF (l_ccc_id IS NOT NULL) THEN
7911        new_cost_tab(1):= SYSTEM.gmf_cost_type(l_ccc_id,l_a_code,0,transaction_row.transaction_cost,0);
7912        new_cost.unit_cost := transaction_row.transaction_cost;
7913      ELSE
7914        RETURN;
7915      END IF;
7916 
7917      IF (old_cost_tab.EXISTS(1)) THEN
7918        merge_costs(old_cost_tab,
7919                    old_cost.onhand_qty,
7920                    transaction_row.trans_qty,
7921                    'A'
7922                    );
7923      END IF;
7924      IF (new_cost_tab.EXISTS(1)) THEN
7925        l_new_cost := new_cost.unit_cost;
7926         create_cost_header
7927           ( transaction_row.inventory_item_id
7928           , transaction_row.lot_number
7929           , transaction_row.orgn_id
7930           , l_cost_type_id
7931           , l_new_cost
7932           , transaction_row.trans_date
7933           , transaction_row.trans_qty + NVL(old_cost.onhand_qty,0)
7934           , transaction_row.doc_id
7935           ,transaction_row.transaction_source_type_id
7936           ,transaction_row.transaction_action_id
7937           , new_cost.header_id
7938           , new_cost.unit_cost
7939           , new_cost.onhand_qty
7940           , l_return_status
7941          );
7942 
7943        IF (l_return_status = 'S') THEN
7944          FOR i in 1 .. new_cost_tab.COUNT
7945          LOOP
7946            create_cost_detail
7947                ( new_cost.header_id
7948                , new_cost_tab(i).cost_cmpntcls_id
7949                , new_cost_tab(i).cost_analysis_code
7950                , 0
7951                , new_cost_tab(i).component_cost
7952                , 0
7953                , l_return_status
7954               );
7955 
7956            IF l_return_status <> 'S'
7957            THEN
7958                 RETURN;
7959            END IF;
7960            create_material_transaction
7961               ( new_cost.header_id
7962               , l_cost_type_id
7963               , transaction_row.trans_date
7964               , transaction_row.trans_qty
7965               , transaction_row.trans_um
7966               , new_cost.onhand_qty * new_cost.unit_cost
7967               , transaction_row.transaction_id
7968               , new_cost.unit_cost
7969               , new_cost.onhand_qty
7970               , NULL
7971               , NULL
7972               , NULL
7973               ,transaction_row.lot_number
7974               , l_return_status
7975               );
7976         END LOOP;
7977       END IF;
7978     END IF;
7979 
7980      IF l_debug_level >= l_debug_level_medium
7981      THEN
7982        fnd_file.put_line
7983        (fnd_file.log,'Leaving Procedure: '||procedure_name);
7984      END IF;
7985  END;
7986 
7987  /*=========================================================
7988   PROCEDURE : process_pdtxf_cost
7989 
7990   DESCRIPTION
7991     This procedure will process process discrete transfers
7992   AUTHOR : Sukarna Reddy  INVCONV June 2005
7993  ==========================================================*/
7994 
7995   PROCEDURE process_pdtxf_cost IS
7996     l_cost_tab l_cost_tab_type;
7997     x_total_cost NUMBER;
7998     l_new_cost NUMBER;
7999     l_trp_cost NUMBER;
8000     l_txf_price NUMBER;
8001     l_ccc_id NUMBER;
8002     l_a_code VARCHAR2(4);
8003     l_trans_id NUMBER;
8004     l_header_id NUMBER;
8005 
8006     l_cmpntcls_id NUMBER;
8007     l_cost_analysis_code VARCHAR2(4);
8008     l_cost_level         NUMBER(1);
8009     l_component_cost     NUMBER;
8010     l_burden_ind         NUMBER(1);
8011     procedure_name VARCHAR2(100);
8012 
8013     CURSOR cur_get_default_cmpt(p_le_id NUMBER,
8014                                 p_trp_cost  NUMBER) IS
8015             SELECT default_ovh_cmpntcls_id,
8016                                 default_ovh_analysis_code,
8017                                 0,
8018                                 p_trp_cost,
8019                                 1
8020                            FROM  gmf_fiscal_policies
8021             WHERE legal_entity_id = p_le_id  ;
8022   BEGIN
8023 
8024     procedure_name := 'process_pdtxf_cost';
8025     IF l_debug_level >= l_debug_level_medium
8026      THEN
8027        fnd_file.put_line
8028        (fnd_file.log,'Entered Procedure: '||procedure_name);
8029      END IF;
8030     OPEN  component_class_cursor(l_le_id,
8031                                  transaction_row.inventory_item_id,
8032                                  transaction_row.orgn_id,
8033                                  transaction_row.trans_date);
8034     FETCH component_class_cursor INTO l_ccc_id,l_a_code,dummy;
8035     CLOSE component_class_cursor;
8036 
8037     IF(transaction_row.trans_qty <> 0) THEN
8038        l_new_cost := transaction_row.transfer_price;
8039        l_trp_cost := transaction_row.transportation_cost/transaction_row.trans_qty;
8040     ELSE
8041        fnd_file.put_line
8042                (fnd_file.log,'ERROR Procedure : '||procedure_name||' Transaction qty is zero.Cannot proceed');
8043        l_return_status := 'E';
8044         RETURN;
8045      END IF;
8046 
8047     IF (old_cost_tab.EXISTS(1)) THEN
8048       IF (l_ccc_id IS NOT NULL) THEN
8049         l_cost_tab(1) := SYSTEM.gmf_cost_type(l_ccc_id,l_a_code,0,l_new_cost,0);
8050       ELSE
8051         l_return_status := 'E';
8052         -- PK added this message as above
8053         fnd_file.put_line
8054           (fnd_file.log,'ERROR Procedure : '||procedure_name||' l_ccc_id has value NULL. Cannot proceed');
8055 
8056         RETURN;
8057       END IF;
8058 
8059     IF( l_trp_cost <> 0) AND nvl(transaction_row.fob_point,-1) = 1 THEN /* ANTHIYAG Bug#5550911 21-Sep-2006 */
8060        OPEN cur_get_default_cmpt(l_le_id, l_trp_cost);
8061        FETCH cur_get_default_cmpt  INTO l_cmpntcls_id,l_cost_analysis_code,l_cost_level,l_component_cost,l_burden_ind;
8062        CLOSE cur_get_default_cmpt;
8063 
8064        IF(l_cmpntcls_id IS NULL OR l_cost_analysis_code IS NULL) THEN
8065            fnd_file.put_line (fnd_file.log,'Procedure : '||procedure_name||' Overhead default component/analysis code in fiscal policies table is not defined. Ignoring the transportation cost');
8066        ELSE
8067           l_cost_tab(2) := SYSTEM.gmf_cost_type(l_cmpntcls_id,l_cost_analysis_code,l_cost_level,l_component_cost,l_burden_ind);
8068        END IF;
8069     END IF;
8070 
8071       l_onhand_qty := old_cost.onhand_qty + transaction_row.trans_qty;
8072 
8073       merge_costs(l_cost_tab,
8074                   0,
8075                   0,
8076                  'C'
8077                  );
8078 
8079       merge_costs(old_cost_tab,
8080                   old_cost.onhand_qty,
8081                   transaction_row.trans_qty,
8082                   'A'
8083                  );
8084       l_new_cost := new_cost.unit_cost;
8085     ELSE
8086       -- This is a new lot with new cost in the target organization
8087       IF (l_ccc_id IS NOT NULL) THEN
8088         l_onhand_qty := transaction_row.trans_qty;
8089         new_cost_tab(1) := SYSTEM.gmf_cost_type(l_ccc_id,l_a_code,0,l_new_cost,0);
8090       ELSE
8091         l_return_status := 'E';
8092         fnd_file.put_line
8093           (fnd_file.log,'ERROR Procedure : '||procedure_name||' loc2 l_ccc_id has value NULL. Cannot proceed');
8094         RETURN;
8095       END IF;
8096     END IF;
8097 
8098 
8099 
8100     create_cost_header
8101             ( transaction_row.inventory_item_id
8102             , transaction_row.lot_number
8103             , transaction_row.orgn_id
8104             , l_cost_type_id
8105             , l_new_cost
8106             , transaction_row.trans_date
8107             , l_onhand_qty
8108             , transaction_row.doc_id
8109             , transaction_row.transaction_source_type_id
8110             , transaction_row.transaction_action_id
8111             , new_cost.header_id
8112             , new_cost.unit_cost
8113             , new_cost.onhand_qty
8114             , l_return_status
8115             );
8116     IF (l_return_status = 'S') THEN
8117       FOR i IN 1..new_cost_tab.COUNT
8118       LOOP
8119         create_cost_detail
8120                    ( new_cost.header_id
8121                    , new_cost_tab(i).cost_cmpntcls_id
8122                    , new_cost_tab(i).cost_analysis_code
8123                    , 0
8124                    , new_cost_tab(i).component_cost
8125                    , 0
8126                    , l_return_status
8127                    );
8128         IF l_return_status <> 'S'
8129         THEN
8130           RETURN;
8131         END IF;
8132       END LOOP;
8133 
8134       -- create data with original transaction cost.
8135 
8136       FOR i IN 1..l_cost_tab.COUNT
8137       LOOP
8138         create_cost_detail
8139                    ( -new_cost.header_id
8140                     , l_cost_tab(i).cost_cmpntcls_id
8141                     , l_cost_tab(i).cost_analysis_code
8142                     , 0
8143                     , l_cost_tab(i).component_cost
8144                     , l_cost_tab(i).burden_ind
8145                     , l_return_status
8146                    );
8147         IF l_return_status <> 'S'
8148         THEN
8149           RETURN;
8150         END IF;
8151       END LOOP;
8152 
8153       IF l_debug_level >= l_debug_level_medium
8154       THEN
8155         fnd_file.put_line
8156                (fnd_file.log,'Procedure : '||procedure_name||' Creating cost transaction');
8157       END IF;
8158 
8159       create_material_transaction
8160               ( new_cost.header_id
8161                ,l_cost_type_id
8162                ,transaction_row.trans_date
8163                ,transaction_row.trans_qty
8164                ,transaction_row.trans_um
8165                ,new_cost.onhand_qty * new_cost.unit_cost
8166                ,transaction_row.transaction_id
8167                ,new_cost.unit_cost
8168                ,new_cost.onhand_qty  /* ANTHIYAG Bug#5550911 21-Sep-2006 */
8169                ,old_cost.unit_cost--  NULL                        --jboppana
8170                ,old_cost.onhand_qty             --NULL jboppana
8171                ,1
8172                ,transaction_row.lot_number
8173                ,l_return_status
8174               );
8175     END IF;
8176     IF l_debug_level >= l_debug_level_medium
8177      THEN
8178        fnd_file.put_line
8179        (fnd_file.log,'Leaving Procedure: '||procedure_name);
8180      END IF;
8181   END;
8182 
8183 
8184 
8185 /* Process process discrete transfers */
8186 
8187 /*=========================================================
8188   PROCEDURE : process_pd_transfers
8189 
8190   DESCRIPTION
8191     This procedure will process - discrete to process transfers
8192   AUTHOR : Sukarna Reddy  INVCONV June 2005
8193  ==========================================================*/
8194 
8195    PROCEDURE process_pd_transfer IS
8196      l_header_id NUMBER;
8197      l_trans_id NUMBER;
8198      procedure_name VARCHAR2(100);
8199    BEGIN
8200       procedure_name := 'Process Pd Transfer';
8201       IF l_debug_level >= l_debug_level_medium
8202      THEN
8203        fnd_file.put_line
8204        (fnd_file.log,'Entered Procedure: '||procedure_name);
8205      END IF;
8206 
8207      IF new_cost_tab.EXISTS(1)
8208      THEN
8209        new_cost_tab.delete;
8210      END IF;
8211 
8212      IF (( transaction_row.fob_point = FOB_SHIPPING AND
8213             transaction_row.transaction_action_id  = LOGICAL_INTRANSIT_RECEIPT
8214            )
8215            OR
8216           (transaction_row.fob_point = FOB_RECEIVING AND
8217              transaction_row.transaction_action_id  = INTRANSIT_RECEIPT
8218              )
8219            OR
8220            (
8221              transaction_row.transaction_action_id = DIRECT_ORG_TRANSFER
8222            )
8223          )
8224      THEN
8225        process_pdtxf_cost;
8226      ELSIF (transaction_row.fob_point = FOB_SHIPPING AND /*jboppana changed source_type_id to fob_point*/
8227             transaction_row.transaction_action_id = INTRANSIT_RECEIPT
8228            )
8229      THEN
8230        -- This transaction is a physical receipt and should not be costed since there is a
8231        -- Logical intransit receipt which was created earlier and costed. We need to point the cost to previous
8232        -- logical intransit receipt.
8233 
8234        SELECT transaction_id
8235          INTO l_trans_id
8236          FROM  mtl_material_transactions
8237         WHERE  transfer_transaction_id = transaction_row.transfer_transaction_id
8238          AND transaction_action_id = 15;
8239 
8240        SELECT cost_header_id
8241           INTO l_header_id
8242           FROM gmf_material_lot_cost_txns gmlc
8243          WHERE  transaction_id = l_trans_id
8244            AND lot_number = transaction_row.lot_number
8245            AND cost_type_id = l_cost_type_id;
8246 
8247        SELECT * INTO new_cost
8248           FROM  gmf_lot_costs
8249          WHERE header_id = l_header_id;
8250 
8251        create_material_transaction
8252          ( p_header_id      => l_header_id
8253           ,p_cost_type_id   => l_cost_type_id
8254           ,p_trans_date     => transaction_row.trans_date
8255           ,p_trans_qty      => transaction_row.trans_qty
8256           ,p_trans_um       => transaction_row.trans_um
8257           ,p_total_cost     => transaction_row.trans_qty * new_cost.unit_cost
8258           ,p_trans_id       => transaction_row.transaction_id
8259           ,p_unit_cost      => new_cost.unit_cost
8260           ,p_onhand_qty     => old_cost.onhand_qty
8261           ,p_old_unit_cost  => NULL
8262           ,p_old_onhand_qty => NULL
8263           ,p_new_cost_ind   => 1
8264           ,p_lot_number     => transaction_row.lot_number
8265           ,x_return_status  => l_return_status
8266          );
8267      END IF;
8268       IF l_debug_level >= l_debug_level_medium
8269      THEN
8270        fnd_file.put_line
8271        (fnd_file.log,'Leaving Procedure: '||procedure_name);
8272      END IF;
8273   EXCEPTION
8274   WHEN OTHERS THEN
8275     fnd_file.put_line(fnd_file.log,'ERROR: '||substr(sqlerrm,1,100) || ' in ' || procedure_name);
8276     l_return_status := 'E';
8277 END;
8278 
8279 
8280 
8281 --*************************************************************************************
8282 --*                                                                                   *
8283 --* This is the main procedure for the rollup, and is the only one that can be called *
8284 --* globally. It is written as a concurrent request.                                  *
8285 --*                                                                                   *
8286 --* The mandatory parameters are:                                                     *
8287 --*                                                                                   *
8288 --* p_co_code               This is used to locate costs for items that are not       *
8289 --*                         costed by lot and also to locate resource costs           *
8290 --*                                                                                   *
8291 --* p_cost_method_code      This is also used to locate item and resource costs       *
8292 --*                                                                                   *
8293 --* p_user                  This is used to tag any rows inserted or updated with     *
8294 --*                         the identity of the user (obsoleted)                      *
8295 --*                                                                                   *
8296 --* The optional parameters are:                                                      *
8297 --*                                                                                   *
8298 --* p_item_no               If specified, only this item's uncosted lots will be      *
8299 --*                         costed                                                    *
8300 --*                                                                                   *
8301 --* p_lot_no                If specified, only this the lot number belonging to the   *
8302 --*                         item specified will be costed. Note: This does not imply  *
8303 --*                         that a range of lots sharing this lot_no will be costed.  *
8304 --*                         If the lot_no exists for the item only that lot will be   *
8305 --*                         processed.                                                *
8306 --*                                                                                   *
8307 --* p_sublot_no             If specified only the lot identified by the concatenation *
8308 --*                         of p_item_no/p_lot_no/p_sublot_no will be costed          *
8309 --*                                                                                   *
8310 --* p_final_run_flag        Indicates this is a final or trial run.                   *
8311 --*                         Valid values are Y and N.                                 *
8312 --*                 								      *
8313 --* HISTORY                                                                           *
8314 --*   19-Aug-2004 Dinesh Vadivel Bug# 3831782                                         *
8315 --*        Added where clause in the queries to ignore the Lot Cost Adjustment Records*
8316 --*        which has no Detail Records(i.e., NULL Adjustment Cost)                    *
8317 --*
8318 --*    26-Nov-2004 Uday Moogala Bug# 4004338
8319 --*       Added Reverse_id in the select clause of INV_TRAN_CURSOR.
8320 --*       Also added new DECODE(...) order by clause in the INV_TRAN_CURSOR.
8321 --*
8322 --*   27-Nov-2004 Dinesh Vadivel Bug# 4004338
8323 --*      Modified the if condition to set the lot_costed_ind if it is final_run to the
8324 --*      reversal records of the product..
8325 --*      Eg : If we records as 100, -100 and 150 then during Final run we are setting
8326 --*              lot_costed_ind to 1 only for the rows 100 and 150.
8327 --*              So modified the code here to set for the -100 transaction record also.
8328 --*
8329 --*   30-Jan-2005 Dinesh Vadivel Bug# 4152397
8330 --*      Uncommented the code which fetches lot_id into l_lot_id for the lot_no
8331 --*      entered on Lot ACP screen.
8332 --*      Also, the inv_tran_cursor inside "ELSIF l_item_id IS NOT NULL .... "
8333 --*      we have filter only those LADJ transactions for that particular Lot_id if any.
8334 --*
8335 --*  24-Feb-2005 Dinesh Vadivel Bug# 4177349
8336 --*      When a batch is reversed to WIP, the Lot Cost process fails at process_reversals
8337 --*      So added check to verify the batch status before calling process_reversals
8338 --*
8339 --*   24-Feb-2005 Dinesh Vadivel Bug# 4187891
8340 --*      Cancellation of Inv Xfer has been modified such that it is considered
8341 --*      as if it is an actual transfer where the source and destination organizations are the same.
8342 --*
8343 --*   24-Feb-2005 Dinesh Vadivel Bug# 4176690
8344 --*       Added a new Date field in the Lot Cost Process Submission Screen.
8345 --*       Lot Cost Process will consider only those transactions upto this date
8346 --*
8347 --*   11-Aug-2006 Anand Thiyagarajan Bug#5460458
8348 --*       Modified code to ignore the PO receipt transactions for consigned items unless received
8349 --*       by Transfer to Regular Options. Also Modified Code to consider the Consigned inventory transactions
8350 --*   18-dec-2006 bug 5705311, Modified the select query to fetch category_id for the cost class, pmarada
8351 --*   30-Jun-2008 Bug 7215069
8352 --*      Change ordering for Receipt transactions. If transactions exist for multiple
8353 --*      document types with same transaction date then first process the receipt transactions.
8354 --*
8355 --*************************************************************************************
8356 
8357 
8358 
8359 PROCEDURE rollup_lot_costs
8360 ( errbuf            OUT NOCOPY VARCHAR2
8361 , retcode           OUT NOCOPY VARCHAR2
8362 , p_le_id   	       IN NUMBER
8363 , p_cost_type_id     IN NUMBER
8364 , p_final_run_flag   IN VARCHAR2
8365 , p_structure_id     IN NUMBER
8366 , p_category_id     IN NUMBER
8367 , p_orgn_id          IN NUMBER
8368 , p_item_id        IN NUMBER
8369 , p_lot_no           IN VARCHAR2
8370 , p_final_run_date IN VARCHAR2
8371 )
8372 IS
8373   inv_tran_cursor inv_tran_cursor_type;
8374 
8375   l_return_code  VARCHAR2(1);
8376   l_trans_date DATE;
8377   x_return_status NUMBER(1) := 0;
8378   l_source_orgn_id NUMBER;
8379   l_source_le_id NUMBER;
8380   procedure_name VARCHAR2(100);
8381 
8382   CURSOR batch_status_cursor(p_batch_id NUMBER)
8383   IS
8384   SELECT batch_status
8385   FROM gme_batch_header
8386   WHERE batch_id = p_batch_id
8387   AND ACTUAL_CMPLT_DATE <= l_final_run_date;
8388 
8389 BEGIN
8390     /* Moved various initialisations here to avoid GSCC warnings and errors */
8391 
8392     l_debug_level_none     := 0;
8393     l_debug_level_low      := 1;
8394     l_debug_level_medium   := 2;
8395     l_debug_level_high     := 3;
8396 
8397     l_tmp := TRUE;
8398 
8399     l_final_run_date := NVL(fnd_date.canonical_to_date(p_final_run_date),SYSDATE); -- Bug 4176690
8400 
8401     l_return_code  := NULL; -- Bug 3476508
8402     procedure_name := 'Rollup Lot Costs';
8403 
8404 
8405       /* uncomment the call below to write to a local file */
8406      --FND_FILE.PUT_NAMES('gmfplcrb.log','gmfplcrb.out','/appslog/opm_top/utl/opmm0dv/log');
8407     --  FND_FILE.PUT_NAMES('gmfplcrb.log','gmfplcrb.out','/slot05/oracle/opml0mtddb/9.2.0/temp');
8408 
8409       fnd_file.put_line
8410       (fnd_File.LOG,'Lot Cost Rollup v 0.1 started on '||to_char(sysdate,'DD-MON-YYYY HH24:MI:SS'));
8411 
8412       -- l_calendar_code := p_calendar_code;  umoogala - replaced with co_code
8413       --l_co_code := p_co_code;
8414       l_le_id := p_le_id;
8415       --l_cost_method_code := p_cost_method_code;
8416       l_cost_type_id := p_cost_type_id;
8417       l_cost_category_id := p_category_id;
8418       l_item_id := p_item_id;
8419       l_lot_no := p_lot_no;
8420       l_orgn_id := p_orgn_id;
8421 
8422 
8423 
8424       l_debug_level := TO_NUMBER(FND_PROFILE.VALUE( 'GMF_CONC_DEBUG' ));
8425       l_cost_alloc_profile := NVL( FND_PROFILE.VALUE('GMF_LOT_COST_ALLOC'), 0);
8426 
8427       -- umoogala 05-Dec-2003
8428       IF  p_final_run_flag = 'Y'
8429       THEN
8430         l_final_run_flag := 1;
8431       ELSE
8432         l_final_run_flag := 0;
8433       END IF;
8434 
8435       -- l_user := p_user;  umoogala - replaced with the following:
8436       l_user_id := FND_PROFILE.VALUE('USER_ID');
8437 
8438       SELECT user_name INTO l_user
8439       FROM   fnd_user
8440       WHERE  user_id = l_user_id;
8441 
8442       -- Initialize WHO columns -- umoogala 05-DEC-2003
8443       l_login_id      := FND_GLOBAL.LOGIN_ID;
8444       l_prog_appl_id  := FND_GLOBAL.PROG_APPL_ID;
8445       l_program_id    := FND_GLOBAL.CONC_PROGRAM_ID;
8446       l_request_id    := FND_GLOBAL.CONC_REQUEST_ID;
8447 
8448 
8449     /* INVCONV sschinch Modified for convergence */
8450 
8451       SELECT m1.default_lot_cost_type_id
8452            , m1.trans_start_date
8453            , m1.cost_mthd_code
8454            , m2.cost_mthd_code
8455       INTO   l_default_cost_type_id,
8456              l_trans_start_date,
8457              l_cost_mthd_code,
8458              l_default_cost_mthd
8459       FROM   cm_mthd_mst m1,
8460              cm_mthd_mst m2
8461       WHERE  m1.cost_type_id = l_cost_type_id
8462       AND    m2.cost_type_id = m1.default_lot_cost_type_id;
8463 
8464 
8465      /******** Bug  4038722 - Dinesh Vadivel - Start **********/
8466      /*Get the Base Currency for the company. Later if needed check whether the unit cost is in
8467       the base currency and if not, convert it to the base currency */
8468      /* INVCONV sschinch */
8469       SELECT base_currency_code
8470       INTO l_base_ccy_code
8471       FROM gmf_fiscal_policies
8472       WHERE legal_entity_id = l_le_id;
8473 
8474 
8475       /******** Bug  4038722 - Dinesh Vadivel - End**********/
8476 
8477 
8478       fnd_file.put_line(fnd_file.log,'Parameters for this run are:');
8479       fnd_file.put_line(fnd_file.log,'Legal Entity Id    = '||p_le_id);
8480       fnd_file.put_line(fnd_file.log,'Cost Type = '||l_cost_mthd_code);
8481       fnd_file.put_line(fnd_file.log,'Default Cost Type = '||l_default_cost_mthd);
8482       fnd_file.put_line(fnd_file.log,'Rate Type Code   = '||l_rate_type_code);
8483       fnd_file.put_line(fnd_file.log,'Base Currency Code   = '||l_base_ccy_code);
8484       fnd_file.put_line(fnd_file.log,'trans start date = '||l_trans_start_date);
8485       fnd_file.put_line(fnd_file.log,'Item Category Id  = '||p_category_id);
8486       fnd_file.put_line(fnd_file.log,'Item Id      = '||p_item_id);
8487       fnd_file.put_line(fnd_file.log,'Lot Number       = '||p_lot_no);
8488       --fnd_file.put_line(fnd_file.log,'Sub-Lot Number   = '||p_sublot_no);
8489       fnd_file.put_line(fnd_file.log,'Debug Level      = '||to_char(l_debug_level));
8490       fnd_file.put_line(fnd_file.log,'User             = '||l_user);
8491       fnd_file.put_line(fnd_file.log,'Final Date = '||to_char(l_final_run_date,'DD-MON-YYYY HH24:MI:SS'));
8492       fnd_file.put_line(fnd_file.log,'Final Run?       = '|| p_final_run_flag);
8493       fnd_file.put_line(fnd_file.log,'Cost Alloc Factor Profile   = '|| l_cost_alloc_profile);
8494 
8495       -- BUG 3476427
8496       -- If this is a final run, and the user has entered limiting parameters then
8497       -- let them know that they will be ignored.
8498 
8499       IF  l_final_run_flag = 1
8500       AND
8501       (   p_category_id IS NOT NULL
8502        OR p_item_id IS NOT NULL
8503        OR p_lot_no IS NOT NULL
8504        OR p_orgn_id IS NOT NULL
8505       )
8506       THEN
8507         fnd_file.put_line
8508         ( fnd_file.log, 'WARNING : Rollup submitted in final mode, limiting parameters will be ignored');
8509 
8510         l_cost_category_id := NULL;
8511         l_item_id := NULL;
8512         l_lot_no := NULL;
8513         l_orgn_id := NULL;
8514         l_tmp := FALSE;
8515       ELSE
8516         IF   p_item_id IS NOT NULL AND p_category_id IS NOT NULL
8517         THEN
8518           fnd_file.put_line
8519           ( fnd_file.log, 'WARNING : Cost Category and item have both been specified, item will be used');
8520           l_cost_category_id := NULL;
8521           l_tmp := FALSE;
8522         END IF;
8523       END IF;
8524 
8525 
8526        -- There are two possibilities for the costing. A lot might be manufactured
8527       -- or bought in. Occasionally a lot might be bought in and later added to by a
8528       -- production batch or vice versa. No matter how the lot is created and/or replenished
8529       -- the sole criterion to decide whether to cost an item's lots using lot costing will
8530       -- be an entry for the item, or its cost_class, in gmf_lot_costed_items
8531 
8532       -- In the case of a lot that is an output of a production batch, we need
8533       -- to explode it and find out what lots went into its manufacture.
8534 
8535       -- If the lot is not from a production batch, then there is no explosion.
8536 
8537       -- In either case, once we have all the transactions that we need, we just have
8538       -- to work through them. The transactions are ordered by date and then by type and
8539       -- if transactions have been back-dated the algorithm will work, but might produce
8540       -- a wrong answer.
8541 
8542       -- For each replenishment we must add a new row to (or update the existing
8543       -- row in) GMF_LOT_COSTS, add new rows to (or update the existing rows in)
8544       -- GMF_LOT_COST_DETAILS and finally create a row in GMF_LOT_COST_TRANSACTIONS
8545       -- that links the inventory transaction to the row in GMF_LOT_COSTS.
8546 
8547       -- For each consumption we leave the GMF_LOT_COSTS and GMF_LOT_COST_DETAILS
8548       -- rows alone and just create the GMF_LOT_COST_TRANSACTIONS row.
8549 
8550       --
8551       -- umoogala 21-Nov-2003
8552       -- The reason for not using BULK COLLECT is, I want the table to be
8553       -- indexed by item_id so that I can easily lookup.
8554       --
8555 
8556       IF l_item_id IS NOT NULL
8557       THEN
8558          BEGIN
8559                 -- modified the query for bug 5705311, pmarada
8560                SELECT 		mic.category_id
8561          	   INTO 		l_cost_category_id
8562                FROM 		mtl_default_category_sets mdc,
8563                      		mtl_category_sets mcs,
8564                           	mtl_item_categories mic,
8565                           	mtl_categories mc
8566                  WHERE 		mic.inventory_item_id = l_item_id
8567                  AND 		mic.organization_id = l_orgn_id
8568                  AND 		mic.category_id = mc.category_id
8569                  AND 		mcs.structure_id = mc.structure_id
8570                  AND 		mdc.functional_area_id = 19
8571          	     AND     	mcs.category_set_id = mic.category_set_id
8572          	     AND     	mcs.category_set_id = mdc.category_set_id;
8573 
8574          EXCEPTION
8575           when NO_DATA_FOUND then
8576              l_cost_category_id := NULL;
8577          END;
8578       END IF;
8579 
8580             -- PK Bug 6822310 always make l_orgn_id as NULL.
8581       IF l_final_run_flag = 0 AND p_orgn_id IS NOT NULL THEN
8582          fnd_file.put_line
8583         ( fnd_file.log, 'WARNING : Lot cost process should consider all lot transactions. Setting l_orgn_id to NULL');
8584         l_orgn_id := NULL;
8585       END IF;
8586 
8587        /* INVCONV sschinch Load Lot costed items and process organizations */
8588            Load_Lot_Costed_Items_gt(p_le_id        => l_le_id,
8589                                    p_orgn_id      => l_orgn_id,
8590                                    p_item_id      => l_item_id,
8591                                    p_category_id  => l_cost_category_id,
8592                                    x_return_status => x_return_status
8593                                   );
8594          IF (x_return_status <> 0) THEN
8595            fnd_file.put_line
8596           (fnd_file.log,'ERROR Procedure : '||procedure_name||' Load_Lot_Costed_Items_gt returned error. Cannot proceed');
8597            l_return_status := 'E';
8598            RETURN;
8599          END IF;
8600 
8601       /* FOR Cur_lc_items IN lot_costed_items (l_co_code, l_cost_method_code) INVCONV sshinch*/
8602       /* sschinch INVCONV indexed by organization id and item id */
8603       FOR Cur_lc_items IN lot_costed_items
8604       LOOP
8605 	      lc_items_tab(Cur_lc_items.inventory_item_id||'-'||cur_lc_items.organization_id) := Cur_lc_items.inventory_item_id;
8606       END LOOP;
8607 
8608 
8609       -- umoogala 05-Dec-2003
8610       -- remove rows from previous trial run.
8611       fnd_file.put_line(fnd_File.LOG, 'Removing rows of previous trial run.');
8612       delete_lot_costs;
8613 
8614       fnd_file.put_line(fnd_File.LOG,'Reading uncosted transactions');
8615 
8616 
8617       -- Cursors to retrieve all transactions for items that are costed by lot
8618       -- that have not yet been processed. The above type is used to store the
8619       -- rows that are returned. There are several cursors depending on how the
8620       -- user has launched the rollup:
8621       --
8622       -- A full rollup will retrieve all transactions for all items/cost classes
8623       -- listed in the gmf_lot_costed_items table. Note that this retrieval will not
8624       -- possess a date range.
8625       --
8626       -- An item-specific rollup will only retrieve transactions for the item specified.
8627       -- If the item has a date range in the gmf_lot_costed_items table this will be
8628       -- used. This option also allows a user to specify an optional lot and sublot.
8629       --
8630       -- A cost class-specific rollup will only retrieved transactions for items in the
8631       -- cost class specified. If the cost class possesses a date range in gmf_lot_costed_items
8632       -- this will be used.
8633 
8634 
8635       --
8636       -- umoogala: replaced itemcost_class with cost_category_id and
8637       -- l_cost_class with l_cost_category_id.
8638       -- Also, added lot_ctl = 1 condition
8639       -- to where clause
8640       --
8641 
8642       -- Since the cursors below were written, a new column (co_code) has been added to the gmf_lot_costed_items table
8643       -- with the result that it is now possible to have rows differing only in this column.
8644 
8645       -- Cursors now possess a third branch that is 'union all'd' into the result set to retrieve the lot cost
8646       -- adjustments. These are disguised as transactions of type LADJ.
8647 
8648     -- Open a cursor that retrieves every uncosted lot costed item's transactions
8649 	  --
8650 	  -- umoogala: replaced itemcost_class with cost_category_id
8651 	  --
8652   /* INVCONV sschinch. Removed all queries and recreated a single query to handle all situations */
8653   OPEN inv_tran_cursor FOR
8654       SELECT * from
8655              (SELECT
8656                      mmt.transaction_source_id  as doc_id,
8657                      mmt.transaction_source_type_id,
8658                      mmt.inventory_item_id,
8659                      mmt.trx_source_line_id,
8660                      NVL(gme.line_type,0) as line_type,
8661                      mtln.lot_number,
8662                      mmt.transaction_date as trans_date,
8663                      mmt.transaction_id as transaction_id,
8664                      mtln.primary_quantity as trans_qty,
8665                      lcig.primary_uom_code as trans_um,
8666                      mmt.organization_id,
8667                      1 source,
8668                      nvl(gtp.transaction_id2,NULL) as reverse_id,
8669                      mmt.transaction_action_id,
8670                      nvl(mmt.transfer_price,0),
8671                      nvl(mmt.transportation_cost,0),
8672                      mmt.fob_point,
8673                      mmt.transfer_transaction_id,
8674                      NVL(mmt.transaction_cost,0),
8675                      mmt.transfer_organization_id
8676                    FROM mtl_material_transactions mmt,
8677                         gme_material_details gme,
8678                         mtl_transaction_lot_numbers mtln,
8679                         gme_transaction_pairs gtp,
8680                         gmf_process_organizations_gt gpo,
8681                         gmf_lot_costed_items_gt lcig
8682                    WHERE
8683                          gpo.organization_id = mmt.organization_id
8684                    AND   mmt.transaction_date >= NVL(l_trans_start_date, mmt.transaction_date)
8685                    AND   mmt.transaction_date <= l_final_run_date
8686                    AND   mmt.trx_source_line_id = gme.material_detail_id
8687                    AND   mmt.transaction_id = gtp.transaction_id1 (+)
8688                    AND   mmt.transaction_id = mtln.transaction_id
8689                    AND   mmt.organization_id = NVL(l_orgn_id,mmt.organization_id)
8690                    AND   mmt.inventory_item_id = lcig.inventory_item_id
8691                    AND   mmt.organization_id   = lcig.organization_id
8692                    AND  mmt.transaction_source_type_id = 5
8693                    AND   mtln.lot_number = nvl(p_lot_no,mtln.lot_number)
8694                    AND  NOT EXISTS (SELECT 1
8695                                     FROM GMF_MATERIAL_LOT_COST_TXNS gmlct
8696                                    WHERE gmlct.transaction_id = mmt.transaction_id /* ANTHIYAG Bug#5285726 07-Jun-2006 */
8697                                    AND   gmlct.cost_type_id = l_cost_type_id
8698                                    AND   gmlct.lot_number  = mtln.lot_number
8699                                    AND   gmlct.final_cost_flag = 1)
8700                  UNION ALL
8701                  SELECT
8702                      mmt.transaction_source_id  as doc_id,
8703                      mmt.transaction_source_type_id,
8704                      mmt.inventory_item_id,
8705                      mmt.trx_source_line_id,
8706                      0 as line_type,
8707                      mtln.lot_number,
8708                      mmt.transaction_date as trans_date,
8709                      mmt.transaction_id as transaction_id,
8710                      mtln.primary_quantity as trans_qty,
8711                      lcig.primary_uom_code as trans_um,
8712                      mmt.organization_id,
8713                      2 source,
8714                      NULL as reverse_id,
8715                      mmt.transaction_action_id,
8716                      nvl(mmt.transfer_price,0),
8717                      nvl(mmt.transportation_cost,0),
8718                      mmt.fob_point,
8719                      mmt.transfer_transaction_id,
8720                      NVL(mmt.transaction_cost,0),
8721                      mmt.transfer_organization_id
8722                    FROM mtl_material_transactions mmt,
8723                         mtl_transaction_lot_numbers mtln,
8724                         gmf_process_organizations_gt gpo,
8725                         gmf_lot_costed_items_gt lcig
8726                    WHERE
8727                          gpo.organization_id = mmt.organization_id
8728                    AND   mmt.transaction_date >= NVL(l_trans_start_date, mmt.transaction_date)
8729                    AND   mmt.transaction_date <= l_final_run_date
8730                    AND   mmt.transaction_id = mtln.transaction_id
8731                    AND   mmt.organization_id = NVL(l_orgn_id,mmt.organization_id)
8732                    AND   mmt.inventory_item_id = lcig.inventory_item_id
8733                    AND   mmt.organization_id   = lcig.organization_id
8734                    AND   mmt.organization_id = NVL(mmt.owning_organization_id, mmt.organization_id) /* ANTHIYAG Bug#5460458 11-Aug-2006 */
8735                    AND   NVL(mmt.owning_tp_type,2) = 2                                              /* ANTHIYAG Bug#5460458 11-Aug-2006 */
8736                    AND   mmt.transaction_source_type_id <> 5
8737                    AND   mmt.transaction_action_id NOT IN (15,22,6,2) /* PK added subinv Xfer */
8738                    AND   mtln.lot_number = nvl(p_lot_no,mtln.lot_number)
8739                    AND   NOT EXISTS (SELECT 1
8740                                     FROM GMF_MATERIAL_LOT_COST_TXNS gmlct
8741                                    WHERE gmlct.transaction_id = mmt.transaction_id /* ANTHIYAG Bug#5285726 07-Jun-2006 */
8742                                    AND   gmlct.cost_type_id = l_cost_type_id
8743                                    AND   gmlct.lot_number  = mtln.lot_number
8744                                    AND   gmlct.final_cost_flag = 1)
8745                 UNION ALL
8746                   SELECT
8747                      mmt.transaction_source_id  as doc_id,
8748                      mmt.transaction_source_type_id,
8749                      mmt.inventory_item_id,
8750                      mmt.trx_source_line_id,
8751                      0 as line_type,
8752                      mtln.lot_number,
8753                      mmt.transaction_date as trans_date,
8754                      mmt.transaction_id as transaction_id,
8755                      mtln.primary_quantity as trans_qty,
8756                      lcig.primary_uom_code as trans_um,
8757                      mmt.organization_id,
8758                      2 source,
8759                      NULL as reverse_id,
8760                      mmt.transaction_action_id,
8761                      nvl(mmt.transfer_price,0),
8762                      nvl(mmt.transportation_cost,0),
8763                      mmt.fob_point,
8764                      mmt.transfer_transaction_id,
8765                      NVL(mmt.transaction_cost,0),
8766                      mmt.transfer_organization_id
8767                    FROM mtl_material_transactions mmt,
8768                         mtl_transaction_lot_numbers mtln,
8769                         gmf_process_organizations_gt gpo,
8770                         gmf_lot_costed_items_gt lcig
8771                    WHERE
8772                          gpo.organization_id = mmt.owning_organization_id
8773                    AND   mmt.transaction_date >= NVL(l_trans_start_date, mmt.transaction_date)
8774                    AND   mmt.transaction_date <= l_final_run_date
8775                    AND   mmt.owning_tp_type    = 2
8776                    AND   mmt.transaction_id = mtln.transaction_id
8777                    AND   mmt.owning_organization_id = NVL(l_orgn_id,mmt.owning_organization_id)
8778                    AND   mmt.transaction_source_type_id = 1
8779                    AND   mmt.transaction_action_id = 6
8780                    AND   mmt.inventory_item_id = lcig.inventory_item_id
8781                    AND   mmt.organization_id   = lcig.organization_id
8782                    AND   mtln.lot_number = nvl(p_lot_no,mtln.lot_number)
8783                    AND  NOT EXISTS (SELECT 1
8784                                     FROM GMF_MATERIAL_LOT_COST_TXNS gmlct
8785                                    WHERE gmlct.transaction_id = mmt.transaction_id /* ANTHIYAG Bug#5285726 07-Jun-2006 */
8786                                    AND   gmlct.cost_type_id = l_cost_type_id
8787                                    AND   gmlct.lot_number  = mtln.lot_number
8788                                    AND   gmlct.final_cost_flag = 1)
8789                   UNION ALL  /*sschinch INVCONV this query will pickup logical shipments and receipts */
8790                     SELECT
8791                      mmt.transaction_source_id  as doc_id,
8792                      mmt.transaction_source_type_id,
8793                      mmt.inventory_item_id,
8794                      mmt.trx_source_line_id,
8795                      0 as line_type,
8796                      mtln.lot_number,
8797                      mmt.transaction_date as trans_date,
8798                      mmt.transaction_id as transaction_id,
8799                      mtln.primary_quantity as trans_qty,
8800                      lcig.primary_uom_code as trans_um,
8801                      mmt.organization_id,
8802                      2 source,
8803                      NULL as reverse_id,
8804                      mmt.transaction_action_id,
8805                      nvl(mmt.transfer_price,0),
8806                      nvl(mmt.transportation_cost,0),
8807                      mmt.fob_point,
8808                      mmt.transfer_transaction_id,
8809                      NVL(mmt.transaction_cost,0),
8810                      mmt.transfer_organization_id
8811                    FROM mtl_material_transactions mmt,
8812                         mtl_transaction_lot_numbers mtln,
8813                         gmf_process_organizations_gt gpo,
8814                         gmf_lot_costed_items_gt lcig
8815                    WHERE
8816                          gpo.organization_id = mmt.organization_id
8817                    AND   mmt.transaction_date >= NVL(l_trans_start_date, mmt.transaction_date)
8818                    AND   mmt.transaction_date <= l_final_run_date
8819                    AND   mmt.transfer_transaction_id = mtln.transaction_id
8820                    AND   mmt.organization_id = NVL(l_orgn_id,mmt.organization_id)
8821                    AND   mmt.inventory_item_id = lcig.inventory_item_id
8822                    AND   mmt.organization_id   = lcig.organization_id
8823                    AND   mmt.transaction_source_type_id IN (8,7,13)
8824                    AND   mmt.transaction_action_id IN (15,22)
8825                    AND   mtln.lot_number = nvl(p_lot_no,mtln.lot_number)
8826                    AND   NOT EXISTS (SELECT 1
8827                                      FROM GMF_MATERIAL_LOT_COST_TXNS gmlct
8828                                      WHERE gmlct.transaction_id = mmt.transaction_id /* ANTHIYAG Bug#5285726 07-Jun-2006 */
8829                                      AND   gmlct.cost_type_id = l_cost_type_id
8830                                      AND   gmlct.lot_number  = mtln.lot_number
8831                                      AND   gmlct.final_cost_flag = 1)
8832                  UNION ALL
8833                    SELECT
8834                      glca.adjustment_id doc_id,
8835                      0 transaction_source_type_id,
8836                      glca.inventory_item_id,
8837                      glca.adjustment_id line_id,
8838                      0 as line_type ,
8839                      glca.lot_number ,
8840                      glca.adjustment_date trans_date ,
8841                      -9 transaction_id,
8842                      0  trans_qty,
8843                      iimb.primary_uom_code trans_um,
8844                      glca.organization_id,
8845                      3 source,
8846                      NULL as reverse_id,
8847                      0 as transaction_action_id,
8848                      0 as transfer_price,
8849                      0 as transportation_cost,
8850                      0 as fob_point,
8851                      0 as transfer_transaction_id,
8852                      0 as transaction_cost,
8853                      0 as transfer_transaction_id
8854                    FROM  gmf_lot_cost_adjustments glca,
8855                          mtl_system_items_b iimb,
8856                          gmf_lot_costed_items_gt glci
8857                    WHERE glca.applied_ind       = 'N'
8858                    AND   glca.adjustment_date  >= NVL(l_trans_start_date, glca.adjustment_date)
8859                    AND   glca.legal_entity_id   = l_le_id
8860                    AND   glca.cost_type_id      = l_cost_type_id
8861                    AND   glca.delete_mark       = 0
8862                    AND   iimb.inventory_item_id = glca.inventory_item_id
8863                    AND   glca.organization_id   = iimb.organization_id
8864                    AND   glca.organization_id   = NVL(l_orgn_id,glca.organization_id)
8865                    AND   glca.inventory_item_id = glci.inventory_item_id
8866                    AND   glca.organization_id   = glci.organization_id
8867                    AND   glca.adjustment_date   <= l_final_run_date
8868                    AND   glca.lot_number = nvl(p_lot_no,glca.lot_number)
8869                   AND EXISTS
8870                        (SELECT 1 FROM gmf_lot_cost_adjustment_dtls
8871                         WHERE adjustment_id = glca.adjustment_id
8872                         AND   delete_mark = 0
8873                        )
8874                 )
8875                 --ORDER BY 7,2,5  /*Bug 7215069 - Changed ordering for Receipt into Stores*/
8876                   ORDER BY 7,decode(transaction_action_id,27,-1,transaction_source_type_id),5
8877                   ,DECODE(line_type,1, DECODE((ABS(DECODE(trans_qty, 0, 1,trans_qty))/DECODE(trans_qty, 0, 1, trans_qty)),
8878                   1, transaction_id ,
8879                   DECODE(reverse_id, NULL, transaction_id, reverse_id+.5)),transaction_id)
8880               ;
8881       FETCH inv_tran_cursor INTO transaction_row;
8882       WHILE inv_tran_cursor%FOUND
8883       LOOP
8884 
8885         SAVEPOINT inv_tran;
8886 
8887         /* Reset the profile variable to the correct one in every loop*/
8888         l_cost_alloc_profile := NVL( FND_PROFILE.VALUE('GMF_LOT_COST_ALLOC'), 0);
8889 
8890         IF ( transaction_row.fob_point = FOB_SHIPPING AND
8891             transaction_row.transaction_action_id  = LOGICAL_INTRANSIT_RECEIPT
8892            )
8893         THEN
8894           /*here transaction_row.trans_qty  will be negative as we take the value from the source org in the inv trans cursor
8895            making the qunatity as positive as we know that this is a receipt and the qunatity will be positive*/
8896           transaction_row.trans_qty := abs(transaction_row.trans_qty);
8897         END IF;
8898 
8899 
8900         -- Forget all data from last time round
8901 
8902         old_cost := NULL;
8903         IF old_cost_tab.exists(1) THEN old_cost_tab.delete; END IF;
8904         IF new_cost_tab.exists(1) THEN new_cost_tab.delete; END IF;
8905         IF l_burdens_tab.exists(1) THEN l_burdens_tab.delete; END IF;
8906         IF l_acqui_cost_tab.exists(1) THEN l_acqui_cost_tab.delete; END IF;
8907 
8908         IF   l_debug_level >= l_debug_level_high
8909         THEN
8910           fnd_file.put_line
8911           (fnd_file.log,'Inside inv_tran_cursor, inventory_item_id = ' || transaction_row.inventory_item_id ||
8912 	  		' lot_number = '||transaction_row.lot_number ||
8913 	  		' orgn = '||l_org_tab(transaction_row.orgn_id) ||
8914 	  		' transaction_id = '||to_char(transaction_row.transaction_id) ||
8915 	  		' reverse_id = '||to_char(transaction_row.reverse_id) ||
8916 	  		' trans_date = '||to_char(transaction_row.trans_date, 'DD-MON-YYYY HH24:MI:SS') ||
8917 			  ' doc type = '||transaction_row.transaction_source_type_id ||
8918            ' action type = '||transaction_row.transaction_action_id ||
8919 			  ' Qty = ' || transaction_row.trans_qty ||
8920 				' ' || transaction_row.trans_um ||
8921 			' source = ' || transaction_row.source ||
8922            ' transfer orgn id = ' || transaction_row.transfer_orgn_id ||
8923            ' line id = ' || transaction_row.line_id);
8924           fnd_file.put_line
8925           (fnd_File.LOG,'Loading existing cost for lot_id '||to_char(transaction_row.lot_number)||' in organization '
8926          		||l_org_tab(transaction_row.orgn_id));
8927         END IF;
8928 
8929          -- Bug 4130869 Added Date field as NULL.. Because, the Date field has no significance here.
8930          -- We have to delete all the records irrespective of trans_date.
8931         /* INVCONV sschinch Commented to replace parameters
8932           OPEN  lot_cost_cursor (transaction_row.whse_code, transaction_row.inventory_item_id, transaction_row.lot_id,NULL);
8933         */
8934         /* INVCONV sschinch */
8935         l_lot_number := transaction_row.lot_number;
8936 
8937         OPEN lot_cost_cursor(transaction_row.orgn_id,
8938                              transaction_row.inventory_item_id,
8939                              transaction_row.lot_number,
8940                              NULL,
8941                              l_cost_type_id);
8942         FETCH lot_cost_cursor INTO old_cost;
8943 
8944         IF lot_cost_cursor%FOUND
8945         THEN
8946           IF   l_debug_level >= l_debug_level_high
8947           THEN
8948             fnd_file.put_line
8949             (fnd_file.log,'Reading existing costs for header ID '||old_cost.header_id);
8950           END IF;
8951 
8952           OPEN  lot_cost_detail_cursor (old_cost.header_id);
8953           FETCH lot_cost_detail_cursor BULK COLLECT INTO old_cost_tab;
8954           CLOSE lot_cost_detail_cursor;
8955         ELSE
8956           old_cost.onhand_qty := 0;
8957         END IF;
8958 
8959         CLOSE lot_cost_cursor;
8960 
8961         IF old_cost_tab.EXISTS(1)
8962         THEN
8963           IF   l_debug_level >= l_debug_level_high
8964           THEN
8965             fnd_file.put_line
8966                 (fnd_file.log,'Lot Cost before this transaction is '||to_char(old_cost.unit_cost,'999999999.99'));
8967           END IF;
8968         ELSE
8969             /* Bug 4227784 - This has to be moved up. We can have a case, where we have header
8970                but not details. So old_cost_tab can be null, even though old_cost has some record.
8971                In that case, we should not initialize onhand_qty to zero*/
8972                 --  old_cost.onhand_qty := 0;
8973           IF   l_debug_level >= l_debug_level_high
8974           THEN
8975              fnd_file.put_line(fnd_file.log,'Previous cost was NULL');
8976           END IF;
8977         END IF;
8978 
8979           IF   l_debug_level >= l_debug_level_high
8980           THEN
8981             fnd_file.put_line(fnd_file.log,' Checking if the Current Lot '||transaction_row.lot_number||' is Costable ?');
8982 
8983           END IF;
8984 
8985         /*IF NOT l_uncostable_lots_tab.EXISTS(transaction_row.lot_id)*/
8986         /*IF is_lot_costable(transaction_row.orgn_id,transaction_row.inventory_item_id,transaction_row.lot_number) IS NOT NULL*/
8987        IF NOT l_uncostable_lots_tab.EXISTS(transaction_row.orgn_id||'-'||transaction_row.inventory_item_id||'-'||transaction_row.lot_number)
8988         THEN
8989            IF   l_debug_level >= l_debug_level_high
8990            THEN
8991                fnd_file.put_line(fnd_file.log,' Yes. Current Lot '||transaction_row.lot_number||' is Costable.');
8992            END IF;
8993 
8994            --
8995 	        -- umoogala: replaced CASE stmt with IF..ELSE..END IF
8996 	        -- CASE stmt is not supported in 8i Db
8997 	        --
8998           -- If the onhand balance for this lot is negative before this transaction is processed
8999           -- we have to process it differently.
9000           -- If the onhand balance will still be negative (or 0) after this transaction has been
9001           -- processed, we simply treat this as an adjustment at the curent cost. Transactions that
9002           -- flip the balance positive are treated as if they had been split into two quantities. The
9003           -- first of which updates the balance to zero at the old cost. The residue of the trans_qty
9004           -- is then used to create a new cost. The 'feature' though is that the new cost is created as
9005           -- the entire quantity has been used in the calculations but the onhand it is set against is
9006           -- the difference beween the old and new quantities. Got that?
9007 
9008           l_residual_qty := old_cost.onhand_qty + transaction_row.trans_qty;
9009 
9010           IF   old_cost.onhand_qty < 0
9011           AND  l_residual_qty <= 0
9012           THEN
9013              fnd_file.put_line(fnd_file.log,' 3');
9014             IF   l_debug_level >= l_debug_level_high
9015             THEN
9016               fnd_file.put_line
9017               (fnd_file.log,'Onhand balance is currently -ve and will remain -ve. Processing txn as an ADJI');
9018             END IF;
9019 
9020             process_adjustment;
9021 
9022           ELSE
9023             IF  old_cost.onhand_qty < 0
9024             AND  l_residual_qty > 0
9025             THEN
9026 
9027               IF   l_debug_level >= l_debug_level_high
9028               THEN
9029                 fnd_file.put_line
9030                 (fnd_file.log,'Onhand balance is currently -ve and will go +ve. Clearing old balance to zero');
9031               END IF;
9032 
9033               old_cost.onhand_qty := 0;
9034             ELSE
9035               IF   l_debug_level >= l_debug_level_high
9036               THEN
9037                 fnd_file.put_line
9038                 (fnd_file.log,'Onhand balance is currently +ve. Processing normally');
9039               END IF;
9040 
9041               l_residual_qty := transaction_row.trans_qty;
9042             END IF;
9043 
9044             /*IF transaction_row.transaction_source_type_id = 'PORC'*/
9045             IF (transaction_row.transaction_source_type_id IN (INTERNAL_REQ,INTERNAL_ORDER,INVENTORY)
9046                 AND transaction_row.transaction_action_id IN (INTRANSIT_RECEIPT,LOGICAL_INTRANSIT_RECEIPT)
9047                )
9048             THEN
9049                   SELECT decode(mp.process_enabled_flag,'N',1,0)
9050                   INTO l_flg_ind
9051                   FROM mtl_parameters mp
9052                   WHERE mp.organization_id = transaction_row.transfer_orgn_id;
9053 
9054               IF (l_flg_ind = 0) THEN
9055                 process_receipt;
9056               ELSE
9057                 process_pd_transfer;
9058               END IF;
9059 
9060             ELSIF ( transaction_row.transaction_source_type_id = PURCHASE_ORDER  -- jboppana
9061                     AND transaction_row.transaction_action_id = RECEIPT_INTO_STORES)
9062             THEN
9063                  process_receipt;
9064             /*ELSIF transaction_row.doc_type = 'PROD' INVCONV sshchinch*/
9065             ELSIF (transaction_row.transaction_source_type_id = BATCH)
9066             THEN
9067 
9068                 OPEN batch_status_cursor(transaction_row.doc_id);
9069                 FETCH batch_status_cursor INTO l_batch_status;
9070                 IF( batch_status_cursor % NOTFOUND) THEN
9071                   l_batch_status := 0;
9072                 END IF;
9073                 CLOSE batch_status_cursor;
9074 
9075 
9076                 IF (transaction_row.line_type IN (-1,2))
9077                 THEN
9078                   process_adjustment;
9079 
9080                 ELSIF transaction_row.line_type = 1       /* Bug 4004338 Uday Moogala - Added */
9081                    AND   transaction_row.trans_qty < 0
9082                    AND   transaction_row.reverse_id IS NOT NULL
9083                 THEN
9084 
9085                   -- If PROD and reversal, then see if there are any txns between the
9086                   -- original yeild and this reversal. If there is none, then we'll
9087                   -- create new header and details row(s) with unit cost prior to the
9088                   -- original yield. Set it to zero, if there are no prior costs.
9089                     process_reversals2;
9090 
9091                 ELSE
9092 
9093                 -- This is a product line of some kind. If the batch has been uncertified the usually positive
9094                 -- transaction quantity will be negative. This is similar to a PO return.
9095 
9096                 -- The costs come from both standard and lot-costed items, together with any resource costs
9097                 -- and burdens. If the lot being yielded does not have a cost in this organization, the procedure
9098                 -- will set them up.
9099 
9100                 -- If there is already a cost for this lot and organization then the costs will be updated
9101                 -- by averaging the new cost with the old cost by using the original and revised quantities.
9102 
9103                 /****** Bug 4177349 - Start ******/
9104 
9105                 --The Status as on Final Date is Completed . So Process Normally through process_batch*/
9106                 IF l_batch_status IN (3,4)  THEN
9107                   process_batch;
9108                 ELSE  /* The Status as on Final Date is not completed. So copy the previous cost for this record or 0$ */
9109                   IF   l_debug_level >= l_debug_level_high
9110                   THEN
9111                     fnd_file.put_line(fnd_file.log,' The Current Batch status is not 3 or 4 ');
9112                   END IF;
9113                   process_wip_batch;
9114                 END IF;
9115 
9116                 IF l_step_tab.EXISTS(1)
9117                 THEN
9118                    l_step_tab.DELETE;
9119                 END IF;
9120               END IF;
9121               /* Consigned Inventory Transfer to Regular*/
9122             ELSIF (transaction_row.transaction_source_type_id = PURCHASE_ORDER
9123                    AND transaction_row.transaction_action_id = OWNERSHIP_TRANSFER
9124                    AND transaction_row.transaction_cost > 0
9125                    AND transaction_row.trans_qty >= 0
9126                   )
9127               THEN
9128                 process_consigned_inventory;
9129             ELSIF (transaction_row.transaction_source_type_id
9130                         IN (ACCOUNT,ACCOUNT_ALIAS,
9131                             CYCLE_COUNT,
9132                             PHYSICAL_INVENTORY,
9133                             INVENTORY,
9134                             MOVE_ORDER)            -- B 6859710 Added MOVE_ORDER
9135                      AND transaction_row.transaction_action_id IN (ISSUE_FROM_STORES,
9136                                                                  CYCLE_COUNT_ADJUSTMENT,
9137                                                                  RECEIPT_INTO_STORES)
9138                   )
9139            THEN
9140              -- Because of the way that creations and adjustments can be entered there might
9141              -- or might not be a cost already. If there is a cost treat all such transactions
9142              -- as adjustments. If there isn't one treat them as creations
9143 
9144              IF old_cost_tab.EXISTS(1)
9145              THEN
9146                process_adjustment;
9147              ELSE
9148                process_creation;
9149              END IF;
9150               /*ELSIF transaction_row.doc_type IN ('TRNI','TRNR')*/
9151            ELSIF (transaction_row.transaction_source_type_id IN (INTERNAL_ORDER,INTERNAL_REQ,INVENTORY) AND
9152                   transaction_row.transaction_action_id = DIRECT_ORG_TRANSFER AND
9153                   transaction_row.trans_qty > 0
9154                  )THEN
9155             /* INVCONV sschinch */
9156             SELECT  transfer_organization_id,
9157                     hoi.org_information2
9158               INTO l_source_orgn_id,
9159                    l_source_le_id
9160               FROM   mtl_material_transactions mmt,
9161                      hr_organization_information hoi
9162              WHERE  mmt.transaction_id = transaction_row.transaction_id
9163                   AND hoi.organization_id = mmt.transfer_organization_id
9164                   AND hoi.org_information_context = 'Accounting Information';
9165                 /*  INVCONV sschinch
9166                   INVCONV sschinchIF l_source_whse_code <> l_target_whse_code
9167                   THEN
9168                 */
9169 
9170                 SELECT decode(mp.process_enabled_flag,'N',1,0)
9171                   INTO l_flg_ind
9172                   FROM mtl_parameters mp
9173                  WHERE mp.organization_id = transaction_row.transfer_orgn_id;
9174 
9175               IF (l_flg_ind = 0) THEN
9176                  process_movement( transaction_row.line_type
9177                                 , l_source_orgn_id
9178                                 , transaction_row.orgn_id
9179                                 , l_source_le_id
9180                                 , l_le_id
9181                                 , transaction_row.trans_date
9182                                 );
9183               ELSE
9184                  process_pd_transfer;
9185               END IF;
9186 
9187         	    /*ELSIF transaction_row.doc_type = 'XFER' INVCONV sschinch*/
9188 	          ELSIF (transaction_row.transaction_source_type_id IN (INTERNAL_ORDER,INTERNAL_REQ,INVENTORY) AND
9189                    transaction_row.transaction_action_id  = DIRECT_ORG_TRANSFER AND
9190                    transaction_row.trans_qty < 0
9191 	                )
9192 	           THEN
9193                 process_adjustment;
9194              ELSIF (transaction_row.transaction_source_type_id IN (INTERNAL_ORDER,INTERNAL_REQ,INVENTORY) AND
9195                    transaction_row.transaction_action_id  = INTRANSIT_SHIPMENT)  -- JBOPPANA
9196 	           THEN
9197                 process_adjustment;
9198                /*ELSIF transaction_row.doc_type IN ('OMSO','OPSO') */
9199             ELSIF transaction_row.transaction_source_type_id IN (SALES_ORDER,INTERNAL_ORDER)
9200                 AND transaction_row.transaction_action_id IN (ISSUE_FROM_STORES,LOGICAL_INTRANSIT_SHIPMENT)
9201               THEN
9202                 process_adjustment;
9203 /* ANTHIYAG Bug#5287514 07-Jun-2006 Start */
9204             ELSIF transaction_row.transaction_source_type_id = PURCHASE_ORDER
9205                 AND transaction_row.transaction_action_id IN (ISSUE_FROM_STORES, DELIVERY_ADJUSTMENTS)
9206               THEN
9207                 process_receipt;
9208 /* ANTHIYAG Bug#5287514 07-Jun-2006 End */
9209             ELSIF transaction_row.transaction_source_type_id = RMA
9210                 AND transaction_row.transaction_action_id = ISSUE_FROM_STORES
9211               THEN
9212                 process_adjustment;
9213             ELSIF transaction_row.transaction_source_type_id = RMA
9214                 AND transaction_row.transaction_action_id = RECEIPT_INTO_STORES
9215               THEN
9216                 process_receipt;
9217 
9218                /*ELSIF transaction_row.doc_type = 'LADJ'*/
9219             ELSIF (transaction_row.transaction_source_type_id = LOT_COST_ADJUSTMENT)
9220               THEN
9221                 process_lot_cost_adjustments;
9222                 /* INVCONV sschinch */
9223             ELSIF (transaction_row.transaction_source_type_id = INVENTORY AND
9224                 transaction_row.transaction_action_id = LOT_SPLIT) THEN
9225                 process_lot_split;
9226             ELSIF (transaction_row.transaction_source_type_id = INVENTORY AND
9227                    transaction_row.transaction_action_id = LOT_MERGE)
9228             THEN
9229                 process_lot_merge;
9230             ELSIF (transaction_row.transaction_source_type_id = INVENTORY AND
9231                    transaction_row.transaction_action_id = LOT_TRANSLATE
9232                   ) THEN
9233               process_lot_translate;
9234             END IF;
9235 
9236               IF l_residual_qty <> transaction_row.trans_qty
9237               THEN
9238                 -- The transaction that has been processed flipped a negative onhand balance back to positive
9239                 -- so we need to adjust the onhand balance in the header to the residual balance
9240 
9241                 IF   l_debug_level >= l_debug_level_high
9242                 THEN
9243                   fnd_file.put_line
9244                   (fnd_file.log,'Onhand balance has flipped from -ve to +ve. Setting onhand qty to residual qty');
9245                 END IF;
9246 
9247                 UPDATE gmf_lot_costs
9248                 SET    onhand_qty = l_residual_qty
9249                 WHERE  header_id = (SELECT max(header_id)
9250                                     FROM   gmf_lot_costs
9251                                     WHERE organization_id = transaction_row.orgn_id
9252                                     AND lot_number = transaction_row.lot_number)
9253                 RETURNING header_id INTO new_cost.header_id;
9254 
9255                 -- B3486228 Also set the transaction qty to the residual
9256                 UPDATE gmf_material_lot_cost_txns
9257                    SET    new_onhand_qty = l_residual_qty
9258                  WHERE  transaction_id = transaction_row.transaction_id /* ANTHIYAG Bug#5285726 07-Jun-2006 */
9259                   AND   cost_header_id = new_cost.header_id;
9260               END IF;
9261             END IF;
9262 
9263             -- For anything other than production transactions we can
9264             -- set the rows to 'costed'. 'PROD' transactions are dealt with
9265             -- in their own procedure above
9266 
9267             IF  l_return_status = 'S'
9268             THEN
9269               IF l_final_run_flag = 1	-- umoogala  05-Dec-2003
9270               THEN
9271                 IF transaction_row.source = 1
9272                 THEN
9273                   IF (transaction_row.transaction_source_type_id <> 5
9274                     OR (transaction_row.transaction_source_type_id = 5  /* ingredients, by products and reversals for products */
9275                     AND (transaction_row.line_type in (-1,2)
9276                     OR (transaction_row.line_type = 1
9277                     AND transaction_row.trans_qty < 0
9278                     AND transaction_row.reverse_id IS NOT NULL
9279                     )
9280                      )
9281                    ))
9282                      -- the lot_Costed_ind to 1 in the process_batch for reversal transactions.
9283                      -- So after Final Run, inv_tran_cursor returns the reversal transaction rows
9284                      -- of the PRODUCT. To solve, this added another condition as
9285                      --  if line_type is product and the tran_qty is negative then set the lot_costed_ind to 1.
9286                 THEN
9287                   -- INVCONV sschinch uncommet if we have this column approved
9288                   /*
9289                   UPDATE mtl_material_lot_numbers
9290                   SET    lot_costed_ind	         = 1
9291                   WHERE  transaction_id = transaction_row.transaction_id
9292                    AND  lot_number = transaction_row.lot_number;
9293                   */
9294                   NULL;
9295                 END IF;
9296               ELSE
9297                 -- This is a lot cost adjustment (source is 3)
9298                 -- This is a lot cost adjustment (source is 3)
9299                 -- PK Bug 6697946 If old_cost.header_id is NULL Use new_cost.header_id
9300                 IF   l_debug_level >= l_debug_level_high THEN
9301                   fnd_file.put_line
9302                  (fnd_file.log,'FINAL Mode old '||old_cost.header_id||' new '||new_cost.header_id||' Onhand '||new_cost.onhand_qty||' adj '||transaction_row.doc_id);
9303                 END IF;
9304                 UPDATE gmf_lot_cost_adjustments
9305                 SET  applied_ind = 'Y',
9306           		       old_cost_header_id = NVL(old_cost.header_id, new_cost.header_id),
9307 		                 new_cost_header_id = new_cost.header_id,
9308 		                 onhand_qty	  = new_cost.onhand_qty
9309                 WHERE  adjustment_id = transaction_row.doc_id;
9310               END IF;
9311 
9312               UPDATE gmf_lot_costs
9313               SET    final_cost_flag = 1
9314               WHERE  header_id = new_cost.header_id;
9315             ELSE
9316 	   	    	  IF transaction_row.source = 3 THEN
9317 	   	    	    -- PK Bug 6697946 If old_cost.header_id is NULL Use new_cost.header_id
9318                             IF   l_debug_level >= l_debug_level_high THEN
9319                                 fnd_file.put_line
9320                                 (fnd_file.log,'TEST Mode old '||old_cost.header_id||' new '||new_cost.header_id||' Onhand '||new_cost.onhand_qty||' adj '||transaction_row.doc_id);
9321                             END IF;
9322 			          UPDATE gmf_lot_cost_adjustments
9323 			             SET  old_cost_header_id = NVL(old_cost.header_id, new_cost.header_id),
9324 			                  new_cost_header_id = new_cost.header_id,
9325 			                  onhand_qty	  = new_cost.onhand_qty
9326 			            WHERE adjustment_id = transaction_row.doc_id;
9327 		          END IF;
9328             END IF;
9329             COMMIT;
9330           ELSE
9331             -- Add this lot to the list of lots that can't be costed
9332             fnd_file.put_line(fnd_file.log,'WARNING: Setting Lot for the orgn/Item/Lot '||transaction_row.orgn_id||'/'||transaction_row.inventory_item_id||'/'||transaction_row.lot_number||' as uncostable');
9333             l_uncostable_lots_tab(transaction_row.orgn_id||'-'||transaction_row.inventory_item_id||'-'||transaction_row.lot_number) := transaction_row.inventory_item_id;
9334             l_tmp := FALSE;
9335 	          l_return_code := 'F';
9336             ROLLBACK TO SAVEPOINT inv_tran;
9337           END IF;
9338 
9339          ELSE
9340              IF   l_debug_level >= l_debug_level_high
9341               THEN
9342                 fnd_file.put_line(fnd_file.log,' Current orgn/Item/Lot '||transaction_row.orgn_id||'/'||transaction_row.inventory_item_id||'/'||transaction_row.lot_number||' is Not Costable');
9343                 fnd_file.put_line(fnd_file.log,' So skipping the transaction: '||transaction_row.transaction_id);
9344               END IF;
9345          END IF; -- skip this txn
9346         FETCH inv_tran_cursor INTO transaction_row;
9347       END LOOP;
9348       CLOSE inv_tran_cursor;
9349 
9350 
9351       IF l_return_code = 'F' OR l_tmp = FALSE
9352       THEN
9353         l_tmp := fnd_concurrent.set_completion_status('WARNING','Errors found during processing.'||
9354 			' Please check the log file for details.');
9355       ELSE
9356         l_tmp := fnd_concurrent.set_completion_status('NORMAL','Process completed successfully.');
9357       END IF;
9358 
9359       fnd_file.put_line
9360       (fnd_file.log,'Lot Cost Rollup finished at '||to_char(sysdate,'DD-MON-YYYY HH24:MI:SS'));
9361       COMMIT;
9362     EXCEPTION
9363     WHEN OTHERS
9364     THEN
9365       fnd_file.put_line(fnd_file.log,'ERROR: '||substr(sqlerrm,1,100) || ' in ' || procedure_name);
9366       l_tmp := fnd_concurrent.set_completion_status('ERROR',sqlerrm || ' in ' || procedure_name);
9367       ROLLBACK;
9368   END rollup_lot_costs;
9369 END GMF_LOT_COSTING_PUB;