1 PACKAGE BODY AHL_UC_UTILIZATION_PVT AS
2 /* $Header: AHLVUCUB.pls 120.8.12020000.2 2012/12/07 15:44:09 sareepar 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 -- SATHAPLI::Bug 8765956, 07-Aug-2009, re-introducing NVL usage.
777 -- NOTE: NVL() should be put for the entire inner SELECT, as it should take effect even if this inner SELECT doesn't
778 -- fetch any rows.
779 SELECT NVL((select ccr.net_reading
780 from csi_counter_readings ccr
781 where ccr.counter_value_id = c.ctr_val_max_seq_no), 0) counter_reading,
782 DEFAULTED_GROUP_ID counter_group_id
783 FROM CSI_COUNTERS_B C
784 WHERE counter_id = c_counter_id
785 -- Changes by jaramana on 28-DEC-2009 for bug 9229943
786 -- Lock the CSI_COUNTERS_B row to prevent incorrect updates
787 FOR UPDATE OF c.ctr_val_max_seq_no;
788
789 -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
790 CURSOR is_counter_change_type_csr(c_counter_id NUMBER) IS
791 select 'Y' from CSI_COUNTERS_B
792 where counter_id = c_counter_id
793 and reading_type = 2;
794
795 l_change_type_flag VARCHAR2(1) := 'N';
796 -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
797
798 l_counter_grp_id NUMBER;
799 l_reading_value NUMBER;
800 l_start_current_value NUMBER;
801
802 l_ctr_grp_log_rec CS_CTR_CAPTURE_READING_PUB.ctr_grp_log_rec_type;
803 l_ctr_rdg_tbl CS_CTR_CAPTURE_READING_PUB.ctr_rdg_tbl_type;
804 l_prop_rdg_tbl CS_CTR_CAPTURE_READING_PUB.prop_rdg_tbl_type;
805 l_return_status VARCHAR2(3);
806 l_msg_count NUMBER;
807 l_msg_data VARCHAR2(2000);
808 l_msg_index_out NUMBER;
809 L_DEBUG_KEY CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_Id';
810
811 BEGIN
812 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
813 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
814 END IF;
815
816 -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
817 OPEN is_counter_change_type_csr(p_utilization_rec.counter_id);
818 FETCH is_counter_change_type_csr INTO l_change_type_flag;
819 IF (is_counter_change_type_csr%FOUND) THEN
820 l_change_type_flag := 'Y';
821 ELSE
822 l_change_type_flag := 'N';
823 END IF;
824 CLOSE is_counter_change_type_csr;
825 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
826 FND_LOG.STRING(G_LEVEL_STATEMENT, L_DEBUG_KEY, 'Counter is change type: ' || l_change_type_flag);
827 END IF;
828 -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
829
830 OPEN get_current_value_id(p_utilization_rec.counter_id);
831 FETCH get_current_value_id INTO l_start_current_value, l_counter_grp_id;
832 IF get_current_value_id%NOTFOUND THEN
833 FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
834 FND_MSG_PUB.add;
835 CLOSE get_current_value_id;
836 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
837 ELSE
838 CLOSE get_current_value_id;
839 END IF;
840 IF p_utilization_rec.delta_flag = 'Y' THEN
841 -- Begin Changes by jaramana on Feb 20, 2008 for Bug 6782765
842 IF (l_change_type_flag = 'Y') THEN
843 -- For Change type counters, always pass the delta value
844 l_reading_value := p_utilization_rec.reading_value;
845 ELSE
846 -- For other counters, always pass the total value
847 l_reading_value := l_start_current_value+p_utilization_rec.reading_value;
848 END IF;
849 ELSE
850 -- Not Delta
851 IF (l_change_type_flag = 'Y') THEN
852 -- For Change type counters, delta_flag should always be Y
853 FND_MESSAGE.set_name('AHL', 'AHL_UC_DELTA_FLAG_INVALID');
854 FND_MESSAGE.set_token('FLAG', p_utilization_rec.delta_flag);
855 FND_MSG_PUB.add;
856 RAISE FND_API.G_EXC_ERROR;
857 END IF;
858 -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
859 l_reading_value := p_utilization_rec.reading_value;
860 END IF;
861 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
862 FND_LOG.STRING(G_LEVEL_STATEMENT,
863 L_DEBUG_KEY,
864 'l_start_current_value = ' || l_start_current_value ||
865 ', p_utilization_rec.delta_flag = ' || p_utilization_rec.delta_flag ||
866 ', p_utilization_rec.reading_value = ' || p_utilization_rec.reading_value ||
867 ', Setting l_reading_value to ' || l_reading_value);
868 END IF;
869
870 -- Update reading for the counter.
871 l_ctr_grp_log_rec.counter_group_id := l_counter_grp_id;
872 l_ctr_grp_log_rec.value_timestamp := SYSDATE;
873 l_ctr_grp_log_rec.source_transaction_id := p_utilization_rec.csi_item_instance_id;
874 l_ctr_grp_log_rec.source_transaction_code := 'CP';
875
876 l_ctr_rdg_tbl(1).counter_id := p_utilization_rec.counter_id;
877 l_ctr_rdg_tbl(1).value_timestamp := p_utilization_rec.reading_date;
878 l_ctr_rdg_tbl(1).counter_reading := l_reading_value;
879 l_ctr_rdg_tbl(1).valid_flag := 'Y';
880 -- Changed from 'Y' to 'N' by jaramana on July 10, 2007 for bug 6127957
881 l_ctr_rdg_tbl(1).override_valid_flag := 'N';
882 --Call CS Counter Update API to update the counter_reading of the start instance
883 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
884 FND_LOG.STRING(G_LEVEL_STATEMENT,
885 L_DEBUG_KEY,
886 'About to call CS_CTR_CAPTURE_READING_PUB.capture_counter_reading');
887 END IF;
888 CS_CTR_CAPTURE_READING_PUB.capture_counter_reading(
889 p_api_version_number => 1.0,
890 p_init_msg_list => FND_API.G_FALSE,
891 p_commit => FND_API.G_FALSE,
892 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
893 p_ctr_grp_log_rec => l_ctr_grp_log_rec,
894 p_ctr_rdg_tbl => l_ctr_rdg_tbl,
895 p_prop_rdg_tbl => l_prop_rdg_tbl,
896 x_return_status => l_return_status,
897 x_msg_count => l_msg_count,
898 x_msg_data => l_msg_data );
899 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
900 FND_LOG.STRING(G_LEVEL_STATEMENT,
901 L_DEBUG_KEY,
902 'Returned from call to CS_CTR_CAPTURE_READING_PUB.capture_counter_reading. l_return_status = ' || l_return_status);
903 END IF;
904 IF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
905 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
906 ELSIF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
907 RAISE FND_API.G_EXC_ERROR;
908 END IF;
909 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
910 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end',
911 'Exiting Procedure.');
912 END IF;
913 END update_reading_id;
914
915 ---------------------------------------------------------------------------------
916
917 --Update the counter reading value of the start instance and all of its components (if
918 --cascade_flag = 'Y'). This procedure assumes the given counter name exists for the start
919 --instance
920 PROCEDURE update_reading_ins(p_utilization_rec IN utilization_rec_type) IS
921 CURSOR csi_relationships_csr(c_csi_item_instance_id NUMBER) IS
922 SELECT subject_id csi_item_instance_id, position_reference
923 FROM csi_ii_relationships
924 START WITH object_id = c_csi_item_instance_id
925 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
926 AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
927 AND relationship_type_code = 'COMPONENT-OF'
928 CONNECT BY object_id = PRIOR subject_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
933 -- Get current counter reading values based on the counter_id
934 -- Cursor get_current_value_id commented out by jaramana on on June 13, 2007
935 -- while fixing bug 6123549 since this cursor is not used in this procedure at all.
936 /***
937 CURSOR get_current_value_id(c_counter_id NUMBER) IS
938 SELECT nvl(counter_reading,0) counter_reading,
939 counter_group_id,
940 uom_code
941 FROM csi_cp_counters_v
942 WHERE counter_id = c_counter_id;
943 ***/
944 -- Get current counter reading values based on the counter_name
945 -- Cursor changed by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
946 -- Removed the use of csi_cp_counters_v and uptook
947 -- changes made via Counters bug 7561677 (FP of 7374316)
948 CURSOR get_current_value_name(c_instance_id NUMBER,
949 c_counter_name VARCHAR2) IS
950 -- SATHAPLI::Bug 8765956, 07-Aug-2009, re-introducing NVL usage.
951 -- NOTE: NVL() should be put for the entire inner SELECT, as it should take effect even if this inner SELECT doesn't
952 -- fetch any rows.
953 SELECT C.DEFAULTED_GROUP_ID counter_group_id,
954 NVL((select ccr.net_reading
955 from csi_counter_readings ccr
956 where ccr.counter_value_id = c.ctr_val_max_seq_no), 0) counter_reading,
957 C.COUNTER_ID counter_id,
958 C.START_DATE_ACTIVE start_date_active,
959 C.END_DATE_ACTIVE end_date_active,
960 C.UOM_CODE uom_code
961 FROM CSI_COUNTERS_VL C, CSI_COUNTER_ASSOCIATIONS CCA
962 WHERE C.COUNTER_ID = CCA.COUNTER_ID(+)
963 AND CCA.SOURCE_OBJECT_CODE = 'CP'
964 AND CCA.SOURCE_OBJECT_ID = c_instance_id
965 AND C.COUNTER_TEMPLATE_NAME = c_counter_name
966 AND trunc(nvl(C.start_date_active, sysdate)) <= trunc(sysdate)
967 AND trunc(nvl(C.end_date_active, sysdate+1)) > trunc(sysdate)
968 -- Changes by jaramana on 28-DEC-2009 for bug 9229943
969 -- Lock the CSI_COUNTERS_VL row to prevent incorrect updates
970 FOR UPDATE OF c.ctr_val_max_seq_no;
971
972 l_get_current_value_name get_current_value_name%ROWTYPE;
973
974 -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
975 CURSOR is_counter_change_type_csr(c_counter_id NUMBER) IS
976 select 'Y' from CSI_COUNTERS_B
977 where counter_id = c_counter_id
978 and reading_type = 2;
979
980 l_change_type_flag VARCHAR2(1) := 'N';
981 -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
982
983 l_utilization_rec utilization_rec_type;
984 l_ratio NUMBER;
985 l_reading_value NUMBER;
986 l_start_current_value NUMBER;
987 l_uom_code cs_counters.uom_code%TYPE;
988
989 l_ctr_grp_log_rec CS_CTR_CAPTURE_READING_PUB.ctr_grp_log_rec_type;
990 l_ctr_rdg_tbl CS_CTR_CAPTURE_READING_PUB.ctr_rdg_tbl_type;
991 l_prop_rdg_tbl CS_CTR_CAPTURE_READING_PUB.prop_rdg_tbl_type;
992 l_return_status VARCHAR2(3);
993 l_msg_count NUMBER;
994 l_msg_data VARCHAR2(2000);
995 l_msg_index_out NUMBER;
996 L_DEBUG_KEY CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_Ins';
997
998 BEGIN
999 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1000 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1001 END IF;
1002 l_utilization_rec := p_utilization_rec;
1003 --First get the current counter reading value for the start instance
1004 --This procedure assumes that counter exists for the instance
1005 OPEN get_current_value_name(l_utilization_rec.csi_item_instance_id,
1006 l_utilization_rec.counter_name);
1007 FETCH get_current_value_name INTO l_get_current_value_name;
1008 IF get_current_value_name%NOTFOUND THEN
1009 FND_MESSAGE.set_name('AHL','AHL_UC_CTR_INST_INVALID');
1010 FND_MESSAGE.set_token('COUNTER', l_utilization_rec.counter_name);
1011 FND_MESSAGE.set_token('INSTANCE', l_utilization_rec.csi_item_instance_id);
1012 FND_MSG_PUB.add;
1013 CLOSE get_current_value_name;
1014 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1015 ELSE
1016 CLOSE get_current_value_name;
1017 END IF;
1018 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1019 FND_LOG.STRING(G_LEVEL_STATEMENT,
1020 L_DEBUG_KEY,
1021 'l_get_current_value_name.counter_id = ' || l_get_current_value_name.counter_id ||
1022 ', l_get_current_value_name.counter_reading = ' || l_get_current_value_name.counter_reading ||
1023 ', l_get_current_value_name.uom_code = ' || l_get_current_value_name.uom_code ||
1024 ', l_get_current_value_name.start_date_active = ' || l_get_current_value_name.start_date_active ||
1025 ', l_get_current_value_name.end_date_active = ' || l_get_current_value_name.end_date_active);
1026 END IF;
1027
1028 l_utilization_rec.counter_id := l_get_current_value_name.counter_id;
1029
1030 -- Begin changes by jaramana on Feb 20, 2008 for Bug 6782765
1031 OPEN is_counter_change_type_csr(l_utilization_rec.counter_id);
1032 FETCH is_counter_change_type_csr INTO l_change_type_flag;
1033 IF (is_counter_change_type_csr%FOUND) THEN
1034 l_change_type_flag := 'Y';
1035 ELSE
1036 l_change_type_flag := 'N';
1037 END IF;
1038 CLOSE is_counter_change_type_csr;
1039 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1040 FND_LOG.STRING(G_LEVEL_STATEMENT, L_DEBUG_KEY, 'Counter is change type: ' || l_change_type_flag);
1041 END IF;
1042 -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
1043
1044 l_start_current_value := l_get_current_value_name.counter_reading;
1045 l_uom_code := l_get_current_value_name.uom_code;
1046 update_reading_id(l_utilization_rec);
1047 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1048 FND_LOG.STRING(G_LEVEL_STATEMENT,
1049 L_DEBUG_KEY, 'Returned from call to update_reading_id');
1050 END IF;
1051
1052 IF (l_utilization_rec.cascade_flag = 'Y') THEN
1053 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1054 FND_LOG.STRING(G_LEVEL_STATEMENT,
1055 L_DEBUG_KEY, 'l_utilization_rec.cascade_flag = Y');
1056 END IF;
1057 -- Process for config items.
1058 FOR child_rec IN csi_relationships_csr(p_utilization_rec.csi_item_instance_id) LOOP
1059 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1060 FND_LOG.STRING(G_LEVEL_STATEMENT,
1061 L_DEBUG_KEY, 'Processing child instance ' || child_rec.csi_item_instance_id);
1062 END IF;
1063 -- Get counter ratio.
1064 IF ahl_util_uc_pkg.extra_node(child_rec.csi_item_instance_id, l_utilization_rec.csi_item_instance_id) THEN
1065 l_ratio := 1;
1066 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1067 FND_LOG.STRING(G_LEVEL_STATEMENT,
1068 L_DEBUG_KEY, 'Instance is an extra node. Setting l_ratio to 1');
1069 END IF;
1070 ELSE
1071 l_ratio := get_counter_ratio(l_utilization_rec.csi_item_instance_id,
1072 child_rec.csi_item_instance_id,
1073 l_uom_code,
1074 l_utilization_rec.rule_code);
1075 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1076 FND_LOG.STRING(G_LEVEL_STATEMENT,
1077 L_DEBUG_KEY, 'Instance is not an extra node. Setting l_ratio to ' || l_ratio);
1078 END IF;
1079 END IF;
1080
1081 -- Get current counter reading values
1082 OPEN get_current_value_name(child_rec.csi_item_instance_id, l_utilization_rec.counter_name);
1083 FETCH get_current_value_name INTO l_get_current_value_name;
1084 IF get_current_value_name%FOUND THEN
1085 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1086 FND_LOG.STRING(G_LEVEL_STATEMENT,
1087 L_DEBUG_KEY, 'get_current_value_name%FOUND is TRUE. ' ||
1088 'l_get_current_value_name.counter_reading = ' || l_get_current_value_name.counter_reading);
1089 END IF;
1090 --Else the given counter name doesn't apply to this instance
1091 --Ensure that if the same counter existing for the component instance, then the counter's
1092 --UOM should be exactly the same as that of start instance's counter. Cheng has confirmed
1093 --this point with Barry.
1094 IF l_get_current_value_name.uom_code <> l_uom_code THEN
1095 FND_MESSAGE.set_name('AHL','AHL_UC_CTR_UOM_INVALID');
1096 FND_MESSAGE.set_token('COUNTER', l_utilization_rec.counter_name);
1097 FND_MESSAGE.set_token('INSTANCE', child_rec.csi_item_instance_id);
1098 FND_MESSAGE.set_token('UOM', l_get_current_value_name.uom_code);
1099 FND_MSG_PUB.add;
1100 CLOSE get_current_value_name;
1101 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1102 ELSE
1103 CLOSE get_current_value_name;
1104 END IF;
1105
1106 IF l_utilization_rec.delta_flag = 'Y' THEN
1107 -- Begin Changes by jaramana on Feb 20, 2008 for Bug 6782765
1108 IF (l_change_type_flag = 'Y') THEN
1109 -- For Change type counters, always pass the multiplied delta value
1110 l_reading_value := l_ratio*l_utilization_rec.reading_value;
1111 ELSE
1112 -- For other counters, always pass the total value
1113 l_reading_value := l_get_current_value_name.counter_reading+l_ratio*l_utilization_rec.reading_value;
1114 END IF;
1115 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1116 FND_LOG.STRING(G_LEVEL_STATEMENT,
1117 L_DEBUG_KEY, 'l_utilization_rec.delta_flag is Y. Setting l_reading_value to ' || l_reading_value);
1118 END IF;
1119 ELSE
1120 -- Not Delta
1121 IF (l_change_type_flag = 'Y') THEN
1122 -- For Change type counters, delta_flag should always be Y
1123 FND_MESSAGE.set_name('AHL', 'AHL_UC_DELTA_FLAG_INVALID');
1124 FND_MESSAGE.set_token('FLAG', l_utilization_rec.delta_flag);
1125 FND_MSG_PUB.add;
1126 RAISE FND_API.G_EXC_ERROR;
1127 END IF;
1128 -- End changes by jaramana on Feb 20, 2008 for Bug 6782765
1129 l_reading_value := l_get_current_value_name.counter_reading+
1130 l_ratio*(l_utilization_rec.reading_value-l_start_current_value);
1131 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1132 FND_LOG.STRING(G_LEVEL_STATEMENT,
1133 L_DEBUG_KEY, 'l_utilization_rec.delta_flag is not Y. Setting l_reading_value to ' || l_reading_value);
1134 END IF;
1135 END IF;
1136 -- Update reading for the counter.
1137 l_ctr_grp_log_rec.counter_group_id := l_get_current_value_name.counter_group_id;
1138 l_ctr_grp_log_rec.value_timestamp := SYSDATE;
1139 l_ctr_grp_log_rec.source_transaction_id := child_rec.csi_item_instance_id;
1140 l_ctr_grp_log_rec.source_transaction_code := 'CP';
1141 l_ctr_rdg_tbl(1).counter_id := l_get_current_value_name.counter_id;
1142 l_ctr_rdg_tbl(1).value_timestamp := l_utilization_rec.reading_date;
1143 l_ctr_rdg_tbl(1).counter_reading := l_reading_value;
1144 l_ctr_rdg_tbl(1).valid_flag := 'Y';
1145 -- Changed from 'Y' to 'N' by jaramana on July 10, 2007 for bug 6127957
1146 l_ctr_rdg_tbl(1).override_valid_flag := 'N';
1147 --Call CS Counter Update API to update the counter_reading of the start instance
1148 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1149 FND_LOG.STRING(G_LEVEL_STATEMENT,
1150 L_DEBUG_KEY, 'About to call CS_CTR_CAPTURE_READING_PUB.capture_counter_reading with ' ||
1151 'l_ctr_rdg_tbl(1).counter_reading = ' || l_ctr_rdg_tbl(1).counter_reading ||
1152 ', l_ctr_rdg_tbl(1).counter_id = ' || l_ctr_rdg_tbl(1).counter_id ||
1153 ', l_ctr_rdg_tbl(1).value_timestamp = ' || l_ctr_rdg_tbl(1).value_timestamp);
1154 END IF;
1155 CS_CTR_CAPTURE_READING_PUB.capture_counter_reading(
1156 p_api_version_number => 1.0,
1157 p_init_msg_list => FND_API.G_FALSE,
1158 p_commit => FND_API.G_FALSE,
1159 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
1160 p_ctr_grp_log_rec => l_ctr_grp_log_rec,
1161 p_ctr_rdg_tbl => l_ctr_rdg_tbl,
1162 p_prop_rdg_tbl => l_prop_rdg_tbl,
1163 x_return_status => l_return_status,
1164 x_msg_count => l_msg_count,
1165 x_msg_data => l_msg_data);
1166 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1167 FND_LOG.STRING(G_LEVEL_STATEMENT,
1168 L_DEBUG_KEY, 'Returned from call to CS_CTR_CAPTURE_READING_PUB.capture_counter_reading. l_return_status = ' || l_return_status);
1169 END IF;
1170 IF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1171 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1172 ELSIF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1173 RAISE FND_API.G_EXC_ERROR;
1174 END IF;
1175 ELSE
1176 CLOSE get_current_value_name;
1177 -- Added by jaramana on October 29, 2007 for bug 6513576
1178 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1179 FND_LOG.STRING(G_LEVEL_STATEMENT,
1180 L_DEBUG_KEY, 'get_current_value_name%FOUND is FALSE.');
1181 END IF;
1182 END IF;
1183 END LOOP;
1184 END IF;
1185 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1186 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure.');
1187 END IF;
1188 END update_reading_ins;
1189
1190 ---------------------------------------------------------------------------------
1191
1192 PROCEDURE update_reading_cn(p_utilization_rec IN utilization_rec_type) IS
1193 TYPE instance_tbl_type IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
1194 /** Begin changes by jaramana on October 29, 2007 for bug 6513576
1195 Cannot use cs_counters and cs_counter_groups anymore **/
1196 -- Cursor changed by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1197 -- Removed the use of csi_cp_counters_v
1198 CURSOR get_components_counter(c_instance_id NUMBER, c_counter_name VARCHAR2) IS
1199 SELECT CI.subject_id
1200 FROM csi_ii_relationships CI
1201 WHERE EXISTS (SELECT 'X'
1202 /*
1203 FROM cs_counters CC,
1204 cs_counter_groups CG
1205 WHERE CC.counter_group_id = CG.counter_group_id
1206 AND CG.source_object_id = CI.subject_id
1207 AND CG.source_object_code = 'CP'
1208 AND CC.name = c_counter_name
1209 AND trunc(nvl(CC.start_date_active,sysdate)) <= trunc(sysdate)
1210 AND trunc(nvl(CC.end_date_active,sysdate+1)) > trunc(sysdate))
1211 */
1212 /*
1213 FROM CSI_CP_COUNTERS_V CCCV
1214 WHERE CCCV.CUSTOMER_PRODUCT_ID = CI.subject_id
1215 AND CCCV.COUNTER_TEMPLATE_NAME = c_counter_name
1216 AND trunc(nvl(CCCV.start_date_active, sysdate)) <= trunc(sysdate)
1217 AND trunc(nvl(CCCV.end_date_active, sysdate+1)) > trunc(sysdate))
1218 */
1219 FROM CSI_COUNTERS_VL C, CSI_COUNTER_ASSOCIATIONS CCA
1220 WHERE CCA.SOURCE_OBJECT_ID = CI.subject_id
1221 AND C.COUNTER_ID = CCA.COUNTER_ID(+)
1222 AND CCA.SOURCE_OBJECT_CODE = 'CP'
1223 AND C.COUNTER_TEMPLATE_NAME = c_counter_name
1224 AND trunc(nvl(C.start_date_active, sysdate)) <= trunc(sysdate)
1225 AND trunc(nvl(C.end_date_active, sysdate+1)) > trunc(sysdate))
1226 START WITH object_id = c_instance_id
1227 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1228 AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
1229 AND relationship_type_code = 'COMPONENT-OF'
1230 CONNECT BY object_id = PRIOR subject_id
1231 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1232 AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
1233 AND relationship_type_code = 'COMPONENT-OF';
1234
1235 CURSOR get_all_ancestors(c_desc_instance_id NUMBER, c_ance_instance_id NUMBER) IS
1236 SELECT object_id
1237 FROM csi_ii_relationships
1238 START WITH subject_id = c_desc_instance_id
1239 AND object_id <> c_ance_instance_id
1240 -- This condition is really required because of the extreme case in which
1241 -- subject_id = c_desc_instance_id and object_id happens to be c_ance_instance_id
1242 -- thus it will include c_ance_instance_id and probably all of its ancestors if it has.
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 CONNECT BY subject_id = PRIOR object_id
1247 AND object_id <> c_ance_instance_id
1248 AND trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
1249 AND trunc(nvl(active_end_date,sysdate+1)) > trunc(sysdate)
1250 AND relationship_type_code = 'COMPONENT-OF';
1251
1252 -- Get counters that match on a given counter name.
1253 CURSOR cs_counters_name_csr(c_csi_item_instance_id NUMBER, c_name VARCHAR2) IS
1254 /*
1255 SELECT ctr.name counter_name, ctr.counter_id, ctr.uom_code, cgrp.counter_group_id
1256 FROM cs_counter_groups cgrp, cs_counters ctr
1257 WHERE cgrp.counter_group_id = ctr.counter_group_id
1258 AND cgrp.source_object_code = 'CP'
1259 AND cgrp.source_object_id = c_csi_item_instance_id
1260 AND ctr.name = c_name
1261 AND trunc(sysdate) >= trunc(nvl(ctr.start_date_active,sysdate))
1262 AND trunc(sysdate) <= trunc(nvl(ctr.end_date_active,sysdate+1));
1263 */
1264 SELECT CCCV.COUNTER_TEMPLATE_NAME counter_name, CCCV.counter_id, CCCV.uom_code, CCCV.counter_group_id
1265 FROM CSI_CP_COUNTERS_V CCCV
1266 WHERE CCCV.CUSTOMER_PRODUCT_ID = c_csi_item_instance_id
1267 AND CCCV.COUNTER_TEMPLATE_NAME = c_name
1268 AND trunc(nvl(CCCV.start_date_active, sysdate)) <= trunc(sysdate)
1269 AND trunc(nvl(CCCV.end_date_active, sysdate+1)) > trunc(sysdate);
1270 /** End changes by jaramana on October 29, 2007 for bug 6513576 **/
1271 l_cs_counters_name_csr cs_counters_name_csr%ROWTYPE;
1272
1273 -- Get current counter reading values based on the counter_id
1274 -- Cursor get_current_value_id commented out by jaramana on on June 13, 2007
1275 -- while fixing bug 6123549 since this cursor is not used in this procedure at all.
1276 /***
1277 CURSOR get_current_value_id(c_counter_id NUMBER) IS
1278 SELECT nvl(counter_reading,0) counter_reading,
1279 counter_group_id,
1280 uom_code
1281 FROM csi_cp_counters_v
1282 WHERE counter_id = c_counter_id;
1283 ***/
1284
1285 l_utilization_rec utilization_rec_type;
1286 l_ctr_grp_log_rec CS_CTR_CAPTURE_READING_PUB.ctr_grp_log_rec_type;
1287 l_ctr_rdg_tbl CS_CTR_CAPTURE_READING_PUB.ctr_rdg_tbl_type;
1288 l_prop_rdg_tbl CS_CTR_CAPTURE_READING_PUB.prop_rdg_tbl_type;
1289 l_return_status VARCHAR2(3);
1290 l_msg_count NUMBER;
1291 l_msg_data VARCHAR2(2000);
1292 l_msg_index_out NUMBER;
1293 l_instance_tbl instance_tbl_type;
1294 l_inst_tmp_tbl instance_tbl_type;
1295 l_parents_tbl instance_tbl_type;
1296 l_inst_idx BINARY_INTEGER;
1297 l_parent_idx BINARY_INTEGER;
1298 l_keep_flag BOOLEAN;
1299 L_DEBUG_KEY CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_Cn';
1300
1301 BEGIN
1302 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1303 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1304 END IF;
1305 l_utilization_rec := p_utilization_rec;
1306 OPEN cs_counters_name_csr(l_utilization_rec.csi_item_instance_id,
1307 l_utilization_rec.counter_name);
1308 FETCH cs_counters_name_csr INTO l_cs_counters_name_csr;
1309 IF cs_counters_name_csr%FOUND THEN
1310 --p_utilization_rec.uom_code := l_cs_counters_name_csr.uom_code;
1311 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1312 FND_LOG.STRING(G_LEVEL_STATEMENT,
1313 L_DEBUG_KEY,
1314 'cs_counters_name_csr%FOUND. Calling update_reading_ins');
1315 END IF;
1316 update_reading_ins(l_utilization_rec);
1317 CLOSE cs_counters_name_csr;
1318 ELSE
1319 CLOSE cs_counters_name_csr;
1320 IF (NVL(l_utilization_rec.delta_flag, 'N') = 'N') THEN
1321 --The start instance doesn't have the given counter associated, reading value is
1322 --net reading but the counter doesn't exists for the start instance
1323 --So raise error and return, no need to go further down.
1324 FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
1325 FND_MSG_PUB.add;
1326 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1327 ELSE
1328 IF (NVL(l_utilization_rec.cascade_flag,'N') = 'Y') THEN
1329 --The start instance doesn't have the given counter associated, reading value is delta
1330 --reading and cascade_flag = 'Y', then get all of its highest level components which
1331 --have the given counter associated but their ancestors don't.
1332 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1333 FND_LOG.STRING(G_LEVEL_STATEMENT,
1334 L_DEBUG_KEY,
1335 'cs_counters_name_csr%FOUND is false. l_utilization_rec.delta_flag is Y and l_utilization_rec.cascade_flag is Y');
1336 END IF;
1337 l_inst_idx :=1;
1338 -- Begin changes made by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1339 OPEN get_components_counter(l_utilization_rec.csi_item_instance_id, l_utilization_rec.counter_name);
1340 FETCH get_components_counter BULK COLLECT INTO l_instance_tbl;
1341 CLOSE get_components_counter;
1342 l_inst_tmp_tbl := l_instance_tbl;
1343 /**
1344 FOR l_get_components_counter IN get_components_counter(l_utilization_rec.csi_item_instance_id,
1345 l_utilization_rec.counter_name) LOOP
1346 l_instance_tbl(l_inst_idx) := l_get_components_counter.subject_id;
1347 l_inst_tmp_tbl(l_inst_idx) := l_instance_tbl(l_inst_idx);
1348 --dbms_output.put_line('l_instance_tbl:'||l_inst_idx||' '||l_instance_tbl(l_inst_idx));
1349 l_inst_idx := l_inst_idx + 1;
1350 END LOOP;
1351 **/
1352 -- End changes made by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1353 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1354 FND_LOG.STRING(G_LEVEL_STATEMENT,
1355 L_DEBUG_KEY,
1356 'l_instance_tbl.count = ' || l_instance_tbl.count);
1357 END IF;
1358 IF l_instance_tbl.count > 0 THEN
1359 FOR i IN l_instance_tbl.FIRST..l_instance_tbl.LAST LOOP
1360 l_keep_flag := TRUE;
1361 --l_inst_tmp_tbl := l_instance_tbl;
1362 --l_inst_tmp_tbl.DELETE(i);
1363 l_parent_idx := 1;
1364 --l_parents_tbl needs to be reset after each loop
1365 IF l_parents_tbl.COUNT > 0 THEN
1366 l_parents_tbl.DELETE;
1367 END IF;
1368 FOR l_get_all_ancestors IN get_all_ancestors(l_instance_tbl(i), l_utilization_rec.csi_item_instance_id) LOOP
1369 l_parents_tbl(l_parent_idx) := l_get_all_ancestors.object_id;
1370 l_parent_idx := l_parent_idx + 1;
1371 END LOOP;
1372 IF l_parents_tbl.COUNT > 0 THEN
1373 <<OUTER1>>
1374 FOR j IN l_parents_tbl.FIRST..l_parents_tbl.LAST LOOP
1375 IF l_inst_tmp_tbl.COUNT > 0 THEN
1376 FOR k IN l_inst_tmp_tbl.FIRST..l_inst_tmp_tbl.LAST LOOP
1377 IF l_parents_tbl(j) = l_inst_tmp_tbl(k) THEN
1378 l_keep_flag := FALSE;
1379 EXIT OUTER1;
1380 END IF;
1381 END LOOP;
1382 END IF;
1383 END LOOP;
1384 END IF;
1385 IF NOT l_keep_flag AND l_instance_tbl.EXISTS(i) THEN
1386 l_instance_tbl.DELETE(i);
1387 END IF;
1388 END LOOP;
1389 END IF;
1390 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1391 FND_LOG.STRING(G_LEVEL_STATEMENT,
1392 L_DEBUG_KEY,
1393 'After processing, l_instance_tbl.count = ' || l_instance_tbl.count);
1394 END IF;
1395 FOR i IN l_instance_tbl.FIRST..l_instance_tbl.LAST LOOP
1396 IF l_instance_tbl.EXISTS(i) THEN
1397 l_utilization_rec.csi_item_instance_id := l_instance_tbl(i);
1398 --p_utilization_rec.cascade_flag := 'Y';
1399 update_reading_ins(l_utilization_rec);
1400 END IF;
1401 END LOOP;
1402 ELSE
1403 --The start instance doesn't have the given counter associated, reading value is delta
1404 --reading and cascade_flag = 'N', then raise error and stop.
1405 FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
1406 FND_MSG_PUB.add;
1407 RAISE FND_API.G_EXC_ERROR;
1408 END IF;
1409 END IF;
1410 END IF;
1411 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1412 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure.');
1413 END IF;
1414 END update_reading_cn;
1415
1416 ---------------------------------------------------------------------------------
1417
1418 PROCEDURE update_reading_all(p_utilization_rec IN utilization_rec_type,
1419 p_based_on IN VARCHAR2)
1420 IS
1421 l_utilization_rec utilization_rec_type;
1422 i NUMBER;
1423 L_DEBUG_KEY CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Update_Reading_All';
1424
1425 /** Begin changes by jaramana on October 29, 2007 for bug 6513576
1426 Cannot use cs_counters and cs_counter_groups anymore **/
1427 --Given start instance_id and uom_code, this cursor is used to get all of the distinct
1428 --counters this start instance has
1429 CURSOR get_inst_counters(c_instance_id NUMBER, c_uom_code VARCHAR2) IS
1430 SELECT DISTINCT CCCV.COUNTER_TEMPLATE_NAME counter_name
1431 FROM CSI_CP_COUNTERS_V CCCV
1432 WHERE CCCV.UOM_CODE = c_uom_code
1433 AND CCCV.CUSTOMER_PRODUCT_ID = c_instance_id
1434 AND trunc(nvl(CCCV.start_date_active, sysdate)) <= trunc(sysdate)
1435 AND trunc(nvl(CCCV.end_date_active, sysdate+1)) > trunc(sysdate);
1436
1437 --Given start instance_id and uom_code, this cursor is used to get all of the distinct
1438 --counters this start instance and all of its components have
1439 -- Cursor changed by jaramana on 03-DEC-2008 for bug 7426643 (FP of 7263702)
1440 -- Removed the use of csi_cp_counters_v
1441 CURSOR get_all_counters(c_instance_id NUMBER, c_uom_code VARCHAR2) IS
1442 SELECT DISTINCT C.COUNTER_TEMPLATE_NAME counter_name
1443 FROM CSI_COUNTERS_VL C, CSI_COUNTER_ASSOCIATIONS CCA
1444 WHERE C.UOM_CODE = c_uom_code
1445 AND trunc(nvl(C.start_date_active, sysdate)) <= trunc(sysdate)
1446 AND trunc(nvl(C.end_date_active, sysdate+1)) > trunc(sysdate)
1447 AND C.COUNTER_ID = CCA.COUNTER_ID(+)
1448 AND CCA.SOURCE_OBJECT_CODE = 'CP'
1449 AND CCA.SOURCE_OBJECT_ID IN (SELECT c_instance_id
1450 FROM DUAL
1451 UNION ALL
1452 SELECT subject_id
1453 FROM csi_ii_relationships CI
1454 START WITH object_id = c_instance_id
1455 AND trunc(nvl(CI.active_start_date,sysdate)) <= trunc(sysdate)
1456 AND trunc(nvl(CI.active_end_date,sysdate+1)) > trunc(sysdate)
1457 AND CI.relationship_type_code = 'COMPONENT-OF'
1458 CONNECT BY object_id = PRIOR subject_id
1459 AND trunc(nvl(CI.active_start_date,sysdate)) <= trunc(sysdate)
1460 AND trunc(nvl(CI.active_end_date,sysdate+1)) > trunc(sysdate)
1461 AND CI.relationship_type_code = 'COMPONENT-OF');
1462
1463 /** End changes by jaramana on October 29, 2007 for bug 6513576 **/
1464
1465 BEGIN
1466 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1467 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1468 END IF;
1469 l_utilization_rec := p_utilization_rec;
1470 IF (p_based_on = ':COUNTERID') THEN
1471 -- No cascade issue no matter whether cascade flag is set to 'Y' or 'N', just update the
1472 -- specific counter_id
1473 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1474 FND_LOG.STRING(G_LEVEL_STATEMENT,
1475 L_DEBUG_KEY,
1476 'p_based_on is COUNTERID. Calling update_reading_id');
1477 END IF;
1478 update_reading_id(l_utilization_rec);
1479 ELSIF (p_based_on = ':COUNTER') THEN
1480 --For a given pair of counter_name and instance_id, it will uniquely identify the counter_id(confirmed).
1481 --If the counter_name exsits in the start instance, and the cascade_flag = 'Y', then the counter ratio
1482 --for the components are calculated from the start instance(here reading_value(can be either delta
1483 --reading or net reading) refers to the counter of
1484 --the start instance). Otherwise, if the counter_name doesn't exist for the start instance and if the
1485 --reading value is net reading then raise error and stop, and if the reading value is delta reading,
1486 --then we get all of the highest level components of the start instance which
1487 --have the counter_name associated but all of their ancestors don't and make each of these components
1488 --as start point(assuming reading_value (only delta reading) refers to their counters) and calculate the
1489 --counter ratio of their own components.
1490 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1491 FND_LOG.STRING(G_LEVEL_STATEMENT,
1492 L_DEBUG_KEY,
1493 'p_based_on is COUNTER. Calling update_reading_cn');
1494 END IF;
1495 update_reading_cn(l_utilization_rec);
1496 ELSIF (p_based_on = ':UOM') THEN
1497 --For a given pair of UOM and instance_id, we may get none, one or multiple counters.
1498 --IF cascade_flag = 'Y' and delta_flag = 'Y', then we traverse down the UC tree with the start instance
1499 --as the starting point and get all of the distinct counters with the same UOM. Otherwise if delta_flag = 'N',
1500 --then we just get all the counters associated with the start instance with the same UOM. For all of these
1501 --distinct counters loop just like p_based_on = ':COUNTER'.
1502 i := 0;
1503 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1504 FND_LOG.STRING(G_LEVEL_STATEMENT,
1505 L_DEBUG_KEY,
1506 'p_based_on is UOM, l_utilization_rec.delta_flag = ' || l_utilization_rec.delta_flag);
1507 END IF;
1508 IF NVL(l_utilization_rec.delta_flag, 'N') = 'N' THEN
1509 FOR l_get_inst_counters IN get_inst_counters(l_utilization_rec.csi_item_instance_id,
1510 l_utilization_rec.uom_code) LOOP
1511 l_utilization_rec.counter_name := l_get_inst_counters.counter_name;
1512 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1513 FND_LOG.STRING(G_LEVEL_STATEMENT,
1514 L_DEBUG_KEY,
1515 'l_get_inst_counters.counter_name = ' || l_get_inst_counters.counter_name ||
1516 ', i = ' || i || ', Calling update_reading_cn');
1517 END IF;
1518 update_reading_cn(l_utilization_rec);
1519 i := i+1;
1520 END LOOP;
1521 ELSE
1522 FOR l_get_all_counters IN get_all_counters(l_utilization_rec.csi_item_instance_id,
1523 l_utilization_rec.uom_code) LOOP
1524 l_utilization_rec.counter_name := l_get_all_counters.counter_name;
1525 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1526 FND_LOG.STRING(G_LEVEL_STATEMENT,
1527 L_DEBUG_KEY,
1528 ' l_get_all_counters.counter_name = ' || l_get_all_counters.counter_name ||
1529 ', i = ' || i || ', Calling update_reading_cn');
1530 END IF;
1531 update_reading_cn(l_utilization_rec);
1532 i := i+1;
1533 END LOOP;
1534 END IF;
1535 IF i=0 THEN
1536 FND_MESSAGE.set_name('AHL','AHL_UC_INST_NO_CTR_FOUND');
1537 FND_MSG_PUB.add;
1538 RAISE FND_API.G_EXC_ERROR;
1539 END IF;
1540 END IF;
1541 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1542 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure.');
1543 END IF;
1544 END update_reading_all;
1545
1546 ---------------------------------------------------------------------------------
1547
1548 FUNCTION get_counter_ratio(p_start_instance_id IN NUMBER,
1549 p_desc_instance_id IN NUMBER,
1550 p_uom_code IN VARCHAR2,
1551 p_rule_code IN VARCHAR2)
1552 RETURN NUMBER IS
1553 -- for counter rules given a relationship_id.
1554 CURSOR ahl_ctr_rule_csr (c_relationship_id NUMBER,
1555 c_uom_code VARCHAR2,
1556 c_rule_code VARCHAR2) IS
1557 SELECT ratio
1558 FROM ahl_ctr_update_rules
1559 WHERE relationship_id = c_relationship_id
1560 AND rule_code = c_rule_code
1561 AND uom_code = c_uom_code;
1562
1563 CURSOR get_ancestors(c_start_instance_id NUMBER, c_desc_instance_id NUMBER) IS
1564 SELECT object_id,
1565 subject_id,
1566 to_number(position_reference) relationship_id
1567 FROM csi_ii_relationships
1568 START WITH subject_id = c_desc_instance_id
1569 AND relationship_type_code = 'COMPONENT-OF'
1570 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1571 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1572 CONNECT BY subject_id = PRIOR object_id
1573 AND subject_id <> c_start_instance_id
1574 AND relationship_type_code = 'COMPONENT-OF'
1575 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1576 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1577
1578 l_rule_code ahl_ctr_update_rules.rule_code%TYPE := p_rule_code;
1579 l_ratio NUMBER;
1580 l_total_ratio NUMBER;
1581 l_position_ref NUMBER;
1582 l_uom_code ahl_ctr_update_rules.uom_code%TYPE;
1583 l_match_found_flag BOOLEAN;
1584 l_table_count NUMBER;
1585 l_posn_master_config_id NUMBER;
1586 L_DEBUG_KEY CONSTANT VARCHAR2(150) := G_LOG_PREFIX || '.Get_Counter_Ratio';
1587
1588 BEGIN
1589 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1590 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Function' ||
1591 ', p_rule_code = ' || p_rule_code);
1592 END IF;
1593 IF (p_rule_code IS NULL OR p_rule_code = FND_API.G_MISS_CHAR) THEN
1594 l_rule_code := 'STANDARD';
1595 END IF;
1596
1597 l_total_ratio := 1;
1598
1599 FOR l_get_ancestor IN get_ancestors(p_start_instance_id, p_desc_instance_id) LOOP
1600 OPEN ahl_ctr_rule_csr(l_get_ancestor.relationship_id, p_uom_code, l_rule_code);
1601 FETCH ahl_ctr_rule_csr INTO l_ratio;
1602 IF ahl_ctr_rule_csr%FOUND THEN
1603 l_total_ratio := l_total_ratio * l_ratio;
1604 IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL) THEN
1605 FND_LOG.STRING(G_LEVEL_STATEMENT,
1606 L_DEBUG_KEY,
1607 'l_ratio = ' || l_ratio || ', Setting l_total_ratio to ' || l_total_ratio);
1608 END IF;
1609 END IF;
1610 CLOSE ahl_ctr_rule_csr;
1611 END LOOP;
1612
1613 IF (G_LEVEL_PROCEDURE >= G_CURRENT_RUNTIME_LEVEL) THEN
1614 FND_LOG.STRING(G_LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Function' ||
1615 '. Returning l_total_ratio as ' || l_total_ratio);
1616 END IF;
1617
1618 RETURN l_total_ratio;
1619
1620 EXCEPTION
1621 WHEN INVALID_NUMBER THEN
1622 FND_MESSAGE.set_name('AHL','AHL_UC_INST_POSITION_INVALID');
1623 FND_MSG_PUB.add;
1624 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1625 END get_counter_ratio;
1626
1627 END AHL_UC_UTILIZATION_PVT;