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;