DBA Data[Home] [Help]

PACKAGE BODY: APPS.AHL_UC_UTILIZATION_PVT

Source


1 PACKAGE BODY AHL_UC_UTILIZATION_PVT AS
2 /* $Header: AHLVUCUB.pls 120.4.12010000.3 2008/12/04 01:15:24 jaramana ship $ */
3 
4 G_PKG_NAME CONSTANT VARCHAR2(30) := 'AHL_UC_UTILIZATION_PVT';
5 
6 G_LOG_PREFIX CONSTANT VARCHAR2(100) := 'ahl.plsql.AHL_UC_UTILIZATION_PVT';
7 
8 -- Added by jaramana on 03-DEC-2008 to improve performance by localising FND_LOG package variables.
9 G_CURRENT_RUNTIME_LEVEL CONSTANT NUMBER := FND_LOG.G_CURRENT_RUNTIME_LEVEL;
10 G_LEVEL_PROCEDURE       CONSTANT NUMBER := FND_LOG.LEVEL_PROCEDURE;
11 G_LEVEL_STATEMENT       CONSTANT NUMBER := FND_LOG.LEVEL_STATEMENT;
12 
13 ----------------------------------------------
14 -- Define local Procedures for Utilization  --
15 ----------------------------------------------
16 -- Convert Value to ID.
17 PROCEDURE convert_value_id(p_utilization_rec IN OUT NOCOPY AHL_UC_UTILIZATION_PVT.utilization_rec_type);
18 
19 -- Validate utilization record and get the two flag variables
20 PROCEDURE validate_utilization_rec(p_utilization_rec IN OUT NOCOPY AHL_UC_UTILIZATION_PVT.utilization_rec_type,
21                                    x_found           OUT NOCOPY VARCHAR2,
22                                    x_based_on        OUT NOCOPY VARCHAR2);
23 
24 -- Update counter reading only for a given counter_id (p_cascade_flag is not applicable)
25 -- It is called by update_reading_ins and update_reading_all
26 PROCEDURE update_reading_id(p_utilization_rec IN utilization_rec_type);
27 
28 -- Update counter readings for a given pair of counter_name and instance. It also update counter
29 -- readings for all the descendants of the start instance if p_cascade_flag is
30 -- set to Yes. The given start instance must have the p_counter_name associated. It is
31 -- called by update_reading_cn
32 PROCEDURE update_reading_ins(p_utilization_rec IN utilization_rec_type);
33 
34 -- Update counter readings for a given given pair of counter_name and instance. It also update counter
35 -- readings for all the descendants of the start instance if p_cascade_flag is
36 -- set to Yes. The given start instance might not have the p_counter_name associated. It is
37 -- called by update_instance_all
38 PROCEDURE update_reading_cn(p_utilization_rec IN utilization_rec_type);
39 
40 -- Update counter reading based on various inputs
41 PROCEDURE update_reading_all(p_utilization_rec IN utilization_rec_type,
42                              p_based_on        IN VARCHAR2);
43 
44 -- To get Counter ratio based on Master Configuration position.
45 FUNCTION get_counter_ratio(p_start_instance_id IN NUMBER,
46                            p_desc_instance_id  IN NUMBER,
47                            p_uom_code          IN VARCHAR2,
48                            p_rule_code         IN VARCHAR2)
49 RETURN NUMBER;
50 
51 -----------------------------------------
52 -- Define Procedure for Utilization    --
53 -----------------------------------------
54 -- Start of Comments --
55 --  Procedure name: update_utilization
56 --  Type:           Private
57 --  Function:       Updates the utilization based on the counter rules defined in the master configuration
58 --                  given the details of an item/counter id/counter name/uom_code.
59 --                  Casacades the updates down to all the children if the p_cascade_flag is set to 'Y'.
60 --  Pre-reqs:
61 --  Parameters:
62 --  Standard IN Parameters:
63 --    p_api_version                   IN      NUMBER                Required
64 --    p_init_msg_list                 IN      VARCHAR2     Default  FND_API.G_FALSE
65 --    p_commit                        IN      VARCHAR2     Default  FND_API.G_FALSE
66 --    p_validation_level              IN      NUMBER       Default  FND_API.G_VALID_LEVEL_FULL
67 --
68 --  Standard OUT Parameters:
69 --    x_return_status                 OUT     VARCHAR2               Required
70 --    x_msg_count                     OUT     NUMBER                 Required
71 --    x_msg_data                      OUT     VARCHAR2               Required
72 --
73 --  Update_Utilization Parameters:
74 --
75 --    p_utilization_tbl                IN      Required.
76 --      For each record, at any given time only one of the following combinations is valid to identify the
77 --      item instance to be updated:
78 --        1.  Organization id and Inventory_item_id    AND  Serial Number.
79 --            This information will identify the part number and serial number of a configuration.
80 --        2.  Counter ID -- if this is passed a specific counter ONLY will be updated irrespective of the value
81 --            of p_cascade_flag.
82 --        3.  CSI_ITEM_INSTANCE_ID -- if this is passed, then this item instance and items down the hierarchy (depends on
83 --            the value p_cascade_flag) will be updated.
84 --      At any given time only one of the following parameters is valid to identify the type of item counters to be
85 --      updated:
86 --        1.  COUNTER_ID
87 --        2.  COUNTER_NAME
88 --        3.  UOM_CODE
89 --
90 --      reading_value                 IN   Required
91 --        This will be the value of the counter reading.
92 --      cascade_flag                  IN   Required
93 --        Can take values Y and N. Y indicates that the counter updates will cascade down the hierarchy
94 --        beginning at the item number passed. If its value is N then only the item counter will be updated.
95 --
96 -- End of Comments --
97 
98 PROCEDURE update_utilization(p_api_version      IN NUMBER,
99                              p_init_msg_list    IN VARCHAR2 := FND_API.G_FALSE,
100                              p_commit           IN VARCHAR2 := FND_API.G_FALSE,
101                              p_validation_level IN NUMBER   := FND_API.G_VALID_LEVEL_FULL,
102                              p_utilization_tbl  IN AHL_UC_UTILIZATION_PVT.utilization_tbl_type,
103                              x_return_status    OUT NOCOPY VARCHAR2,
104                              x_msg_count        OUT NOCOPY NUMBER,
105                              x_msg_data         OUT NOCOPY VARCHAR2)
106 IS
107   l_api_name        CONSTANT VARCHAR2(30) := 'update_utilization';
108   l_api_version     CONSTANT NUMBER       := 1.0;
109   l_utilization_rec AHL_UC_UTILIZATION_PVT.utilization_rec_type;
110   l_utilization_tbl AHL_UC_UTILIZATION_PVT.utilization_tbl_type DEFAULT p_utilization_tbl;
111   l_found           VARCHAR2(50) := NULL;
112   l_based_on        VARCHAR2(50) := NULL;
113 
114   L_DEBUG_KEY              CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Utilization';
115 
116 BEGIN
117 
118   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
119     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin',
120                    'Entering Procedure. p_utilization_tbl.count = ' || p_utilization_tbl.count);
121   END IF;
122 
123   -- Initialize API return status to success
124   x_return_status := FND_API.G_RET_STS_SUCCESS;
125 
126   -- Standard start of API savepoint
127   SAVEPOINT update_utilization;
128 
129   -- Standard call to check for call compatibility
130   IF NOT FND_API.compatible_api_call(l_api_version, p_api_version, l_api_name,
131                                      G_PKG_NAME) THEN
132     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
133   END IF;
134 
135   -- Initialize message list if p_init_msg_list is set to TRUE
136   IF FND_API.to_boolean(p_init_msg_list) THEN
137     FND_MSG_PUB.initialize;
138   END IF;
139 
140   FOR i IN l_utilization_tbl.FIRST..l_utilization_tbl.LAST LOOP
141     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
142       FND_LOG.STRING(G_LEVEL_STATEMENT,
143                      L_DEBUG_KEY,
144                      'Processing record ' || i);
145     END IF;
146     l_utilization_rec := l_utilization_tbl(i);
147     -- Convert value's to ID's.
148     convert_value_id(l_utilization_rec);
149     -- Validate input parameters.
150     validate_utilization_rec(l_utilization_rec, l_found, l_based_on);
151     l_utilization_tbl(i) := l_utilization_rec;
152   END LOOP;
153 
154   -- Check Error Message stack.
155   x_msg_count := FND_MSG_PUB.count_msg;
156   IF x_msg_count > 0 THEN
157     RAISE  FND_API.G_EXC_ERROR;
158   END IF;
159 
160   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
161     FND_LOG.STRING(G_LEVEL_STATEMENT,
162                    L_DEBUG_KEY,
163                    'After successful completion of Value To Id conversion and Validation of all records in table.');
164   END IF;
165   -- Perform updates.
166   FOR i IN l_utilization_tbl.FIRST..l_utilization_tbl.LAST LOOP
167     l_utilization_rec := l_utilization_tbl(i);
168     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
169       FND_LOG.STRING(G_LEVEL_STATEMENT,
170                      L_DEBUG_KEY,
171                      'About to call update_reading_all for record ' || i ||
172                      ', l_based_on = ' || l_based_on);
173     END IF;
174     update_reading_all(l_utilization_rec, l_based_on);
175   END LOOP;
176 
177   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
178     FND_LOG.STRING(G_LEVEL_STATEMENT,
179                    L_DEBUG_KEY,
180                    'After successful completion of update_reading_all calls for all records in table.');
181   END IF;
182 
183   -- Check Error Message stack.
184   x_msg_count := FND_MSG_PUB.count_msg;
185   IF x_msg_count > 0 THEN
186     RAISE  FND_API.G_EXC_ERROR;
187   END IF;
188 
189   -- Standard check of p_commit
190   IF FND_API.TO_BOOLEAN(p_commit) THEN
191     COMMIT WORK;
192   END IF;
193 
194   -- Standard call to get message count and if count is 1, get message info
195   FND_MSG_PUB.count_and_get(
196     p_count => x_msg_count,
197     p_data  => x_msg_data,
198     p_encoded => fnd_api.g_false);
199 
200   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
201     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure');
202   END IF;
203 
204 EXCEPTION
205   WHEN FND_API.G_EXC_ERROR THEN
206     x_return_status := FND_API.G_RET_STS_ERROR;
207     ROLLBACK to update_utilization;
208     FND_MSG_PUB.count_and_get(p_count => x_msg_count,
209                               p_data  => x_msg_data,
210                               p_encoded => fnd_api.g_false);
211   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
212     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
213     ROLLBACK to update_utilization;
214     FND_MSG_PUB.count_and_get(p_count => x_msg_count,
215                               p_data  => x_msg_data,
216                               p_encoded => fnd_api.g_false);
217  WHEN OTHERS THEN
218     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
219     ROLLBACK to update_utilization;
220     IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
221       fnd_msg_pub.add_exc_msg(p_pkg_name       => G_PKG_NAME,
222                               p_procedure_name => 'update_utilization',
223                               p_error_text     => SQLERRM);
224     END IF;
225     FND_MSG_PUB.count_and_get(p_count => x_msg_count,
226                               p_data  => x_msg_data,
227                               p_encoded => fnd_api.g_false);
228 END update_utilization;
229 
230 ---------------------------------------------------------------------------------
231 
232 PROCEDURE convert_value_id(p_utilization_rec IN OUT NOCOPY
233                           AHL_UC_UTILIZATION_PVT.utilization_rec_type)
234 IS
235   -- For organization id.
236   CURSOR mtl_parameters_csr(c_org_code VARCHAR2) IS
237     SELECT organization_id
238       FROM mtl_parameters
239      WHERE organization_code = c_org_code;
240 
241   -- For inventory_item_id.
242   CURSOR mtl_system_items_csr(c_item_number VARCHAR2,
243                               c_inv_organization_id NUMBER) IS
244     SELECT inventory_item_id
245       FROM ahl_mtl_items_ou_v
246      WHERE concatenated_segments = c_item_number
247        AND inventory_org_id = c_inv_organization_id;
248 
249   -- For instance_id.
250   CURSOR csi_item_instance_csr(c_instance_number VARCHAR2) IS
251     SELECT instance_id
252       FROM csi_item_instances
253      WHERE instance_number = c_instance_number;
254 
255   l_return_val      BOOLEAN;
256   l_lookup_code     fnd_lookups.lookup_code%TYPE;
257   l_organization_id NUMBER;
258   l_inventory_id    NUMBER;
259   l_instance_id     NUMBER;
260   L_DEBUG_KEY       CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Convert_Value_Id';
261 
262 BEGIN
263   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
264     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
265   END IF;
266 
267   -- For Inventory Organization Code.
268   IF ((p_utilization_rec.organization_id IS NULL) OR
269       (p_utilization_rec.organization_id = FND_API.G_MISS_NUM)) THEN
270     -- if code is present.
271     IF ((p_utilization_rec.organization_code IS NOT NULL) AND
272         (p_utilization_rec.organization_code <> FND_API.G_MISS_CHAR)) THEN
273       OPEN mtl_parameters_csr(p_utilization_rec.organization_code);
274       FETCH mtl_parameters_csr INTO l_organization_id;
275       IF (mtl_parameters_csr%FOUND) THEN
276         p_utilization_rec.organization_id := l_organization_id;
277       ELSE
278         FND_MESSAGE.set_name('AHL','AHL_UC_ORG_INVALID');
279         FND_MESSAGE.set_token('ORG',p_utilization_rec.organization_code);
280         FND_MSG_PUB.add;
281       END IF;
282       CLOSE mtl_parameters_csr;
283     END IF;
284   END IF;
285   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
286     FND_LOG.STRING(G_LEVEL_STATEMENT,
287                    L_DEBUG_KEY,
288                    'p_utilization_rec.organization_id = ' || p_utilization_rec.organization_id);
289   END IF;
290 
291   -- For Rule_Code_meaning.
292   IF ((p_utilization_rec.rule_code IS NULL) OR
293       (p_utilization_rec.rule_code = FND_API.G_MISS_CHAR)) THEN
294     -- Check if meaning exists.
295     IF ((p_utilization_rec.Rule_meaning IS NOT NULL) AND
296         (p_utilization_rec.Rule_meaning <> FND_API.G_MISS_CHAR)) THEN
297       AHL_UTIL_MC_PKG.convert_to_lookupcode('AHL_COUNTER_RULE_TYPE',
298                                             p_utilization_rec.Rule_meaning,
299                                             l_lookup_code,
300                                             l_return_val);
301       IF (l_return_val) THEN
302         p_utilization_rec.rule_code := l_lookup_code;
303       ELSE
304         FND_MESSAGE.set_name('AHL','AHL_UC_RCODE_INVALID');
305         FND_MESSAGE.set_token('CODE',p_utilization_rec.Rule_meaning);
306         FND_MSG_PUB.add;
307       END IF;
308     END IF;
309   END IF;
310   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
311     FND_LOG.STRING(G_LEVEL_STATEMENT,
312                    L_DEBUG_KEY,
313                    'p_utilization_rec.rule_code = ' || p_utilization_rec.rule_code);
314   END IF;
315 
316   -- For Inventory item.
317   IF ((p_utilization_rec.inventory_item_id IS NULL) OR
318       (p_utilization_rec.inventory_item_id = FND_API.G_MISS_NUM)) THEN
319     -- check if name exists.
320     IF ((p_utilization_rec.item_number IS NOT NULL) AND
321         (p_utilization_rec.item_number <> FND_API.G_MISS_CHAR)) THEN
322       OPEN mtl_system_items_csr(p_utilization_rec.item_number,
323                                 p_utilization_rec.organization_id);
324       FETCH mtl_system_items_csr INTO l_inventory_id;
325       IF (mtl_system_items_csr%FOUND) THEN
326         p_utilization_rec.inventory_item_id := l_inventory_id;
327       ELSE
328         FND_MESSAGE.set_name('AHL','AHL_MC_INV_INVALID');
329         FND_MESSAGE.set_token('INV_ITEM',p_utilization_rec.item_number);
330         FND_MSG_PUB.add;
331       END IF;
332       CLOSE mtl_system_items_csr;
333     END IF;
334   END IF;
335   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
336     FND_LOG.STRING(G_LEVEL_STATEMENT,
337                    L_DEBUG_KEY,
338                    'p_utilization_rec.inventory_item_id = ' || p_utilization_rec.inventory_item_id);
339   END IF;
340 
341   -- For Instance.
342   IF ((p_utilization_rec.csi_item_instance_id IS NULL) OR
343       (p_utilization_rec.csi_item_instance_id = FND_API.G_MISS_NUM)) THEN
344     -- check if name exists.
345     IF ((p_utilization_rec.csi_item_instance_number IS NOT NULL) AND
346         (p_utilization_rec.csi_item_instance_number <> FND_API.G_MISS_CHAR)) THEN
347       OPEN csi_item_instance_csr(p_utilization_rec.csi_item_instance_number);
348       FETCH csi_item_instance_csr INTO l_instance_id;
349       IF (csi_item_instance_csr%FOUND) THEN
350         p_utilization_rec.csi_item_instance_id := l_instance_id;
351       ELSE
352         FND_MESSAGE.set_name('AHL','AHL_UC_INSTANCE_INVALID');
353         FND_MESSAGE.set_token('INSTANCE',p_utilization_rec.csi_item_instance_number);
354         FND_MSG_PUB.add;
355       END IF;
356       CLOSE csi_item_instance_csr;
357     END IF;
358   END IF;
359   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
360     FND_LOG.STRING(G_LEVEL_STATEMENT,
361                    L_DEBUG_KEY,
362                    'p_utilization_rec.csi_item_instance_id = ' || p_utilization_rec.csi_item_instance_id);
363   END IF;
364 
365   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
366     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure');
367   END IF;
368 
369 END convert_value_id;
370 
371 ---------------------------------------------------------------------------------
372 
373 PROCEDURE validate_utilization_rec(p_utilization_rec IN OUT NOCOPY AHL_UC_UTILIZATION_PVT.utilization_rec_type,
374                                    x_found           OUT NOCOPY VARCHAR2,
375                                    x_based_on        OUT NOCOPY VARCHAR2)
376 IS
377   -- Get location type code.
378   CURSOR csi_item_instances_csr(c_instance_id NUMBER) IS
379     SELECT location_type_code
380       FROM csi_item_instances
381      WHERE instance_id = c_instance_id
382        AND TRUNC(sysdate) < TRUNC(NVL(active_end_date, sysdate+1));
383 
384    -- Validate Counter ID.
385    CURSOR cs_counters_csr (c_counter_id NUMBER) IS
386      SELECT cgrp.source_object_id
387        FROM cs_counters ctr, cs_counter_groups cgrp
388       WHERE cgrp.counter_group_id = ctr.counter_group_id
389         AND cgrp.source_object_code = 'CP'
390         AND ctr.counter_id = c_counter_id
391         AND trunc(sysdate) >= trunc(nvl(ctr.start_date_active,sysdate))
392         AND trunc(sysdate) < trunc(nvl(ctr.end_date_active,sysdate+1));
393 
394    CURSOR csi_item_serial_csr(c_inventory_item_id NUMBER,
395                               c_organization_id   NUMBER,
396                               c_serial_number     VARCHAR2) IS
397      SELECT instance_id,
398             instance_usage_code,
399             active_start_date,
400             active_end_date
401        FROM csi_item_instances csi
402       WHERE inventory_item_id = c_inventory_item_id
403         AND last_vld_organization_id = c_organization_id
404         AND serial_number = c_serial_number;
405 
406    CURSOR mtl_units_of_measure_csr(c_uom_code VARCHAR2) IS
407      SELECT 'X'
408        FROM mtl_units_of_measure_vl
409       WHERE uom_code = c_uom_code;
410 
411    -- Validate counter name.
412    CURSOR cs_counter_name_csr(c_counter_name VARCHAR2) IS
413      SELECT 'X'
414        FROM cs_counters ctr
415       WHERE ctr.name = c_counter_name
416         AND trunc(sysdate) >= trunc(nvl(ctr.start_date_active,sysdate))
417         AND trunc(sysdate) < trunc(nvl(ctr.end_date_active,sysdate+1));
418 
419    CURSOR ahl_unit_config_csr (c_instance_id NUMBER) IS
420      SELECT unit_config_header_id
421        FROM ahl_unit_config_headers
422       WHERE csi_item_instance_id = c_instance_id
423         AND trunc(sysdate) >= trunc(nvl(active_start_date,sysdate))
424         AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1));
425 
426    l_csi_item_instance_id       NUMBER;
427    l_tmp_instance_id            NUMBER := p_utilization_rec.csi_item_instance_id;
428    l_csi_top_node_id            NUMBER;
429    l_parent_uc_header_id        NUMBER;
430    l_parent_uc_instance_id      NUMBER;
431    l_root_uc_header_id          NUMBER;
432    l_root_uc_instance_id        NUMBER;
433    l_root_uc_status_code        FND_LOOKUP_VALUES_VL.lookup_code%TYPE;
434    l_root_active_uc_status_code FND_LOOKUP_VALUES_VL.lookup_code%TYPE;
435    l_root_uc_header_ovn         NUMBER;
436    l_csi_instance_usage_code    CSI_LOOKUPS.lookup_code%TYPE;
437    l_junk                       VARCHAR2(30);
438    l_return_val                 BOOLEAN;
439 
440    l_config_status              ahl_unit_config_headers.unit_config_status_code%TYPE;
441    l_master_config_status       ahl_mc_headers_b.config_status_code%TYPE;
442    l_master_config_name         ahl_mc_headers_b.name%TYPE;
443    l_master_config_id           NUMBER;
444 
445    l_unit_config_name           ahl_unit_config_headers.name%TYPE;
446    l_location_type_code         csi_item_instances.location_type_code%TYPE;
447    l_active_end_date            DATE;
448    l_active_start_date          DATE;
449 
450    l_found                      VARCHAR2(50) := NULL;
451    l_based_on                   VARCHAR2(50) := NULL;
452 
453    L_DEBUG_KEY       CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Validate_Utilization_Rec';
454 
455 BEGIN
456   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
457     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
458   END IF;
459 
460   -- Check if counter_id is valid.
461   IF (p_utilization_rec.counter_id IS NOT NULL) AND
462      (p_utilization_rec.counter_id <> FND_API.G_MISS_NUM) THEN
463     OPEN cs_counters_csr(p_utilization_rec.counter_id);
464     FETCH cs_counters_csr INTO l_csi_item_instance_id;
465     IF (cs_counters_csr%NOTFOUND) THEN
466       FND_MESSAGE.set_name('AHL','AHL_UC_CSCTR_INVALID');
467       FND_MESSAGE.set_token('CTRID',p_utilization_rec.counter_id);
468       FND_MSG_PUB.add;
469       --dbms_output.put_line('Counter ID not found');
470     ELSE
471       l_based_on :=  l_based_on || ':' || 'COUNTERID';
472       l_found := l_found || ':' || 'COUNTER';
473 
474       -- Find out the csi item status code.
475       OPEN csi_item_instances_csr(l_csi_item_instance_id);
476       FETCH csi_item_instances_csr INTO l_location_type_code;
477       IF (csi_item_instances_csr%NOTFOUND) THEN
478         FND_MESSAGE.set_name('AHL','AHL_UC_CSII_INVALID');
479         FND_MESSAGE.set_token('CSII',p_utilization_rec.csi_item_instance_id);
480         FND_MSG_PUB.add;
481         --dbms_output.put_line('CSI Item Instance not found');
482       ELSE
483         l_tmp_instance_id := l_csi_item_instance_id;
484       END IF; -- csi not found.
485       CLOSE csi_item_instances_csr;
486     END IF;
487     CLOSE cs_counters_csr;
488   END IF;
489   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
490     FND_LOG.STRING(G_LEVEL_STATEMENT,
491                    L_DEBUG_KEY,
492                    'Validated Counter Id.');
493   END IF;
494 
495   -- Check if Inventory item and serial number are valid and exist in csi_item_instances.
496   IF (p_utilization_rec.inventory_item_id IS NOT NULL) AND
497      (p_utilization_rec.inventory_item_id <> FND_API.G_MISS_NUM) THEN
498     OPEN csi_item_serial_csr(p_utilization_rec.inventory_item_id,
499                              p_utilization_rec.organization_id,
500                              p_utilization_rec.serial_number);
501     FETCH csi_item_serial_csr INTO l_csi_item_instance_id, l_csi_instance_usage_code,
502                                    l_active_start_date, l_active_end_date;
503     IF (csi_item_serial_csr%NOTFOUND) THEN
504       FND_MESSAGE.set_name('AHL','AHL_UC_INV_SERIAL_INVALID');
505       FND_MESSAGE.set_token('INV_ITEM',p_utilization_rec.inventory_item_id);
506       FND_MESSAGE.set_token('SERIAL',p_utilization_rec.serial_number);
507       FND_MSG_PUB.add;
508       --dbms_output.put_line('Inventory item not found');
509     ELSIF (trunc(sysdate)) < trunc(nvl(l_active_end_date, sysdate+1)) THEN
510       l_found := l_found || ':' || 'INVENTORY';
511       l_tmp_instance_id := l_csi_item_instance_id;
512     ELSE
513       -- Item expired.
514       FND_MESSAGE.set_name('AHL','AHL_UC_INVITEM_INVALID');
515       FND_MESSAGE.set_token('INV_ITEM',p_utilization_rec.inventory_item_id);
516       FND_MESSAGE.set_token('SERIAL',p_utilization_rec.serial_number);
517       FND_MSG_PUB.add;
518       --dbms_output.put_line('Inventory item not found');
519     END IF;
520     CLOSE csi_item_serial_csr;
521   END IF;
522   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
523     FND_LOG.STRING(G_LEVEL_STATEMENT,
524                    L_DEBUG_KEY,
525                    'Validated inventory_item_id, serial and instance.');
526   END IF;
527 
528   -- Check if csi_item_instance_id present.
529   IF (p_utilization_rec.csi_item_instance_id IS NOT NULL) AND
530      (p_utilization_rec.csi_item_instance_id <> FND_API.G_MISS_NUM) THEN
531     OPEN csi_item_instances_csr(p_utilization_rec.csi_item_instance_id);
532     FETCH csi_item_instances_csr INTO l_location_type_code;
533     IF (csi_item_instances_csr%NOTFOUND) THEN
534       FND_MESSAGE.set_name('AHL','AHL_UC_CSII_INVALID');
535       FND_MESSAGE.set_token('CSII',p_utilization_rec.csi_item_instance_id);
536       FND_MSG_PUB.add;
537       --dbms_output.put_line('CSI Item Instance not found');
538     ELSIF (l_location_type_code IN ('PO','INVENTORY','PROJECT','IN-TRANSIT')) THEN
539       FND_MESSAGE.set_name('AHL','AHL_UC_CSII_INVALID');
540       FND_MESSAGE.set_token('CSII',p_utilization_rec.csi_item_instance_id);
541       FND_MSG_PUB.add;
542       --dbms_output.put_line('CSI Item Instance location invalid');
543     ELSE
544       l_found := l_found || ':' || 'INSTANCE';
545     END IF;  /* csi item_instance */
546     CLOSE csi_item_instances_csr;
547   END IF;
548   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
549     FND_LOG.STRING(G_LEVEL_STATEMENT,
550                    L_DEBUG_KEY,
551                    'Validated instance location.');
552   END IF;
553 
554   p_utilization_rec.csi_item_instance_id := l_tmp_instance_id;
555   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
556     FND_LOG.STRING(G_LEVEL_STATEMENT,
557                    L_DEBUG_KEY,
558                    'Setting p_utilization_rec.csi_item_instance_id to ' || p_utilization_rec.csi_item_instance_id);
559   END IF;
560 
561   -- Check Error Message stack.
562   IF FND_MSG_PUB.count_msg > 0 THEN
563     RAISE  FND_API.G_EXC_ERROR;
564   END IF;
565 
566   -- Raise error if no or too many parameters.
567   IF (l_found IS NULL) THEN
568     FND_MESSAGE.set_name('AHL','AHL_UC_UPARAM_NULL');
569     FND_MSG_PUB.add;
570     --dbms_output.put_line('Part number information is null');
571     RAISE  FND_API.G_EXC_ERROR;
572   ELSIF l_found <> ':INVENTORY' AND
573     l_found <> ':INSTANCE'  AND
574     l_found <> ':COUNTER'
575   THEN
576     FND_MESSAGE.set_name('AHL','AHL_UC_UPARAM_INVALID');
577     FND_MSG_PUB.add;
578     --dbms_output.put_line('Too many parameters for part number.');
579     RAISE  FND_API.G_EXC_ERROR;
580   END IF;
581 
582   -- Check if unit config is complete.
583   -- First get its parent_uc_header_id
584   ahl_util_uc_pkg.get_parent_uc_header(p_utilization_rec.csi_item_instance_id,
585                                        l_parent_uc_header_id,
586                                        l_parent_uc_instance_id);
587   IF l_parent_uc_header_id IS NULL THEN
588     --Then check to see whether this instance happens to be a top unit instance
589     OPEN ahl_unit_config_csr(p_utilization_rec.csi_item_instance_id);
590     FETCH ahl_unit_config_csr INTO l_parent_uc_header_id;
591     IF ahl_unit_config_csr%NOTFOUND THEN
592       --Means this instance is definately not in a UC
593       FND_MESSAGE.set_name('AHL','AHL_UC_INSTANCE_NOT_IN_UC');
594       FND_MESSAGE.set_token('INSTANCE', p_utilization_rec.csi_item_instance_id);
595       FND_MSG_PUB.add;
596     END IF;
597     CLOSE ahl_unit_config_csr;
598     --dbms_output.put_line('CSI Item Instance not found');
599   ELSE
600     ahl_util_uc_pkg.get_root_uc_attr(
601       p_uc_header_id          => l_parent_uc_header_id,
602       x_uc_header_id          => l_root_uc_header_id,
603       x_instance_id           => l_root_uc_instance_id,
604       x_uc_status_code        => l_root_uc_status_code,
605       x_active_uc_status_code => l_root_active_uc_status_code,
606       x_uc_header_ovn         => l_root_uc_header_ovn);
607 
608     IF (l_root_uc_status_code NOT IN ('COMPLETE', 'INCOMPLETE', 'DRAFT')) THEN
609        -- 'DRAFT' needs to be removed after testing
610        FND_MESSAGE.set_name('AHL','AHL_UC_STATUS_INVALID');
611        FND_MESSAGE.set_token('STATUS',l_root_uc_status_code);
612        FND_MSG_PUB.add;
613        --dbms_output.put_line('UC Status invalid');
614     END IF;
615   END IF;
616   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
617     FND_LOG.STRING(G_LEVEL_STATEMENT,
618                    L_DEBUG_KEY,
619                    'Validated UC of instance');
620   END IF;
621 
622   -- Check values of cascade_flag.
623   IF (p_utilization_rec.cascade_flag IS NOT NULL AND
624       p_utilization_rec.cascade_flag NOT IN ('Y','N'))
625   THEN
626     FND_MESSAGE.set_name('AHL','AHL_UC_CASCADE_INVALID');
627     FND_MESSAGE.set_token('FLAG',p_utilization_rec.cascade_flag);
628     FND_MSG_PUB.add;
629      --dbms_output.put_line('Cascade flag is invalid.');
630   END IF;
631   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
632     FND_LOG.STRING(G_LEVEL_STATEMENT,
633                    L_DEBUG_KEY,
634                    'Validated p_utilization_rec.cascade_flag: ' || p_utilization_rec.cascade_flag);
635   END IF;
636 
637   -- Check values of delta_flag.
638   IF (p_utilization_rec.delta_flag IS NOT NULL AND
639       p_utilization_rec.delta_flag NOT IN ('Y','N'))
640   THEN
641     FND_MESSAGE.set_name('AHL','AHL_UC_DELTA_FLAG_INVALID');
642     FND_MESSAGE.set_token('FLAG',p_utilization_rec.delta_flag);
643     FND_MSG_PUB.add;
644      --dbms_output.put_line('Delta flag is invalid.');
645   END IF;
646   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
647     FND_LOG.STRING(G_LEVEL_STATEMENT,
648                    L_DEBUG_KEY,
649                    'Validated p_utilization_rec.delta_flag: ' || p_utilization_rec.delta_flag);
650   END IF;
651 
652   -- Check Error Message stack.
653   IF FND_MSG_PUB.count_msg > 0 THEN
654     RAISE  FND_API.G_EXC_ERROR;
655   END IF;
656 
657   -- Check UOM_CODE.
658   IF (p_utilization_rec.uom_code IS NOT NULL)  AND
659      (p_utilization_rec.uom_code <> FND_API.G_MISS_CHAR)  THEN
660     OPEN mtl_units_of_measure_csr(p_utilization_rec.uom_code);
661     FETCH mtl_units_of_measure_csr INTO l_junk;
662     IF (mtl_units_of_measure_csr%NOTFOUND) THEN
663       FND_MESSAGE.set_name('AHL','AHL_UC_UZ_UOM_INVALID');
664       FND_MESSAGE.set_token('UOM_CODE',p_utilization_rec.uom_code);
665       FND_MSG_PUB.add;
666       --dbms_output.put_line('UOM CODE not found');
667     ELSE
668       l_based_on :=  l_based_on || ':' || 'UOM';
669     END IF;
670     CLOSE mtl_units_of_measure_csr;
671   END IF;
672   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
673     FND_LOG.STRING(G_LEVEL_STATEMENT,
674                    L_DEBUG_KEY,
675                    'Validated p_utilization_rec.uom_code: ' || p_utilization_rec.uom_code);
676   END IF;
677 
678   -- Check Counter Name.
679   IF (p_utilization_rec.counter_name IS NOT NULL) AND
680      (p_utilization_rec.counter_name <> FND_API.G_MISS_CHAR)
681   THEN
682     OPEN cs_counter_name_csr(p_utilization_rec.counter_name);
683     FETCH cs_counter_name_csr INTO l_junk;
684     IF (cs_counter_name_csr%NOTFOUND) THEN
685       FND_MESSAGE.set_name('AHL','AHL_UC_CTRNAME_INVALID');
686       FND_MESSAGE.set_token('CTR_NAME',p_utilization_rec.counter_name);
687       FND_MSG_PUB.add;
688         --dbms_output.put_line('Counter Name not found');
689     ELSE
690       l_based_on :=  l_based_on || ':' || 'COUNTER';
691     END IF;
692     CLOSE cs_counter_name_csr;
693   END IF;
694   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
695     FND_LOG.STRING(G_LEVEL_STATEMENT,
696                    L_DEBUG_KEY,
697                    'Validated p_utilization_rec.counter_name: ' || p_utilization_rec.counter_name);
698   END IF;
699 
700   -- Validate Rule Code.
701   IF (p_utilization_rec.rule_code IS NOT NULL AND
702       NOT(AHL_UTIL_MC_PKG.validate_lookup_code('AHL_COUNTER_RULE_TYPE', p_utilization_rec.rule_code))) THEN
703     FND_MESSAGE.set_name('AHL','AHL_UC_RCODE_INVALID');
704     FND_MESSAGE.set_token('CODE',p_utilization_rec.rule_code);
705     FND_MSG_PUB.add;
706     --dbms_output.put_line('Invalid Rule code');
707   END IF;
708   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
709     FND_LOG.STRING(G_LEVEL_STATEMENT,
710                    L_DEBUG_KEY,
711                    'Validated p_utilization_rec.rule_code: ' || p_utilization_rec.rule_code);
712   END IF;
713 
714   -- Default reading date
715   IF (p_utilization_rec.reading_date IS NULL OR
716       p_utilization_rec.reading_date = FND_API.G_MISS_DATE) THEN
717     p_utilization_rec.reading_date := SYSDATE;
718   END IF;
719   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
720     FND_LOG.STRING(G_LEVEL_STATEMENT,
721                    L_DEBUG_KEY,
722                    'Validated p_utilization_rec.reading_date: ' || p_utilization_rec.reading_date);
723   END IF;
724 
725   --Validate Reading.
726   --If reading_value is delta reading, then this value can be positive (ascending counter)
727   --or negative (descending counter). And If reading value is net reading, then we require
728   --the specific counter name provided or counter names with the speicific UOMs provided exist
729   --for the start instance itself.
730   IF (p_utilization_rec.reading_value IS NULL OR p_utilization_rec.reading_value = FND_API.G_MISS_NUM) THEN
731     FND_MESSAGE.set_name('AHL','AHL_UC_READING_INVALID');
732     FND_MSG_PUB.add;
733   END IF;
734   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
735     FND_LOG.STRING(G_LEVEL_STATEMENT,
736                    L_DEBUG_KEY,
737                    'Validated p_utilization_rec.reading_value: ' || p_utilization_rec.reading_value);
738   END IF;
739 
740   -- Check Error Message stack.
741   IF FND_MSG_PUB.count_msg > 0 THEN
742     RAISE  FND_API.G_EXC_ERROR;
743   END IF;
744 
745   -- Raise error if no or too many parameters.
746   IF (l_based_on IS NULL) THEN
747     FND_MESSAGE.set_name('AHL','AHL_UC_UBASED_ON_NULL');
748     FND_MSG_PUB.add;
749     --dbms_output.put_line('Part number information is null');
750     RAISE  FND_API.G_EXC_ERROR;
751   ELSIF (l_based_on <> ':UOM' AND
752          l_based_on <> ':COUNTER' AND
753          l_based_on <> ':COUNTERID' ) THEN
754     FND_MESSAGE.set_name('AHL','AHL_UC_UBASED_ON_INVALID');
755     FND_MSG_PUB.add;
756     --dbms_output.put_line('Input parameters contain both UOM Code and Counter Name');
757     RAISE  FND_API.G_EXC_ERROR;
758   END IF;
759   x_found := l_found;
760   x_based_on := l_based_on;
761   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
762     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end',
763     'Exiting Procedure. x_found = ' || x_found || ', x_based_on = ' || x_based_on);
764   END IF;
765 
766 END validate_utilization_rec;
767 
768 ---------------------------------------------------------------------------------
769 
770 PROCEDURE update_reading_id(p_utilization_rec IN utilization_rec_type) IS
771   -- Get current counter reading values based on the counter_id
772   CURSOR get_current_value_id(c_counter_id NUMBER) IS
773  -- Changed by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
774  -- To take advantage of the fix made in Counters bug 7561677 (FP of 7374316)
775  -- and also to ignore disabled counter readings
776 /*
777     SELECT nvl(counter_reading,0) counter_reading,
778            counter_group_id
779       FROM csi_cp_counters_v
780      WHERE counter_id = c_counter_id
781      -- order by added by jaramana on June 13, 2007 to fix bug 6123549
782      -- Since csi_cp_counters_v was modified by CSI in R12 to get all
783      -- counter readings and not just the most recent one.
784      ORDER BY value_timestamp desc;
785 */
786      SELECT (select ccr.net_reading
787                from csi_counter_readings ccr
788               where ccr.counter_value_id = c.ctr_val_max_seq_no) counter_reading,
789             DEFAULTED_GROUP_ID counter_group_id
790        FROM CSI_COUNTERS_B C
791       WHERE counter_id = c_counter_id;
792 
793   -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
794   CURSOR is_counter_change_type_csr(c_counter_id NUMBER) IS
795     select 'Y' from CSI_COUNTERS_B
796     where counter_id = c_counter_id
797       and reading_type = 2;
798 
799   l_change_type_flag  VARCHAR2(1) := 'N';
800   -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
801 
802   l_counter_grp_id  NUMBER;
803   l_reading_value   NUMBER;
804   l_start_current_value NUMBER;
805 
806   l_ctr_grp_log_rec CS_CTR_CAPTURE_READING_PUB.ctr_grp_log_rec_type;
807   l_ctr_rdg_tbl     CS_CTR_CAPTURE_READING_PUB.ctr_rdg_tbl_type;
808   l_prop_rdg_tbl    CS_CTR_CAPTURE_READING_PUB.prop_rdg_tbl_type;
809   l_return_status   VARCHAR2(3);
810   l_msg_count       NUMBER;
811   l_msg_data        VARCHAR2(2000);
812   l_msg_index_out   NUMBER;
813   L_DEBUG_KEY       CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_Id';
814 
815 BEGIN
816   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
817     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
818   END IF;
819 
820   -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
821   OPEN is_counter_change_type_csr(p_utilization_rec.counter_id);
822   FETCH is_counter_change_type_csr INTO l_change_type_flag;
823   IF (is_counter_change_type_csr%FOUND) THEN
824     l_change_type_flag := 'Y';
825   ELSE
826     l_change_type_flag := 'N';
827   END IF;
828   CLOSE is_counter_change_type_csr;
829   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
830     FND_LOG.STRING(G_LEVEL_STATEMENT, L_DEBUG_KEY, 'Counter is change type: ' || l_change_type_flag);
831   END IF;
832   -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
833 
834   OPEN get_current_value_id(p_utilization_rec.counter_id);
835   FETCH get_current_value_id INTO l_start_current_value, l_counter_grp_id;
836   IF get_current_value_id%NOTFOUND THEN
837     FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
838     FND_MSG_PUB.add;
839     CLOSE get_current_value_id;
840     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
841   ELSE
842     CLOSE get_current_value_id;
843   END IF;
844   IF p_utilization_rec.delta_flag = 'Y' THEN
845     -- Begin Changes by jaramana on Feb 20, 2008 for Bug 6782765
846     IF (l_change_type_flag = 'Y') THEN
847       -- For Change type counters, always pass the delta value
848       l_reading_value := p_utilization_rec.reading_value;
849     ELSE
850       -- For other counters, always pass the total value
851       l_reading_value := l_start_current_value+p_utilization_rec.reading_value;
852     END IF;
853   ELSE
854     -- Not Delta
855     IF (l_change_type_flag = 'Y') THEN
856       -- For Change type counters, delta_flag should always be Y
857       FND_MESSAGE.set_name('AHL', 'AHL_UC_DELTA_FLAG_INVALID');
858       FND_MESSAGE.set_token('FLAG', p_utilization_rec.delta_flag);
859       FND_MSG_PUB.add;
860       RAISE FND_API.G_EXC_ERROR;
861     END IF;
862     -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
863     l_reading_value := p_utilization_rec.reading_value;
864   END IF;
865   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
866     FND_LOG.STRING(G_LEVEL_STATEMENT,
867                    L_DEBUG_KEY,
868                    'l_start_current_value = ' || l_start_current_value ||
869                    ', p_utilization_rec.delta_flag = ' || p_utilization_rec.delta_flag ||
870                    ', p_utilization_rec.reading_value = ' || p_utilization_rec.reading_value ||
871                    ', Setting l_reading_value to ' || l_reading_value);
872   END IF;
873 
874   -- Update reading for the counter.
875   l_ctr_grp_log_rec.counter_group_id := l_counter_grp_id;
876   l_ctr_grp_log_rec.value_timestamp := SYSDATE;
877   l_ctr_grp_log_rec.source_transaction_id := p_utilization_rec.csi_item_instance_id;
878   l_ctr_grp_log_rec.source_transaction_code := 'CP';
879 
880   l_ctr_rdg_tbl(1).counter_id := p_utilization_rec.counter_id;
881   l_ctr_rdg_tbl(1).value_timestamp := p_utilization_rec.reading_date;
882   l_ctr_rdg_tbl(1).counter_reading := l_reading_value;
883   l_ctr_rdg_tbl(1).valid_flag := 'Y';
884   -- Changed from 'Y' to 'N' by jaramana on July 10, 2007 for bug 6127957
885   l_ctr_rdg_tbl(1).override_valid_flag := 'N';
886   --Call CS Counter Update API to update the counter_reading of the start instance
887   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
888     FND_LOG.STRING(G_LEVEL_STATEMENT,
889                    L_DEBUG_KEY,
890                    'About to call CS_CTR_CAPTURE_READING_PUB.capture_counter_reading');
891   END IF;
892   CS_CTR_CAPTURE_READING_PUB.capture_counter_reading(
893                    p_api_version_number => 1.0,
894                    p_init_msg_list      => FND_API.G_FALSE,
895                    p_commit             => FND_API.G_FALSE,
896                    p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
897                    p_ctr_grp_log_rec    => l_ctr_grp_log_rec,
898                    p_ctr_rdg_tbl        => l_ctr_rdg_tbl,
899                    p_prop_rdg_tbl       => l_prop_rdg_tbl,
900                    x_return_status      => l_return_status,
901                    x_msg_count          => l_msg_count,
902                    x_msg_data           => l_msg_data );
903   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
904     FND_LOG.STRING(G_LEVEL_STATEMENT,
905                    L_DEBUG_KEY,
906                    'Returned from call to CS_CTR_CAPTURE_READING_PUB.capture_counter_reading. l_return_status = ' || l_return_status);
907   END IF;
908   IF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
909     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
910   ELSIF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
911     RAISE FND_API.G_EXC_ERROR;
912   END IF;
913   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
914     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end',
915     'Exiting Procedure.');
916   END IF;
917 END update_reading_id;
918 
919 ---------------------------------------------------------------------------------
920 
921 --Update the counter reading value of the start instance and all of its components (if
922 --cascade_flag = 'Y'). This procedure assumes the given counter name exists for the start
923 --instance
924 PROCEDURE update_reading_ins(p_utilization_rec IN utilization_rec_type) IS
925   CURSOR csi_relationships_csr(c_csi_item_instance_id NUMBER) IS
926     SELECT subject_id csi_item_instance_id, position_reference
927       FROM csi_ii_relationships
928 START WITH object_id = c_csi_item_instance_id
929        AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
930        AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
931        AND relationship_type_code = 'COMPONENT-OF'
932 CONNECT BY object_id = PRIOR subject_id
933        AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
934        AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
935        AND relationship_type_code = 'COMPONENT-OF';
936 
937    -- Get current counter reading values based on the counter_id
938    -- Cursor get_current_value_id commented out by jaramana on on June 13, 2007
939    --  while fixing bug 6123549 since this cursor is not used in this procedure at all.
940    /***
941    CURSOR get_current_value_id(c_counter_id NUMBER) IS
942      SELECT nvl(counter_reading,0) counter_reading,
943             counter_group_id,
944             uom_code
945        FROM csi_cp_counters_v
946       WHERE counter_id = c_counter_id;
947    ***/
948    -- Get current counter reading values based on the counter_name
949    -- Cursor changed by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
950    -- Removed the use of csi_cp_counters_v and uptook
951    -- changes made via Counters bug 7561677 (FP of 7374316)
952    CURSOR get_current_value_name(c_instance_id NUMBER,
953                                  c_counter_name VARCHAR2) IS
954 /*
955      SELECT nvl(counter_reading,0) counter_reading,
956             counter_group_id,
957             counter_id,
958             start_date_active,
959             end_date_active,
960             uom_code
961        FROM csi_cp_counters_v
962       WHERE customer_product_id = c_instance_id
963         AND counter_template_name = c_counter_name
964         AND trunc(nvl(start_date_active, sysdate)) <= trunc(sysdate)
965         AND trunc(nvl(end_date_active, sysdate+1)) > trunc(sysdate)
966    ORDER BY value_timestamp desc;
967 */
968      SELECT C.DEFAULTED_GROUP_ID counter_group_id,
969             (select ccr.net_reading
970                from csi_counter_readings ccr
971               where ccr.counter_value_id = c.ctr_val_max_seq_no) counter_reading,
972             C.COUNTER_ID counter_id,
973             C.START_DATE_ACTIVE start_date_active,
974             C.END_DATE_ACTIVE end_date_active,
975             C.UOM_CODE uom_code
976        FROM CSI_COUNTERS_VL C, CSI_COUNTER_ASSOCIATIONS CCA
977       WHERE C.COUNTER_ID = CCA.COUNTER_ID(+)
978         AND CCA.SOURCE_OBJECT_CODE = 'CP'
979         AND CCA.SOURCE_OBJECT_ID = c_instance_id
980         AND C.COUNTER_TEMPLATE_NAME = c_counter_name
981         AND trunc(nvl(C.start_date_active, sysdate)) <= trunc(sysdate)
982         AND trunc(nvl(C.end_date_active, sysdate+1)) > trunc(sysdate);
983 
984    l_get_current_value_name get_current_value_name%ROWTYPE;
985 
986    -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
987    CURSOR is_counter_change_type_csr(c_counter_id NUMBER) IS
988      select 'Y' from CSI_COUNTERS_B
989      where counter_id = c_counter_id
990        and reading_type = 2;
991 
992    l_change_type_flag  VARCHAR2(1) := 'N';
993    -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
994 
995    l_utilization_rec utilization_rec_type;
996    l_ratio           NUMBER;
997    l_reading_value   NUMBER;
998    l_start_current_value NUMBER;
999    l_uom_code        cs_counters.uom_code%TYPE;
1000 
1001    l_ctr_grp_log_rec CS_CTR_CAPTURE_READING_PUB.ctr_grp_log_rec_type;
1002    l_ctr_rdg_tbl     CS_CTR_CAPTURE_READING_PUB.ctr_rdg_tbl_type;
1003    l_prop_rdg_tbl    CS_CTR_CAPTURE_READING_PUB.prop_rdg_tbl_type;
1004    l_return_status   VARCHAR2(3);
1005    l_msg_count       NUMBER;
1006    l_msg_data        VARCHAR2(2000);
1007    l_msg_index_out   NUMBER;
1008    L_DEBUG_KEY       CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_Ins';
1009 
1010 BEGIN
1011   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1012     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1013   END IF;
1014   l_utilization_rec := p_utilization_rec;
1015   --First get the current counter reading value for the start instance
1016   --This procedure assumes that counter exists for the instance
1017   OPEN get_current_value_name(l_utilization_rec.csi_item_instance_id,
1018                               l_utilization_rec.counter_name);
1019   FETCH get_current_value_name INTO l_get_current_value_name;
1020   IF get_current_value_name%NOTFOUND THEN
1021     FND_MESSAGE.set_name('AHL','AHL_UC_CTR_INST_INVALID');
1022     FND_MESSAGE.set_token('COUNTER', l_utilization_rec.counter_name);
1023     FND_MESSAGE.set_token('INSTANCE', l_utilization_rec.csi_item_instance_id);
1024     FND_MSG_PUB.add;
1025     CLOSE get_current_value_name;
1026     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1027   ELSE
1028     CLOSE get_current_value_name;
1029   END IF;
1030   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1031     FND_LOG.STRING(G_LEVEL_STATEMENT,
1032                    L_DEBUG_KEY,
1033                    'l_get_current_value_name.counter_id = ' || l_get_current_value_name.counter_id ||
1034                    ', l_get_current_value_name.counter_reading = ' || l_get_current_value_name.counter_reading ||
1035                    ', l_get_current_value_name.uom_code = ' || l_get_current_value_name.uom_code ||
1036                    ', l_get_current_value_name.start_date_active = ' || l_get_current_value_name.start_date_active ||
1037                    ', l_get_current_value_name.end_date_active = ' || l_get_current_value_name.end_date_active);
1038   END IF;
1039 
1040   l_utilization_rec.counter_id := l_get_current_value_name.counter_id;
1041 
1042   -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
1043   OPEN is_counter_change_type_csr(l_utilization_rec.counter_id);
1044   FETCH is_counter_change_type_csr INTO l_change_type_flag;
1045   IF (is_counter_change_type_csr%FOUND) THEN
1046     l_change_type_flag := 'Y';
1047   ELSE
1048     l_change_type_flag := 'N';
1049   END IF;
1050   CLOSE is_counter_change_type_csr;
1051   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1052     FND_LOG.STRING(G_LEVEL_STATEMENT, L_DEBUG_KEY, 'Counter is change type: ' || l_change_type_flag);
1053   END IF;
1054   -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
1055 
1056   l_start_current_value := l_get_current_value_name.counter_reading;
1057   l_uom_code := l_get_current_value_name.uom_code;
1058   update_reading_id(l_utilization_rec);
1059   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1060     FND_LOG.STRING(G_LEVEL_STATEMENT,
1061                    L_DEBUG_KEY, 'Returned from call to update_reading_id');
1062   END IF;
1063 
1064   IF (l_utilization_rec.cascade_flag = 'Y') THEN
1065     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1066       FND_LOG.STRING(G_LEVEL_STATEMENT,
1067                      L_DEBUG_KEY, 'l_utilization_rec.cascade_flag = Y');
1068     END IF;
1069   -- Process for config items.
1070     FOR child_rec IN csi_relationships_csr(p_utilization_rec.csi_item_instance_id) LOOP
1071       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1072         FND_LOG.STRING(G_LEVEL_STATEMENT,
1073                        L_DEBUG_KEY, 'Processing child instance ' || child_rec.csi_item_instance_id);
1074       END IF;
1075       -- Get counter ratio.
1076       IF ahl_util_uc_pkg.extra_node(child_rec.csi_item_instance_id, l_utilization_rec.csi_item_instance_id) THEN
1077         l_ratio := 1;
1078         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1079           FND_LOG.STRING(G_LEVEL_STATEMENT,
1080                          L_DEBUG_KEY, 'Instance is an extra node. Setting l_ratio to 1');
1081         END IF;
1082       ELSE
1083         l_ratio := get_counter_ratio(l_utilization_rec.csi_item_instance_id,
1084                                      child_rec.csi_item_instance_id,
1085                                      l_uom_code,
1086                                      l_utilization_rec.rule_code);
1087         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1088           FND_LOG.STRING(G_LEVEL_STATEMENT,
1089                          L_DEBUG_KEY, 'Instance is not an extra node. Setting l_ratio to ' || l_ratio);
1090         END IF;
1091       END IF;
1092 
1093       -- Get current counter reading values
1094       OPEN get_current_value_name(child_rec.csi_item_instance_id, l_utilization_rec.counter_name);
1095       FETCH get_current_value_name INTO l_get_current_value_name;
1096       IF get_current_value_name%FOUND THEN
1097         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1098           FND_LOG.STRING(G_LEVEL_STATEMENT,
1099                          L_DEBUG_KEY, 'get_current_value_name%FOUND is TRUE. ' ||
1100                          'l_get_current_value_name.counter_reading = ' || l_get_current_value_name.counter_reading);
1101         END IF;
1102       --Else the given counter name doesn't apply to this instance
1103       --Ensure that if the same counter existing for the component instance, then the counter's
1104       --UOM should be exactly the same as that of start instance's counter. Cheng has confirmed
1105       --this point with Barry.
1106         IF l_get_current_value_name.uom_code <> l_uom_code THEN
1107           FND_MESSAGE.set_name('AHL','AHL_UC_CTR_UOM_INVALID');
1108           FND_MESSAGE.set_token('COUNTER', l_utilization_rec.counter_name);
1109           FND_MESSAGE.set_token('INSTANCE', child_rec.csi_item_instance_id);
1110           FND_MESSAGE.set_token('UOM', l_get_current_value_name.uom_code);
1111           FND_MSG_PUB.add;
1112           CLOSE get_current_value_name;
1113           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1114         ELSE
1115           CLOSE get_current_value_name;
1116         END IF;
1117 
1118         IF l_utilization_rec.delta_flag = 'Y' THEN
1119           -- Begin Changes by jaramana on Feb 20, 2008 for Bug 6782765
1120           IF (l_change_type_flag = 'Y') THEN
1121             -- For Change type counters, always pass the multiplied delta value
1122             l_reading_value := l_ratio*l_utilization_rec.reading_value;
1123           ELSE
1124             -- For other counters, always pass the total value
1125             l_reading_value := l_get_current_value_name.counter_reading+l_ratio*l_utilization_rec.reading_value;
1126           END IF;
1127           IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1128             FND_LOG.STRING(G_LEVEL_STATEMENT,
1129                            L_DEBUG_KEY, 'l_utilization_rec.delta_flag is Y. Setting l_reading_value to ' || l_reading_value);
1130           END IF;
1131         ELSE
1132           -- Not Delta
1133           IF (l_change_type_flag = 'Y') THEN
1134             -- For Change type counters, delta_flag should always be Y
1135             FND_MESSAGE.set_name('AHL', 'AHL_UC_DELTA_FLAG_INVALID');
1136             FND_MESSAGE.set_token('FLAG', l_utilization_rec.delta_flag);
1137             FND_MSG_PUB.add;
1138             RAISE FND_API.G_EXC_ERROR;
1139           END IF;
1140           -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
1141           l_reading_value := l_get_current_value_name.counter_reading+
1142                              l_ratio*(l_utilization_rec.reading_value-l_start_current_value);
1143           IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1144             FND_LOG.STRING(G_LEVEL_STATEMENT,
1145                            L_DEBUG_KEY, 'l_utilization_rec.delta_flag is not Y. Setting l_reading_value to ' || l_reading_value);
1146           END IF;
1147         END IF;
1148         -- Update reading for the counter.
1149         l_ctr_grp_log_rec.counter_group_id := l_get_current_value_name.counter_group_id;
1150         l_ctr_grp_log_rec.value_timestamp := SYSDATE;
1151         l_ctr_grp_log_rec.source_transaction_id := child_rec.csi_item_instance_id;
1152         l_ctr_grp_log_rec.source_transaction_code := 'CP';
1153         l_ctr_rdg_tbl(1).counter_id := l_get_current_value_name.counter_id;
1154         l_ctr_rdg_tbl(1).value_timestamp := l_utilization_rec.reading_date;
1155         l_ctr_rdg_tbl(1).counter_reading := l_reading_value;
1156         l_ctr_rdg_tbl(1).valid_flag := 'Y';
1157         -- Changed from 'Y' to 'N' by jaramana on July 10, 2007 for bug 6127957
1158         l_ctr_rdg_tbl(1).override_valid_flag := 'N';
1159         --Call CS Counter Update API to update the counter_reading of the start instance
1160         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1161           FND_LOG.STRING(G_LEVEL_STATEMENT,
1162                          L_DEBUG_KEY, 'About to call CS_CTR_CAPTURE_READING_PUB.capture_counter_reading with ' ||
1163                          'l_ctr_rdg_tbl(1).counter_reading = ' || l_ctr_rdg_tbl(1).counter_reading ||
1164                          ', l_ctr_rdg_tbl(1).counter_id = ' || l_ctr_rdg_tbl(1).counter_id ||
1165                          ', l_ctr_rdg_tbl(1).value_timestamp = ' || l_ctr_rdg_tbl(1).value_timestamp);
1166         END IF;
1167         CS_CTR_CAPTURE_READING_PUB.capture_counter_reading(
1168                    p_api_version_number => 1.0,
1169                    p_init_msg_list      => FND_API.G_FALSE,
1170                    p_commit             => FND_API.G_FALSE,
1171                    p_validation_level   => FND_API.G_VALID_LEVEL_FULL,
1172                    p_ctr_grp_log_rec    => l_ctr_grp_log_rec,
1173                    p_ctr_rdg_tbl        => l_ctr_rdg_tbl,
1174                    p_prop_rdg_tbl       => l_prop_rdg_tbl,
1175                    x_return_status      => l_return_status,
1176                    x_msg_count          => l_msg_count,
1177                    x_msg_data           => l_msg_data);
1178         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1179           FND_LOG.STRING(G_LEVEL_STATEMENT,
1180                          L_DEBUG_KEY, 'Returned from call to CS_CTR_CAPTURE_READING_PUB.capture_counter_reading. l_return_status = ' || l_return_status);
1181         END IF;
1182         IF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1183           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1184         ELSIF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1185           RAISE FND_API.G_EXC_ERROR;
1186         END IF;
1187       ELSE
1188         CLOSE get_current_value_name;
1189         -- Added by jaramana on October 29, 2007 for bug 6513576
1190         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1191           FND_LOG.STRING(G_LEVEL_STATEMENT,
1192                          L_DEBUG_KEY, 'get_current_value_name%FOUND is FALSE.');
1193         END IF;
1194       END IF;
1195     END LOOP;
1196   END IF;
1197   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1198     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure.');
1199   END IF;
1200 END update_reading_ins;
1201 
1202 ---------------------------------------------------------------------------------
1203 
1204 PROCEDURE update_reading_cn(p_utilization_rec IN utilization_rec_type) IS
1205   TYPE instance_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
1206 /** Begin changes by jaramana on October 29, 2007 for bug 6513576
1207     Cannot use cs_counters and cs_counter_groups anymore **/
1208    -- Cursor changed by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1209    -- Removed the use of csi_cp_counters_v
1210   CURSOR get_components_counter(c_instance_id NUMBER, c_counter_name VARCHAR2) IS
1211     SELECT CI.subject_id
1212       FROM csi_ii_relationships CI
1213      WHERE EXISTS (SELECT 'X'
1214 /*
1215                      FROM cs_counters CC,
1216                           cs_counter_groups CG
1217                     WHERE CC.counter_group_id = CG.counter_group_id
1218                       AND CG.source_object_id = CI.subject_id
1219                       AND CG.source_object_code = 'CP'
1220                       AND CC.name = c_counter_name
1221                       AND trunc(nvl(CC.start_date_active,sysdate)) <= trunc(sysdate)
1222                       AND trunc(nvl(CC.end_date_active,sysdate+1)) > trunc(sysdate))
1223 */
1224 /*
1225                      FROM CSI_CP_COUNTERS_V CCCV
1226                     WHERE CCCV.CUSTOMER_PRODUCT_ID = CI.subject_id
1227                       AND CCCV.COUNTER_TEMPLATE_NAME = c_counter_name
1228                       AND trunc(nvl(CCCV.start_date_active, sysdate)) <= trunc(sysdate)
1229                       AND trunc(nvl(CCCV.end_date_active, sysdate+1)) > trunc(sysdate))
1230 */
1231                      FROM CSI_COUNTERS_VL C, CSI_COUNTER_ASSOCIATIONS CCA
1232                     WHERE CCA.SOURCE_OBJECT_ID = CI.subject_id
1233                       AND C.COUNTER_ID = CCA.COUNTER_ID(+)
1234                       AND CCA.SOURCE_OBJECT_CODE = 'CP'
1235                       AND C.COUNTER_TEMPLATE_NAME = c_counter_name
1236                       AND trunc(nvl(C.start_date_active, sysdate)) <= trunc(sysdate)
1237                       AND trunc(nvl(C.end_date_active, sysdate+1)) > trunc(sysdate))
1238 START WITH object_id = c_instance_id
1239        AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1240        AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
1241        AND relationship_type_code = 'COMPONENT-OF'
1242 CONNECT BY object_id = PRIOR subject_id
1243        AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1244        AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
1245        AND relationship_type_code = 'COMPONENT-OF';
1246 
1247   CURSOR get_all_ancestors(c_desc_instance_id NUMBER, c_ance_instance_id NUMBER) IS
1248     SELECT object_id
1249       FROM csi_ii_relationships
1250 START WITH subject_id = c_desc_instance_id
1251        AND object_id <> c_ance_instance_id
1252        -- This condition is really required because of the extreme case in which
1253        -- subject_id = c_desc_instance_id and object_id happens to be c_ance_instance_id
1254        -- thus it will include c_ance_instance_id and probably all of its ancestors if it has.
1255        AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1256        AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
1257        AND relationship_type_code = 'COMPONENT-OF'
1258 CONNECT BY subject_id = PRIOR object_id
1259        AND object_id <> c_ance_instance_id
1260        AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1261        AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
1262        AND relationship_type_code = 'COMPONENT-OF';
1263 
1264    -- Get counters that match on a given counter name.
1265    CURSOR cs_counters_name_csr(c_csi_item_instance_id NUMBER, c_name VARCHAR2) IS
1266 /*
1267       SELECT ctr.name counter_name, ctr.counter_id, ctr.uom_code, cgrp.counter_group_id
1268       FROM cs_counter_groups cgrp, cs_counters ctr
1269       WHERE cgrp.counter_group_id = ctr.counter_group_id
1270       AND  cgrp.source_object_code = 'CP'
1271       AND  cgrp.source_object_id = c_csi_item_instance_id
1272       AND  ctr.name = c_name
1273       AND  trunc(sysdate) >= trunc(nvl(ctr.start_date_active,sysdate))
1274       AND  trunc(sysdate) <= trunc(nvl(ctr.end_date_active,sysdate+1));
1275 */
1276       SELECT CCCV.COUNTER_TEMPLATE_NAME counter_name, CCCV.counter_id, CCCV.uom_code, CCCV.counter_group_id
1277         FROM CSI_CP_COUNTERS_V CCCV
1278        WHERE CCCV.CUSTOMER_PRODUCT_ID = c_csi_item_instance_id
1279          AND CCCV.COUNTER_TEMPLATE_NAME = c_name
1280          AND trunc(nvl(CCCV.start_date_active, sysdate)) <= trunc(sysdate)
1281          AND trunc(nvl(CCCV.end_date_active, sysdate+1)) > trunc(sysdate);
1282  /** End changes by jaramana on October 29, 2007 for bug 6513576 **/
1283      l_cs_counters_name_csr cs_counters_name_csr%ROWTYPE;
1284 
1285    -- Get current counter reading values based on the counter_id
1286    -- Cursor get_current_value_id commented out by jaramana on on June 13, 2007
1287    --  while fixing bug 6123549 since this cursor is not used in this procedure at all.
1288    /***
1289    CURSOR get_current_value_id(c_counter_id NUMBER) IS
1290      SELECT nvl(counter_reading,0) counter_reading,
1291             counter_group_id,
1292             uom_code
1293        FROM csi_cp_counters_v
1294       WHERE counter_id = c_counter_id;
1295    ***/
1296 
1297    l_utilization_rec utilization_rec_type;
1298    l_ctr_grp_log_rec CS_CTR_CAPTURE_READING_PUB.ctr_grp_log_rec_type;
1299    l_ctr_rdg_tbl     CS_CTR_CAPTURE_READING_PUB.ctr_rdg_tbl_type;
1300    l_prop_rdg_tbl    CS_CTR_CAPTURE_READING_PUB.prop_rdg_tbl_type;
1301    l_return_status   VARCHAR2(3);
1302    l_msg_count       NUMBER;
1303    l_msg_data        VARCHAR2(2000);
1304    l_msg_index_out   NUMBER;
1305    l_instance_tbl    instance_tbl_type;
1306    l_inst_tmp_tbl    instance_tbl_type;
1307    l_parents_tbl     instance_tbl_type;
1308    l_inst_idx        BINARY_INTEGER;
1309    l_parent_idx      BINARY_INTEGER;
1310    l_keep_flag       BOOLEAN;
1311    L_DEBUG_KEY       CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_Cn';
1312 
1313 BEGIN
1314   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1315     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1316   END IF;
1317   l_utilization_rec := p_utilization_rec;
1318   OPEN cs_counters_name_csr(l_utilization_rec.csi_item_instance_id,
1319                             l_utilization_rec.counter_name);
1320   FETCH cs_counters_name_csr INTO l_cs_counters_name_csr;
1321   IF cs_counters_name_csr%FOUND THEN
1322     --p_utilization_rec.uom_code := l_cs_counters_name_csr.uom_code;
1323     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1324       FND_LOG.STRING(G_LEVEL_STATEMENT,
1325                      L_DEBUG_KEY,
1326                      'cs_counters_name_csr%FOUND. Calling update_reading_ins');
1327     END IF;
1328     update_reading_ins(l_utilization_rec);
1329     CLOSE cs_counters_name_csr;
1330   ELSE
1331     CLOSE cs_counters_name_csr;
1332     IF (NVL(l_utilization_rec.delta_flag, 'N') = 'N') THEN
1333       --The start instance doesn't have the given counter associated, reading value is
1334       --net reading but the counter doesn't exists for the start instance
1335       --So raise error and return, no need to go further down.
1336       FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
1337       FND_MSG_PUB.add;
1338       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1339     ELSE
1340       IF (NVL(l_utilization_rec.cascade_flag,'N') = 'Y') THEN
1341       --The start instance doesn't have the given counter associated, reading value is delta
1342       --reading and cascade_flag = 'Y', then get all of its highest level components which
1343       --have the given counter associated but their ancestors don't.
1344         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1345           FND_LOG.STRING(G_LEVEL_STATEMENT,
1346                          L_DEBUG_KEY,
1347                          'cs_counters_name_csr%FOUND is false. l_utilization_rec.delta_flag is Y and l_utilization_rec.cascade_flag is Y');
1348         END IF;
1349         l_inst_idx :=1;
1350         -- Begin changes made by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1351         OPEN get_components_counter(l_utilization_rec.csi_item_instance_id, l_utilization_rec.counter_name);
1352         FETCH get_components_counter BULK COLLECT INTO l_instance_tbl;
1353         CLOSE get_components_counter;
1354         l_inst_tmp_tbl := l_instance_tbl;
1355         /**
1356         FOR l_get_components_counter IN get_components_counter(l_utilization_rec.csi_item_instance_id,
1357                                                                l_utilization_rec.counter_name) LOOP
1358           l_instance_tbl(l_inst_idx) := l_get_components_counter.subject_id;
1359           l_inst_tmp_tbl(l_inst_idx) := l_instance_tbl(l_inst_idx);
1360           --dbms_output.put_line('l_instance_tbl:'||l_inst_idx||' '||l_instance_tbl(l_inst_idx));
1361           l_inst_idx := l_inst_idx + 1;
1362         END LOOP;
1363         **/
1364         -- End changes made by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1365         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1366           FND_LOG.STRING(G_LEVEL_STATEMENT,
1367                          L_DEBUG_KEY,
1368                          'l_instance_tbl.count = ' || l_instance_tbl.count);
1369         END IF;
1370         IF l_instance_tbl.count > 0 THEN
1371           FOR i IN l_instance_tbl.FIRST..l_instance_tbl.LAST LOOP
1372             l_keep_flag := TRUE;
1373             --l_inst_tmp_tbl := l_instance_tbl;
1374             --l_inst_tmp_tbl.DELETE(i);
1375             l_parent_idx := 1;
1376             --l_parents_tbl needs to be reset after each loop
1377             IF l_parents_tbl.COUNT > 0 THEN
1378               l_parents_tbl.DELETE;
1379             END IF;
1380             FOR l_get_all_ancestors IN get_all_ancestors(l_instance_tbl(i), l_utilization_rec.csi_item_instance_id) LOOP
1381               l_parents_tbl(l_parent_idx) :=  l_get_all_ancestors.object_id;
1382               l_parent_idx := l_parent_idx + 1;
1383             END LOOP;
1384             IF l_parents_tbl.COUNT > 0 THEN
1385               <<OUTER1>>
1386               FOR j IN l_parents_tbl.FIRST..l_parents_tbl.LAST LOOP
1387                 IF l_inst_tmp_tbl.COUNT > 0 THEN
1388                   FOR k IN l_inst_tmp_tbl.FIRST..l_inst_tmp_tbl.LAST LOOP
1389                     IF l_parents_tbl(j) = l_inst_tmp_tbl(k) THEN
1390                       l_keep_flag := FALSE;
1391                       EXIT OUTER1;
1392                     END IF;
1393                   END LOOP;
1394                 END IF;
1395               END LOOP;
1396             END IF;
1397             IF NOT l_keep_flag AND l_instance_tbl.EXISTS(i) THEN
1398               l_instance_tbl.DELETE(i);
1399             END IF;
1400           END LOOP;
1401         END IF;
1402         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1403           FND_LOG.STRING(G_LEVEL_STATEMENT,
1404                          L_DEBUG_KEY,
1405                          'After processing, l_instance_tbl.count = ' || l_instance_tbl.count);
1406         END IF;
1407         FOR i IN l_instance_tbl.FIRST..l_instance_tbl.LAST LOOP
1408           IF l_instance_tbl.EXISTS(i) THEN
1409             l_utilization_rec.csi_item_instance_id := l_instance_tbl(i);
1410             --p_utilization_rec.cascade_flag := 'Y';
1411             update_reading_ins(l_utilization_rec);
1412           END IF;
1413         END LOOP;
1414       ELSE
1415         --The start instance doesn't have the given counter associated, reading value is delta
1416         --reading and cascade_flag = 'N', then raise error and stop.
1417         FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
1418         FND_MSG_PUB.add;
1419         RAISE FND_API.G_EXC_ERROR;
1420       END IF;
1421     END IF;
1422   END IF;
1423   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1424     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure.');
1425   END IF;
1426 END update_reading_cn;
1427 
1428 ---------------------------------------------------------------------------------
1429 
1430 PROCEDURE update_reading_all(p_utilization_rec IN utilization_rec_type,
1431                              p_based_on        IN VARCHAR2)
1432 IS
1433   l_utilization_rec  utilization_rec_type;
1434   i NUMBER;
1435   L_DEBUG_KEY       CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_All';
1436 
1437 /** Begin changes by jaramana on October 29, 2007 for bug 6513576
1438     Cannot use cs_counters and cs_counter_groups anymore **/
1439   --Given start instance_id and uom_code, this cursor is used to get all of the distinct
1440   --counters this start instance has
1441   CURSOR get_inst_counters(c_instance_id NUMBER, c_uom_code VARCHAR2) IS
1442 /*
1443     SELECT DISTINCT CC.NAME counter_name
1444       FROM cs_counters CC,
1445            cs_counter_groups CG
1446      WHERE CC.counter_group_id = CG.counter_group_id
1447        AND CG.source_object_code = 'CP'
1448        AND CG.source_object_id = c_instance_id
1449        AND CC.uom_code = c_uom_code
1450        AND trunc(nvl(CC.start_date_active, sysdate)) <= trunc(sysdate)
1451        AND trunc(nvl(CC.end_date_active, sysdate+1)) > trunc(sysdate);
1452 */
1453     SELECT DISTINCT CCCV.COUNTER_TEMPLATE_NAME counter_name
1454       FROM CSI_CP_COUNTERS_V CCCV
1455      WHERE CCCV.UOM_CODE = c_uom_code
1456        AND CCCV.CUSTOMER_PRODUCT_ID = c_instance_id
1457        AND trunc(nvl(CCCV.start_date_active, sysdate)) <= trunc(sysdate)
1458        AND trunc(nvl(CCCV.end_date_active, sysdate+1)) > trunc(sysdate);
1459 
1460   --Given start instance_id and uom_code, this cursor is used to get all of the distinct
1461   --counters this start instance and all of its components have
1462   -- Cursor changed by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1463   -- Removed the use of csi_cp_counters_v
1464   CURSOR get_all_counters(c_instance_id NUMBER, c_uom_code VARCHAR2) IS
1465     SELECT DISTINCT C.COUNTER_TEMPLATE_NAME counter_name
1466       FROM CSI_COUNTERS_VL C, CSI_COUNTER_ASSOCIATIONS CCA
1467      WHERE C.UOM_CODE = c_uom_code
1468        AND trunc(nvl(C.start_date_active, sysdate)) <= trunc(sysdate)
1469        AND trunc(nvl(C.end_date_active, sysdate+1)) > trunc(sysdate)
1470        AND C.COUNTER_ID = CCA.COUNTER_ID(+)
1471        AND CCA.SOURCE_OBJECT_CODE = 'CP'
1472        AND CCA.SOURCE_OBJECT_ID IN (SELECT c_instance_id
1473 /*
1474     SELECT DISTINCT CCCV.COUNTER_TEMPLATE_NAME counter_name
1475       FROM CSI_CP_COUNTERS_V CCCV
1476      WHERE CCCV.UOM_CODE = c_uom_code
1477        AND trunc(nvl(CCCV.start_date_active, sysdate)) <= trunc(sysdate)
1478        AND trunc(nvl(CCCV.end_date_active, sysdate+1)) > trunc(sysdate)
1479        AND CCCV.CUSTOMER_PRODUCT_ID IN (SELECT c_instance_id
1480 */
1481                                      FROM DUAL
1482                                 UNION ALL
1483                                    SELECT subject_id
1484                                      FROM csi_ii_relationships CI
1485                                START WITH object_id = c_instance_id
1486                                       AND trunc(nvl(CI.active_start_date,sysdate)) <= trunc(sysdate)
1487                                       AND trunc(nvl(CI.active_end_date,sysdate+1)) > trunc(sysdate)
1488                                       AND CI.relationship_type_code = 'COMPONENT-OF'
1489                                CONNECT BY object_id = PRIOR subject_id
1490                                       AND trunc(nvl(CI.active_start_date,sysdate)) <= trunc(sysdate)
1491                                       AND trunc(nvl(CI.active_end_date,sysdate+1)) > trunc(sysdate)
1492                                       AND CI.relationship_type_code = 'COMPONENT-OF');
1493 
1494 /** End changes by jaramana on October 29, 2007 for bug 6513576 **/
1495 
1496 BEGIN
1497   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1498     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1499   END IF;
1500   l_utilization_rec := p_utilization_rec;
1501   IF (p_based_on = ':COUNTERID') THEN
1502     -- No cascade issue no matter whether cascade flag is set to 'Y' or 'N', just update the
1503     -- specific counter_id
1504     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1505       FND_LOG.STRING(G_LEVEL_STATEMENT,
1506                      L_DEBUG_KEY,
1507                      'p_based_on is COUNTERID. Calling update_reading_id');
1508     END IF;
1509     update_reading_id(l_utilization_rec);
1510   ELSIF (p_based_on = ':COUNTER') THEN
1511     --For a given pair of counter_name and instance_id, it will uniquely identify the counter_id(confirmed).
1512     --If the counter_name exsits in the start instance, and the cascade_flag = 'Y', then the counter ratio
1513     --for the components are calculated from the start instance(here reading_value(can be either delta
1514     --reading or net reading) refers to the counter of
1515     --the start instance). Otherwise, if the counter_name doesn't exist for the start instance and if the
1516     --reading value is net reading then raise error and stop, and if the reading value is delta reading,
1517     --then we get all of the highest level components of the start instance which
1518     --have the counter_name associated but all of their ancestors don't and make each of these components
1519     --as start point(assuming reading_value (only delta reading) refers to their counters) and calculate the
1520     --counter ratio of their own components.
1521     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1522       FND_LOG.STRING(G_LEVEL_STATEMENT,
1523                      L_DEBUG_KEY,
1524                      'p_based_on is COUNTER. Calling update_reading_cn');
1525     END IF;
1526     update_reading_cn(l_utilization_rec);
1527   ELSIF (p_based_on = ':UOM') THEN
1528     --For a given pair of UOM and instance_id, we may get none, one or multiple counters.
1529     --IF cascade_flag = 'Y' and delta_flag = 'Y', then we traverse down the UC tree with the start instance
1530     --as the starting point and get all of the distinct counters with the same UOM. Otherwise if delta_flag = 'N',
1531     --then we just get all the counters associated with the start instance with the same UOM. For all of these
1532     --distinct counters loop just like p_based_on = ':COUNTER'.
1533     i := 0;
1534     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1535       FND_LOG.STRING(G_LEVEL_STATEMENT,
1536                      L_DEBUG_KEY,
1537                      'p_based_on is UOM, l_utilization_rec.delta_flag = ' || l_utilization_rec.delta_flag);
1538     END IF;
1539     IF NVL(l_utilization_rec.delta_flag, 'N') = 'N' THEN
1540       FOR l_get_inst_counters IN get_inst_counters(l_utilization_rec.csi_item_instance_id,
1541                                                    l_utilization_rec.uom_code) LOOP
1542         l_utilization_rec.counter_name := l_get_inst_counters.counter_name;
1543         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1544           FND_LOG.STRING(G_LEVEL_STATEMENT,
1545                          L_DEBUG_KEY,
1546                          'l_get_inst_counters.counter_name = ' || l_get_inst_counters.counter_name ||
1547                          ', i = ' || i || ', Calling update_reading_cn');
1548         END IF;
1549         update_reading_cn(l_utilization_rec);
1550         i := i+1;
1551       END LOOP;
1552     ELSE
1553       FOR l_get_all_counters IN get_all_counters(l_utilization_rec.csi_item_instance_id,
1554                                                  l_utilization_rec.uom_code) LOOP
1555         l_utilization_rec.counter_name := l_get_all_counters.counter_name;
1556         IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1557           FND_LOG.STRING(G_LEVEL_STATEMENT,
1558                          L_DEBUG_KEY,
1559                          ' l_get_all_counters.counter_name = ' || l_get_all_counters.counter_name ||
1560                          ', i = ' || i || ', Calling update_reading_cn');
1561         END IF;
1562         update_reading_cn(l_utilization_rec);
1563         i := i+1;
1564       END LOOP;
1565     END IF;
1566     IF i=0 THEN
1567       FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
1568       FND_MSG_PUB.add;
1569       RAISE FND_API.G_EXC_ERROR;
1570     END IF;
1571   END IF;
1572   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1573     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure.');
1574   END IF;
1575 END update_reading_all;
1576 
1577 ---------------------------------------------------------------------------------
1578 
1579 FUNCTION get_counter_ratio(p_start_instance_id IN NUMBER,
1580                            p_desc_instance_id  IN NUMBER,
1581                            p_uom_code          IN VARCHAR2,
1582                            p_rule_code         IN VARCHAR2)
1583 RETURN NUMBER IS
1584   -- for counter rules given a relationship_id.
1585   CURSOR ahl_ctr_rule_csr (c_relationship_id NUMBER,
1586                            c_uom_code        VARCHAR2,
1587                            c_rule_code       VARCHAR2) IS
1588     SELECT ratio
1589       FROM ahl_ctr_update_rules
1590      WHERE relationship_id = c_relationship_id
1591        AND rule_code = c_rule_code
1592        AND uom_code  = c_uom_code;
1593 
1594   CURSOR get_ancestors(c_start_instance_id NUMBER, c_desc_instance_id NUMBER) IS
1595     SELECT object_id,
1596            subject_id,
1597            to_number(position_reference) relationship_id
1598       FROM csi_ii_relationships
1599 START WITH subject_id = c_desc_instance_id
1600        AND relationship_type_code = 'COMPONENT-OF'
1601        AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1602        AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1603 CONNECT BY subject_id = PRIOR object_id
1604        AND subject_id <> c_start_instance_id
1605        AND relationship_type_code = 'COMPONENT-OF'
1606        AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1607        AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1608 
1609   l_rule_code             ahl_ctr_update_rules.rule_code%TYPE := p_rule_code;
1610   l_ratio                 NUMBER;
1611   l_total_ratio           NUMBER;
1612   l_position_ref          NUMBER;
1613   l_uom_code              ahl_ctr_update_rules.uom_code%TYPE;
1614   l_match_found_flag      BOOLEAN;
1615   l_table_count           NUMBER;
1616   l_posn_master_config_id NUMBER;
1617   L_DEBUG_KEY       CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Get_Counter_Ratio';
1618 
1619 BEGIN
1620   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1621     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Function' ||
1622                    ', p_rule_code = ' || p_rule_code);
1623   END IF;
1624   IF (p_rule_code IS NULL OR p_rule_code = FND_API.G_MISS_CHAR) THEN
1625     l_rule_code := 'STANDARD';
1626   END IF;
1627 
1628   l_total_ratio := 1;
1629 
1630   FOR l_get_ancestor IN get_ancestors(p_start_instance_id, p_desc_instance_id) LOOP
1631     OPEN ahl_ctr_rule_csr(l_get_ancestor.relationship_id, p_uom_code, l_rule_code);
1632     FETCH ahl_ctr_rule_csr INTO l_ratio;
1633     IF ahl_ctr_rule_csr%FOUND THEN
1634       l_total_ratio := l_total_ratio * l_ratio;
1635       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1636         FND_LOG.STRING(G_LEVEL_STATEMENT,
1637                        L_DEBUG_KEY,
1638                        'l_ratio = ' || l_ratio || ', Setting l_total_ratio to ' || l_total_ratio);
1639       END IF;
1640     END IF;
1641     CLOSE ahl_ctr_rule_csr;
1642   END LOOP;
1643 
1644   IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1645     FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Function' ||
1646                    '. Returning l_total_ratio as ' || l_total_ratio);
1647   END IF;
1648 
1649   RETURN l_total_ratio;
1650 
1651 EXCEPTION
1652   WHEN INVALID_NUMBER THEN
1653     FND_MESSAGE.set_name('AHL','AHL_UC_INST_POSITION_INVALID');
1654     FND_MSG_PUB.add;
1655     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1656 END get_counter_ratio;
1657 
1658 END AHL_UC_UTILIZATION_PVT;