DBA Data[Home] [Help]

PACKAGE BODY: APPS.AHL_PRD_DISPOSITION_PVT

Source


1 PACKAGE BODY AHL_PRD_DISPOSITION_PVT AS
2 /* $Header: AHLVDISB.pls 120.17.12020000.2 2012/12/14 07:52:11 shnatu ship $ */
3 
4   G_PKG_NAME         CONSTANT  VARCHAR2(30) := 'AHL_PRD_DISPOSITION_PVT';
5   G_APP_NAME         CONSTANT  VARCHAR2(3) := 'AHL';
6   G_LOG_PREFIX       CONSTANT  VARCHAR2(60) := 'ahl.plsql.'||G_PKG_NAME||'.';
7 
8   g_module_type VARCHAR2(30)  := NULL;
9 
10   G_PART_CHANGE_INSTALL  CONSTANT VARCHAR2(1) := 'I';
11   G_PART_CHANGE_REMOVE   CONSTANT VARCHAR2(1) := 'R';
12   G_PART_CHANGE_SWAP     CONSTANT VARCHAR2(1) := 'S';
13 
14   G_WO_RELEASED_STATUS   CONSTANT VARCHAR2(1) := '3';
15 
16 ------------------------
17 -- Declare Local Functions --
18 ------------------------
19 --FUNCTION isPositionEmpty(p_path_position_id IN NUMBER)
20 --RETURN BOOLEAN;
21 
22  FUNCTION get_unit_instance_id(p_workorder_id IN NUMBER) RETURN NUMBER;
23  FUNCTION workorder_Editable(p_workorder_id IN NUMBER) RETURN BOOLEAN;
24  FUNCTION get_root_instance_id(p_instance_id IN NUMBER) RETURN NUMBER;
25  FUNCTION get_issued_quantity(p_disposition_id IN NUMBER) RETURN NUMBER;
26  -- Added function by rbhavsar on 09/27/2007 for Bug 6411059
27  FUNCTION root_node_in_uc_headers(p_instance_id IN NUMBER) RETURN BOOLEAN;
28 
29 ------------------------
30 -- Declare Procedures --
31 ------------------------
32 PROCEDURE create_disposition(
33     p_api_version           IN             NUMBER    := 1.0,
34     p_init_msg_list         IN             VARCHAR2  := FND_API.G_TRUE,
35     p_commit                IN             VARCHAR2  := FND_API.G_FALSE,
36     p_validation_level      IN             NUMBER    := FND_API.G_VALID_LEVEL_FULL,
37     p_module_type           IN             VARCHAR2  := NULL,
38     p_x_disposition_rec     IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
39     -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
40     p_mr_asso_tbl           IN             AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type,
41     x_return_status         OUT NOCOPY     VARCHAR2,
42     x_msg_count             OUT NOCOPY     NUMBER,
43     x_msg_data              OUT NOCOPY     VARCHAR2
44 );
45 
46 PROCEDURE update_disposition(
47     p_api_version           IN             NUMBER    := 1.0,
48     p_init_msg_list         IN             VARCHAR2  := FND_API.G_TRUE,
49     p_commit                IN             VARCHAR2  := FND_API.G_FALSE,
50     p_validation_level      IN             NUMBER    := FND_API.G_VALID_LEVEL_FULL,
51     p_module_type           IN             VARCHAR2  := NULL,
52     p_x_disposition_rec     IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
53     -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
54     p_mr_asso_tbl           IN             AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type,
55     x_return_status         OUT NOCOPY     VARCHAR2,
56     x_msg_count             OUT NOCOPY     NUMBER,
57     x_msg_data              OUT NOCOPY     VARCHAR2
58 );
59 
60 PROCEDURE CREATE_SR(
61     p_init_msg_list               IN  VARCHAR2  := FND_API.G_TRUE,
62     p_disposition_rec             IN  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
63     -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
64     p_mr_asso_tbl                 IN  AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type,
65     x_primary_sr_id               OUT NOCOPY  NUMBER,
66     x_non_routine_workorder_id	OUT NOCOPY  NUMBER,
67     x_return_status               OUT NOCOPY  VARCHAR2,
68     x_msg_count                   OUT NOCOPY  NUMBER,
69     x_msg_data                    OUT NOCOPY  VARCHAR2
70 );
71 
72 
73 PROCEDURE Validate_Disposition_Types (
74     x_return_status       OUT  NOCOPY    VARCHAR2,
75     x_msg_count           OUT  NOCOPY    NUMBER,
76     x_msg_data            OUT  NOCOPY    VARCHAR2,
77     p_disposition_rec     IN  AHL_PRD_DISPOSITION_PVT.disposition_rec_type);
78 
79 PROCEDURE Calculate_Status (
80     p_disposition_Rec     IN  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
81     x_status_code         OUT  NOCOPY   VARCHAR2);
82 
83 PROCEDURE convert_values_to_ids(p_x_prd_disposition_rec IN OUT NOCOPY AHL_PRD_DISPOSITION_PVT.disposition_rec_type);
84 
85 PROCEDURE validate_for_create(p_disposition_rec  IN  AHL_PRD_DISPOSITION_PVT.disposition_rec_type);
86 
87 PROCEDURE derive_columns(p_x_disposition_rec IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type);
88 
89 PROCEDURE validate_workorder(p_workorder_id IN NUMBER);
90 
91 PROCEDURE validate_path_position(p_path_position_id IN NUMBER);
92 
93 PROCEDURE validate_collection_id(p_collection_id IN NUMBER);
94 
95 PROCEDURE validate_item(p_inventory_item_id IN NUMBER, p_organization_id IN NUMBER, p_workorder_id IN NUMBER);
96 
97 PROCEDURE validate_instance(p_instance_id IN NUMBER, p_workorder_id IN NUMBER, p_path_position_id IN NUMBER,
98                             p_part_change_id IN NUMBER);
99 
100 PROCEDURE validate_wo_operation(p_workorder_id IN NUMBER, p_wo_operation_id IN NUMBER);
101 
102 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
103 -- Modified the API to take disposition quantity as an additional IN parameter.
104 PROCEDURE validate_part_change(p_part_change_id IN NUMBER, p_disp_instance_id IN NUMBER, p_disp_quantity IN NUMBER);
105 
106 PROCEDURE validate_Item_Control(p_item_id IN NUMBER, p_org_id IN NUMBER,
107                                 p_serial_number IN VARCHAR2,
108                                 p_item_rev_number IN VARCHAR2,
109                                 p_lot_number IN VARCHAR2);
110 
111 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
112 -- The API update_item_location and its use has been commented out. Its functionality will
113 -- now be handled in the API AHL_PRD_NONROUTINE_PVT.process_nonroutine_job.
114 
115 -- SURRKUMA :: ER 9213556 Create NR for Next Higher Position, 13-DEC-2010
116 -- Now update_item_location API is needed to move the non-serialized items to SR work order created for
117 -- parent position. It will be called only when the create NR for next higher position flag is checked.
118 -- Following Procedure and Function added by jaramana on October 8, 2007 for ER 5903256
119 PROCEDURE update_item_location(p_workorder_id  IN         NUMBER,
120                                p_instance_id   IN         NUMBER,
121                                x_return_status OUT NOCOPY VARCHAR2);
122 
123 FUNCTION Get_NonMWO_WIP_Entity_Id(p_workorder_id IN NUMBER) RETURN NUMBER;
124 
125 
126 ------------------------------------------------------------------
127 ----------- BEGIN DEFINITION OF PROCEDURES AND FUNCTIONS ---------
128 ------------------------------------------------------------------
129 -- Define procedure create_job_dispositions
130 -- This API is used to get all default dispositions for a job from its related route
131 -- and then put them into the dispostion entity.
132 PROCEDURE create_job_dispositions(
133   p_api_version           IN  NUMBER := 1.0,
134   p_init_msg_list         IN  VARCHAR2 := FND_API.G_FALSE,
135   p_commit                IN  VARCHAR2 := FND_API.G_FALSE,
136   p_validation_level      IN  NUMBER := FND_API.G_VALID_LEVEL_FULL,
137   x_return_status         OUT NOCOPY VARCHAR2,
138   x_msg_count             OUT NOCOPY NUMBER,
139   x_msg_data              OUT NOCOPY VARCHAR2,
140   p_workorder_id          IN  NUMBER)
141 IS
142   l_api_name       CONSTANT   VARCHAR2(30)   := 'create_job_dispositions';
143   l_api_version    CONSTANT   NUMBER         := 1.0;
144   l_return_status             VARCHAR2(1);
145   l_msg_count                 NUMBER;
146   l_msg_data                  VARCHAR2(2000);
147   l_relationship_id           NUMBER;
148   l_children_no               NUMBER;
149   l_route_mtl_req_tbl         ahl_ltp_mtl_req_pvt.route_mtl_req_tbl_type;
150   l_unit_instance_id          NUMBER;
151   l_installed_inst_id         NUMBER;
152   l_serial_number             csi_item_instances.serial_number%TYPE;
153   l_lot_number                csi_item_instances.lot_number%TYPE;
154   l_inv_item_id               NUMBER;
155   l_master_org_id             NUMBER;
156   l_last_vld_org_id           NUMBER;
157   l_disp_org_id               NUMBER;
158   l_lowest_unit_inst_id       NUMBER;
159   l_mapping_status            VARCHAR2(30);
160   l_disposition_id            NUMBER;
161   l_disposition_h_id          NUMBER;
162   l_dummy_char                VARCHAR2(1);
163   l_dummy_rowid               VARCHAR2(100);
164   l_dummy_num                 NUMBER;
165   i                           NUMBER;
166   CURSOR get_job_attrs IS
167 /*
168 SELECT route_id,
169            item_instance_id,
170            scheduled_start_date,
171            job_status_code,
172            job_number,
173            organization_id
174       FROM ahl_workorders_v
175      WHERE workorder_id = p_workorder_id;
176 */
177 -- Modified by SURRKUMA for Service Bulletin on 17-Jun-11
178 -- AnRaj: Changed query, Perf Bug#4908609,Issue#1
179 select   WO.route_id route_id,
180          NVL(VTS.INSTANCE_ID, VST.ITEM_INSTANCE_ID) item_instance_id,
181          WDJ.SCHEDULED_START_DATE scheduled_start_date,
182          WO.status_code job_status_code,
183          WO.workorder_name job_number,
184          VST.ORGANIZATION_ID organization_id,
185          VST.VISIT_ID visit_id
186 from     AHL_WORKORDERS WO,
187          WIP_DISCRETE_JOBS WDJ,
188          AHL_VISITS_VL VST,
189          AHL_VISIT_TASKS_VL VTS
190 where    WDJ.WIP_ENTITY_ID = WO.WIP_ENTITY_ID and
191          WO.VISIT_TASK_ID = VTS.VISIT_TASK_ID and
192          VST.VISIT_ID = VTS.VISIT_ID and
193          WO.WORKORDER_ID = p_workorder_id;
194 l_job_attrs get_job_attrs%ROWTYPE;
195 
196   CURSOR get_mtl_req_flags(c_rt_oper_material_id NUMBER) IS
197     SELECT --'N' include_flag, Once the column include_flag is added, then replace 'N' with it.
198            --Refer enhancement bug 3502592
199            exclude_flag
200       FROM ahl_rt_oper_materials
201      WHERE rt_oper_material_id = c_rt_oper_material_id;
202      l_mtl_req_flags get_mtl_req_flags%ROWTYPE;
203   CURSOR check_item_org(c_inventory_item_id NUMBER, c_organization_id NUMBER) IS
204     SELECT 'X'
205       FROM mtl_system_items_kfv
206      WHERE inventory_item_id = c_inventory_item_id
207        AND organization_id = c_organization_id;
208   CURSOR check_unit_instance(c_instance_id NUMBER) IS
209     SELECT csi_item_instance_id
210       FROM ahl_unit_config_headers
211      WHERE csi_item_instance_id = c_instance_id
212        AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
213   CURSOR get_sub_unit_instance(c_instance_id NUMBER) IS
214     SELECT object_id
215       FROM csi_ii_relationships
216      WHERE object_id IN (SELECT csi_item_instance_id
217                            FROM ahl_unit_config_headers
218                           WHERE trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE))
219 START WITH subject_id = c_instance_id
220        AND relationship_type_code = 'COMPONENT-OF'
221        AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
222        AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
223 CONNECT BY subject_id = PRIOR object_id
224        AND relationship_type_code = 'COMPONENT-OF'
225        AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
226        AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
227   CURSOR get_instance_attrs(c_instance_id NUMBER) IS
228     SELECT serial_number,
229            lot_number,
230            inventory_item_id,
231            last_vld_organization_id,
232            inv_master_organization_id
233       FROM csi_item_instances
234      WHERE instance_id = c_instance_id;
235 
236 BEGIN
237   --Initialize API return status to success
238   x_return_status := FND_API.G_RET_STS_SUCCESS;
239 
240   --Standard Start of API savepoint
241   SAVEPOINT create_job_dispositions;
242 
243   --Standard call to check for call compatibility.
244   IF NOT FND_API.compatible_api_call(
245     l_api_version,
246     p_api_version,
247     l_api_name,
248     G_PKG_NAME)
249   THEN
250     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
251   END IF;
252 
253   --Initialize message list if p_init_msg_list is set to TRUE.
254   IF FND_API.to_boolean( p_init_msg_list ) THEN
255     FND_MSG_PUB.initialize;
256   END IF;
257 
258   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
259     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
260                    G_LOG_PREFIX||l_api_name||': Begin API',
261                    'At the start of the procedure and p_workorder_id ='||p_workorder_id);
262   END IF;
263 
264   --Validate the input parameter
265   OPEN get_job_attrs;
266   FETCH get_job_attrs INTO l_job_attrs;
267   IF get_job_attrs%NOTFOUND THEN
268     --Comment out this check because the p_workoder_id passed should always be valid
269     /*
270     FND_MESSAGE.set_name('AHL', 'AHL_PRD_DISP_JOB_ID_INVALID');
271     FND_MESSAGE.set_token('JOBID', p_workorder_id);
272     FND_MSG_PUB.add;
273     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
274     CLOSE get_job_attrs;
275     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
276     */
277     CLOSE get_job_attrs;
278     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
279       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
280                      G_LOG_PREFIX||l_api_name||': After normal execution',
281                      'Returned but nothing done because the job is not in the view and it might be a master workorder!');
282     END IF;
283     RETURN;
284   ELSIF l_job_attrs.job_status_code IN (4, 12) THEN
285     --Complete(4) and Closed(12)
286     FND_MESSAGE.set_name('AHL', 'AHL_PRD_DISP_JOB_STS_INVALID');
287     FND_MESSAGE.set_token('JOB', l_job_attrs.job_number);
288     FND_MSG_PUB.add;
289     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
290     CLOSE get_job_attrs;
291     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
292   ELSIF l_job_attrs.item_instance_id IS NULL THEN
293     FND_MESSAGE.set_name('AHL', 'AHL_PRD_DISP_JOB_INST_NULL');
294     FND_MESSAGE.set_token('JOB', l_job_attrs.job_number);
295     FND_MSG_PUB.add;
296     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
297     CLOSE get_job_attrs;
298     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
299   ELSIF l_job_attrs.route_id IS NULL THEN
300     CLOSE get_job_attrs;
301     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
302       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
303                      G_LOG_PREFIX||l_api_name||': After normal execution',
304                     'Returned but nothing done because there is no route associated to the job');
305     END IF;
306     RETURN;
307   ELSE
308     CLOSE get_job_attrs;
309   END IF;
310 
311   --Call ahl_ltp_mtl_req_pvt.get_route_mtl_req to get the default dispositions for the job
312 
313   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
314     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
315                    G_LOG_PREFIX||l_api_name||': In normal execution',
316                    'Just before calling ahl_ltp_mtl_req_pvt.get_route_mtl_req and p_route_id='||
317                    l_job_attrs.route_id||' p_item_instance_id='||l_job_attrs.item_instance_id||
318                    ' p_requirement_date='||l_job_attrs.scheduled_start_date);
319   END IF;
320   ahl_ltp_mtl_req_pvt.get_route_mtl_req(
321     p_api_version           => 1.0,
322     p_init_msg_list         => FND_API.G_FALSE,
323     p_validation_level      => FND_API.G_VALID_LEVEL_FULL,
324     x_return_status         => l_return_status,
325     x_msg_count             => l_msg_count,
326     x_msg_data              => l_msg_data,
327     p_route_id              => l_job_attrs.route_id,
328     p_mr_route_id           => NULL,
329     p_item_instance_id      => l_job_attrs.item_instance_id,
330     p_visit_id              => l_job_attrs.visit_id, -- Added by surrkuma for Service Bulletin, 07-Jun-2011
331     p_requirement_date      => l_job_attrs.scheduled_start_date,
332     p_request_type          => 'PLANNED',
333     x_route_mtl_req_tbl     => l_route_mtl_req_tbl);
334 
335   IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
336     RAISE FND_API.G_EXC_ERROR;
337   ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
338     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
339   END IF;
340   ----dbms_output.put_line('After calling ltp API, the count='||l_route_mtl_req_tbl.COUNT);
341   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
342     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
343                    G_LOG_PREFIX||l_api_name||': In normal execution',
344 	           'After calling LTP API and x_return_status='||l_return_status||
345                    ' The count of the returned records = '||l_route_mtl_req_tbl.COUNT);
346   END IF;
347 
348   IF l_route_mtl_req_tbl.COUNT > 0 THEN
349     FOR i IN l_route_mtl_req_tbl.FIRST..l_route_mtl_req_tbl.LAST LOOP
350       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
351         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
352                        G_LOG_PREFIX||l_api_name||': In normal execution',
353                        'In mtl_req_tbl loop and i='||i||' and count = '||l_route_mtl_req_tbl.COUNT);
354         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
355                        G_LOG_PREFIX||l_api_name,
356                        'For index ' || i || ', rt_oper_material_id = '||
357                        l_route_mtl_req_tbl(i).rt_oper_material_id||', position_path_id = '||
358                        l_route_mtl_req_tbl(i).position_path_id||', item_group_id = '||
359                        l_route_mtl_req_tbl(i).item_group_id||', inventory_item_id = '||
360                        l_route_mtl_req_tbl(i).inventory_item_id);
361       END IF;
362       OPEN get_mtl_req_flags(l_route_mtl_req_tbl(i).rt_oper_material_id);
363       FETCH get_mtl_req_flags INTO l_mtl_req_flags;
364       ----dbms_output.put_line('In loop '|| i||' and rt_oper_material_id='||l_route_mtl_req_tbl(i).rt_oper_material_id);
365       IF get_mtl_req_flags%NOTFOUND THEN
366         FND_MESSAGE.set_name('AHL', 'AHL_PRD_DISP_MTL_REQ_ID_INV');
367         FND_MESSAGE.set_token('REQID', l_route_mtl_req_tbl(i).rt_oper_material_id);
368         FND_MSG_PUB.add;
369         CLOSE get_mtl_req_flags;
370         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
371       END IF;
372       CLOSE get_mtl_req_flags;
373       --dbms_output.put_line('Before check flag');
374       --Filter out the record which should not be included
375       IF (l_mtl_req_flags.exclude_flag = 'Y') THEN
376         l_route_mtl_req_tbl.DELETE(i);
377         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
378           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
379                          G_LOG_PREFIX||l_api_name||': In normal execution',
380 	                 'The disposition record is deleted and i='||i||' because the exclude_flag=Y');
381         END IF;
382         ----dbms_output.put_line('Yes it is deleted '||i);
383       END IF;
384       --This default logic is per Jay's requirement
385       ----dbms_output.put_line('Before apply Jay''s logic');
386       IF l_route_mtl_req_tbl.EXISTS(i) THEN
387         l_inv_item_id := l_route_mtl_req_tbl(i).inventory_item_id;
388         IF l_route_mtl_req_tbl(i).position_path_id IS NOT NULL THEN
389           l_route_mtl_req_tbl(i).item_group_id := NULL;
390           l_inv_item_id := NULL;
391         ELSIF l_route_mtl_req_tbl(i).item_group_id IS NOT NULL THEN
392           l_inv_item_id := NULL;
393           -- Added by jaramana on April 26, 2005 to fix the issue
394           -- where we are unable to update the Disposition for a Item Group with
395           -- a Revision Controlled Item when created from Push To Production
396           l_disp_org_id := l_job_attrs.organization_id;
397         ELSIF l_route_mtl_req_tbl(i).inventory_item_id IS NOT NULL THEN
398           OPEN check_item_org(l_route_mtl_req_tbl(i).inventory_item_id,
399                               l_job_attrs.organization_id);
400           FETCH check_item_org INTO l_dummy_char;
401           IF check_item_org%NOTFOUND THEN
402             IF (FND_LOG.LEVEL_EVENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
403               FND_LOG.STRING(FND_LOG.LEVEL_EVENT,
404                              G_LOG_PREFIX||l_api_name||': In normal execution',
405 			     'inventory_item_id = '||l_route_mtl_req_tbl(i).inventory_item_id||
406                              'job_organization_id = '||l_job_attrs.organization_id||
407                              'The item does not exist in the organization of the job and this disposition record will be ignored.');
408             END IF;
409             l_route_mtl_req_tbl.DELETE(i);
410           ELSE
411             --In this case, the column organization_id in dispositions table will be the same as
412             --the job organization_id
413             l_disp_org_id := l_job_attrs.organization_id;
414           END IF;
415           CLOSE check_item_org;
416         END IF;
417       END IF;
418       --When position_path_id is not null, we should derive the instance attributes if
419       --the position is not empty
420       ----dbms_output.put_line('position_path_id='||l_route_mtl_req_tbl(i).position_path_id);
421       IF (l_route_mtl_req_tbl.EXISTS(i) AND
422           l_route_mtl_req_tbl(i).position_path_id IS NOT NULL) THEN
423         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
424           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
425                          G_LOG_PREFIX||l_api_name||': In normal execution',
426 	                 'Exists and position_path_id is not null');
427         END IF;
428         ----dbms_output.put_line('Yes exists');
429         --Check the job instance is a unit instance?
430         OPEN check_unit_instance(l_job_attrs.item_instance_id);
431         FETCH check_unit_instance INTO l_unit_instance_id;
432         IF check_unit_instance%NOTFOUND THEN
433           CLOSE check_unit_instance;
434           --The job instance is not a unit instance but a component instance, then get its
435           --lowest unit instance. Assuming the result of the hierarchy query is what we expected
436           --that the lowest sub unit instance_id will be the first one to be displayed.
437           OPEN get_sub_unit_instance(l_job_attrs.item_instance_id);
438           FETCH get_sub_unit_instance INTO l_unit_instance_id;
439           IF get_sub_unit_instance%NOTFOUND THEN
440             FND_MESSAGE.set_name('AHL', 'AHL_PRD_DISP_JOB_INST_INVALID');
441             FND_MESSAGE.set_token('INSTANCE', l_job_attrs.item_instance_id);
442             FND_MESSAGE.set_token('JOB', l_job_attrs.job_number);
443             FND_MSG_PUB.add;
444             CLOSE get_sub_unit_instance;
445             RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
446           ELSE
447             CLOSE get_sub_unit_instance;
448           END IF;
449         ELSE
450           CLOSE check_unit_instance;
451         END IF;
452         --Call Path Position API to get the installed instance if the given unit has a
453         --matching path_position_id
454         ----dbms_output.put_line('Before calling path API');
455         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
456          FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
457                         G_LOG_PREFIX||l_api_name||': in normal execution',
458 	                'Before calling mc path position API and p_position_id ='||
459                         l_route_mtl_req_tbl(i).position_path_id||' p_csi_item_instance_id='||
460                         l_unit_instance_id);
461         END IF;
462         AHL_MC_PATH_POSITION_PVT.get_pos_instance(
463                                  p_api_version          => 1.0,
464                                  p_init_msg_list        => FND_API.G_FALSE,
465                                  p_commit               => FND_API.G_FALSE,
466                                  p_validation_level     => FND_API.G_VALID_LEVEL_FULL,
467                                  x_return_status        => l_return_status,
468                                  x_msg_count            => l_msg_count,
469                                  x_msg_data             => l_msg_data,
470                                  p_position_id          => l_route_mtl_req_tbl(i).position_path_id,
471                                  p_csi_item_instance_id => l_unit_instance_id,
472                                  x_item_instance_id     => l_installed_inst_id,
473                                  x_lowest_uc_csi_id     => l_lowest_unit_inst_id,
474                                  x_mapping_status       => l_mapping_status);
475 
476         IF (FND_LOG.LEVEL_EVENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
477           FND_LOG.STRING(FND_LOG.LEVEL_EVENT,
478                          G_LOG_PREFIX||l_api_name||': Within the procedure ',
479                          'Returned from call to AHL_MC_PATH_POSITION_PVT.get_pos_instance:' ||
480                          ' x_return_status = ' || l_return_status ||
481                          ', x_mapping_status = ' || l_mapping_status ||
482                          ', x_item_instance_id = ' || l_installed_inst_id ||
483                          ', x_lowest_uc_csi_id = ' || l_lowest_unit_inst_id);
484         END IF;
485 
486         IF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
487           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
488         ELSIF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
489           RAISE FND_API.G_EXC_ERROR;
490         END IF;
491 
492         IF (l_mapping_status = 'NA') THEN
493           FND_MESSAGE.set_name('AHL', 'AHL_PRD_DISP_PATH_POS_INV');
494           FND_MESSAGE.set_token('POSITION', l_route_mtl_req_tbl(i).position_path_id);
495           FND_MESSAGE.set_token('INSTANCE', l_unit_instance_id);
496           FND_MSG_PUB.add;
497           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
498           -- Position does not apply to current unit
499         ELSIF (l_mapping_status = 'EMPTY') THEN
500           l_installed_inst_id := NULL;
501           l_serial_number := NULL;
502           l_lot_number := NULL;
503           l_inv_item_id := NULL;
504           l_last_vld_org_id := NULL;
505           l_master_org_id := NULL;
506           l_disp_org_id := NULL;
507         ELSIF (l_mapping_status = 'MATCH') THEN
508           OPEN get_instance_attrs(l_installed_inst_id);
509           FETCH get_instance_attrs INTO
510                 l_serial_number,
511                 l_lot_number,
512                 l_inv_item_id,
513                 l_last_vld_org_id,
514                 l_master_org_id;
515           CLOSE get_instance_attrs;
516           --Check to see whether the item of the instance exists in the job's organization,
517           --if not, then ignore this record
518           OPEN check_item_org(l_inv_item_id, l_job_attrs.organization_id);
519           FETCH check_item_org INTO l_dummy_char;
520           IF check_item_org%NOTFOUND THEN
521             IF (FND_LOG.LEVEL_EVENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
522               FND_LOG.STRING(FND_LOG.LEVEL_EVENT,
523                              G_LOG_PREFIX||l_api_name||': In normal execution',
524 			     'inventory_item_id = '||l_route_mtl_req_tbl(i).inventory_item_id||
525                              'instance_id = '||l_installed_inst_id||
526                              'job_organization_id = '||l_job_attrs.organization_id||
527                              'The item of the instance does not exsit in the organization of the job and this disposition record will be ignored');
528             END IF;
529             l_route_mtl_req_tbl.DELETE(i);
530           ELSE
531             --In this case we need to ensure that the organization_id in
532             --dispositions table should be derived from the instance's organization
533             l_disp_org_id := nvl(l_last_vld_org_id, l_master_org_id);
534           END IF;
535           CLOSE check_item_org;
536         END IF;
537       END IF;
538       --dbms_output.put_line('Before calling table handler API');
539       --Insert the record into the disposition entity table
540       IF (l_route_mtl_req_tbl.EXISTS(i)) THEN
541         BEGIN
542           SELECT ahl_prd_dispositions_b_s.NEXTVAL
543           INTO l_disposition_id
544           FROM dual;
545           IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
546             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
547                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
548                            'disposition_id = '||l_disposition_id);
549             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
550                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
551                            'workorder_id = '||p_workorder_id);
552             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
553                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
554                            'path_position_id = '||l_route_mtl_req_tbl(i).position_path_id);
555             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
556                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
557                            'inventory_item_id = '||l_route_mtl_req_tbl(i).inventory_item_id);
558             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
559                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
560                            'inv_master_org_id = '||l_route_mtl_req_tbl(i).inv_master_org_id);
561             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
562                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
563                            'item_group_id= '||l_route_mtl_req_tbl(i).item_group_id);
564             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
565                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
566                            'l_installed_inst_id='||l_installed_inst_id);
567             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
568                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
569                            'l_serial_number='||l_serial_number);
570             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
571                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
572                            'l_lot_number='||l_lot_number);
573             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
574                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
575                            'quantity='||l_route_mtl_req_tbl(i).quantity);
576             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
577                            G_LOG_PREFIX||l_api_name||': Before calling table handler',
578                            'uom_code='||l_route_mtl_req_tbl(i).uom_code);
579           END IF;
580 
581           AHL_PRD_DISPOSITIONS_PKG.INSERT_ROW(
582             X_ROWID => l_dummy_rowid,
583             X_DISPOSITION_ID => l_disposition_id,
584             X_OBJECT_VERSION_NUMBER => 1.0,
585             X_WORKORDER_ID => p_workorder_id,
586             X_PART_CHANGE_ID => NULL,
587             X_PATH_POSITION_ID => l_route_mtl_req_tbl(i).position_path_id,
588             X_INVENTORY_ITEM_ID => l_inv_item_id,
589             X_ORGANIZATION_ID => l_disp_org_id,
590             X_ITEM_GROUP_ID => l_route_mtl_req_tbl(i).item_group_id,
591             X_CONDITION_ID => NULL,
592             X_INSTANCE_ID => l_installed_inst_id,
593             X_SERIAL_NUMBER => l_serial_number,
594             X_LOT_NUMBER => l_lot_number,
595             X_IMMEDIATE_DISPOSITION_CODE => NULL,
596             X_SECONDARY_DISPOSITION_CODE => NULL,
597             X_STATUS_CODE => NULL,
598             X_QUANTITY => l_route_mtl_req_tbl(i).quantity,
599             X_UOM => l_route_mtl_req_tbl(i).uom_code,
600             X_COLLECTION_ID => NULL,
601             X_PRIMARY_SERVICE_REQUEST_ID => NULL,
602             X_NON_ROUTINE_WORKORDER_ID => NULL,
603             X_WO_OPERATION_ID => NULL,
604             X_ITEM_REVISION => NULL,
605             --We may need to get the item_revision from ahl_rt_oper_materials later
606             X_ATTRIBUTE_CATEGORY => NULL,
607             X_ATTRIBUTE1 => NULL,
608             X_ATTRIBUTE2 => NULL,
609             X_ATTRIBUTE3 => NULL,
610             X_ATTRIBUTE4 => NULL,
611             X_ATTRIBUTE5 => NULL,
612             X_ATTRIBUTE6 => NULL,
613             X_ATTRIBUTE7 => NULL,
614             X_ATTRIBUTE8 => NULL,
615             X_ATTRIBUTE9 => NULL,
616             X_ATTRIBUTE10 => NULL,
617             X_ATTRIBUTE11 => NULL,
618             X_ATTRIBUTE12 => NULL,
619             X_ATTRIBUTE13 => NULL,
620             X_ATTRIBUTE14 => NULL,
621             X_ATTRIBUTE15 => NULL,
622             X_COMMENTS => NULL,
623             X_CREATION_DATE => SYSDATE,
624             X_CREATED_BY => FND_GLOBAL.user_id,
625             X_LAST_UPDATE_DATE => SYSDATE,
626             X_LAST_UPDATED_BY => FND_GLOBAL.user_id,
627             X_LAST_UPDATE_LOGIN => FND_GLOBAL.login_id);
628 
629         --Insert the same record into the Disposition History table as well
630           SELECT AHL_PRD_DISPOSITIONS_B_H_S.NEXTVAL
631             INTO l_disposition_h_id
632             FROM dual;
633           AHL_PRD_DISPOSITIONS_B_H_PKG.INSERT_ROW(
634             X_ROWID => l_dummy_rowid,
635             X_DISPOSITION_H_ID => l_disposition_h_id,
636             X_DISPOSITION_ID => l_disposition_id,
637             X_OBJECT_VERSION_NUMBER => 1.0,
638             X_WORKORDER_ID => p_workorder_id,
639             X_PART_CHANGE_ID => NULL,
640             X_PATH_POSITION_ID => l_route_mtl_req_tbl(i).position_path_id,
641             X_INVENTORY_ITEM_ID => l_inv_item_id,
642             X_ORGANIZATION_ID => l_disp_org_id,
643             X_ITEM_GROUP_ID => l_route_mtl_req_tbl(i).item_group_id,
644             X_CONDITION_ID => NULL,
645             X_INSTANCE_ID => l_installed_inst_id,
646             X_SERIAL_NUMBER => l_serial_number,
647             X_LOT_NUMBER => l_lot_number,
648             X_IMMEDIATE_DISPOSITION_CODE => NULL,
649             X_SECONDARY_DISPOSITION_CODE => NULL,
650             X_STATUS_CODE => NULL,
651             X_QUANTITY => l_route_mtl_req_tbl(i).quantity,
652             X_UOM => l_route_mtl_req_tbl(i).uom_code,
653             X_COLLECTION_ID => NULL,
654             X_PRIMARY_SERVICE_REQUEST_ID => NULL,
655             X_NON_ROUTINE_WORKORDER_ID => NULL,
656             X_WO_OPERATION_ID => NULL,
657             X_ITEM_REVISION => NULL,
658             --We may need to get the item_revision from ahl_rt_oper_materials later
659             X_ATTRIBUTE_CATEGORY => NULL,
660             X_ATTRIBUTE1 => NULL,
661             X_ATTRIBUTE2 => NULL,
662             X_ATTRIBUTE3 => NULL,
663             X_ATTRIBUTE4 => NULL,
664             X_ATTRIBUTE5 => NULL,
665             X_ATTRIBUTE6 => NULL,
666             X_ATTRIBUTE7 => NULL,
667             X_ATTRIBUTE8 => NULL,
668             X_ATTRIBUTE9 => NULL,
669             X_ATTRIBUTE10 => NULL,
670             X_ATTRIBUTE11 => NULL,
671             X_ATTRIBUTE12 => NULL,
672             X_ATTRIBUTE13 => NULL,
673             X_ATTRIBUTE14 => NULL,
674             X_ATTRIBUTE15 => NULL,
675             X_COMMENTS => NULL,
676             X_CREATION_DATE => SYSDATE,
677             X_CREATED_BY => FND_GLOBAL.user_id,
678             X_LAST_UPDATE_DATE => SYSDATE,
679             X_LAST_UPDATED_BY => FND_GLOBAL.user_id,
680             X_LAST_UPDATE_LOGIN => FND_GLOBAL.login_id);
681           EXCEPTION
682             WHEN NO_DATA_FOUND THEN --This +100 is raised explicitly in INSERT_ROW
683               FND_MESSAGE.set_name( 'AHL', 'AHL_COM_INSERT_FAILED' );
684               FND_MSG_PUB.add;
685             WHEN OTHERS THEN
686               IF ( SQLCODE = -1 ) THEN --DUP_VAL_ON_INDEX
687                 FND_MESSAGE.set_name( 'AHL', 'AHL_COM_DUPLICATE_RECORD' );
688                 FND_MSG_PUB.add;
689               ELSE
690                 RAISE;
691               END IF;
692         END;
693       END IF;
694       --To clear the local variable, otherwise it carries the previous one if the current one
695       --should be null
696       l_installed_inst_id := NULL;
697       l_serial_number := NULL;
698       l_lot_number := NULL;
699       l_master_org_id := NULL;
700       l_last_vld_org_id := NULL;
701       l_disp_org_id := NULL;
702       l_inv_item_id := NULL;
703     END LOOP;
704   END IF;
705 
706   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
707     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
708                    G_LOG_PREFIX||l_api_name||': After normal execution',
709                    'At the end of the procedure');
710   END IF;
711 
712   -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
713   l_msg_count := FND_MSG_PUB.count_msg;
714   IF l_msg_count > 0 THEN
715     x_msg_count := l_msg_count;
716     RAISE FND_API.G_EXC_ERROR;
717   END IF;
718 
719   -- Perform the Commit (if requested)
720   IF FND_API.to_boolean(p_commit) THEN
721     COMMIT;
722   END IF;
723 
724   -- Count and Get messages (optional)
725   FND_MSG_PUB.count_and_get(
726     p_encoded  => FND_API.G_FALSE,
727     p_count    => x_msg_count,
728     p_data     => x_msg_data);
729 
730 EXCEPTION
731   WHEN FND_API.G_EXC_ERROR THEN
732     ROLLBACK TO create_job_dispositions;
733     x_return_status := FND_API.G_RET_STS_ERROR ;
734     FND_MSG_PUB.count_and_get(
735       p_encoded  => FND_API.G_FALSE,
736       p_count    => x_msg_count,
737       p_data     => x_msg_data);
738 
739   WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
740     ROLLBACK TO create_job_dispositions;
741     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
742     FND_MSG_PUB.count_and_get(
743       p_encoded  => FND_API.G_FALSE,
744       p_count    => x_msg_count,
745       p_data     => x_msg_data);
746 
747   WHEN OTHERS THEN
748     ROLLBACK TO create_job_dispositions;
749     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
750     IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
751     THEN
752       FND_MSG_PUB.add_exc_msg(
753         p_pkg_name         => G_PKG_NAME,
754         p_procedure_name   => l_api_name,
755         p_error_text       => SUBSTRB(SQLERRM,1,240));
756     END IF;
757     FND_MSG_PUB.count_and_get(
758       p_encoded  => FND_API.G_FALSE,
759       p_count    => x_msg_count,
760       p_data     => x_msg_data);
761 
762 END create_job_dispositions;
763 
764 ------------------------------------------------------------------
765 -- Start of Comments --
766 --  Procedure name    : process_disposition
767 --  Type              : Private
768 --  Function          : create or update a disposition based on the input from disposition record.
769 --  Pre-reqs    :
770 --  Parameters  :
771 --
772 --  Standard IN  Parameters :
773 --      p_api_version                   IN      NUMBER       Default  1.0
774 --      p_init_msg_list                 IN      VARCHAR2     Default  FND_API.G_TRUE
775 --      p_commit                        IN      VARCHAR2     Default  FND_API.G_FALSE
776 --      p_validation_level              IN      NUMBER       Default  FND_API.G_VALID_LEVEL_FULL
777 --  Standard OUT Parameters :
778 --      x_return_status                 OUT     VARCHAR2               Required
779 --      x_msg_count                     OUT     NUMBER                 Required
780 --      x_msg_data                      OUT     VARCHAR2               Required
781 --
782 --  p_module_type                       IN      VARCHAR2               Required.
783 --
784 --      This parameter indicates the front-end form interface. The default value is 'JSP'. If the value
785 --      is JSP, then this API clears out all id columns and validations are done using the values based
786 --      on which the Id's are populated.
787 --
788 --  process_disposition Parameters:
789 --
790 --       p_x_disposition_rec     IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type    Required
791 --         Disposition record
792 --       p_mr_asso_tbl           IN             AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type  Required
793 --         Table of MRs associated to the Disposition's Primary NR
794 --         (Parameter added by jaramana on Oct 9, 2007 for ER 5883257)
795 --
796 --  Version :
797 --               Initial Version   1.0
798 --
799 --  End of Comments.
800 --------------------------------------------------------------------------------------------------------------
801 
802 PROCEDURE process_disposition(
803     p_api_version           IN             NUMBER    := 1.0,
804     p_init_msg_list         IN             VARCHAR2  := FND_API.G_TRUE,
805     p_commit                IN             VARCHAR2  := FND_API.G_FALSE,
806     p_validation_level      IN             NUMBER    := FND_API.G_VALID_LEVEL_FULL,
807     p_module_type           IN             VARCHAR2  := NULL,
808     p_x_disposition_rec     IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
809     -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
810     p_mr_asso_tbl           IN             AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type,
811     x_return_status         OUT NOCOPY     VARCHAR2,
812     x_msg_count             OUT NOCOPY     NUMBER,
813     x_msg_data              OUT NOCOPY     VARCHAR2) IS
814 
815 
816   l_api_version      CONSTANT NUMBER := 1.0;
817   l_api_name         CONSTANT VARCHAR2(30) := 'process_disposition';
818   l_return_status  VARCHAR2(1) := FND_API.G_RET_STS_SUCCESS;
819   l_init_msg_list  VARCHAR2(1)  := FND_API.G_FALSE;
820   l_commit         VARCHAR2(1)  := FND_API.G_FALSE;
821   L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'process_disposition';
822   l_prev_err_count      NUMBER;
823 
824 BEGIN
825 
826   -- Standard start of API savepoint
827   SAVEPOINT process_disposition_pvt;
828   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
829     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
830   END IF;
831 
832 --dbms_output.put_line(SubStr('Begin  Process_Disposition', 1, 255));
833   -- Standard call to check for call compatibility
834   IF NOT FND_API.Compatible_API_Call( l_api_version, p_api_version,l_api_name, G_PKG_NAME )
835   THEN
836     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
837   END IF;
838 
839     -- Initialize message list if p_init_msg_list is set to TRUE
840   IF FND_API.To_Boolean( p_init_msg_list)
841   THEN
842     FND_MSG_PUB.Initialize;
843     --dbms_output.put_line(SubStr('Current MSG Count: ' || TO_CHAR(FND_MSG_PUB.count_msg), 1, 255));
844   END IF;
845   /* Begin Fix for 4071599 on Dec 22, 2004 by JR */
846   l_prev_err_count := NVL(FND_MSG_PUB.count_msg,0);
847   /* End Fix for 4071599 on Dec 22, 2004 by JR */
848 
849   -- Initialize API return status to success
850   x_return_status := FND_API.G_RET_STS_SUCCESS;
851   g_module_type := p_module_type;
852 
853   -- Begin Processing HERE
854 
855   IF p_x_disposition_rec.operation_flag = G_OP_CREATE THEN
856      create_disposition(   p_api_version,
857                            l_init_msg_list,
858                            l_commit,
859                            p_validation_level,
860                            p_module_type ,
861                            p_x_disposition_rec,
862                            p_mr_asso_tbl, -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
863                            x_return_status ,
864                            x_msg_count,
865                            x_msg_data);
866 
867   ELSIF p_x_disposition_rec.operation_flag = G_OP_UPDATE THEN
868      update_disposition( p_api_version,
869                            l_init_msg_list,
870                            l_commit,
871                            p_validation_level,
872                            p_module_type ,
873                            p_x_disposition_rec,
874                            p_mr_asso_tbl, -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
875                            x_return_status ,
876                            x_msg_count,
877                            x_msg_data);
878 
879      IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
880        FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'After calling update_dispositon- x_msg_data: ' || x_msg_data
881                   || ' x_msg_count: ' || x_msg_count);
882      END IF;
883   END IF;
884 
885  -- Check Error Message stack.
886   x_msg_count := FND_MSG_PUB.count_msg;
887 
888 
889   IF  x_msg_count - l_prev_err_count > 0 THEN
890      RAISE  FND_API.G_EXC_ERROR;
891   END IF;
892 
893   -- Standard check of p_commit
894   IF FND_API.TO_BOOLEAN(p_commit) THEN
895       COMMIT WORK;
896   END IF;
897 
898   -- Standard call to get message count and if count is 1, get message info
899   FND_MSG_PUB.Count_And_Get
900     ( p_count => x_msg_count,
901       p_data  => x_msg_data,
902       p_encoded => fnd_api.g_false
903     );
904 
905   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
906     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'End Procedure');
907   END IF;
908 --dbms_output.put_line(SubStr('End  Process_Disposition', 1, 255));
909 
910 EXCEPTION
911  WHEN FND_API.G_EXC_ERROR THEN
912    Rollback to process_disposition_pvt;
913    x_return_status := FND_API.G_RET_STS_ERROR;
914    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
915                               p_data  => x_msg_data,
916                               p_encoded => fnd_api.g_false);
917     IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
918        FND_LOG.STRING(FND_LOG.LEVEL_EXCEPTION, L_DEBUG_KEY, 'Execution Exception: ' || x_msg_data);
919     END IF;
920     --dbms_output.put_line(SubStr('Execution Exception', 1, 255));
921 
922 
923  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
924    Rollback to process_disposition_pvt;
925    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
926    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
927                               p_data  => x_msg_data,
928                               p_encoded => fnd_api.g_false);
929 
930   IF (FND_LOG.LEVEL_UNEXPECTED >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
931     FND_LOG.STRING(FND_LOG.LEVEL_UNEXPECTED, L_DEBUG_KEY, 'Unexpected Exception: ' || x_msg_data);
932   END IF;
933  --dbms_output.put_line(SubStr('Unexpected Exception', 1, 255));
934 
935  WHEN OTHERS THEN
936     Rollback to process_disposition_pvt;
937     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
938     IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
939        fnd_msg_pub.add_exc_msg(p_pkg_name       => G_PKG_NAME,
940                                p_procedure_name => l_api_name,
941                                p_error_text     => SUBSTR(SQLERRM,1,500));
942     END IF;
943     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
944                                p_data  => x_msg_data,
945                                p_encoded => fnd_api.g_false);
946 
947     IF (FND_LOG.LEVEL_UNEXPECTED >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
948       FND_LOG.STRING(FND_LOG.LEVEL_UNEXPECTED, L_DEBUG_KEY, 'Other Exception: ' || x_msg_data);
949     END IF;
950 
951 
952     --dbms_output.put_line(SubStr('Other Exception', 1, 255));
953 END process_disposition;
954 
955 
956 --------------CREATE_DISPOSITION---------------------------------------------------
957 
958 PROCEDURE create_disposition(
959     p_api_version           IN             NUMBER    := 1.0,
960     p_init_msg_list         IN             VARCHAR2  := FND_API.G_TRUE,
961     p_commit                IN             VARCHAR2  := FND_API.G_FALSE,
962     p_validation_level      IN             NUMBER    := FND_API.G_VALID_LEVEL_FULL,
963     p_module_type           IN             VARCHAR2  := NULL,
964     p_x_disposition_rec     IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
965     -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
966     p_mr_asso_tbl           IN             AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type,
967     x_return_status         OUT NOCOPY     VARCHAR2,
968     x_msg_count             OUT NOCOPY     NUMBER,
969     x_msg_data              OUT NOCOPY     VARCHAR2
970 ) IS
971 
972 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
973 -- Cursor to check whether the disposition item is serialized or not.
974 CURSOR chk_non_serialized_csr(p_inventory_item_id NUMBER, p_item_org_id NUMBER) IS
975        SELECT 'X'
976        FROM   mtl_system_items_b
977        WHERE  inventory_item_id          = p_inventory_item_id
978        AND    organization_id            = p_item_org_id
979        AND    serial_number_control_code = 1;
980 
981 -- SATHAPLI::FP OGMA Issue# 86 - Automatic Material Return, 27-Dec-2007
982 -- Cursor to fetch the part change details.
983 CURSOR part_change_dtls_csr(p_part_change_id IN NUMBER) IS
984        SELECT removed_instance_id, part_change_type
985        FROM   ahl_part_changes
986        WHERE   part_change_id = p_part_change_id;
987 
988  -- Added by jaramana on 03-FEB-2011 for bug 10647408; sorao for Backporting project
989  -- Cursor to check whether removed instance is in job or not.
990 /**
991  CURSOR chk_disp_inst_job_csr (p_instance_id NUMBER, p_workorder_id NUMBER) IS
992      SELECT 'Y'
993      FROM   ahl_workorders awo, csi_item_instances csi
994      WHERE  awo.wip_entity_id = csi.wip_job_id
995      AND    awo.workorder_id  = p_workorder_id
996      AND    csi.instance_id   = p_instance_id;
997 **/
998 
999  -- Changed by jaramana on 31-MAR-2011 for bug 11856373 to compare using
1000  -- the item and quantity of the disposition rather than the actual instance id; sorao for backporting
1001  CURSOR chk_disp_inst_job_csr (p_disposition_id NUMBER, p_workorder_id NUMBER) IS
1002      SELECT 'Y'
1003        FROM ahl_workorders awo, csi_item_instances csi, ahl_prd_dispositions_b disp
1004       WHERE awo.workorder_id = p_workorder_id
1005         AND csi.wip_job_id = awo.wip_entity_id
1006         AND csi.INVENTORY_ITEM_ID = disp.INVENTORY_ITEM_ID
1007         AND csi.QUANTITY = disp.QUANTITY;
1008 
1009 -- Cursor to get the first released non-master workorder id for a given NR summary workorder.
1010 CURSOR get_rel_nonmaster_wo_id_csr(c_nr_wo_id NUMBER) IS
1011     SELECT workorder_id
1012     FROM   ahl_workorders
1013     WHERE  master_workorder_flag = 'N'
1014     AND    wip_entity_id IN
1015            (SELECT child_object_id
1016             FROM   wip_sched_relationships
1017             START WITH parent_object_id      = (SELECT wip_entity_id FROM ahl_workorders WHERE workorder_id = c_nr_wo_id)
1018             CONNECT BY parent_object_id      = PRIOR child_object_id
1019             AND        parent_object_type_id = PRIOR child_object_type_id
1020             AND        relationship_type     = 1
1021            )
1022     AND    status_code           = G_WO_RELEASED_STATUS
1023     ORDER BY workorder_id;
1024 
1025 -- Added by jaramana on 17-JUN-2011 for bug 10195920
1026 CURSOR instance_lock_csr(c_instance_id IN NUMBER) IS
1027     SELECT 'X'
1028       FROM csi_item_instances
1029      WHERE instance_id = c_instance_id
1030        AND serial_number IS NOT NULL
1031      FOR UPDATE OF instance_id;
1032 
1033 
1034 l_inst_in_job_flag    VARCHAR2(1) := 'N';
1035 l_rel_nm_wo_id        NUMBER;
1036 
1037 l_disposition_h_id   NUMBER;
1038 l_dummy_char VARCHAR(30);
1039 l_primary_service_request_id NUMBER;
1040 l_non_routine_workorder_id NUMBER;
1041 l_calculated_status VARCHAR(30);
1042 l_return_status VARCHAR(30);
1043 
1044 l_removed_instance_id NUMBER;
1045 l_part_change_type    VARCHAR2(1);
1046 l_ahl_mtltxn_rec      AHL_PRD_MTLTXN_PVT.Ahl_Mtltxn_Rec_Type;
1047 l_dummy               VARCHAR2(1);
1048 
1049 l_msg_count NUMBER;
1050 L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'create_disposition';
1051 
1052 BEGIN
1053 
1054 
1055 
1056   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1057     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1058   END IF;
1059   --dbms_output.put_line(SubStr('Begin  Create_Disposition', 1, 255));
1060 
1061    IF (p_module_type = 'JSP') THEN
1062     IF (p_x_disposition_rec.WORKORDER_ID  = FND_API.G_MISS_NUM) THEN
1063         p_x_disposition_rec.WORKORDER_ID  := null;
1064     END IF;
1065     IF (p_x_disposition_rec.PART_CHANGE_ID  = FND_API.G_MISS_NUM) THEN
1066         p_x_disposition_rec.PART_CHANGE_ID  := null;
1067     END IF;
1068     IF (p_x_disposition_rec.PATH_POSITION_ID  = FND_API.G_MISS_NUM) THEN
1069         p_x_disposition_rec.PATH_POSITION_ID  := null;
1070     END IF;
1071     IF (p_x_disposition_rec.INVENTORY_ITEM_ID  = FND_API.G_MISS_NUM) THEN
1072         p_x_disposition_rec.INVENTORY_ITEM_ID  := null;
1073     END IF;
1074     IF (p_x_disposition_rec.ITEM_GROUP_ID  = FND_API.G_MISS_NUM) THEN
1075         p_x_disposition_rec.ITEM_GROUP_ID  := null;
1076     END IF;
1077     IF (p_x_disposition_rec.CONDITION_ID  = FND_API.G_MISS_NUM) THEN
1078         p_x_disposition_rec.CONDITION_ID  := null;
1079     END IF;
1080     IF (p_x_disposition_rec.INSTANCE_ID  = FND_API.G_MISS_NUM) THEN
1081         p_x_disposition_rec.INSTANCE_ID  := null;
1082     END IF;
1083     IF (p_x_disposition_rec.SERIAL_NUMBER  = FND_API.G_MISS_CHAR) THEN
1084         p_x_disposition_rec.SERIAL_NUMBER  := null;
1085     END IF;
1086     IF (p_x_disposition_rec.LOT_NUMBER  = FND_API.G_MISS_CHAR) THEN
1087         p_x_disposition_rec.LOT_NUMBER  := null;
1088     END IF;
1089     IF (p_x_disposition_rec.IMMEDIATE_DISPOSITION_CODE  = FND_API.G_MISS_CHAR) THEN
1090         p_x_disposition_rec.IMMEDIATE_DISPOSITION_CODE  := null;
1091     END IF;
1092     IF (p_x_disposition_rec.SECONDARY_DISPOSITION_CODE  = FND_API.G_MISS_CHAR) THEN
1093         p_x_disposition_rec.SECONDARY_DISPOSITION_CODE  := null;
1094     END IF;
1095     IF (p_x_disposition_rec.STATUS_CODE  = FND_API.G_MISS_CHAR) THEN
1096         p_x_disposition_rec.STATUS_CODE  := null;
1097     END IF;
1098     IF (p_x_disposition_rec.QUANTITY  = FND_API.G_MISS_NUM) THEN
1099         p_x_disposition_rec.QUANTITY  := null;
1100     END IF;
1101     IF (p_x_disposition_rec.UOM  = FND_API.G_MISS_CHAR) THEN
1102         p_x_disposition_rec.UOM  := null;
1103     END IF;
1104     IF (p_x_disposition_rec.COLLECTION_ID  = FND_API.G_MISS_NUM) THEN
1105         p_x_disposition_rec.COLLECTION_ID  := null;
1106     END IF;
1107     IF (p_x_disposition_rec.PRIMARY_SERVICE_REQUEST_ID  = FND_API.G_MISS_NUM) THEN
1108         p_x_disposition_rec.PRIMARY_SERVICE_REQUEST_ID  := null;
1109     END IF;
1110     IF (p_x_disposition_rec.NON_ROUTINE_WORKORDER_ID  = FND_API.G_MISS_NUM) THEN
1111         p_x_disposition_rec.NON_ROUTINE_WORKORDER_ID  := null;
1112     END IF;
1113     IF (p_x_disposition_rec.WO_OPERATION_ID  = FND_API.G_MISS_NUM) THEN
1114         p_x_disposition_rec.WO_OPERATION_ID  := null;
1115     END IF;
1116     IF (p_x_disposition_rec.ITEM_REVISION  = FND_API.G_MISS_CHAR) THEN
1117         p_x_disposition_rec.ITEM_REVISION  := null;
1118     END IF;
1119   END IF;
1120 
1121 
1122   IF p_validation_level = FND_API.G_VALID_LEVEL_FULL  THEN
1123     convert_values_to_ids(p_x_disposition_rec);
1124   END IF;
1125 
1126 
1127   -- Added by jaramana on 17-JUN-2011 for bug 10195920; sorao for backporting project
1128   -- Lock the instance to prevent concurrent creation of a duplicate disposition for the same instance
1129   OPEN instance_lock_csr(p_x_disposition_rec.instance_id);
1130   FETCH instance_lock_csr INTO l_dummy;
1131 
1132 -- Derive Columns from other know columns
1133 
1134   derive_columns(p_x_disposition_rec);
1135 
1136   validate_for_create(p_x_disposition_rec);
1137 
1138   --Validate Disposition Types
1139   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1140     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before validate disposition_type');
1141   END IF;
1142    --dbms_output.put_line(SubStr('Before validate disposition type ', 1, 255));
1143    Validate_Disposition_Types (
1144       --  p_api_version  =>   p_api_version,
1145      --   p_init_msg_list =>  p_init_msg_list,
1146      --   p_commit =>   p_commit,
1147      --   p_validation_level  => p_validation_level,
1148         x_return_status => x_return_status,
1149         x_msg_count => x_msg_count,
1150         x_msg_data => x_msg_data ,
1151         p_disposition_rec  =>  p_x_disposition_rec);
1152 
1153   --Calculate Status
1154   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1155     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before calculate_status');
1156   END IF;
1157    --dbms_output.put_line(SubStr('Before calculate status', 1, 255));
1158    Calculate_Status (
1159     p_disposition_Rec   => p_x_disposition_Rec,
1160     x_status_code       => l_calculated_status);
1161 
1162     p_x_disposition_Rec.status_code := l_calculated_status;
1163 
1164     --prepare for insert
1165     Select AHL_PRD_DISPOSITIONS_B_S.NEXTVAL into p_x_disposition_rec.disposition_id from dual;
1166     --setting object version number for create
1167     p_x_disposition_rec.object_version_number := 1;
1168     --setting up user/create/update information
1169     p_x_disposition_rec.created_by := fnd_global.user_id;
1170     p_x_disposition_rec.creation_date := SYSDATE;
1171     p_x_disposition_rec.last_updated_by := fnd_global.user_id;
1172     p_x_disposition_rec.last_update_date := SYSDATE;
1173     p_x_disposition_rec.last_update_login := fnd_global.login_id ;
1174 
1175   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1176     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before Insert_Row');
1177   END IF;
1178    --dbms_output.put_line(SubStr('Create_Disposition -  Before Insert_Row', 1, 255));
1179   AHL_PRD_DISPOSITIONS_PKG.INSERT_ROW(
1180   		x_rowid                => l_dummy_char,
1181   		x_disposition_id       =>  p_x_disposition_rec.disposition_id,
1182   		x_object_version_number   =>  p_x_disposition_rec.object_version_number,
1183   		x_workorder_id         =>  p_x_disposition_rec.workorder_id ,
1184   		x_part_change_id       =>  p_x_disposition_rec.part_change_id,
1185   		x_path_position_id     =>  p_x_disposition_rec.path_position_id,
1186   		x_inventory_item_id    =>  p_x_disposition_rec.inventory_item_id,
1187   		x_organization_id      =>  p_x_disposition_rec.item_org_id,
1188   		x_item_group_id        =>  p_x_disposition_rec.item_group_id,
1189   		x_condition_id         =>  p_x_disposition_rec.condition_id,
1190   		x_instance_id          =>  p_x_disposition_rec.instance_id,
1191   		x_serial_number        =>  p_x_disposition_rec.serial_number,
1192   		x_lot_number           =>  p_x_disposition_rec.lot_number,
1193   		x_immediate_disposition_code  =>  p_x_disposition_rec.immediate_disposition_code ,
1194   		x_secondary_disposition_code  =>  p_x_disposition_rec.secondary_disposition_code,
1195   		x_status_code          =>  p_x_disposition_rec.status_code,
1196   		x_quantity             =>  p_x_disposition_rec.quantity,
1197   		x_uom                  =>  p_x_disposition_rec.uom,
1198   		x_collection_id        =>  p_x_disposition_rec.collection_id,
1199   		x_primary_service_request_id   =>  p_x_disposition_rec.primary_service_request_id ,
1200   		x_non_routine_workorder_id     =>  p_x_disposition_rec.non_routine_workorder_id,
1201   		x_wo_operation_id              => p_x_disposition_rec.wo_operation_id,
1202   		x_item_revision                => p_x_disposition_rec.item_revision,
1203   		x_attribute_category   =>  p_x_disposition_rec.attribute_category,
1204   		x_attribute1           =>  p_x_disposition_rec.attribute1,
1205   		x_attribute2           =>  p_x_disposition_rec.attribute2,
1206   		x_attribute3           =>  p_x_disposition_rec.attribute3,
1207   		x_attribute4           =>  p_x_disposition_rec.attribute4,
1208   		x_attribute5           =>  p_x_disposition_rec.attribute5,
1209   		x_attribute6           =>  p_x_disposition_rec.attribute6,
1210   		x_attribute7           =>  p_x_disposition_rec.attribute7,
1211   		x_attribute8           =>  p_x_disposition_rec.attribute8,
1212   		x_attribute9           =>  p_x_disposition_rec.attribute9,
1213   		x_attribute10          =>  p_x_disposition_rec.attribute10,
1214   		x_attribute11          =>  p_x_disposition_rec.attribute11,
1215   		x_attribute12          =>  p_x_disposition_rec.attribute12,
1216   		x_attribute13          =>  p_x_disposition_rec.attribute13,
1217   		x_attribute14          =>  p_x_disposition_rec.attribute14,
1218   		x_attribute15          =>  p_x_disposition_rec.attribute15,
1219   		x_comments             =>  p_x_disposition_rec.comments,
1220   		x_creation_date        =>  p_x_disposition_rec.creation_date ,
1221   		x_created_by           =>  p_x_disposition_rec.created_by,
1222   		x_last_update_date     =>  p_x_disposition_rec.last_update_date,
1223   		x_last_updated_by      =>  p_x_disposition_rec.last_updated_by,
1224   		x_last_update_login    =>  p_x_disposition_rec.last_update_login
1225   );
1226   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1227     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'AfterInsert_Row');
1228   END IF;
1229 
1230   -- create service request and non-routine job
1231   -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
1232   -- Add a check for the create_work_order_option attribute too.
1233   IF p_x_disposition_rec.primary_service_request_id IS NULL AND p_x_disposition_rec.instance_id IS NOT NULL   --  ITEM is tracked
1234      AND(p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE') OR
1235          p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'))
1236      AND(p_x_disposition_rec.create_work_order_option <> 'CREATE_SR_NO') THEN
1237 
1238     -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
1239     -- The option CREATE_WO_NO is not valid for non-serialized items. If chosen, throw an error.
1240     IF (p_x_disposition_rec.create_work_order_option = 'CREATE_WO_NO') THEN
1241       OPEN chk_non_serialized_csr(p_x_disposition_rec.inventory_item_id, p_x_disposition_rec.item_org_id);
1242       FETCH chk_non_serialized_csr INTO l_dummy;
1243       IF (chk_non_serialized_csr%FOUND) THEN
1244         FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_NON_SRL_SR');
1245         FND_MSG_PUB.ADD;
1246       END IF;
1247       CLOSE chk_non_serialized_csr;
1248     END IF;
1249 
1250     -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
1251     l_msg_count := FND_MSG_PUB.count_msg;
1252     IF l_msg_count > 0 THEN
1253       x_msg_count := l_msg_count;
1254       RAISE FND_API.G_EXC_ERROR;
1255     END IF;
1256     Create_SR (p_init_msg_list => FND_API.G_FALSE,
1257                p_disposition_rec => p_x_disposition_rec,
1258                -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
1259                p_mr_asso_tbl    => p_mr_asso_tbl,
1260                x_primary_sr_id => l_primary_service_request_id,
1261                x_non_routine_workorder_id =>  l_non_routine_workorder_id,
1262                x_return_status  => x_return_status,
1263                x_msg_count      => x_msg_count,
1264                x_msg_data       => x_msg_data);
1265     --reinitialize message stack and ignore any warning message
1266     IF x_return_status = FND_API.G_RET_STS_SUCCESS THEN
1267       FND_MSG_PUB.Initialize;
1268     END IF;
1269 
1270     p_x_disposition_rec.primary_service_request_id := l_primary_service_request_id;
1271     p_x_disposition_rec.non_routine_workorder_id := l_non_routine_workorder_id;
1272 
1273     --update the just modified field without changing object version number.
1274     UPDATE AHL_PRD_DISPOSITIONS_B SET primary_service_request_id = p_x_disposition_rec.primary_service_request_id,
1275                                       non_routine_workorder_id  = p_x_disposition_rec.non_routine_workorder_id,
1276                                       status_code = p_x_disposition_rec.status_code
1277                                 WHERE disposition_id =  p_x_disposition_rec.disposition_id;
1278   END IF;
1279 
1280   Select AHL_PRD_DISPOSITIONS_B_H_S.NEXTVAL into l_disposition_h_id from dual;
1281   AHL_PRD_DISPOSITIONS_B_H_PKG.INSERT_ROW(
1282   		x_rowid                =>  l_dummy_char,
1283 		x_disposition_h_id     =>  l_disposition_h_id,
1284   		x_disposition_id       =>  p_x_disposition_rec.disposition_id,
1285   		x_object_version_number   =>  p_x_disposition_rec.object_version_number,
1286   		x_workorder_id         =>  p_x_disposition_rec.workorder_id ,
1287   		x_part_change_id       =>  p_x_disposition_rec.part_change_id,
1288   		x_path_position_id     =>  p_x_disposition_rec.path_position_id,
1289   		x_inventory_item_id    =>  p_x_disposition_rec.inventory_item_id,
1290   		x_organization_id      =>  p_x_disposition_rec.item_org_id,
1291   		x_item_group_id        =>  p_x_disposition_rec.item_group_id,
1292   		x_condition_id         =>  p_x_disposition_rec.condition_id,
1293   		x_instance_id          => p_x_disposition_rec.instance_id,
1294   		x_serial_number        =>  p_x_disposition_rec.serial_number,
1295   		x_lot_number           =>  p_x_disposition_rec.lot_number,
1296   		x_immediate_disposition_code  =>  p_x_disposition_rec.immediate_disposition_code ,
1297   		x_secondary_disposition_code  =>  p_x_disposition_rec.secondary_disposition_code,
1298   		x_status_code          =>  p_x_disposition_rec.status_code,
1299   		x_quantity             =>  p_x_disposition_rec.quantity,
1300   		x_uom                  =>  p_x_disposition_rec.uom,
1301   		x_collection_id        =>  p_x_disposition_rec.collection_id,
1302   		x_primary_service_request_id   =>  p_x_disposition_rec.primary_service_request_id ,
1303   		x_non_routine_workorder_id     =>  p_x_disposition_rec.non_routine_workorder_id,
1304   		x_wo_operation_id              => p_x_disposition_rec.wo_operation_id,
1305   		x_item_revision                => p_x_disposition_rec.item_revision,
1306   		x_attribute_category   =>  p_x_disposition_rec.attribute_category,
1307   		x_attribute1           =>  p_x_disposition_rec.attribute1,
1308   		x_attribute2           =>  p_x_disposition_rec.attribute2,
1309   		x_attribute3           =>  p_x_disposition_rec.attribute3,
1310   		x_attribute4           =>  p_x_disposition_rec.attribute4,
1311   		x_attribute5           =>  p_x_disposition_rec.attribute5,
1312   		x_attribute6           =>  p_x_disposition_rec.attribute6,
1313   		x_attribute7           =>  p_x_disposition_rec.attribute7,
1314   		x_attribute8           =>  p_x_disposition_rec.attribute8,
1315   		x_attribute9           =>  p_x_disposition_rec.attribute9,
1316   		x_attribute10          =>  p_x_disposition_rec.attribute10,
1317   		x_attribute11          =>  p_x_disposition_rec.attribute11,
1318   		x_attribute12          =>  p_x_disposition_rec.attribute12,
1319   		x_attribute13          =>  p_x_disposition_rec.attribute13,
1320   		x_attribute14          =>  p_x_disposition_rec.attribute14,
1321   		x_attribute15          =>  p_x_disposition_rec.attribute15,
1322   		x_comments             =>  p_x_disposition_rec.comments,
1323 
1324   		x_creation_date        =>  p_x_disposition_rec.creation_date ,
1325   		x_created_by           =>  p_x_disposition_rec.created_by,
1326   		x_last_update_date     =>  p_x_disposition_rec.last_update_date,
1327   		x_last_updated_by      =>  p_x_disposition_rec.last_updated_by,
1328   		x_last_update_login    =>  p_x_disposition_rec.last_update_login
1329   );
1330 
1331   -- SATHAPLI::FP OGMA Issue# 86 - Automatic Material Return, 27-Dec-2007
1332   -- If the instance was just removed in Serviceable condition return the part to the Visit Locator.
1333   -- Note that the ReturnTo_Workorder_Locator will return only if the locator is set at the Visit level.
1334   -- For FP OGMA Issue# 105 - Non-Serialized Item Maintenance, if the instance was removed in 'Inspection'
1335   -- condition, then it should not be returned to the locator.
1336   IF (NVL(x_return_status, FND_API.G_RET_STS_SUCCESS) = FND_API.G_RET_STS_SUCCESS AND
1337       p_x_disposition_rec.part_change_id IS NOT NULL AND
1338       p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) AND
1339       p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1) AND
1340       p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_INSPECTION'), -1)) THEN
1341     OPEN part_change_dtls_csr(p_x_disposition_rec.part_change_id);
1342     FETCH part_change_dtls_csr INTO l_removed_instance_id, l_part_change_type;
1343     CLOSE part_change_dtls_csr;
1344     -- Changed by jaramana on 17-FEB-2011 for bug 11676572; sorao for backporting project
1345     --IF (l_removed_instance_id = p_x_disposition_rec.instance_id AND  -- Removed instance is the Disposition instance
1346     IF (((l_removed_instance_id = p_x_disposition_rec.instance_id) OR (p_x_disposition_rec.serial_number IS NULL)) AND  -- Removed instance is the Disposition instance or Non Serialized
1347 
1348 	NVL(l_part_change_type, 'X') IN ('R', 'S')) THEN  -- Removal or Swap
1349 
1350       -- Change by jaramana on 06-DEC-2011 to capture instance condition in IB
1351       -- Functionality required as part of Various Execution Enhancements (VEE)
1352       -- Part Removal has happened: Update Instance condition
1353       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1354         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to call AHL_PRD_PARTS_CHANGE_PVT.Update_Part_Condition with ' ||
1355                        ' p_instance_id = ' || l_removed_instance_id ||
1356                        ', and p_instance_condition_id = ' || p_x_disposition_rec.condition_id);
1357       END IF;
1358       AHL_PRD_PARTS_CHANGE_PVT.Update_Part_Condition(p_init_msg_list         => FND_API.G_FALSE,
1359                                                      p_commit                => FND_API.G_FALSE,
1360                                                      p_validation_level      => FND_API.G_VALID_LEVEL_FULL,
1361                                                      p_instance_id           => l_removed_instance_id,
1362                                                      p_instance_condition_id => p_x_disposition_rec.condition_id,
1363                                                      x_return_status         => x_return_status,
1364                                                      x_msg_data              => x_msg_data,
1365                                                      x_msg_count             => x_msg_count);
1366       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1367         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Returned from AHL_PRD_PARTS_CHANGE_PVT.Update_Part_Condition: ' ||
1368                        ' x_return_status = ' || x_return_status);
1369       END IF;
1370       IF x_return_status = FND_API.G_RET_STS_ERROR THEN
1371         RAISE FND_API.G_EXC_ERROR;
1372       ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1373         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1374       END IF;
1375 
1376       IF (p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) AND
1377           p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1) AND
1378           p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_INSPECTION'), -1)) THEN
1379         -- Serviceable Removal: Move part to WO locator
1380         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1381           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to call AHL_PRD_PARTS_CHANGE_PVT.ReturnTo_Workorder_Locator with ' ||
1382                          ' part change id = ' || p_x_disposition_rec.part_change_id ||
1383                          ' and disposition_id = ' || p_x_disposition_rec.disposition_id);
1384         END IF;
1385         AHL_PRD_PARTS_CHANGE_PVT.ReturnTo_Workorder_Locator(p_part_change_id => p_x_disposition_rec.part_change_id,
1386                                                             p_disposition_id => p_x_disposition_rec.disposition_id,
1387                                                             x_return_status  => x_return_status,
1388                                                             x_msg_data       => x_msg_data,
1389                                                             x_msg_count      => x_msg_count,
1390                                                             x_ahl_mtltxn_rec => l_ahl_mtltxn_rec);
1391 
1392         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1393           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Returned from AHL_PRD_PARTS_CHANGE_PVT.ReturnTo_Workorder_Locator: ' ||
1394                          ' x_return_status = ' || x_return_status);
1395         END IF;
1396         IF x_return_status = FND_API.G_RET_STS_ERROR THEN
1397           RAISE FND_API.G_EXC_ERROR;
1398         ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1399           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1400         END IF;
1401       END IF;  -- If Serviceable Removal
1402     END IF;  -- If Part Removal has happened
1403   END IF;  -- x_return_status is Success and Part Change has happened
1404 
1405   -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
1406   -- If the part is removed in 'Inspection' condition, then move the disposition to Complete status.
1407   IF (p_x_disposition_rec.condition_id = NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_INSPECTION'), -1) AND
1408       p_x_disposition_rec.part_change_id IS NOT NULL) THEN
1409     UPDATE AHL_PRD_DISPOSITIONS_B
1410     SET    status_code = 'COMPLETE'
1411     WHERE  disposition_id = p_x_disposition_rec.disposition_id;
1412   END IF;
1413 
1414   -- Changes by jaramana on 03-FEB-2011 for bug 10647408
1415   -- For Non Serialized tracked items, if an unserviceable removal was done with Create Work Order in released option
1416   -- then the disposition should be deemed complete as soon as the quantity is moved to the newly created work order.
1417   -- This is to prevent the Material returns UI from incorrectly showing this disposition quantity as available for return
1418   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1419     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to check if Disposition status can be set to Complete for non Inspection.' ||
1420       ' p_x_disposition_rec.condition_id = ' || p_x_disposition_rec.condition_id ||
1421       ', NVL(fnd_profile.value(AHL_MTL_MAT_STATUS_UNSERVICABLE), -1) = ' || NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) ||
1422       ', NVL(fnd_profile.value(AHL_MTL_MAT_STATUS_MRB), -1) = ' || NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1) ||
1423       ', p_x_disposition_rec.part_change_id = ' || p_x_disposition_rec.part_change_id ||
1424       ', l_non_routine_workorder_id = ' || l_non_routine_workorder_id ||
1425       ', l_primary_service_request_id = ' || l_primary_service_request_id);
1426   END IF;
1427 
1428   -- Changes by jaramana on 31-MAR-2011 for bug 11856373;sorao for backporting project
1429   -- Do not use the part change id for determining this
1430  IF (p_x_disposition_rec.serial_number IS NULL AND p_x_disposition_rec.instance_id IS NOT NULL AND
1431       (p_x_disposition_rec.condition_id = NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) OR
1432        p_x_disposition_rec.condition_id = NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1)) AND
1433       l_non_routine_workorder_id IS NOT NULL) THEN
1434 
1435     -- Cursor to get the removal instance removed by jaramana on 31-MAR-2011 for bug 11856373
1436     -- Do not use the removed instance for this check
1437 
1438     -- Get the first released non-master workorder id for the NR summary workorder
1439     OPEN get_rel_nonmaster_wo_id_csr(p_x_disposition_rec.non_routine_workorder_id);
1440     FETCH get_rel_nonmaster_wo_id_csr INTO l_rel_nm_wo_id;
1441     IF (get_rel_nonmaster_wo_id_csr%FOUND) THEN
1442       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1443         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'l_rel_nm_wo_id = ' || l_rel_nm_wo_id);
1444       END IF;
1445 
1446       -- Check if the instance has already been moved to the new NR work order (non-master)
1447      --OPEN chk_disp_inst_job_csr (p_x_disposition_rec.instance_id, l_rel_nm_wo_id);
1448       -- Changed by jaramana on 31-MAR-2011 to compare using the item and quantity of the disposition
1449       -- rather than the removed instance id
1450       OPEN chk_disp_inst_job_csr (p_x_disposition_rec.disposition_id, l_rel_nm_wo_id);
1451       FETCH chk_disp_inst_job_csr INTO l_inst_in_job_flag;
1452       CLOSE chk_disp_inst_job_csr;
1453       IF (l_inst_in_job_flag = 'Y') THEN
1454         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1455           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Non Ser. trk. item unserv. removal with Create WO in rel. option. Removed instance moved to NR WO. Setting Disp. status to COMPLETE.');
1456         END IF;
1457         -- All checks completed: Change the Disposition status to COMPLETE
1458         UPDATE AHL_PRD_DISPOSITIONS_B
1459            SET status_code = 'COMPLETE'
1460          WHERE disposition_id = p_x_disposition_rec.disposition_id;
1461 	 ELSE
1462         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1463           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Instance not in work order. l_rel_nm_wo_id = ' || l_rel_nm_wo_id);
1464         END IF;
1465       END IF;
1466     ELSE
1467       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1468         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'No Released Work Orders Found');
1469       END IF;
1470     END IF;
1471     CLOSE get_rel_nonmaster_wo_id_csr;
1472   END IF;
1473   -- End changes by jaramana on 03-FEB-2011 for bug 10647408
1474 
1475   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1476     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'end create_disposition disposition_id:' ||p_x_disposition_rec.disposition_id);
1477   END IF;
1478 
1479     -- Added by jaramana on 17-JUN-2011 for bug 10195920
1480   -- Close the cursor that locked the instance
1481   CLOSE instance_lock_csr;
1482 
1483   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1484      FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'End Procedure');
1485   END IF;
1486   --dbms_output.put_line(SubStr('End  Create_Disposition', 1, 255));
1487 END create_disposition;
1488 
1489 
1490 --------------UPDATE_DISPOSITION---------------------------------------------------
1491 
1492 PROCEDURE update_disposition(
1493     p_api_version           IN             NUMBER    := 1.0,
1494     p_init_msg_list         IN             VARCHAR2  := FND_API.G_TRUE,
1495     p_commit                IN             VARCHAR2  := FND_API.G_FALSE,
1496     p_validation_level      IN             NUMBER    := FND_API.G_VALID_LEVEL_FULL,
1497     p_module_type           IN             VARCHAR2  := NULL,
1498     p_x_disposition_rec     IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
1499     -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
1500     p_mr_asso_tbl           IN             AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type,
1501     x_return_status         OUT NOCOPY     VARCHAR2,
1502     x_msg_count             OUT NOCOPY     NUMBER,
1503     x_msg_data              OUT NOCOPY     VARCHAR2
1504   ) IS
1505 
1506 CURSOR disposition_csr(p_disposition_id IN NUMBER) IS
1507        SELECT *
1508 --    AnRaj: Changed query, Perf Bug#4908609,Issue#4
1509 --	   FROM ahl_prd_dispositions_v
1510 	   FROM ahl_prd_dispositions_vl
1511 	   WHERE disposition_id = p_disposition_id ;
1512 
1513 
1514 CURSOR get_organization_csr(p_workorder_id IN NUMBER) IS
1515       SELECT vi.organization_id from  ahl_workorders wo, ahl_visits_b vi
1516        WHERE wo.workorder_id = p_workorder_id
1517 	     AND wo.visit_id = vi.visit_id;
1518 
1519 CURSOR val_lot_number_csr(p_lot_number IN VARCHAR2, p_inventory_item_id IN NUMBER) IS
1520        SELECT 'x' FROM mtl_lot_numbers
1521        WHERE lot_number = p_lot_number
1522          AND inventory_item_id = p_inventory_item_id
1523        UNION
1524        SELECT 'x' FROM csi_item_instances csi
1525        WHERE lot_number = p_lot_number
1526          AND inventory_item_id = p_inventory_item_id;
1527 
1528 CURSOR val_serial_number_csr(p_serial_number IN VARCHAR2, p_inventory_item_id IN NUMBER) IS
1529        SELECT 'x' FROM mtl_serial_numbers
1530        WHERE serial_number = p_serial_number
1531          AND inventory_item_id = p_inventory_item_id
1532        UNION
1533        SELECT 'x' FROM csi_item_instances csi
1534        WHERE serial_number = p_serial_number
1535          AND inventory_item_id = p_inventory_item_id;
1536 
1537 CURSOR item_revisions_csr (p_revision  IN  VARCHAR2, p_item_id IN NUMBER, p_organization_id IN NUMBER)  IS
1538        SELECT 'x' FROM   mtl_item_revisions
1539         WHERE  inventory_item_id = p_item_id
1540             AND organization_id = p_organization_id
1541             AND revision = p_revision;
1542 
1543 -- Added by jaramana on October 8, 2007 for ER 5903256
1544 CURSOR check_nr_wo_status_csr(p_nr_workorder_id IN NUMBER) IS
1545        SELECT 'Y'
1546         FROM AHL_WORKORDERS WO, AHL_VISIT_TASKS_B TSK, AHL_UNIT_EFFECTIVITIES_B UE
1547         WHERE WO.workorder_id = NVL(p_nr_workorder_id, -1)
1548           AND TSK.VISIT_TASK_ID = WO.VISIT_TASK_ID
1549           AND UE.UNIT_EFFECTIVITY_ID = TSK.UNIT_EFFECTIVITY_ID
1550           AND UE.STATUS_CODE IS NULL;
1551 
1552 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
1553 -- Cursor to check whether the disposition item is serialized or not.
1554 CURSOR chk_non_serialized_csr(p_inventory_item_id NUMBER, p_item_org_id NUMBER) IS
1555        SELECT 'X'
1556        FROM   mtl_system_items_b
1557        WHERE  inventory_item_id          = p_inventory_item_id
1558        AND    organization_id            = p_item_org_id
1559        AND    serial_number_control_code = 1;
1560 
1561 -- SATHAPLI::FP OGMA Issue# 86 - Automatic Material Return, 27-Dec-2007
1562 -- Cursor to fetch the part change details.
1563 CURSOR part_change_dtls_csr(p_part_change_id IN NUMBER) IS
1564        SELECT removed_instance_id, part_change_type
1565        FROM   ahl_part_changes
1566        WHERE  part_change_id = p_part_change_id;
1567 
1568 l_exist VARCHAR(1);
1569 
1570 -- SATHAPLI::Bug 7111116, 21-May-2008, fix start
1571 -- Cursor to get the first released non-master workorder id for a given NR summary workorder.
1572 CURSOR get_rel_nonmaster_wo_id_csr(c_nr_wo_id NUMBER) IS
1573     SELECT workorder_id
1574     FROM   ahl_workorders
1575     WHERE  master_workorder_flag = 'N'
1576     AND    wip_entity_id IN
1577            (SELECT child_object_id
1578             FROM   wip_sched_relationships
1579             START WITH parent_object_id      = (SELECT wip_entity_id FROM ahl_workorders WHERE workorder_id = c_nr_wo_id)
1580             CONNECT BY parent_object_id      = PRIOR child_object_id
1581             AND        parent_object_type_id = PRIOR child_object_type_id
1582             AND        relationship_type     = 1
1583            )
1584     AND    status_code           = G_WO_RELEASED_STATUS
1585     ORDER BY workorder_id;
1586 
1587 -- Cursor to get the removed instance id for a given part change id.
1588 CURSOR get_rem_inst_id_csr(c_part_change_id NUMBER) IS
1589     SELECT removed_instance_id
1590     FROM   ahl_part_changes
1591     WHERE  part_change_id = c_part_change_id;
1592 -- SATHAPLI::Bug 7111116, 21-May-2008, fix end
1593 
1594  -- Added by jaramana on 03-FEB-2011 for bug 10647408
1595  -- Cursor to check whether removed instance is in the given workorder or not.
1596  /**
1597  CURSOR chk_disp_inst_job_csr (p_instance_id NUMBER, p_workorder_id NUMBER) IS
1598      SELECT 'Y'
1599      FROM   ahl_workorders awo, csi_item_instances csi
1600      WHERE  awo.wip_entity_id = csi.wip_job_id
1601      AND    awo.workorder_id  = p_workorder_id
1602      AND    csi.instance_id   = p_instance_id;
1603 **/
1604 
1605  -- Changed by jaramana on 31-MAR-2011 for bug 11856373 to compare using
1606  -- the item and quantity of the disposition rather than the actual instance id
1607  CURSOR chk_disp_inst_job_csr (p_disposition_id NUMBER, p_workorder_id NUMBER) IS
1608      SELECT 'Y'
1609        FROM ahl_workorders awo, csi_item_instances csi, ahl_prd_dispositions_b disp
1610       WHERE awo.workorder_id = p_workorder_id
1611         AND csi.wip_job_id = awo.wip_entity_id
1612         AND csi.INVENTORY_ITEM_ID = disp.INVENTORY_ITEM_ID
1613         AND csi.QUANTITY = disp.QUANTITY;
1614 
1615 l_inst_in_job_flag    VARCHAR2(1) := 'N';
1616 
1617 l_disposition_rec     disposition_csr%ROWTYPE;
1618 -- l_disposition_rec  AHL_PRD_DISPOSITION_PVT.disposition_rec_type;
1619 l_primary_service_request_id NUMBER;
1620 l_non_routine_workorder_id NUMBER;
1621 l_calculated_status VARCHAR(30);
1622 l_disposition_h_id NUMBER;
1623 l_dummy_char   VARCHAR2(30);
1624 l_return_status VARCHAR2(30);
1625 
1626 l_pos_empty BOOLEAN;
1627 l_assoc_quantity NUMBER;
1628 
1629 L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'update_disposition';
1630 l_init_msg_list  VARCHAR2(1)  := FND_API.G_FALSE;
1631 l_commit         VARCHAR2(1)  := FND_API.G_FALSE;
1632 l_msg_count NUMBER;
1633 l_plan_id   NUMBER;
1634 l_msg_data  VARCHAR2(2000);
1635 
1636 l_removed_instance_id NUMBER;
1637 l_part_change_type    VARCHAR2(1);
1638 l_ahl_mtltxn_rec      AHL_PRD_MTLTXN_PVT.Ahl_Mtltxn_Rec_Type;
1639 l_dummy               VARCHAR(1);
1640 
1641 -- SATHAPLI::Bug 7111116, 21-May-2008
1642 l_move_item_ins_tbl   AHL_PRD_PARTS_CHANGE_PVT.move_item_instance_tbl_type;
1643 l_rel_nm_wo_id        NUMBER;
1644 l_primary_sr_created  BOOLEAN := FALSE;
1645 
1646 cursor is_qa_coll_reqd(p_plan_id IN NUMBER) IS
1647 select 'x' from qa_plan_transactions_v
1648 where mandatory_collection_flag = 1 and enabled_flag = 1
1649 and plan_id = p_plan_id;
1650 
1651 BEGIN
1652 
1653   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1654     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
1655   END IF;
1656 
1657 
1658   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1659     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY || '', 'update Disposition_id' || p_x_disposition_rec.disposition_id );
1660   END IF;
1661 
1662   --dbms_output.put_line(SubStr('Begin  Update_Disposition', 1, 255));
1663 
1664 
1665   OPEN disposition_csr(p_x_disposition_rec.disposition_id);
1666   FETCH disposition_csr INTO l_disposition_rec;
1667 
1668   IF (disposition_csr%NOTFOUND) THEN
1669     CLOSE disposition_csr;   --close cursor before raising exeption
1670     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_NOT_FOUND');
1671     FND_MSG_PUB.ADD;
1672     RAISE FND_API.G_EXC_ERROR;
1673   END IF;
1674   CLOSE disposition_csr;
1675 
1676   IF(p_x_disposition_rec.OBJECT_VERSION_NUMBER <> l_disposition_rec.OBJECT_VERSION_NUMBER) THEN
1677       FND_MESSAGE.Set_Name('AHL', 'AHL_COM_RECORD_CHANGED');
1678       FND_MSG_PUB.ADD;
1679       RAISE FND_API.G_EXC_ERROR;
1680   END IF;
1681 
1682   IF l_disposition_rec.status_code = 'TERMINATED' THEN
1683     FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_DIS_UPDATE_TERMINATE');        --Cannot update a terminated disposition.
1684     FND_MSG_PUB.ADD;
1685     RAISE FND_API.G_EXC_ERROR;
1686   END IF;
1687 
1688   --Handle JSP module
1689    --Handle GMiss and merge the updating record with the one from database
1690 
1691   IF (p_module_type = 'JSP') THEN
1692     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1693       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Merging data');
1694     END IF;
1695     --dbms_output.put_line(SubStr('Update_disp:Merging data', 1, 255));
1696     IF p_x_disposition_rec.workorder_id IS NULL THEN
1697 	    p_x_disposition_rec.workorder_id := l_disposition_rec.workorder_id;
1698 	ELSIF (p_x_disposition_rec.workorder_id  = FND_API.G_MISS_NUM) THEN
1699         p_x_disposition_rec.workorder_id  := null;
1700     END IF;
1701     IF p_x_disposition_rec.part_change_id IS NULL THEN
1702 	    p_x_disposition_rec.part_change_id := l_disposition_rec.part_change_id;
1703     ELSIF (p_x_disposition_rec.part_change_id  = FND_API.G_MISS_NUM) THEN
1704         p_x_disposition_rec.part_change_id  := null;
1705     END IF;
1706     IF p_x_disposition_rec.path_position_id IS NULL THEN
1707 	    p_x_disposition_rec.path_position_id := l_disposition_rec.path_position_id;
1708     ELSIF (p_x_disposition_rec.path_position_id  = FND_API.G_MISS_NUM) THEN
1709         p_x_disposition_rec.path_position_id  := null;
1710     END IF;
1711     IF p_x_disposition_rec.item_org_id IS NULL THEN
1712 	    p_x_disposition_rec.item_org_id := l_disposition_rec.organization_id;
1713     ELSIF (p_x_disposition_rec.item_org_id  = FND_API.G_MISS_NUM) THEN
1714         p_x_disposition_rec.item_org_id  := null;
1715     END IF;
1716     IF p_x_disposition_rec.inventory_item_id IS NULL THEN
1717 	    p_x_disposition_rec.inventory_item_id := l_disposition_rec.inventory_item_id;
1718     ELSIF (p_x_disposition_rec.inventory_item_id  = FND_API.G_MISS_NUM) THEN
1719         p_x_disposition_rec.inventory_item_id  := null;
1720     END IF;
1721 
1722     IF p_x_disposition_rec.item_group_id IS NULL THEN
1723 	    p_x_disposition_rec.item_group_id := l_disposition_rec.item_group_id;
1724     ELSIF (p_x_disposition_rec.item_group_id  = FND_API.G_MISS_NUM) THEN
1725         p_x_disposition_rec.item_group_id  := null;
1726     END IF;
1727     IF p_x_disposition_rec.condition_id IS NULL THEN
1728 	    p_x_disposition_rec.condition_id := l_disposition_rec.condition_id;
1729     ELSIF (p_x_disposition_rec.condition_id  = FND_API.G_MISS_NUM) THEN
1730         p_x_disposition_rec.condition_id  := null;
1731     END IF;
1732     IF p_x_disposition_rec.instance_id IS NULL THEN
1733 	    p_x_disposition_rec.instance_id := l_disposition_rec.instance_id;
1734     ELSIF (p_x_disposition_rec.instance_id  = FND_API.G_MISS_NUM) THEN
1735         p_x_disposition_rec.instance_id  := null;
1736     END IF;
1737     IF p_x_disposition_rec.serial_number IS NULL THEN
1738 	    p_x_disposition_rec.serial_number := l_disposition_rec.serial_number;
1739     ELSIF (p_x_disposition_rec.serial_number  = FND_API.G_MISS_CHAR) THEN
1740         p_x_disposition_rec.serial_number  := null;
1741     END IF;
1742     IF p_x_disposition_rec.lot_number IS NULL THEN
1743 	    p_x_disposition_rec.lot_number := l_disposition_rec.lot_number;
1744     ELSIF (p_x_disposition_rec.lot_number  = FND_API.G_MISS_CHAR) THEN
1745         p_x_disposition_rec.lot_number  := null;
1746     END IF;
1747     IF p_x_disposition_rec.immediate_disposition_code IS NULL THEN
1748 	    p_x_disposition_rec.immediate_disposition_code := l_disposition_rec.immediate_disposition_code;
1749     ELSIF (p_x_disposition_rec.immediate_disposition_code  = FND_API.G_MISS_CHAR) THEN
1750         p_x_disposition_rec.immediate_disposition_code  := null;
1751     END IF;
1752     IF p_x_disposition_rec.secondary_disposition_code IS NULL THEN
1753 	    p_x_disposition_rec.secondary_disposition_code := l_disposition_rec.secondary_disposition_code;
1754     ELSIF (p_x_disposition_rec.secondary_disposition_code  = FND_API.G_MISS_CHAR) THEN
1755         p_x_disposition_rec.secondary_disposition_code  := null;
1756     END IF;
1757     IF p_x_disposition_rec.status_code IS NULL THEN
1758 	    p_x_disposition_rec.status_code := l_disposition_rec.status_code;
1759     ELSIF (p_x_disposition_rec.status_code  = FND_API.G_MISS_CHAR) THEN
1760         p_x_disposition_rec.status_code  := null;
1761     END IF;
1762     IF p_x_disposition_rec.quantity IS NULL THEN
1763 	    p_x_disposition_rec.quantity := l_disposition_rec.quantity;
1764     ELSIF (p_x_disposition_rec.quantity  = FND_API.G_MISS_NUM) THEN
1765         p_x_disposition_rec.quantity  := null;
1766     END IF;
1767     IF p_x_disposition_rec.uom IS NULL THEN
1768 	    p_x_disposition_rec.uom := l_disposition_rec.uom;
1769     ELSIF (p_x_disposition_rec.uom  = FND_API.G_MISS_CHAR) THEN
1770         p_x_disposition_rec.uom  := null;
1771     END IF;
1772     IF p_x_disposition_rec.comments IS NULL THEN
1773 	    p_x_disposition_rec.comments := l_disposition_rec.comments;
1774     ELSIF (p_x_disposition_rec.comments  = FND_API.G_MISS_CHAR) THEN
1775         p_x_disposition_rec.comments  := null;
1776     END IF;
1777     IF p_x_disposition_rec.collection_id IS NULL THEN
1778 	    p_x_disposition_rec.collection_id := l_disposition_rec.collection_id;
1779     ELSIF (p_x_disposition_rec.collection_id  = FND_API.G_MISS_NUM) THEN
1780         p_x_disposition_rec.collection_id  := null;
1781     END IF;
1782     IF p_x_disposition_rec.primary_service_request_id IS NULL THEN
1783 	    p_x_disposition_rec.primary_service_request_id := l_disposition_rec.primary_service_request_id;
1784     ELSIF (p_x_disposition_rec.primary_service_request_id  = FND_API.G_MISS_NUM) THEN
1785         p_x_disposition_rec.primary_service_request_id  := null;
1786     END IF;
1787     IF p_x_disposition_rec.non_routine_workorder_id IS NULL THEN
1788 	    p_x_disposition_rec.non_routine_workorder_id := l_disposition_rec.non_routine_workorder_id;
1789     ELSIF (p_x_disposition_rec.non_routine_workorder_id  = FND_API.G_MISS_NUM) THEN
1790         p_x_disposition_rec.non_routine_workorder_id  := null;
1791     END IF;
1792     IF p_x_disposition_rec.wo_operation_id IS NULL THEN
1793 	    p_x_disposition_rec.wo_operation_id := l_disposition_rec.wo_operation_id;
1794     ELSIF (p_x_disposition_rec.wo_operation_id  = FND_API.G_MISS_NUM) THEN
1795         p_x_disposition_rec.wo_operation_id  := null;
1796     END IF;
1797     IF p_x_disposition_rec.item_revision IS NULL THEN
1798 	    p_x_disposition_rec.item_revision := l_disposition_rec.item_revision;
1799     ELSIF (p_x_disposition_rec.item_revision  = FND_API.G_MISS_CHAR) THEN
1800         p_x_disposition_rec.item_revision  := null;
1801     END IF;
1802 
1803    IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1804       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'After Merging data');
1805     END IF;
1806    --dbms_output.put_line(SubStr('Update_disp:End Merging data', 1, 255));
1807   END IF;
1808   --END MERGING DATA
1809 
1810   IF p_validation_level = FND_API.G_VALID_LEVEL_FULL  THEN
1811     convert_values_to_ids(p_x_disposition_rec);
1812   END IF;
1813 
1814   --VALIDATE THAT THESE ATTRIBUTE SHOULD NOT BE CHANGED
1815   --dbms_output.put_line('Start validate for changes..............');
1816   IF nvl(p_x_disposition_rec.workorder_id, -1) <> nvl(l_disposition_rec.workorder_id, -1) THEN
1817     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_WO_ID_CHNG');         --Workorder id Cannot be change
1818     FND_MSG_PUB.ADD;
1819   END IF;
1820   IF l_disposition_rec.part_change_id  IS NOT NULL
1821      AND nvl (p_x_disposition_rec.part_change_id, -1) <> l_disposition_rec.part_change_id THEN
1822     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_PARTCHG_ID_CHNG');         --Part Change Cannot be change
1823     FND_MSG_PUB.ADD;
1824   END IF;
1825 
1826   IF l_disposition_rec.inventory_item_id IS NOT NULL
1827    AND nvl(p_x_disposition_rec.inventory_item_id, -1) <> l_disposition_rec.inventory_item_id THEN
1828      --dbms_output.put_line('In Error message AHL_PRD_DIS_ITEM_REV_CHNG');
1829      FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_CHG');         --Item cannot be changed
1830      FND_MSG_PUB.ADD;
1831   END IF;
1832 
1833  /* IF nvl (p_x_disposition_rec.item_revision, ' ') <> nvl(l_disposition_rec.item_revision, ' ') THEN
1834     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_REV_CHNG');         --ITem Revision Cannot be change
1835     FND_MSG_PUB.ADD;
1836   END IF;
1837   */
1838   IF nvl(p_x_disposition_rec.item_group_id, -1) <> nvl(l_disposition_rec.item_group_id, -1) THEN
1839     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_GRP_CHNG');         --Item Group Cannot be change
1840     FND_MSG_PUB.ADD;
1841   END IF;
1842   --IF nvl(p_x_disposition_rec.instance_id, -1) <> nvl(l_disposition_rec.instance_id, -1) THEN
1843   --Instance can only be changed once (originally it is not changeable at all)
1844   --Updated by Jerry on 01/26/2005 for fixing bug 4089750
1845   IF (l_disposition_rec.instance_id IS NOT NULL AND (p_x_disposition_rec.instance_id IS NULL OR
1846       p_x_disposition_rec.instance_id <> l_disposition_rec.instance_id)) THEN
1847     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INST_CHNG');
1848     FND_MSG_PUB.ADD;
1849   ELSIF ((l_disposition_rec.instance_id IS NULL AND
1850          p_x_disposition_rec.instance_id IS NULL AND
1851         --    AnRaj: Changed query, Perf Bug#4908609,Issue#4
1852         -- l_disposition_rec.trackable_flag = 'Y' AND
1853          (l_disposition_rec.instance_id is not null or l_disposition_rec.path_position_id is not null) AND
1854          p_x_disposition_rec.status_code <> 'TERMINATED' AND --Added on 03/02/05 when verifying
1855          l_disposition_rec.part_change_id IS NULL AND        --bug fix 4093642 on SCMTSB2
1856          p_x_disposition_rec.part_change_id IS NULL) AND     -- Added by rbhavsar on Aug 07, 2007 for FP bug 6318339, base bug 6058419
1857          (l_disposition_rec.immediate_disposition_code is NULL)) THEN
1858     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INSTANCE_VALUE_REQ');
1859     FND_MSG_PUB.ADD;
1860   ELSIF (l_disposition_rec.instance_id IS NULL AND p_x_disposition_rec.instance_id IS NOT NULL) THEN
1861     BEGIN
1862       SELECT 'X' INTO l_dummy_char
1863         FROM csi_item_instances
1864        WHERE instance_id = p_x_disposition_rec.instance_id
1865          AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
1866          AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1867     EXCEPTION
1868       WHEN NO_DATA_FOUND THEN
1869         FND_MESSAGE.set_name(G_APP_NAME,'AHL_PRD_INV_INST_NUM');
1870         FND_MESSAGE.set_token('INTANCE_NUM', p_x_disposition_rec.instance_number);
1871         FND_MSG_PUB.ADD;
1872     END;
1873   END IF;
1874   /* Commented out on 02/02/2005 by Jerry for fixing bug 4089750
1875   IF nvl(p_x_disposition_rec.instance_id, -1) <> nvl(l_disposition_rec.instance_id, -1) THEN
1876     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INST_CHNG');         --Instance Cannot be change
1877     FND_MSG_PUB.ADD;
1878   END IF;
1879   */
1880   /* Begin Fix for 4075758 on Dec 21. 2004 */
1881   -- For non-tracked, serial or lot controlled items, the serial
1882   -- and/or and lot number may be provided during update mode also
1883   /*****
1884   IF nvl(p_x_disposition_rec.serial_number, ' ') <> nvl(l_disposition_rec.serial_number, ' ') THEN
1885     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_SERIAL_NUM_CHNG');         --Serial Number Cannot be change
1886     FND_MSG_PUB.ADD;
1887   END IF;
1888 
1889   IF nvl(p_x_disposition_rec.lot_number, ' ') <> nvl(l_disposition_rec.lot_number, ' ') THEN
1890     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_LOT_NUM_CHNG');         --Lot Number Cannot be change
1891     FND_MSG_PUB.ADD;
1892   END IF;
1893   ******/
1894   IF nvl(p_x_disposition_rec.serial_number, ' ') <> nvl(l_disposition_rec.serial_number, nvl(p_x_disposition_rec.serial_number, ' ')) THEN
1895     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_SERIAL_NUM_CHNG');         --Serial Number Can be set once
1896     FND_MSG_PUB.ADD;
1897   END IF;
1898   IF nvl(p_x_disposition_rec.serial_number, ' ') <> nvl(l_disposition_rec.serial_number, ' ') THEN
1899     -- Serial Number has been set: Validate
1900     OPEN val_serial_number_csr(p_x_disposition_rec.serial_number, p_x_disposition_rec.inventory_item_id);
1901     FETCH val_serial_number_csr INTO l_exist;
1902     IF (val_serial_number_csr%NOTFOUND) THEN
1903       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_SERIAL');    -- Invalid serial number and item combination
1904       FND_MSG_PUB.ADD;
1905     END IF;
1906     CLOSE val_serial_number_csr;
1907   END IF;
1908 
1909   IF nvl(p_x_disposition_rec.lot_number, ' ') <> nvl(l_disposition_rec.lot_number, nvl(p_x_disposition_rec.lot_number, ' ')) THEN
1910     FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_LOT_NUM_CHNG');         --Lot Number Can be set once
1911     FND_MSG_PUB.ADD;
1912   END IF;
1913   IF nvl(p_x_disposition_rec.lot_number, ' ') <> nvl(l_disposition_rec.lot_number, ' ') THEN
1914     -- Lot Number has been set: Validate
1915     OPEN val_lot_number_csr(p_x_disposition_rec.lot_number, p_x_disposition_rec.inventory_item_id);
1916     FETCH val_lot_number_csr INTO l_exist;
1917     IF (val_lot_number_csr%NOTFOUND) THEN
1918       FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_INV_LOT');    -- Invalid Lot number and item combination
1919       FND_MSG_PUB.ADD;
1920     END IF;
1921     CLOSE val_lot_number_csr;
1922   END IF;
1923 
1924  --Item Revision
1925   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1926           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Item Revision old: ' || l_disposition_rec.item_revision || ' new: ' || p_x_disposition_rec.item_revision);
1927 	END IF;
1928  IF nvl(p_x_disposition_rec.item_revision, ' ') <> nvl(l_disposition_rec.item_revision, nvl(p_x_disposition_rec.item_revision, ' ')) THEN
1929     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_REV_CHNG');         --item revision Number Can be set once
1930     FND_MSG_PUB.ADD;
1931     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1932           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Item Revision Change old: ' || l_disposition_rec.item_revision || ' new: ' || p_x_disposition_rec.item_revision);
1933     END IF;
1934   END IF;
1935   IF nvl(p_x_disposition_rec.item_revision, ' ') <> nvl(l_disposition_rec.item_revision, ' ') THEN
1936     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1937           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Validate item revision: ' || p_x_disposition_rec.item_revision);
1938     END IF;
1939 	-- item revision Number has been set: Validate
1940     OPEN item_revisions_csr (p_x_disposition_rec.item_revision, p_x_disposition_rec.inventory_item_id, p_x_disposition_rec.item_org_id);
1941     FETCH item_revisions_csr INTO l_exist;
1942     IF (item_revisions_csr%NOTFOUND) THEN
1943       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_ITEM_REV');    -- Invalid serial number and item combination
1944       FND_MSG_PUB.ADD;
1945     END IF;
1946     CLOSE item_revisions_csr;
1947   END IF;
1948 
1949   /* End Fix for 4075758 on Dec 21. 2004 */
1950 
1951   IF l_disposition_rec.Collection_Id IS NOT NULL
1952     AND nvl(p_x_disposition_rec.Collection_id, -1) <> nvl(l_disposition_rec.Collection_Id, -1) THEN
1953       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_COLLECT_ID_CHNG');         --Workorder Cannot be changed
1954       FND_MSG_PUB.ADD;
1955   END IF;
1956   IF nvl(p_x_disposition_rec.Primary_Service_Request_id , -1) <> nvl(l_disposition_rec.Primary_Service_Request_id , -1) THEN
1957     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_SR_ID_CHNG');         --Primary Service Request Cannot be changed
1958     FND_MSG_PUB.ADD;
1959   END IF;
1960   IF nvl(p_x_disposition_rec.Non_Routine_Workorder_id , -1) <> nvl(l_disposition_rec.Non_Routine_Workorder_id , -1) THEN
1961     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_NONRTN_WO_CHNG');         --Non Routine Workorder Cannot be changed
1962     FND_MSG_PUB.ADD;
1963   END IF;
1964 
1965   IF (l_disposition_rec.UOM IS NOT NULL AND (nvl(p_x_disposition_rec.UOM, 'null') <> l_disposition_rec.UOM)) THEN
1966     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_UOM_CHNG');         --UOM Cannot be changed
1967     FND_MSG_PUB.ADD;
1968   END IF;
1969 
1970 
1971   IF(workorder_editable(p_x_disposition_rec.workorder_id) = FALSE) THEN
1972     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_WO_NOT_EDITABLE');       --Cannot Update Disposition Because Workorder is not editable.
1973     FND_MSG_PUB.ADD;
1974   END IF;
1975 
1976   --Disposition Status can only be changed to Terminated by the user.
1977   IF nvl(p_x_disposition_rec.status_code, 'dummy') <> 'TERMINATED' AND nvl(p_x_disposition_rec.status_code, 'dummy') <> nvl(l_disposition_rec.status_code, 'dummy') THEN
1978     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_STATUS_CHNG');         --Disposition Status cannot be changed excepte changed
1979     FND_MSG_PUB.ADD;
1980   END IF;
1981 
1982   --if existing item is null and item group is not null then item need to be enter
1983   IF l_disposition_rec.inventory_item_id IS NULL AND l_disposition_rec.item_group_id IS NOT NULL THEN
1984     IF p_x_disposition_rec.inventory_item_id IS NOT NULL THEN
1985         --derive organization
1986 		OPEN get_organization_csr(p_x_disposition_rec.workorder_id);
1987         FETCH get_organization_csr INTO p_x_disposition_rec.item_org_id;
1988 	    IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1989           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Derived Org: ' || p_x_disposition_rec.item_org_id);
1990         END IF;
1991         --dbms_output.put_line(SubStr('Derived Org: ' || p_x_disposition_rec.item_org_id, 1, 255));
1992         CLOSE get_organization_csr;
1993 
1994 		--dbms_output.put_line(SubStr('Update_disp:allow change item', 1, 255));
1995 
1996 
1997 	     validate_item(p_x_disposition_rec.inventory_item_id, p_x_disposition_rec.item_org_id, p_x_disposition_rec.workorder_id);
1998 
1999 		--start fix Bug#4075758 Item is non-tracked
2000 	    validate_Item_Control(p_x_disposition_rec.inventory_item_id , p_x_disposition_rec.item_org_id,
2001                                          p_x_disposition_rec.serial_number,
2002                                           p_x_disposition_rec.item_revision,
2003 										  p_x_disposition_rec.lot_number);
2004 		--end  Bug#4075758
2005     ELSE
2006         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_REQ');         --Item is required
2007 		FND_MSG_PUB.ADD;
2008     END IF;
2009   ELSE   --ignore the new organization id change just use the existing one
2010     p_x_disposition_rec.item_org_id := l_disposition_rec.organization_id;
2011   END IF;
2012 
2013  --Validate Workorder operation change
2014   IF(nvl(p_x_disposition_rec.wo_operation_id, -1) <> nvl(l_disposition_rec.wo_operation_id, -1)) THEN
2015     validate_wo_operation(p_x_disposition_rec.workorder_id, p_x_disposition_rec.wo_operation_id);
2016 
2017   END IF;
2018 
2019   IF p_x_disposition_rec.path_position_id IS NOT NULL AND p_x_disposition_rec.instance_id IS NULL THEN
2020     l_pos_empty := TRUE;
2021   END IF;
2022 
2023   --Validate Quantity Change
2024   IF p_x_disposition_rec.quantity IS NULL AND l_pos_empty <> TRUE THEN
2025     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_QTY_REQ');         --Quantity is required
2026     FND_MSG_PUB.ADD;
2027   ELSIF p_x_disposition_rec.quantity <= 0 THEN
2028     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_QTY_LESS_ZERO');         --Invalid Quantity.  Quantity must be greater than zero
2029     FND_MSG_PUB.ADD;
2030   ELSIF p_x_disposition_rec.quantity <> l_disposition_rec.quantity THEN
2031     IF nvl(p_x_disposition_rec.status_code, ' ') = 'COMPLETE' THEN
2032       FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_QTY_CHNG');     -- Quantity cannot be changed
2033       FND_MSG_PUB.ADD;
2034     END IF;
2035 
2036    /* Commented out on 02/02/2005 by Jerry for fixing bug 4089750
2037     IF p_x_disposition_rec.instance_id IS NOT NULL THEN
2038 	  FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_QTY_INST_QTY');     -- Quantity cannot be different from instance's quantity
2039       FND_MSG_PUB.ADD;
2040     END IF;
2041    */
2042 
2043     l_assoc_quantity := AHL_PRD_DISP_MTL_TXN_PVT.Calculate_Txned_Qty(p_x_disposition_rec.disposition_id);
2044     IF (p_x_disposition_rec.quantity < l_assoc_quantity) THEN
2045 	   FND_MESSAGE.set_name(G_APP_NAME, 'AHL_PRD_DIS_LESS_THAN_ASSC_QTY');    -- Quantity cannot be less then material transaction associated quantity
2046 	   FND_MESSAGE.Set_Token('QUANTITY', p_x_disposition_rec.quantity );
2047 	   FND_MESSAGE.Set_Token('ASSC_QTY', l_assoc_quantity );
2048 	   FND_MSG_PUB.ADD;
2049 	END IF;
2050 
2051   END IF;
2052   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2053       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'end validate changes');
2054   END IF;
2055    --dbms_output.put_line(SubStr('Update_disp:End Validate Change', 1, 255));
2056 
2057    -- Validate part_change
2058    IF(p_x_disposition_rec.part_change_id IS NOT NULL AND l_disposition_rec.part_change_id IS NULL) THEN
2059           -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
2060           -- Modified the API to take disposition quantity as an additional IN parameter.
2061 	  validate_part_change(p_x_disposition_rec.part_change_id, p_x_disposition_rec.instance_id, p_x_disposition_rec.quantity);
2062    END IF;
2063 
2064   --COLLECTION ID
2065   -- Added by jaramana on March 25, 2005 to fix bug 4243200
2066   -- First check if a QA PLan is defined in the workorder Org.
2067   AHL_QA_RESULTS_PVT.get_qa_plan( p_api_version   => 1.0,
2068                                   p_init_msg_list => FND_API.G_False,
2069                                   p_commit => FND_API.G_FALSE,
2070                                   p_validation_level => FND_API.G_VALID_LEVEL_FULL,
2071                                   p_default => FND_API.G_FALSE,
2072                                   p_organization_id => p_x_disposition_rec.item_org_id,
2073                                   p_transaction_number => 2004,  -- MRB_TRANSACTION_NUMBER
2074                                   p_col_trigger_value => fnd_profile.value('AHL_MRB_DISP_PLAN_TYPE'),
2075                                   x_return_status => l_return_status,
2076                                   x_msg_count => l_msg_count,
2077                                   x_msg_data => l_msg_data,
2078                                   x_plan_id  => l_plan_id);
2079 /**
2080   IF p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB') AND p_x_disposition_rec.instance_id IS NOT NULL THEN       -- status is MRB and tracked item
2081 **/
2082   IF p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB') AND
2083      p_x_disposition_rec.instance_id IS NOT NULL AND
2084      l_plan_id IS NOT NULL THEN       -- status is MRB and tracked item and QA plan is defined in Org
2085     IF p_x_disposition_rec.collection_id IS NULL THEN
2086       OPEN is_qa_coll_reqd(l_plan_id);
2087       FETCH is_qa_coll_reqd INTO l_dummy;
2088       IF(is_qa_coll_reqd%FOUND) THEN
2089         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_QA_RESULT_REQ');    --  QA Result Required
2090         FND_MSG_PUB.ADD;
2091       END IF;
2092       CLOSE is_qa_coll_reqd;
2093     ELSE
2094       validate_collection_id(p_x_disposition_rec.collection_id);
2095     END IF;
2096   END IF;
2097   -- End fix for bug 4243200
2098 
2099 
2100   -- SERVICE REQUEST
2101   IF ((p_x_disposition_rec.instance_id IS NULL
2102        OR
2103 	   (nvl(p_x_disposition_rec.condition_id, -1) <> fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')
2104            AND nvl(p_x_disposition_rec.condition_id, -1) <> fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE')
2105 	   )
2106 	 )
2107      AND
2108 	 ( p_x_disposition_rec.summary IS NOT NULL OR p_x_disposition_rec.problem_code IS NOT NULL
2109 	       OR p_x_disposition_rec.severity_id IS NOT NULL
2110 	 )) THEN
2111 	    FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_SR_NOT_REQ');      --Non Conformance (SR) information is not required
2112         FND_MSG_PUB.ADD;
2113   END IF;
2114 
2115   -- create service request and non-routine job
2116   -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
2117   -- Add a check for the create_work_order_option attribute too.
2118   IF p_x_disposition_rec.primary_service_request_id IS NULL AND p_x_disposition_rec.instance_id IS NOT NULL   -- AND ITEM is  tracked
2119      AND(p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE') OR
2120          p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'))
2121      AND(p_x_disposition_rec.create_work_order_option <> 'CREATE_SR_NO') THEN
2122        --dbms_output.put_line(SubStr('Update_Disp Before Create_SR', 1, 255));
2123 
2124        -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
2125        -- The option CREATE_WO_NO is not valid for non-serialized items. If chosen, throw an error.
2126        IF (p_x_disposition_rec.create_work_order_option = 'CREATE_WO_NO') THEN
2127          OPEN chk_non_serialized_csr(p_x_disposition_rec.inventory_item_id, p_x_disposition_rec.item_org_id);
2128          FETCH chk_non_serialized_csr INTO l_dummy;
2129          IF (chk_non_serialized_csr%FOUND) THEN
2130            FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_NON_SRL_SR');
2131            FND_MSG_PUB.ADD;
2132          END IF;
2133          CLOSE chk_non_serialized_csr;
2134        END IF;
2135 
2136        -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
2137        l_msg_count := FND_MSG_PUB.count_msg;
2138        IF l_msg_count > 0 THEN
2139        x_msg_count := l_msg_count;
2140          RAISE FND_API.G_EXC_ERROR;
2141        END IF;
2142        Create_SR (p_init_msg_list            => FND_API.G_FALSE,
2143                   p_disposition_rec          => p_x_disposition_rec,
2144                   -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
2145                   p_mr_asso_tbl              => p_mr_asso_tbl,
2146                   x_primary_sr_id            => l_primary_service_request_id,
2147                   x_non_routine_workorder_id => l_non_routine_workorder_id,
2148                   x_return_status            => x_return_status,
2149                   x_msg_count                => x_msg_count,
2150                   x_msg_data                 => x_msg_data);
2151        --reinitialize message stack and ignore any warning message
2152        IF x_return_status = FND_API.G_RET_STS_SUCCESS THEN
2153          FND_MSG_PUB.Initialize;
2154 
2155          -- SATHAPLI::Bug 7111116, 21-May-2008
2156          -- set the l_primary_sr_created flag to TRUE
2157          l_primary_sr_created := TRUE;
2158        END IF;
2159        p_x_disposition_rec.primary_service_request_id := l_primary_service_request_id;
2160        p_x_disposition_rec.non_routine_workorder_id := l_non_routine_workorder_id;
2161   END IF;     --end create SR
2162 
2163 
2164   --Validate disposition type
2165    IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2166       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before validate_disposition_types');
2167     END IF;
2168    --dbms_output.put_line(SubStr('Before validate disposition type', 1, 255));
2169    Validate_Disposition_Types (
2170      --   p_api_version  =>   p_api_version,
2171      --   p_init_msg_list =>  l_init_msg_list,
2172      --   p_commit =>   l_commit,
2173      --   p_validation_level  => p_validation_level,
2174         x_return_status => x_return_status,
2175         x_msg_count => x_msg_count,
2176         x_msg_data => x_msg_data ,
2177         p_disposition_rec  =>  p_x_disposition_rec);
2178 
2179   -- Calculate disposition status
2180     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2181       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before calculate_status');
2182     END IF;
2183    --dbms_output.put_line(SubStr('Before calculate status'|| p_x_disposition_Rec.status_code, 1, 255));
2184    Calculate_Status (
2185     p_disposition_Rec   => p_x_disposition_Rec,
2186     x_status_code       =>  l_calculated_status);
2187 
2188    p_x_disposition_Rec.status_code := l_calculated_status;
2189    IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2190       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'After calculate status' || p_x_disposition_Rec.status_code);
2191     END IF;
2192    --dbms_output.put_line(SubStr('After calculate status' ||p_x_disposition_Rec.status_code, 1, 255));
2193   -- setting up object version number
2194   p_x_disposition_rec.object_version_number := p_x_disposition_rec.object_version_number + 1;
2195   --setting up user/create/update information
2196   p_x_disposition_rec.last_updated_by := fnd_global.user_id;
2197   p_x_disposition_rec.last_update_date := SYSDATE;
2198   p_x_disposition_rec.last_update_login := fnd_global.login_id;
2199 
2200   -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
2201   -- If the part is removed in 'Inspection' condition, then move the disposition to Complete status.
2202     -- SURRKUMA :: BUG 12658774 - STATUS 'COMPLETED' SHOWN EVEN AFTER TERMINATION, 25-Nov-2011; sorao for backporting
2203   IF (p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_INSPECTION') AND
2204   p_x_disposition_rec.part_change_id IS NOT NULL AND p_x_disposition_rec.status_code <> 'TERMINATED') THEN
2205     p_x_disposition_rec.status_code := 'COMPLETE';
2206   END IF;
2207 
2208   -- Changes by jaramana on 03-FEB-2011 for bug 10647408
2209   -- For Non Serialized tracked items, if an unserviceable removal was done with Create Work Order in released option
2210   -- then the disposition should be deemed complete as soon as the quantity is moved to the newly created work order.
2211   -- This is to prevent the Material returns UI from incorrectly showing this disposition quantity as available for return
2212     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2213     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to check if Disposition status can be set to Complete for non Inspection.' ||
2214       ' p_x_disposition_rec.serial_number = ' || p_x_disposition_rec.serial_number ||
2215       ', p_x_disposition_rec.instance_id = ' || p_x_disposition_rec.instance_id ||
2216       ', p_x_disposition_rec.condition_id = ' || p_x_disposition_rec.condition_id ||
2217       ', p_x_disposition_rec.status_code = ' || p_x_disposition_rec.status_code ||
2218       ', NVL(fnd_profile.value(AHL_MTL_MAT_STATUS_UNSERVICABLE), -1) = ' || NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) ||
2219       ', NVL(fnd_profile.value(AHL_MTL_MAT_STATUS_MRB), -1) = ' || NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1) ||
2220       ', p_x_disposition_rec.part_change_id = ' || p_x_disposition_rec.part_change_id ||
2221       ', l_non_routine_workorder_id = ' || l_non_routine_workorder_id ||
2222       ', l_primary_service_request_id = ' || l_primary_service_request_id);
2223   END IF;
2224   -- Changes by jaramana on 31-MAR-2011 for bug 11856373
2225   -- Do not use the part change id for determining this
2226   IF (p_x_disposition_rec.serial_number IS NULL AND p_x_disposition_rec.instance_id IS NOT NULL AND
2227       (p_x_disposition_rec.condition_id = NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) OR
2228        p_x_disposition_rec.condition_id = NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1)) AND
2229       l_non_routine_workorder_id IS NOT NULL) THEN
2230 
2231     -- Cursor to get the removal instance removed by jaramana on 31-MAR-2011 for bug 11856373
2232     -- Do not use the removed instance for this check
2233 
2234 
2235     -- Get the first released non-master workorder id for the NR summary workorder
2236     OPEN get_rel_nonmaster_wo_id_csr(p_x_disposition_rec.non_routine_workorder_id);
2237     FETCH get_rel_nonmaster_wo_id_csr INTO l_rel_nm_wo_id;
2238     IF (get_rel_nonmaster_wo_id_csr%FOUND) THEN
2239       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2240         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'l_rel_nm_wo_id = ' || l_rel_nm_wo_id);
2241       END IF;
2242 
2243       -- Check if the instance has already been moved to the new NR work order (non-master)
2244       --OPEN chk_disp_inst_job_csr (l_removed_instance_id, l_rel_nm_wo_id);
2245       -- Changed by jaramana on 31-MAR-2011 to compare using the item and quantity of the disposition
2246       -- rather than the removed instance id
2247       OPEN chk_disp_inst_job_csr (p_x_disposition_rec.disposition_id, l_rel_nm_wo_id);
2248       FETCH chk_disp_inst_job_csr INTO l_inst_in_job_flag;
2249       CLOSE chk_disp_inst_job_csr;
2250       IF (l_inst_in_job_flag = 'Y') THEN
2251         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2252           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Non Ser. trk. item unserv. removal with Create WO in rel. option. Removed instance moved to NR WO. Setting Disp. status to COMPLETE.');
2253         END IF;
2254         -- All conditions are met: Set the disposition status to COMPLETE
2255         p_x_disposition_rec.status_code := 'COMPLETE';
2256 	ELSE
2257         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2258           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Instance not in work order. l_rel_nm_wo_id = ' || l_rel_nm_wo_id);
2259         END IF;
2260       END IF;
2261     ELSE
2262       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2263         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'No Released Work Order Found');
2264       END IF;
2265     END IF;
2266     CLOSE get_rel_nonmaster_wo_id_csr;
2267   END IF;
2268   -- End changes by jaramana on 03-FEB-2011 for bug 10647408
2269 
2270   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2271       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before update_row');
2272   END IF;
2273   --dbms_output.put_line(SubStr('Update_disp:Before call Update_Row', 1, 255));
2274   AHL_PRD_DISPOSITIONS_PKG.UPDATE_ROW(
2275   		x_disposition_id       =>  p_x_disposition_rec.disposition_id,
2276   		x_object_version_number   =>  p_x_disposition_rec.object_version_number,
2277   		x_workorder_id         =>  p_x_disposition_rec.workorder_id ,
2278   		x_part_change_id       =>  p_x_disposition_rec.part_change_id,
2279   		x_path_position_id     =>  p_x_disposition_rec.path_position_id,
2280   		x_inventory_item_id    =>  p_x_disposition_rec.inventory_item_id,
2281   		x_organization_id      =>  p_x_disposition_rec.item_org_id,
2282   		x_item_group_id        =>  p_x_disposition_rec.item_group_id,
2283   		x_condition_id         =>  p_x_disposition_rec.condition_id,
2284   		x_instance_id          =>  p_x_disposition_rec.instance_id,
2285   		x_serial_number        =>  p_x_disposition_rec.serial_number,
2286   		x_lot_number           =>  p_x_disposition_rec.lot_number,
2287   		x_immediate_disposition_code  =>  p_x_disposition_rec.immediate_disposition_code ,
2288   		x_secondary_disposition_code  =>  p_x_disposition_rec.secondary_disposition_code,
2289   		x_status_code          =>  p_x_disposition_rec.status_code,
2290   		x_quantity             =>  p_x_disposition_rec.quantity,
2291   		x_uom                  =>  p_x_disposition_rec.uom,
2292   		x_collection_id        =>  p_x_disposition_rec.collection_id,
2293   		x_primary_service_request_id   =>  p_x_disposition_rec.primary_service_request_id ,
2294   		x_non_routine_workorder_id     =>  p_x_disposition_rec.non_routine_workorder_id,
2295   		x_wo_operation_id              => p_x_disposition_rec.wo_operation_id,
2296   		x_item_revision                => p_x_disposition_rec.item_revision,
2297   		x_attribute_category   =>  p_x_disposition_rec.attribute_category,
2298   		x_attribute1           =>  p_x_disposition_rec.attribute1,
2299   		x_attribute2           =>  p_x_disposition_rec.attribute2,
2300   		x_attribute3           =>  p_x_disposition_rec.attribute3,
2301   		x_attribute4           =>  p_x_disposition_rec.attribute4,
2302   		x_attribute5           =>  p_x_disposition_rec.attribute5,
2303   		x_attribute6           =>  p_x_disposition_rec.attribute6,
2304   		x_attribute7           =>  p_x_disposition_rec.attribute7,
2305   		x_attribute8           =>  p_x_disposition_rec.attribute8,
2306   		x_attribute9           =>  p_x_disposition_rec.attribute9,
2307   		x_attribute10          =>  p_x_disposition_rec.attribute10,
2308   		x_attribute11          =>  p_x_disposition_rec.attribute11,
2309   		x_attribute12          =>  p_x_disposition_rec.attribute12,
2310   		x_attribute13          =>  p_x_disposition_rec.attribute13,
2311   		x_attribute14          =>  p_x_disposition_rec.attribute14,
2312   		x_attribute15          =>  p_x_disposition_rec.attribute15,
2313   		x_comments             =>  p_x_disposition_rec.comments,
2314   		x_last_update_date     =>  p_x_disposition_rec.last_update_date,
2315   		x_last_updated_by      =>  p_x_disposition_rec.last_updated_by,
2316   		x_last_update_login    =>  p_x_disposition_rec.last_update_login
2317   );
2318 
2319   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2320     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'After update_row');
2321   END IF;
2322   --dbms_output.put_line(SubStr('Update_disp:After call Update_Row', 1, 255));
2323 --dbms_output.put_line(SubStr('Update_disp: l_disposition_rec.creation_date ' || l_disposition_rec.creation_date, 1, 255));
2324 --dbms_output.put_line(SubStr('Update_disp: l_disposition_rec.created_by ' || l_disposition_rec.created_by, 1, 255));
2325 
2326 
2327   Select AHL_PRD_DISPOSITIONS_B_H_S.NEXTVAL into l_disposition_h_id from dual;
2328     --dbms_output.put_line(SubStr('Update_disp:Before insert into history table', 1, 255));
2329 
2330   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2331       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before insert into history table');
2332   END IF;
2333   AHL_PRD_DISPOSITIONS_B_H_PKG.INSERT_ROW(
2334   		x_rowid                =>  l_dummy_char,
2335 		x_disposition_h_id     => l_disposition_h_id,
2336   		x_disposition_id       =>  p_x_disposition_rec.disposition_id,
2337   		x_object_version_number   => p_x_disposition_rec.object_version_number,
2338   		x_workorder_id         =>  p_x_disposition_rec.workorder_id ,
2339   		x_part_change_id       =>   p_x_disposition_rec.part_change_id,
2340   		x_path_position_id     =>   p_x_disposition_rec.path_position_id,
2341   		x_inventory_item_id    =>   p_x_disposition_rec.inventory_item_id,
2342   		x_organization_id      =>  p_x_disposition_rec.item_org_id,
2343   		x_item_group_id        =>   p_x_disposition_rec.item_group_id,
2344   		x_condition_id         =>   p_x_disposition_rec.condition_id,
2345   		x_instance_id          =>   p_x_disposition_rec.instance_id,
2346   		x_serial_number        =>   p_x_disposition_rec.serial_number,
2347   		x_lot_number           =>   p_x_disposition_rec.lot_number,
2348   		x_immediate_disposition_code  =>   p_x_disposition_rec.immediate_disposition_code ,
2349   		x_secondary_disposition_code  =>   p_x_disposition_rec.secondary_disposition_code,
2350   		x_status_code          =>   p_x_disposition_rec.status_code,
2351   		x_quantity             =>    p_x_disposition_rec.quantity,
2352   		x_uom                  =>    p_x_disposition_rec.uom,
2353   		x_collection_id        =>    p_x_disposition_rec.collection_id,
2354   		x_primary_service_request_id   =>    p_x_disposition_rec.primary_service_request_id ,
2355   		x_non_routine_workorder_id     =>    p_x_disposition_rec.non_routine_workorder_id,
2356   		x_wo_operation_id              =>   p_x_disposition_rec.wo_operation_id,
2357   		x_item_revision                =>   p_x_disposition_rec.item_revision,
2358   		x_attribute_category   =>    p_x_disposition_rec.attribute_category,
2359   		x_attribute1           =>   p_x_disposition_rec.attribute1,
2360   		x_attribute2           =>   p_x_disposition_rec.attribute2,
2361   		x_attribute3           =>   p_x_disposition_rec.attribute3,
2362   		x_attribute4           =>   p_x_disposition_rec.attribute4,
2363   		x_attribute5           =>   p_x_disposition_rec.attribute5,
2364   		x_attribute6           =>   p_x_disposition_rec.attribute6,
2365   		x_attribute7           =>   p_x_disposition_rec.attribute7,
2366   		x_attribute8           =>   p_x_disposition_rec.attribute8,
2367   		x_attribute9           =>   p_x_disposition_rec.attribute9,
2368   		x_attribute10          =>   p_x_disposition_rec.attribute10,
2369   		x_attribute11          =>   p_x_disposition_rec.attribute11,
2370   		x_attribute12          =>   p_x_disposition_rec.attribute12,
2371   		x_attribute13          =>   p_x_disposition_rec.attribute13,
2372   		x_attribute14          =>   p_x_disposition_rec.attribute14,
2373   		x_attribute15          =>   p_x_disposition_rec.attribute15,
2374   		x_comments             =>   p_x_disposition_rec.comments,
2375   		x_creation_date        =>   l_disposition_rec.creation_date ,
2376   		x_created_by           =>   l_disposition_rec.created_by,
2377   		x_last_update_date     =>  p_x_disposition_rec.last_update_date,
2378   		x_last_updated_by      =>  p_x_disposition_rec.last_updated_by,
2379   		x_last_update_login    =>  p_x_disposition_rec.last_update_login
2380   );
2381 
2382   -- Added by jaramana on October 8, 2007 for ER 5903256
2383   -- If the instance was just removed and a NR WO was already created
2384   -- Change the location of the instance to the NR WO.
2385   l_exist := NULL;
2386   OPEN check_nr_wo_status_csr(p_x_disposition_rec.non_routine_workorder_id);
2387   FETCH check_nr_wo_status_csr INTO l_exist;
2388   CLOSE check_nr_wo_status_csr;
2389   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2390       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to check if instance location needs to be changed. ' ||
2391           ' p_x_disposition_rec.non_routine_workorder_id = ' || p_x_disposition_rec.non_routine_workorder_id ||
2392           ', l_disposition_rec.part_change_id = ' || l_disposition_rec.part_change_id ||
2393           ', p_x_disposition_rec.part_change_id = ' || p_x_disposition_rec.part_change_id ||
2394           ', NR UE with null status exists: ' || NVL(l_exist, 'N'));
2395   END IF;
2396 
2397 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
2398 -- The API update_item_location and its use has been commented out. Its functionality will
2399 -- now be handled in the API AHL_PRD_NONROUTINE_PVT.process_nonroutine_job.
2400 /*
2401   IF (NVL(x_return_status, FND_API.G_RET_STS_SUCCESS) = FND_API.G_RET_STS_SUCCESS AND
2402       p_x_disposition_rec.non_routine_workorder_id IS NOT NULL AND
2403       l_disposition_rec.part_change_id IS NULL AND
2404       p_x_disposition_rec.part_change_id IS NOT NULL AND
2405       l_exist IS NOT NULL) THEN
2406     update_item_location(p_workorder_id  => p_x_disposition_rec.non_routine_workorder_id,
2407                          p_instance_id   => p_x_disposition_rec.instance_id,
2408                          x_return_status => x_return_status);
2409   END IF;
2410   -- End addition by jaramana on February 21, 2007 for ER 5854667
2411 */
2412 
2413   -- SATHAPLI::Bug 7111116, 21-May-2008, fix start
2414   -- If the following two conditions are met, i.e.:
2415   -- 1) unserviceable removal has happened
2416   -- 2) there exists a primary NR with released workorder for this disposition
2417   -- then the removed part should be assigned to the released NR workorder.
2418   -- This should be done only if the primary SR was not created along with removal in this cycle itself.
2419   IF (l_disposition_rec.part_change_id IS NULL AND p_x_disposition_rec.part_change_id IS NOT NULL
2420       AND
2421       (p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE')
2422        OR
2423        p_x_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')
2424       )
2425       AND
2426       p_x_disposition_rec.non_routine_workorder_id IS NOT NULL
2427       AND
2428       NOT l_primary_sr_created)
2429   THEN
2430       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2431           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_debug_key,
2432                          'About to check if the removed instance location needs to be changed.');
2433       END IF;
2434 
2435       -- get the first released non-master workorder id for the NR summary workorder
2436       OPEN get_rel_nonmaster_wo_id_csr(p_x_disposition_rec.non_routine_workorder_id);
2437       FETCH get_rel_nonmaster_wo_id_csr INTO l_rel_nm_wo_id;
2438       IF (get_rel_nonmaster_wo_id_csr%FOUND) THEN
2439           IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2440               FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_debug_key,
2441               'First released non-master workorder id => '||l_rel_nm_wo_id);
2442           END IF;
2443 
2444           -- get the removed instance id, which can be different from the disposition instance id for non-serialized items
2445           OPEN get_rem_inst_id_csr(p_x_disposition_rec.part_change_id);
2446           FETCH get_rem_inst_id_csr INTO l_removed_instance_id;
2447           IF (get_rem_inst_id_csr%FOUND) THEN
2448               -- move the removed part to the released NR workorder
2449               l_move_item_ins_tbl(1).instance_id       := l_removed_instance_id;
2450               l_move_item_ins_tbl(1).quantity          := p_x_disposition_rec.quantity;
2451               l_move_item_ins_tbl(1).from_workorder_id := p_x_disposition_rec.workorder_id;
2452               l_move_item_ins_tbl(1).to_workorder_id   := l_rel_nm_wo_id;
2453 
2454               IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2455                   FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_debug_key,
2456                   'About to call the API AHL_PRD_PARTS_CHANGE_PVT.move_instance_location with the parameters:'||
2457                   ' instance_id => '||l_removed_instance_id||
2458                   ' ,quantity => '||p_x_disposition_rec.quantity||
2459                   ' ,to_workorder_id => '||l_rel_nm_wo_id);
2460               END IF;
2461 
2462               -- call the required API
2463               AHL_PRD_PARTS_CHANGE_PVT.move_instance_location(
2464                   p_api_version            => 1.0,
2465                   p_init_msg_list          => FND_API.G_FALSE,
2466                   p_commit                 => FND_API.G_FALSE,
2467                   p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
2468                   p_module_type            => NULL,
2469                   p_default                => FND_API.G_TRUE,
2470                   p_move_item_instance_tbl => l_move_item_ins_tbl,
2471                   x_return_status          => x_return_status,
2472                   x_msg_count              => x_msg_count,
2473                   x_msg_data               => x_msg_data
2474               );
2475 
2476               IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2477                   FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_debug_key,
2478                   'Call to the API AHL_PRD_PARTS_CHANGE_PVT.move_instance_location returned with status => '||x_return_status);
2479               END IF;
2480 
2481               -- check the API call return status
2482               IF (x_return_status = FND_API.G_RET_STS_ERROR) THEN
2483                   CLOSE get_rem_inst_id_csr;
2484                   CLOSE get_rel_nonmaster_wo_id_csr;
2485                   RAISE FND_API.G_EXC_ERROR;
2486               ELSIF (x_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2487                   CLOSE get_rem_inst_id_csr;
2488                   CLOSE get_rel_nonmaster_wo_id_csr;
2489                   RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2490               END IF;
2491 
2492 	      -- Changes by jaramana on 03-FEB-2011 for bug 10647408
2493               -- For Non Serialized tracked items, if an unserviceable removal was done with Create Work Order in released option
2494               -- then the disposition should be deemed complete as soon as the quantity is moved to the newly created work order.
2495               -- This is to prevent the Material returns UI from incorrectly showing this disposition quantity as available for return
2496               IF (p_x_disposition_rec.serial_number IS NULL) THEN
2497                 UPDATE AHL_PRD_DISPOSITIONS_B
2498                    SET status_code = 'COMPLETE'
2499                  WHERE disposition_id = p_x_disposition_rec.disposition_id;
2500               END IF;
2501               -- End changes by jaramana on 03-FEB-2011 for bug 10647408
2502 
2503           END IF;
2504           CLOSE get_rem_inst_id_csr;
2505       END IF;
2506       CLOSE get_rel_nonmaster_wo_id_csr;
2507   END IF;
2508   -- SATHAPLI::Bug 7111116, 21-May-2008, fix end
2509 
2510   -- SATHAPLI::FP OGMA Issue# 86 - Automatic Material Return, 27-Dec-2007
2511   -- If the instance was just removed in Serviceable condition return the part to the Visit Locator.
2512   -- Note that the ReturnTo_Workorder_Locator will return only if the locator is set at the Visit level.
2513   -- For FP OGMA Issue# 105 - Non-Serialized Item Maintenance, if the instance was removed in 'Inspection'
2514   -- condition, then it should not be returned to the locator.
2515   IF (NVL(x_return_status, FND_API.G_RET_STS_SUCCESS) = FND_API.G_RET_STS_SUCCESS AND
2516       l_disposition_rec.part_change_id IS NULL AND
2517       p_x_disposition_rec.part_change_id IS NOT NULL AND
2518       p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) AND
2519       p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1) AND
2520       p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_INSPECTION'), -1)) THEN
2521     OPEN part_change_dtls_csr(p_x_disposition_rec.part_change_id);
2522     FETCH part_change_dtls_csr INTO l_removed_instance_id, l_part_change_type;
2523     CLOSE part_change_dtls_csr;
2524 -- Changed by jaramana on 17-FEB-2011 for bug 11676572 ;sorao for backporting project
2525     --IF (l_removed_instance_id = p_x_disposition_rec.instance_id AND  -- Removed instance is the Disposition instance
2526     IF (((l_removed_instance_id = p_x_disposition_rec.instance_id) OR (p_x_disposition_rec.serial_number IS NULL)) AND  -- Removed instance is the Disposition instance or Non Serialized
2527         NVL(l_part_change_type, 'X') IN ('R', 'S')) THEN  -- Removal or Swap
2528 
2529       -- Change by jaramana on 06-DEC-2011 to capture instance condition in IB
2530       -- Functionality required as part of Various Execution Enhancements (VEE)
2531       -- Part Removal has happened: Update Instance condition
2532       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2533         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to call AHL_PRD_PARTS_CHANGE_PVT.Update_Part_Condition with ' ||
2534                        ' p_instance_id = ' || l_removed_instance_id ||
2535                        ', and p_instance_condition_id = ' || p_x_disposition_rec.condition_id);
2536       END IF;
2537       AHL_PRD_PARTS_CHANGE_PVT.Update_Part_Condition(p_init_msg_list         => FND_API.G_FALSE,
2538                                                      p_commit                => FND_API.G_FALSE,
2539                                                      p_validation_level      => FND_API.G_VALID_LEVEL_FULL,
2540                                                      p_instance_id           => l_removed_instance_id,
2541                                                      p_instance_condition_id => p_x_disposition_rec.condition_id,
2542                                                      x_return_status         => x_return_status,
2543                                                      x_msg_data              => x_msg_data,
2544                                                      x_msg_count             => x_msg_count);
2545       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2546         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Returned from AHL_PRD_PARTS_CHANGE_PVT.Update_Part_Condition: ' ||
2547                        ' x_return_status = ' || x_return_status);
2548       END IF;
2549       IF x_return_status = FND_API.G_RET_STS_ERROR THEN
2550         RAISE FND_API.G_EXC_ERROR;
2551       ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
2552         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2553       END IF;
2554 
2555       IF (p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE'), -1) AND
2556           p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'), -1) AND
2557           p_x_disposition_rec.condition_id <> NVL(fnd_profile.value('AHL_MTL_MAT_STATUS_INSPECTION'), -1)) THEN
2558         -- Serviceable Removal: Move part to WO locator
2559         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2560           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to call AHL_PRD_PARTS_CHANGE_PVT.ReturnTo_Workorder_Locator with ' ||
2561                          ' part change id = ' || p_x_disposition_rec.part_change_id ||
2562                          ' and disposition_id = ' || p_x_disposition_rec.disposition_id);
2563         END IF;
2564         AHL_PRD_PARTS_CHANGE_PVT.ReturnTo_Workorder_Locator(p_part_change_id => p_x_disposition_rec.part_change_id,
2565                                                             p_disposition_id => p_x_disposition_rec.disposition_id,
2566                                                             x_return_status  => x_return_status,
2567                                                             x_msg_data       => x_msg_data,
2568                                                             x_msg_count      => x_msg_count,
2569                                                             x_ahl_mtltxn_rec => l_ahl_mtltxn_rec);
2570         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2571           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Returned from AHL_PRD_PARTS_CHANGE_PVT.ReturnTo_Workorder_Locator: ' ||
2572                          ' x_return_status = ' || x_return_status);
2573         END IF;
2574         IF x_return_status = FND_API.G_RET_STS_ERROR THEN
2575           RAISE FND_API.G_EXC_ERROR;
2576         ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
2577           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2578         END IF;
2579       END IF;  -- If Serviceable Removal
2580     END IF;  -- If Part Removal has happened
2581   END IF;  -- x_return_status is Success and Part Change has just happened
2582 
2583  --dbms_output.put_line(SubStr('Update_disp:After insert history', 1, 255));
2584    IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2585      FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'End Procedure');
2586    END IF;
2587 
2588 END UPDATE_DISPOSITION;
2589 
2590 ------------------------------------------------------------------
2591 
2592 PROCEDURE CREATE_SR(
2593           p_init_msg_list               IN          VARCHAR2 := FND_API.G_TRUE,
2594           p_disposition_rec	        IN          AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
2595           -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
2596           p_mr_asso_tbl                 IN          AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type,
2597           x_primary_sr_id               OUT NOCOPY  NUMBER,
2598           x_non_routine_workorder_id    OUT NOCOPY  NUMBER,
2599           x_return_status               OUT NOCOPY  VARCHAR2,
2600           x_msg_count                   OUT NOCOPY  NUMBER,
2601           x_msg_data                    OUT NOCOPY  VARCHAR2
2602           ) IS
2603 
2604  -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
2605  CURSOR get_rem_inst_id_csr (p_part_change_id NUMBER) IS
2606      SELECT removed_instance_id
2607      FROM   ahl_part_changes
2608      WHERE  part_change_id = p_part_change_id;
2609 
2610  -- Cursor to check whether removed instance is in job or not.
2611  CURSOR chk_disp_inst_job_csr (p_instance_id NUMBER, p_workorder_id NUMBER) IS
2612      SELECT 'Y'
2613      FROM   ahl_workorders awo, csi_item_instances csi
2614      WHERE  awo.wip_entity_id = csi.wip_job_id
2615      AND    awo.workorder_id  = p_workorder_id
2616      AND    csi.instance_id   = p_instance_id;
2617 
2618 -- Added by changes by by jaramana on 25-APR-2011 for bug 11870333
2619 CURSOR get_rel_nonmaster_wo_id_csr(c_nr_wo_id NUMBER) IS
2620     SELECT workorder_id
2621     FROM   ahl_workorders
2622     WHERE  master_workorder_flag = 'N'
2623     AND    wip_entity_id IN
2624            (SELECT child_object_id
2625             FROM   wip_sched_relationships
2626             START WITH parent_object_id      = (SELECT wip_entity_id FROM ahl_workorders WHERE workorder_id = c_nr_wo_id)
2627             CONNECT BY parent_object_id      = PRIOR child_object_id
2628             AND        parent_object_type_id = PRIOR child_object_type_id
2629             AND        relationship_type     = 1
2630            )
2631     AND    status_code           = G_WO_RELEASED_STATUS
2632     ORDER BY workorder_id;
2633 
2634 --sareepar Added for Bug #13372980 on 25/04/2012
2635 -- Cursor to get originating workorder details
2636 CURSOR get_orig_workorder_det_csr(p_workorder_id NUMBER) IS
2637     SELECT scheduled_start_date
2638     FROM ahl_workorders_v
2639     WHERE workorder_id = p_workorder_id;
2640 
2641 
2642  l_rel_nm_wo_id        NUMBER;
2643  l_move_item_ins_tbl   AHL_PRD_PARTS_CHANGE_PVT.move_item_instance_tbl_type;
2644 
2645  l_sr_task_tbl    AHL_PRD_NONROUTINE_PVT.sr_task_tbl_type;
2646  l_visit_id    NUMBER;
2647 
2648 
2649  -- Variable added by jaramana on Oct 9, 2007 for ER 5883257
2650  l_mr_asso_tbl AHL_PRD_NONROUTINE_PVT.MR_Association_tbl_type := p_mr_asso_tbl;
2651 
2652 
2653  L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'Create_SR';
2654  l_msg_index_out NUMBER;
2655 
2656  l_inst_in_job_flag    VARCHAR2(1) := 'N';
2657  l_removed_instance_id NUMBER;
2658 
2659  --sareepar Added for Bug #13372980 on 25/04/2012
2660  l_workorder_start_date DATE;
2661 
2662 BEGIN
2663 
2664   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2665     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
2666   END IF;
2667 
2668   -- Initialize message list if p_init_msg_list is set to TRUE
2669   IF FND_API.To_Boolean( p_init_msg_list)
2670   THEN
2671     FND_MSG_PUB.Initialize;
2672   END IF;
2673      --dbms_output.put_line('Begin Create SR -----------------------------');
2674        --dbms_output.put_line('Begin Create SR ');
2675       -- Populate sr_task_tbl
2676             l_sr_task_tbl(0).Request_date:= sysdate;
2677             l_sr_task_tbl(0).Summary := p_disposition_rec.summary;
2678 
2679             -- SURRKUMA :: ER 9213556 Ceate NR for next higher position flag
2680             -- Set the instance id of the parent position if create NR for next higher position flag is checked
2681             -- NOTE: the parent instance id will be set only when the checkbox is checked, so we can use it to
2682             --       check for checkbox.
2683             IF (p_disposition_rec.parent_instance_id IS NOT NULL) THEN
2684               l_sr_task_tbl(0).Instance_id := p_disposition_rec.parent_instance_id;
2685             -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
2686             -- NR record instance id should be set conditionally, as given below: -
2687             -- i.e. if part change occurred, then set it with the removed instance as it can be different for non-serialized items
2688             --      else, set it with disposition instance
2689             ELSIF (p_disposition_rec.part_change_id IS NOT NULL) THEN
2690               OPEN get_rem_inst_id_csr(p_disposition_rec.part_change_id);
2691               FETCH get_rem_inst_id_csr INTO l_removed_instance_id;
2692               CLOSE get_rem_inst_id_csr;
2693               l_sr_task_tbl(0).Instance_id := l_removed_instance_id;
2694             ELSE
2695               l_sr_task_tbl(0).Instance_id := p_disposition_rec.instance_id;
2696             END IF;
2697 
2698             l_sr_task_tbl(0).Problem_code := p_disposition_rec.problem_code;
2699             l_sr_task_tbl(0).duration := p_disposition_rec.duration;
2700 	-- AVIKUKUM::PIE::FP::19-OCT-2010
2701 		    l_sr_task_tbl(0).service_type_code := p_disposition_rec.service_type_code;
2702 		    l_sr_task_tbl(0).service_type := p_disposition_rec.service_type;
2703 
2704             SELECT visit_id INTO l_visit_id FROM AHL_WORKORDERS WHERE workorder_id = p_disposition_rec.workorder_id;
2705 
2706             l_sr_task_tbl(0).Visit_id:=	 l_visit_id;
2707             l_sr_task_tbl(0).Originating_wo_id:= p_disposition_rec.workorder_id;
2708             l_sr_task_tbl(0).Operation_type	:= 'CREATE' ;
2709             l_sr_task_tbl(0).Severity_id :=  p_disposition_rec.severity_id;
2710             l_sr_task_tbl(0).source_program_code := 'AHL_NONROUTINE';
2711 
2712             --data provided for service request to add record to the cs_incident_links table
2713             l_sr_task_tbl(0).object_id := p_disposition_rec.disposition_id;
2714             l_sr_task_tbl(0).Object_type := 'AHL_PRD_DISP';
2715             l_sr_task_tbl(0).link_id  := 6;
2716 
2717             --sareepar Added for Bug #13372980 on 25/04/2012
2718             OPEN get_orig_workorder_det_csr(p_disposition_rec.workorder_id);
2719             FETCH get_orig_workorder_det_csr into l_workorder_start_date;
2720             CLOSE get_orig_workorder_det_csr;
2721             l_sr_task_tbl(0).workorder_start_time := l_workorder_start_date;
2722 
2723 
2724             --dbms_output.put_line('l_sr_task_tbl(0).Request_date: '|| l_sr_task_tbl(0).Request_date);
2725             --dbms_output.put_line('l_sr_task_tbl(0).Summary: '|| l_sr_task_tbl(0).Summary);
2726             --dbms_output.put_line('l_sr_task_tbl(0).Instance_id: '|| l_sr_task_tbl(0).Instance_id);
2727             --dbms_output.put_line('l_sr_task_tbl(0).Problem_code: '|| l_sr_task_tbl(0).Problem_code);
2728             --dbms_output.put_line('l_sr_task_tbl(0).Visit_id: '|| l_sr_task_tbl(0).Visit_id);
2729             --dbms_output.put_line('l_sr_task_tbl(0).Originating_wo_id: '|| l_sr_task_tbl(0).Originating_wo_id);
2730             --dbms_output.put_line('l_sr_task_tbl(0).Operation_type: '|| l_sr_task_tbl(0).Operation_type);
2731             --dbms_output.put_line('l_sr_task_tbl(0).Severity_id: '|| l_sr_task_tbl(0).Severity_id);
2732            --dbms_output.put_line('l_sr_task_tbl(0).source_program_code: '|| l_sr_task_tbl(0).source_program_code);
2733 
2734 		  IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2735              FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2736 		              '--Request_date: '|| l_sr_task_tbl(0).Request_date
2737                      || '--Summary: '|| l_sr_task_tbl(0).Summary
2738                      || '--Instance_id: '|| l_sr_task_tbl(0).Instance_id
2739                      || '--Problem_code: '|| l_sr_task_tbl(0).Problem_code
2740                      || '--Visit_id: '|| l_sr_task_tbl(0).Visit_id
2741                      || '--Originating_wo_id: '|| l_sr_task_tbl(0).Originating_wo_id
2742                      || '--Operation_type: '|| l_sr_task_tbl(0).Operation_type
2743                      || '--Severity_id: '|| l_sr_task_tbl(0).Severity_id
2744                      || '--source_program_code: '|| l_sr_task_tbl(0).source_program_code
2745                      || '--workorder start date: '|| l_sr_task_tbl(0).workorder_start_time
2746                      );
2747 
2748 		  END IF;
2749          --  dbms_output.put_line('l_sr_task_tbl(0).type_id: '|| l_sr_task_tbl(0).type_id);
2750          --  dbms_output.put_line('l_sr_task_tbl(0).type_name: '|| l_sr_task_tbl(0).type_name);
2751            --dbms_output.put_line('Before Call process_nonroutine_job --return_status'  || x_return_status);
2752 
2753       -- Added by jaramana on October 9, 2007 for ER 5903318
2754       IF (p_disposition_rec.CREATE_WORK_ORDER_OPTION = 'CREATE_RELEASE_WO') THEN
2755          l_sr_task_tbl(0).wo_create_flag := 'Y';
2756          l_sr_task_tbl(0).wo_release_flag := 'Y';
2757       ELSIF (p_disposition_rec.CREATE_WORK_ORDER_OPTION = 'CREATE_WO') THEN
2758          l_sr_task_tbl(0).wo_create_flag := 'Y';
2759          l_sr_task_tbl(0).wo_release_flag := 'N';
2760       ELSIF (p_disposition_rec.CREATE_WORK_ORDER_OPTION = 'CREATE_WO_NO') THEN
2761          l_sr_task_tbl(0).wo_create_flag := 'N';
2762          l_sr_task_tbl(0).wo_release_flag := 'N';
2763       END IF;
2764 
2765       -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
2766       -- Check whether the disposition instance/removed instance is issued to the job or not.
2767       -- NOTE: the l_sr_task_tbl(0).Instance_id set above can be used here as it is set with all the required checks
2768       OPEN chk_disp_inst_job_csr (l_sr_task_tbl(0).Instance_id, p_disposition_rec.workorder_id);
2769       FETCH chk_disp_inst_job_csr INTO l_inst_in_job_flag;
2770       CLOSE chk_disp_inst_job_csr;
2771 
2772       -- Set the move_qty_to_nr_workorder flag to 'Y' conditionally.
2773       IF(p_disposition_rec.CREATE_WORK_ORDER_OPTION = 'CREATE_RELEASE_WO' AND l_inst_in_job_flag = 'Y') THEN
2774         l_sr_task_tbl(0).move_qty_to_nr_workorder := 'Y';
2775       ELSE
2776         l_sr_task_tbl(0).move_qty_to_nr_workorder := 'N';
2777       END IF;
2778 
2779       -- SURRKUMA :: ER 9213556 Ceate NR for next higher position
2780       -- Set the instance quantity to 1 when the SR is going to be created for the parent position
2781       IF (p_disposition_rec.parent_instance_id IS NOT NULL) THEN
2782         l_sr_task_tbl(0).instance_quantity := 1;
2783       -- set the NR instance quantity
2784       ELSE
2785         l_sr_task_tbl(0).instance_quantity := p_disposition_rec.quantity;
2786       END IF;
2787 
2788       -- Following two attributes added by jaramana on 18-NOV-2008 for bug 7566597
2789       l_sr_task_tbl(0).resolution_code    := p_disposition_rec.resolution_code;
2790       l_sr_task_tbl(0).resolution_meaning := p_disposition_rec.resolution_meaning;
2791 
2792       --Calling Service Request API--
2793       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2794         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before process_nonroutine_job');
2795       END IF;
2796       AHL_PRD_NONROUTINE_PVT.process_nonroutine_job (
2797                                                p_api_version => 1.0,
2798                                                p_commit =>  Fnd_Api.g_false,
2799                                                p_module_type => NULL,
2800                                                x_return_status => x_return_status,
2801                                                x_msg_count => x_msg_count,
2802                                                x_msg_data => x_msg_data,
2803                                                p_x_sr_task_tbl => l_sr_task_tbl,
2804                                   -- Parameter added by jaramana on Oct 9, 2007 for ER 5883257
2805                                                p_x_mr_asso_tbl => l_mr_asso_tbl
2806                                                );
2807 
2808     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2809       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'After process non_nonroutine_job'
2810                      || '-- x_return_status = '||x_return_status || '| x_msg_count = '||TO_CHAR(x_msg_count));
2811     END IF;
2812 
2813 
2814     --debuging codes
2815     --dbms_output.put_line('After Call process_nonroutine_job');
2816     --dbms_output.put_line(SubStr('x_return_status = '||x_return_status,1,255));
2817     --dbms_output.put_line(SubStr('x_msg_count = '||TO_CHAR(x_msg_count), 1, 255));
2818 --dbms_output.put_line(SubStr('x_msg_data = '||x_msg_data,1,255));
2819 
2820    FOR i IN 1..x_msg_count LOOP
2821      FND_MSG_PUB.get (
2822       p_msg_index      => i,
2823       p_encoded        => FND_API.G_FALSE,
2824       p_data           => x_msg_data,
2825       p_msg_index_out  => l_msg_index_out );
2826      --dbms_output.put_line(SubStr('x_msg_data = '||x_msg_data,1,255));
2827     END LOOP;
2828 
2829     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2830       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Incident id: ' ||l_sr_task_tbl(0).incident_id);
2831       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Nonroutine_wo_id: ' ||l_sr_task_tbl(0).Nonroutine_wo_id);
2832     END IF;
2833 	--dbms_output.put_line('Incident_id: ' || l_sr_task_tbl(0).incident_id);
2834     --dbms_output.put_line('Nonroutine_wo_id: ' || l_sr_task_tbl(0).Nonroutine_wo_id);
2835 
2836 
2837     -- Check return status.
2838     IF x_return_status = FND_API.G_RET_STS_ERROR THEN
2839        RAISE FND_API.G_EXC_ERROR;
2840     ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
2841        RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2842     END IF;
2843 
2844 
2845    x_primary_sr_id := l_sr_task_tbl(0).incident_id;
2846    x_non_routine_workorder_id := l_sr_task_tbl(0).Nonroutine_wo_id;
2847 
2848 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
2849 -- The API update_item_location and its use has been commented out. Its functionality will
2850 -- now be handled in the API AHL_PRD_NONROUTINE_PVT.process_nonroutine_job.
2851 
2852 -- SURRKUMA :: ER 9213556 Ceate NR for next higher position flag
2853 -- The API update_item_location is needed now to move the non-serialized items to SR work order
2854 -- created for the parent position when the create NR for next higher position flag is checked.
2855 -- NOTE: the parent instance id will be set only when the checkbox is checked, so we can use it to
2856 --       check for checkbox.
2857   IF (p_disposition_rec.parent_instance_id IS NOT NULL) THEN
2858       -- Added by jaramana on October 8, 2007 for ER 5903256
2859       -- Automatically change the location of the removed unserviceable instance to the Non Routine Work Order
2860       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2861         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'l_sr_task_tbl(0).Nonroutine_wo_id: ' || l_sr_task_tbl(0).Nonroutine_wo_id);
2862         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'p_disposition_rec.part_change_id: ' || p_disposition_rec.part_change_id);
2863       END IF;
2864       IF (l_sr_task_tbl(0).Nonroutine_wo_id IS NOT NULL AND
2865           p_disposition_rec.part_change_id IS NOT NULL) THEN
2866         -- Begin changes by by jaramana on 25-APR-2011 for bug 11870333
2867         -- Since the instance quantity can be more than the Disposition quantity, call the Part Change method to move
2868 /***
2869         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2870           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'About to call update_item_location.');
2871         END IF;
2872 
2873         update_item_location(p_workorder_id  => l_sr_task_tbl(0).Nonroutine_wo_id,
2874                              p_instance_id   => p_disposition_rec.instance_id,
2875                              x_return_status => x_return_status);
2876 ***/
2877         -- get the first released non-master workorder id for the NR summary workorder
2878         OPEN get_rel_nonmaster_wo_id_csr(l_sr_task_tbl(0).Nonroutine_wo_id);
2879         FETCH get_rel_nonmaster_wo_id_csr INTO l_rel_nm_wo_id;
2880         IF (get_rel_nonmaster_wo_id_csr%FOUND) THEN
2881           IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2882               FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_debug_key,
2883               'First released non-master workorder id => '|| l_rel_nm_wo_id);
2884           END IF;
2885 
2886           -- get the removed instance id, which can be different from the disposition instance id for non-serialized items
2887           OPEN get_rem_inst_id_csr(p_disposition_rec.part_change_id);
2888           FETCH get_rem_inst_id_csr INTO l_removed_instance_id;
2889           IF (get_rem_inst_id_csr%FOUND) THEN
2890             -- move the removed part to the released NR workorder
2891             l_move_item_ins_tbl(1).instance_id       := l_removed_instance_id;
2892             l_move_item_ins_tbl(1).quantity          := p_disposition_rec.quantity;
2893             l_move_item_ins_tbl(1).from_workorder_id := p_disposition_rec.workorder_id;
2894             l_move_item_ins_tbl(1).to_workorder_id   := l_rel_nm_wo_id;
2895 
2896             IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2897                 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_debug_key,
2898                 'About to call the API AHL_PRD_PARTS_CHANGE_PVT.move_instance_location with the parameters:'||
2899                 ' instance_id => ' || l_removed_instance_id ||
2900                 ', quantity => ' || p_disposition_rec.quantity ||
2901                 ', from Work order id: ' || p_disposition_rec.workorder_id ||
2902                 ', to_workorder_id => '||l_rel_nm_wo_id);
2903             END IF;
2904 
2905               -- call the required API
2906             AHL_PRD_PARTS_CHANGE_PVT.move_instance_location(
2907                 p_api_version            => 1.0,
2908                 p_init_msg_list          => FND_API.G_FALSE,
2909                 p_commit                 => FND_API.G_FALSE,
2910                 p_validation_level       => FND_API.G_VALID_LEVEL_FULL,
2911                 p_module_type            => NULL,
2912                 p_default                => FND_API.G_TRUE,
2913                 p_move_item_instance_tbl => l_move_item_ins_tbl,
2914                 x_return_status          => x_return_status,
2915                 x_msg_count              => x_msg_count,
2916                 x_msg_data               => x_msg_data
2917             );
2918 
2919             IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2920                 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_debug_key,
2921                 'Call to the API AHL_PRD_PARTS_CHANGE_PVT.move_instance_location returned with status => '||x_return_status);
2922             END IF;
2923 
2924             -- check the API call return status
2925             IF (x_return_status = FND_API.G_RET_STS_ERROR) THEN
2926                 CLOSE get_rem_inst_id_csr;
2927                 CLOSE get_rel_nonmaster_wo_id_csr;
2928                 RAISE FND_API.G_EXC_ERROR;
2929             ELSIF (x_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2930                 CLOSE get_rem_inst_id_csr;
2931                 CLOSE get_rel_nonmaster_wo_id_csr;
2932                 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2933             END IF;  -- x_return_status check
2934           END IF;  -- get_rem_inst_id_csr%FOUND
2935           CLOSE get_rem_inst_id_csr;
2936         END IF;  -- get_rel_nonmaster_wo_id_csr%FOUND
2937         CLOSE get_rel_nonmaster_wo_id_csr;
2938         -- End changes by by jaramana on 25-APR-2011 for bug 11870333
2939       END IF;  -- NRWO and PC exist
2940   END IF;  -- Parent Instance is not null (NHP check box checked)
2941   -- End changes for ER 5903256
2942   --End chnages for ER 9213556
2943 
2944   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2945      FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure');
2946    END IF;
2947 	--dbms_output.put_line('End Create SR -----------------------------');
2948 END Create_SR;
2949 
2950 
2951 --------------DERIVE_COLUMNS---------------------------------------------------
2952 PROCEDURE derive_columns(p_x_disposition_rec IN OUT NOCOPY  AHL_PRD_DISPOSITION_PVT.disposition_rec_type)
2953 IS
2954 
2955 CURSOR get_organization_csr(p_workorder_id IN NUMBER) IS
2956       SELECT vi.organization_id from  ahl_workorders wo, ahl_visits_b vi
2957        WHERE wo.workorder_id = p_workorder_id
2958        AND wo.visit_id = vi.visit_id;
2959 
2960 CURSOR get_instance_from_serial(p_item_id IN NUMBER, p_serial_num IN  VARCHAR2) IS
2961          SELECT instance_id FROM CSI_ITEM_INSTANCES
2962          WHERE inventory_item_id = p_item_id AND serial_number = p_serial_num;
2963 
2964 CURSOR get_instance_from_lot(p_item_id IN NUMBER, p_lot_num IN  VARCHAR2) IS
2965          SELECT instance_id FROM CSI_ITEM_INSTANCES
2966          WHERE inventory_item_id = p_item_id AND lot_number = p_lot_num;
2967 
2968 CURSOR instance_csr(p_instance_id IN NUMBER) IS
2969          SELECT inventory_item_id,
2970                 quantity,
2971                 unit_of_measure,
2972                 last_vld_organization_id,
2973                 inv_master_organization_id,
2974                 serial_number,
2975                 lot_number,
2976                 inventory_revision
2977           from csi_item_instances
2978          WHERE instance_id = p_instance_id;
2979 
2980 
2981 instance_rec instance_csr%ROWTYPE;
2982 
2983 l_unit_instance_id NUMBER;    --instance id of the Unit
2984 l_count NUMBER;
2985 
2986 l_position_instance_id NUMBER;
2987 l_derived_path_pos_id NUMBER;
2988 l_derived_org_id NUMBER;
2989 l_dummy_lowest_uc_id NUMBER;
2990 l_dummy_status  VARCHAR(30);
2991 
2992 x_return_status VARCHAR2(30);
2993 x_msg_count VARCHAR2(30);
2994 x_msg_data VARCHAR(2000);
2995 
2996 
2997 L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'derive_columns';
2998 
2999 BEGIN
3000 
3001   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3002     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
3003   END IF;
3004   --dbms_output.put_line(SubStr('Begin Derive Column', 1, 255));
3005 
3006 
3007   /* JR: 25-SEP-2004
3008      When creating a disposition from the Part Change UI,
3009      for a unit, path_position_id will not be null and
3010      p_disposition_rec.instance_id will contain the following values:
3011      Removal: The removed instance id
3012      Swap:    The swapped out (removed) instance id
3013      Install: Null
3014      and for an IB Tree, path_position_id will be null and
3015      p_disposition_rec.instance_id will contain the following values:
3016      Removal: The removed instance id
3017      Swap:    The swapped out (removed) instance id
3018      Install: The installed instance id
3019   */
3020   IF (p_x_disposition_rec.path_position_id IS NOT NULL) THEN
3021     -- derive instance from path position.
3022     -- Get the instance in the position only if instance has not been
3023     -- passed and if this API has NOT been called from Part Change
3024     IF (p_x_disposition_rec.instance_id IS NULL AND p_x_disposition_rec.part_change_id IS NULL) THEN
3025       l_unit_instance_id := get_unit_instance_id(p_x_disposition_rec.workorder_id);
3026       IF l_unit_instance_id IS NOT NULL THEN
3027         AHL_MC_PATH_POSITION_PVT.Get_Pos_Instance (
3028             p_api_version            => 1.0,
3029             x_return_status          => x_return_status,
3030             x_msg_count              => x_msg_count,
3031             x_msg_data               => x_msg_data,
3032             p_position_id            => p_x_disposition_rec.path_position_id,
3033             p_csi_item_instance_id   => l_unit_instance_id,
3034             x_item_instance_id       => l_position_instance_id,
3035             x_lowest_uc_csi_id       => l_dummy_lowest_uc_id,
3036             x_mapping_status         => l_dummy_status
3037         );
3038         p_x_disposition_rec.instance_id := l_position_instance_id;
3039         -- Check return status.
3040         IF x_return_status = FND_API.G_RET_STS_ERROR THEN
3041           RAISE FND_API.G_EXC_ERROR;
3042         ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
3043           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3044         END IF;
3045 
3046         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3047           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,'derived Position Instance_id: ' || p_x_disposition_rec.instance_id);
3048         END IF;
3049         --dbms_output.put_line(SubStr('derived Position Instance_id: ' || p_x_disposition_rec.instance_id, 1, 255));
3050       END IF;
3051     -- Added by jaramana on June 23, 2006 to fix Bug 5205851
3052     ELSE
3053       IF (p_x_disposition_rec.instance_id IS NULL AND p_x_disposition_rec.part_change_id IS NOT NULL) THEN
3054         -- Disposition being created from Part Change UI for installing to an Empty position
3055         -- Default the condition of the Disposition to Serviceable if not already set
3056         IF (p_x_disposition_rec.condition_id IS NULL) THEN
3057           IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3058             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Defaulting Condition to ' || fnd_profile.value('AHL_MTL_MAT_STATUS_SERVICABLE'));
3059           END IF;
3060           p_x_disposition_rec.condition_id := fnd_profile.value('AHL_MTL_MAT_STATUS_SERVICABLE');
3061           IF (p_x_disposition_rec.condition_id IS NULL) THEN
3062             IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3063               FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Profile AHL_MTL_MAT_STATUS_SERVICABLE not set. Unable to derive Default Condition.');
3064             END IF;
3065             -- Raise an Exception
3066             FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_SVC_COND_PRF_NOT_SET');
3067             FND_MSG_PUB.ADD;
3068             RAISE FND_API.G_EXC_ERROR;
3069           END IF;
3070         END IF;
3071       END IF;
3072     END IF;
3073   -- Following added by jaramana on August 07, 2007 for the bug 6328554 (FP of 5948917)
3074   ELSE
3075     -- IB Tree
3076     IF (p_x_disposition_rec.instance_id IS NOT NULL AND
3077         p_x_disposition_rec.part_change_id IS NOT NULL AND
3078         p_x_disposition_rec.condition_id IS NULL) THEN
3079       -- Install of an Instance to an IB Tree from the Part Change UI with creation of
3080       -- a new Disposition: Default the condition to Serviceable
3081       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3082         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Defaulting Condition to ' || fnd_profile.value('AHL_MTL_MAT_STATUS_SERVICABLE'));
3083       END IF;
3084       p_x_disposition_rec.condition_id := fnd_profile.value('AHL_MTL_MAT_STATUS_SERVICABLE');
3085       IF (p_x_disposition_rec.condition_id IS NULL) THEN
3086         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3087           FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Profile AHL_MTL_MAT_STATUS_SERVICABLE not set. Unable to derive Default Condition.');
3088         END IF;
3089         -- Raise an Exception
3090         FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_SVC_COND_PRF_NOT_SET');
3091         FND_MSG_PUB.ADD;
3092         RAISE FND_API.G_EXC_ERROR;
3093       END IF;
3094     END IF;
3095   -- End addition by jaramana on August 07, 2007 for the bug 6328554 (FP of 5948917)
3096   END IF;
3097 
3098   --derive instance_id
3099   IF p_x_disposition_rec.instance_id IS NULL THEN
3100     --derive  instance_id from item and serial_number
3101     IF p_x_disposition_rec.inventory_item_id IS NOT NULL AND p_x_disposition_rec.serial_number IS NOT NULL THEN
3102       OPEN get_instance_from_serial(p_x_disposition_rec.inventory_item_id,
3103                                     p_x_disposition_rec.serial_number);
3104       FETCH get_instance_from_serial INTO  p_x_disposition_rec.instance_id;
3105       CLOSE get_instance_from_serial;
3106     END IF;
3107     --from item and lot_number derive instance_id
3108     IF p_x_disposition_rec.inventory_item_id IS NOT NULL AND p_x_disposition_rec.lot_number IS NOT NULL THEN
3109       OPEN get_instance_from_lot(p_x_disposition_rec.inventory_item_id,
3110                                  p_x_disposition_rec.lot_number);
3111       FETCH get_instance_from_lot INTO  p_x_disposition_rec.instance_id;
3112       CLOSE get_instance_from_lot;
3113     END IF;
3114     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3115       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,'derived instance: ' || p_x_disposition_rec.instance_id);
3116     END IF;
3117     --dbms_output.put_line(SubStr('derived instance: ' || p_x_disposition_rec.instance_id, 1, 255));
3118   END IF;
3119 
3120   -- from INSTANCE derive organization, item, quantity and uom
3121   IF (p_x_disposition_rec.instance_id IS NOT NULL) THEN
3122     OPEN instance_csr(p_x_disposition_rec.instance_id);
3123     FETCH instance_csr INTO instance_rec;
3124     CLOSE instance_csr;
3125 
3126     l_derived_org_id := nvl(instance_rec.last_vld_organization_id, instance_rec.inv_master_organization_id);  --derive organization from instance
3127     IF p_x_disposition_rec.inventory_item_id IS NULL THEN
3128       p_x_disposition_rec.inventory_item_id := instance_rec.inventory_item_id;
3129 
3130       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3131         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,'derived item_id ' || instance_rec.inventory_item_id);
3132       END IF;
3133       --dbms_output.put_line(SubStr('derived item_id ' || instance_rec.inventory_item_id, 1, 255));
3134     END IF;
3135     IF p_x_disposition_rec.quantity IS NULL THEN
3136       p_x_disposition_rec.quantity := instance_rec.quantity;
3137       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3138         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'derived quantity ' || instance_rec.quantity);
3139       END IF;
3140       --dbms_output.put_line(SubStr('derived quantity ' || instance_rec.quantity, 1, 255));
3141     END IF;
3142     IF p_x_disposition_rec.uom IS NULL THEN
3143       p_x_disposition_rec.uom := instance_rec.unit_of_measure;
3144       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3145         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'derived uom ' || instance_rec.unit_of_measure);
3146       END IF;
3147       --dbms_output.put_line(SubStr('derived uom ' || instance_rec.unit_of_measure, 1, 255));
3148     END IF;
3149 
3150     --Jerry added on 10/04/05 for fixing an internal bug found by Shailaja/Vadim
3151     IF p_x_disposition_rec.serial_number IS NULL THEN
3152       p_x_disposition_rec.serial_number:= instance_rec.serial_number;
3153       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3154         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'derived serial_number ' || instance_rec.serial_number);
3155       END IF;
3156     END IF;
3157 
3158     IF p_x_disposition_rec.lot_number IS NULL THEN
3159       p_x_disposition_rec.lot_number:= instance_rec.lot_number;
3160       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3161         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'derived lot_number ' || instance_rec.lot_number);
3162       END IF;
3163     END IF;
3164 
3165     IF p_x_disposition_rec.item_revision IS NULL THEN
3166       p_x_disposition_rec.item_revision := instance_rec.inventory_revision;
3167       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3168         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'derived item_revision ' || instance_rec.inventory_revision);
3169       END IF;
3170     END IF;
3171     --Jerry's change finishes here
3172 
3173     --Derive path_position_id
3174     IF p_x_disposition_rec.path_position_id IS NULL THEN
3175 
3176       -- Updated by rbhavsar on 09/27/2007 for Bug 6411059
3177       -- START: Added IF statement to check if root node of the instance is in uc headers table
3178       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3179                   FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,' Before calling Map_Instance_To_Pos_ID ' || p_x_disposition_rec.path_position_id ||
3180                    ' Instance id ' || p_x_disposition_rec.instance_id );
3181       END IF;
3182 
3183       IF (root_node_in_uc_headers(p_x_disposition_rec.instance_id) = TRUE) THEN
3184          AHL_MC_PATH_POSITION_PVT.Map_Instance_To_Pos_ID (
3185            p_api_version           =>  1.0,
3186            x_return_status         =>  x_return_status,
3187            x_msg_count             =>  x_msg_count,
3188            x_msg_data              =>  x_msg_data,
3189            p_csi_item_instance_id  =>  p_x_disposition_rec.instance_id,
3190            x_path_position_id      =>  l_derived_path_pos_id);
3191 
3192          IF x_return_status = FND_API.G_RET_STS_ERROR THEN
3193            RAISE FND_API.G_EXC_ERROR;
3194          ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
3195            RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3196          END IF;
3197 
3198          p_x_disposition_rec.path_position_id := l_derived_path_pos_id;
3199          IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3200            FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'derived path_position_id ' || l_derived_path_pos_id);
3201          END IF;
3202 
3203       END IF; -- END: Updated by rbhavsar Bug 6411059
3204 
3205       --dbms_output.put_line(SubStr('derived path_position_id ' || l_derived_path_pos_id, 1, 255));
3206     END IF;  -- path_position_id is null
3207   END IF;  -- instance_id is not null
3208 
3209   --derive organizationid  for item from workorder only if instance is null
3210   IF(p_x_disposition_rec.inventory_item_id IS NOT NULL AND p_x_disposition_rec.instance_id IS NULL) THEN
3211     OPEN get_organization_csr(p_x_disposition_rec.workorder_id);
3212     FETCH get_organization_csr INTO l_derived_org_id;
3213     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3214       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Derived Org: ' || p_x_disposition_rec.item_org_id);
3215     END IF;
3216     --dbms_output.put_line(SubStr('Derived Org: ' || p_x_disposition_rec.item_org_id, 1, 255));
3217     CLOSE get_organization_csr;
3218   END IF;
3219 
3220   --assign derived organization id to disposition record's item_org_id
3221   --ignore organization id from user's input
3222   p_x_disposition_rec.item_org_id := l_derived_org_id;
3223 
3224   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3225      FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure');
3226   END IF;
3227   --dbms_output.put_line(SubStr('End Derive Column', 1, 255));
3228 
3229 END derive_columns;
3230 
3231 
3232 
3233 ---------------------------LOCAL VALIDATION PROCEDURES------------------------------------
3234 
3235 PROCEDURE validate_for_create(p_disposition_rec IN AHL_PRD_DISPOSITION_PVT.disposition_rec_type)
3236 IS
3237 
3238 CURSOR exist_position_csr(p_path_position_id IN NUMBER, p_workorder_id IN NUMBER) IS
3239        SELECT 'X' FROM ahl_mc_path_positions pos
3240        WHERE pos.path_position_id = p_path_position_id
3241        AND EXISTS
3242            (SELECT pos2.path_pos_common_id FROM ahl_prd_dispositions_b dis, ahl_mc_path_positions pos2
3243             WHERE dis.path_position_id IS NOT NULL
3244              AND  dis.path_position_id = pos2.path_position_id
3245              AND dis.workorder_id =  p_workorder_id
3246              AND nvl(dis.status_code, 'dummy') NOT IN ('COMPLETE', 'TERMINATED')
3247              AND pos.path_pos_common_id = pos2.path_pos_common_id);
3248 
3249 --Begin Performance Tuning
3250 CURSOR get_wo_instance_id(p_workorder_id IN NUMBER) IS
3251        SELECT nvl(VTS.INSTANCE_ID,VST.ITEM_INSTANCE_ID)
3252 	   FROM ahl_workorders wo, AHL_VISITS_VL VST, AHL_VISIT_TASKS_VL VTS
3253        WHERE workorder_id = p_workorder_id
3254          and  WO.VISIT_TASK_ID=VTS.VISIT_TASK_ID
3255          AND VST.VISIT_ID=VTS.VISIT_ID;
3256 --End performance Tunning
3257 
3258 CURSOR item_in_itemgrp_csr(p_inventory_item_id IN NUMBER, p_item_group_id IN NUMBER) IS
3259        SELECT 'x' FROM ahl_item_associations_b
3260        WHERE inventory_item_id = p_Inventory_item_id
3261          AND item_group_id = p_item_group_id;
3262 
3263 -- cursor changed by anraj
3264 -- backend validation to check that while create the Item Group given is of type NON-TRACKED
3265 CURSOR val_item_group_csr(p_item_group_id IN NUMBER) IS
3266        SELECT 'x' FROM ahl_item_groups_b
3267 	   WHERE item_group_id = p_item_group_id
3268          AND status_code = 'COMPLETE' AND type_code = 'NON-TRACKED';
3269 
3270 
3271 /* Begin Fix for 4075758 on Dec 21. 2004 by JR */
3272   -- For non-tracked items, serial or lot numbers
3273   -- need to be validated only against MTL tables.
3274 /******
3275 CURSOR val_lot_number_csr(p_lot_number IN VARCHAR2, p_inventory_item_id IN NUMBER) IS
3276        SELECT 'x' FROM csi_item_instances csi
3277        WHERE lot_number = p_lot_number
3278          AND inventory_item_id = p_inventory_item_id;
3279 
3280 CURSOR val_serial_number_csr(p_serial_number IN VARCHAR2, p_inventory_item_id IN NUMBER) IS
3281        SELECT 'x' FROM csi_item_instances csi
3282        WHERE serial_number = p_serial_number
3283          AND inventory_item_id = p_inventory_item_id;
3284 ******/
3285 CURSOR val_lot_number_csr(p_lot_number IN VARCHAR2, p_inventory_item_id IN NUMBER) IS
3286        SELECT 'x' FROM mtl_lot_numbers
3287        WHERE lot_number = p_lot_number
3288          AND inventory_item_id = p_inventory_item_id
3289        UNION
3290        SELECT 'x' FROM csi_item_instances csi
3291        WHERE lot_number = p_lot_number
3292          AND inventory_item_id = p_inventory_item_id;
3293 
3294 CURSOR val_serial_number_csr(p_serial_number IN VARCHAR2, p_inventory_item_id IN NUMBER) IS
3295        SELECT 'x' FROM mtl_serial_numbers
3296        WHERE serial_number = p_serial_number
3297          AND inventory_item_id = p_inventory_item_id
3298        UNION
3299        SELECT 'x' FROM csi_item_instances csi
3300        WHERE serial_number = p_serial_number
3301          AND inventory_item_id = p_inventory_item_id;
3302 /* End Fix for 4075758 on Dec 21. 2004 */
3303 
3304 CURSOR instance_quantity_csr(p_instance_id IN NUMBER) IS
3305        SELECT quantity from csi_item_instances WHERE instance_id = p_instance_id;
3306 
3307 CURSOR instance_uom_csr(p_instance_id IN NUMBER) IS
3308        SELECT unit_of_measure from csi_item_instances WHERE instance_id = p_instance_id;
3309 
3310 CURSOR item_class_uom_csr(p_uom_code IN VARCHAR2, p_inventory_item_id NUMBER) IS
3311 /*
3312        SELECT 'X' FROM ahl_item_class_uom_v
3313        WHERE uom_code = p_uom_code AND inventory_item_id = p_inventory_item_id;
3314 */
3315       --AnRaj: Changed query, Perf Bug#4908609,Issue#2
3316       SELECT   'X'
3317       from     MTL_UNITS_OF_MEASURE_TL
3318       where    uom_class = (
3319                               select   distinct uom.uom_class
3320                               from     MTL_UNITS_OF_MEASURE_TL uom
3321                               where    uom.uom_code = (  select   distinct primary_uom_code
3322                                                          from     mtl_system_items
3323                                                          where    inventory_item_id = p_inventory_item_id
3324                                                       )
3325                            )
3326       and      uom_code = p_uom_code;
3327 
3328 CURSOR val_Collection_id_csr(p_collection_id IN NUMBER) IS
3329        SELECT 'x' FROM qa_results WHERE collection_id = p_collection_id;
3330 
3331 CURSOR get_item_id_csr(p_instance_id IN NUMBER) IS
3332        SELECT inventory_item_id from csi_item_instances WHERE instance_id = p_instance_id;
3333 
3334 CURSOR val_uom_csr(p_uom IN VARCHAR2) IS
3335        SELECT  'x' FROM mtl_units_of_measure_vl
3336        WHERE uom_code = p_uom;
3337 
3338 CURSOR item_revisions_csr (p_revision  IN  VARCHAR2, p_item_id IN NUMBER, p_organization_id IN NUMBER)  IS
3339        SELECT 'x' FROM   mtl_item_revisions
3340         WHERE  inventory_item_id = p_item_id
3341             AND organization_id = p_organization_id
3342             AND revision = p_revision;
3343 
3344 CURSOR part_change_csr(c_part_change_id IN NUMBER) IS
3345        SELECT REMOVED_INSTANCE_ID, INSTALLED_INSTANCE_ID, PART_CHANGE_TYPE
3346        FROM AHL_PART_CHANGES
3347        WHERE PART_CHANGE_ID = c_part_change_id;
3348 
3349 -- Added the following for fixing Bug#:4059944
3350 -- To find whether the Item is IB Trackable
3351 CURSOR item_is_ib_trackable(p_inventory_item_id IN NUMBER) IS
3352 	SELECT NVL(MTL.comms_nl_trackable_flag, 'N')  trackable_flag
3353 	FROM   MTL_SYSTEM_ITEMS_KFV MTL
3354 	WHERE MTL.INVENTORY_ITEM_ID= p_inventory_item_id;
3355 
3356 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
3357 -- Cursor to check whether the disposition item is serialized or not.
3358 CURSOR chk_non_serialized_csr(p_inventory_item_id NUMBER, p_item_org_id NUMBER) IS
3359 	SELECT 'X'
3360 	FROM   mtl_system_items_b
3361         WHERE  inventory_item_id          = p_inventory_item_id
3362         AND    organization_id            = p_item_org_id
3363         AND    serial_number_control_code = 1;
3364 
3365 item_is_trackable VARCHAR2(1);
3366 
3367 l_serial_control  NUMBER;
3368 l_qty_revision_control NUMBER;
3369 l_lot_control NUMBER;
3370 
3371 
3372 
3373 l_exist VARCHAR(1);
3374 l_quantity NUMBER;
3375 l_uom VARCHAR(3);
3376 
3377 l_wo_organization_id NUMBER;
3378 
3379 l_unit_instance_id NUMBER;
3380 l_pos_instance_id NUMBER;
3381 l_parent_instance_id NUMBER;
3382 l_dummy_rel_id NUMBER;
3383 l_dummy_lowest_uc_id NUMBER;
3384 l_mapping_status  VARCHAR(30);
3385 l_return_status VARCHAR(30);
3386 l_msg_count  NUMBER;
3387 l_msg_data   VARCHAR(200);
3388 
3389 l_wo_instance_id NUMBER;
3390 l_wo_root_instance_id NUMBER;        --Root Instance of workorder instance
3391 l_dis_root_instance_id NUMBER;      --Root Instance of disposition instance.
3392 l_item_id NUMBER;
3393 
3394 l_position_empty BOOLEAN := FALSE;
3395 
3396 l_pc_rem_instance_id  NUMBER;
3397 l_pc_inst_instance_id NUMBER;
3398 l_pc_type             VARCHAR2(1);
3399 
3400 l_plan_id   NUMBER;
3401 
3402 
3403 L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'validate_for_create';
3404 l_dummy          VARCHAR2(1);
3405 l_srl_flag       VARCHAR2(1)            := 'Y';
3406 
3407 cursor is_qa_coll_reqd(p_plan_id IN NUMBER) IS
3408 select 'x' from qa_plan_transactions_v
3409 where mandatory_collection_flag = 1 and enabled_flag = 1
3410 and plan_id = p_plan_id;
3411 
3412 BEGIN
3413 
3414   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3415     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
3416   END IF;
3417   --dbms_output.put_line(SubStr('Begin Validate_For_Create', 1, 255));
3418 
3419   --WORKORDER
3420   IF (p_disposition_rec.workorder_id IS NULL) THEN
3421     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_WO_ID_REQ');       -- Workorder is required to create disposition.
3422     FND_MSG_PUB.ADD;
3423     RAISE FND_API.G_EXC_ERROR;
3424   ELSE
3425     validate_workorder(p_disposition_rec.workorder_id);
3426     IF(workorder_editable(p_disposition_rec.workorder_id) = FALSE) THEN
3427       FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_WO_NOT_EDITABLE');  --Cannot Create Disposition Because Workorder is not editable.
3428       FND_MSG_PUB.ADD;
3429       RAISE FND_API.G_EXC_ERROR;
3430     END IF;
3431   END IF;
3432 
3433   IF (p_disposition_rec.path_position_id IS NULL AND p_disposition_rec.inventory_item_id IS NULL) THEN
3434     FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_POS_OR_ITEM_REQ');    --Path Position or Item is required to create a disposition
3435     FND_MSG_PUB.ADD;
3436     RAISE FND_API.G_EXC_ERROR;
3437   END IF;
3438 
3439   IF p_disposition_rec.item_org_id IS NOT NULL AND p_disposition_rec.inventory_item_id IS NULL THEN
3440     FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_CANNOT_ENTER_ORG');    --Cannot enter organization id.
3441     FND_MSG_PUB.ADD;
3442   END IF;
3443 
3444   -- Validate Part Change and get details
3445   IF(p_disposition_rec.part_change_id IS NOT NULL) THEN
3446     OPEN part_change_csr(p_disposition_rec.part_change_id);
3447     FETCH part_change_csr INTO l_pc_rem_instance_id,
3448                                l_pc_inst_instance_id,
3449                                l_pc_type;
3450     IF (part_change_csr%NOTFOUND) THEN
3451       CLOSE part_change_csr;
3452       FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_INV_PART_CHG_ID');    -- Invalid part change id
3453       FND_MESSAGE.SET_TOKEN('PART_CHNG_ID', p_disposition_rec.part_change_id);
3454       FND_MSG_PUB.ADD;
3455       RAISE FND_API.G_EXC_ERROR;
3456     END IF;
3457     CLOSE part_change_csr;
3458   END IF;
3459 
3460   --PATH POSITION VALIDATION  ---------------------------------
3461   IF (p_disposition_rec.path_position_id IS NOT NULL) THEN
3462     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3463       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Check Path Position');
3464     END IF;
3465     --dbms_output.put_line(SubStr('In Validate_For_Create -- Check Path Position ', 1, 255));
3466     --Check for valid path_position_id
3467     validate_path_position(p_disposition_rec.path_position_id);
3468 
3469     -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
3470     -- Multiple dispositions can be created for non-serialized item/position. So relax the only-one-disposition
3471     -- restriction for non-serilized item/position.
3472     OPEN chk_non_serialized_csr(p_disposition_rec.inventory_item_id, p_disposition_rec.item_org_id);
3473     FETCH chk_non_serialized_csr INTO l_dummy;
3474     IF (chk_non_serialized_csr%NOTFOUND) THEN
3475       -- The chk_non_serialized_csr will not fetch results if item id is NULL.
3476       -- If item id is NULL, then this disposition is being created for empty position.
3477       -- Check for non-serialized position by calling the API AHL_MC_PATH_POSITION_PVT.Is_Position_Serial_Controlled
3478       IF (p_disposition_rec.inventory_item_id IS NULL) THEN
3479         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3480             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
3481                            'Before API AHL_MC_PATH_POSITION_PVT.Is_Position_Serial_Controlled call l_srl_flag => '||l_srl_flag);
3482         END IF;
3483 
3484         l_srl_flag := AHL_MC_PATH_POSITION_PVT.Is_Position_Serial_Controlled(
3485                                                                              NULL,
3486                                                                              p_disposition_rec.path_position_id
3487                                                                             );
3488 
3489         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3490             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
3491                            'After API AHL_MC_PATH_POSITION_PVT.Is_Position_Serial_Controlled call l_srl_flag => '||l_srl_flag);
3492         END IF;
3493       END IF;
3494 
3495       --If item/position is serialized, then validate that path position does not exist in other dispositions
3496       IF (l_srl_flag = 'Y') THEN
3497         OPEN exist_position_csr(p_disposition_rec.path_position_id, p_disposition_rec.workorder_id);
3498         FETCH exist_position_csr INTO l_exist;
3499         IF(exist_position_csr%FOUND) THEN
3500           FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_POS_OTHER');
3501           FND_MSG_PUB.ADD;
3502         END IF;
3503         CLOSE exist_position_csr;
3504       END IF; -- if l_srl_flag = 'Y'
3505     END IF; -- if chk_non_serialized_csr%NOTFOUND
3506     CLOSE chk_non_serialized_csr;
3507 
3508     --Check if workorder's instance is in UC tree
3509     l_unit_instance_id := get_unit_instance_id(p_disposition_rec.workorder_id);
3510     IF(l_unit_instance_id IS NULL) THEN
3511       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_NOT_UC_NO_POS');    --Workorder's instance does not belong to UC hence path position is not allowed
3512       FND_MSG_PUB.ADD;
3513       RAISE FND_API.G_EXC_ERROR;
3514     END IF;
3515 
3516     IF (FND_LOG.LEVEL_EVENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3517       FND_LOG.STRING(FND_LOG.LEVEL_EVENT, L_DEBUG_KEY, 'About to call AHL_MC_PATH_POSITION_PVT.Get_Pos_Instance with ' ||
3518                ' p_position_id = ' || p_disposition_rec.path_position_id ||
3519                ', p_csi_item_instance_id = ' || l_unit_instance_id);
3520     END IF;
3521 
3522     AHL_MC_PATH_POSITION_PVT.Get_Pos_Instance (
3523       p_api_version           => 1.0,
3524       x_return_status         => l_return_status,
3525       x_msg_count             => l_msg_count,
3526       x_msg_data              => l_msg_data,
3527       p_position_id           => p_disposition_rec.path_position_id,
3528       p_csi_item_instance_id  => l_unit_instance_id,
3529       x_item_instance_id      => l_pos_instance_id,
3530       x_parent_instance_id    => l_parent_instance_id,
3531       x_relationship_id       => l_dummy_rel_id,
3532       x_lowest_uc_csi_id      => l_dummy_lowest_uc_id,
3533       x_mapping_status        => l_mapping_status
3534     );
3535 
3536     IF (FND_LOG.LEVEL_EVENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3537       FND_LOG.STRING(FND_LOG.LEVEL_EVENT, L_DEBUG_KEY, 'Returned from call to AHL_MC_PATH_POSITION_PVT.Get_Pos_Instance: ' ||
3538                ' x_return_status ' || l_return_status ||
3539                ', x_parent_instance_id ' || l_parent_instance_id ||
3540                ', x_mapping_status = ' || l_mapping_status);
3541     END IF;
3542     -- Check return status.
3543     IF l_return_status = FND_API.G_RET_STS_ERROR THEN
3544       RAISE FND_API.G_EXC_ERROR;
3545     ELSIF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
3546       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3547     END IF;
3548 
3549     -- SATHAPLI:: Bug 6836572, 19-Mar-2008
3550     -- If the workorder instance is root instance of an installed sub UC, and the sub UC has been removed during parts change, then
3551     -- the API get_unit_instance_id would return the sub UC's root instance, instead of the top most UC's root instance. This
3552     -- would result in the API AHL_MC_PATH_POSITION_PVT.Get_Pos_Instance returning x_mapping_status as 'NA'.
3553     -- To bypass this, we can just check for the part change to have taken place or not. If yes, then we can go ahead with the
3554     -- Disposition creation.
3555 
3556     IF (l_mapping_status = 'NA') THEN
3557       -- Check if removal was done or not.
3558       IF(p_disposition_rec.part_change_id IS NOT NULL) THEN
3559         -- Ensure that the disposition instance is the same as the removed instance.
3560         IF (NVL(p_disposition_rec.instance_id, -1) <> l_pc_rem_instance_id) THEN
3561           FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_INSTANT_ID');
3562           FND_MESSAGE.SET_TOKEN('INSTANT_ID', p_disposition_rec.instance_id);
3563           FND_MSG_PUB.ADD;
3564         END IF;
3565       ELSE
3566         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_POS_NOT_WO_UC');    --Position is not in the same Unit Configuration as that of workorder instance.
3567         FND_MSG_PUB.ADD;
3568       END IF; -- part change check
3569     ELSIF (l_mapping_status = 'PARENT_EMPTY') THEN
3570        FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_PARENT_EMPTY');    --Cannot select a position whose parent is empty
3571        FND_MSG_PUB.ADD;
3572     ELSIF (l_mapping_status = 'EMPTY') THEN
3573       -- Check if this create_disposition is called from Part Change
3574       IF(p_disposition_rec.part_change_id IS NOT NULL) THEN
3575         IF (l_pc_type = G_PART_CHANGE_REMOVE) THEN
3576           -- Disposition is for the removed instance
3577           -- Ensure that the disposition instance is the same as the removed instance
3578           IF (NVL(p_disposition_rec.instance_id, -1) <> l_pc_rem_instance_id) THEN
3579             FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_INSTANT_ID');
3580             FND_MESSAGE.SET_TOKEN('INSTANT_ID', p_disposition_rec.instance_id);
3581             FND_MSG_PUB.ADD;
3582           END IF;
3583         ELSE
3584           -- G_PART_CHANGE_INSTALL and G_PART_CHANGE_SWAP are not possible since the position is empty
3585           -- May have to throw an exception if control come here
3586           NULL;
3587         END IF;
3588       ELSE
3589         l_position_empty := TRUE;
3590         IF (p_disposition_rec.instance_id IS NOT NULL) THEN
3591           FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_POS_EMPTY_NO_INST');   --Position is empty cannot enter instance number.
3592           FND_MSG_PUB.ADD;
3593         END IF;
3594         --Check if parent instance of this empty position is in the same tree as workorder instance
3595         OPEN get_wo_instance_id(p_disposition_rec.workorder_id);
3596         FETCH get_wo_instance_id INTO l_wo_instance_id;
3597         CLOSE get_wo_instance_id;
3598         IF l_parent_instance_id <> l_wo_instance_id THEN  --only need to check when instance is not the same as workorder instance
3599           --get root instance for workorder instance
3600           l_wo_root_instance_id := get_root_instance_id(l_wo_instance_id);
3601 
3602           --get root instance for the empty position parent instance
3603           l_dis_root_instance_id := get_root_instance_id(l_parent_instance_id);
3604 
3605           IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3606             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'l_wo_instance_id = ' || l_wo_instance_id ||
3607                ', l_wo_root_instance_id = ' || l_wo_root_instance_id ||
3608                ', l_parent_instance_id = ' || l_parent_instance_id ||
3609                ', l_dis_root_instance_id = ' || l_dis_root_instance_id);
3610           END IF;
3611 
3612           IF nvl(l_wo_root_instance_id, -1) <> nvl(l_dis_root_instance_id, -1) THEN
3613             FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_POS_NOT_WO_UC');   -- Instance is not in the same unit as workorder instance
3614             FND_MSG_PUB.ADD;
3615             RAISE FND_API.G_EXC_ERROR;
3616           END IF;
3617         END IF;
3618       END IF; -- Part Change
3619     ELSIF (l_mapping_status = 'MATCH') THEN
3620       -- Check if this create_disposition is called from Part Change
3621       IF(p_disposition_rec.part_change_id IS NOT NULL) THEN
3622         -- Position is not empty and Part Change has already happened
3623         IF (l_pc_type = G_PART_CHANGE_INSTALL) THEN
3624           -- Disposition is for the empty position (before the install)
3625           IF (p_disposition_rec.instance_id IS NOT NULL) THEN
3626             FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_INSTANT_ID');
3627             FND_MESSAGE.SET_TOKEN('INSTANT_ID', p_disposition_rec.instance_id);
3628             FND_MSG_PUB.ADD;
3629             RAISE FND_API.G_EXC_ERROR;
3630           END IF;
3631           l_position_empty := TRUE;
3632         ELSIF (l_pc_type = G_PART_CHANGE_SWAP) THEN
3633           -- Disposition is for the instance that was swapped out
3634           -- Ensure that the disposition instance is the same as the removed instance
3635           IF (NVL(p_disposition_rec.instance_id, l_pc_rem_instance_id) <> l_pc_rem_instance_id) THEN
3636             FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_INSTANT_ID');
3637             FND_MESSAGE.SET_TOKEN('INSTANT_ID', p_disposition_rec.instance_id);
3638             FND_MSG_PUB.ADD;
3639           END IF;
3640         ELSE
3641           -- G_PART_CHANGE_REMOVE is not possible since the position is not empty
3642           -- May have to throw an exception if control come here
3643           NULL;
3644         END IF;
3645       ELSE
3646         IF(nvl(l_pos_instance_id, -1) <> nvl(p_disposition_rec.instance_id, -1)) THEN
3647           FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INST_NO_MATCH');    -- Position's instance and disposition instance do not match
3648           FND_MESSAGE.Set_Token('POS_INSTANT_ID', l_pos_instance_id);
3649           FND_MESSAGE.Set_Token('DIS_INSTANT_ID', p_disposition_rec.instance_id);
3650           FND_MSG_PUB.ADD;
3651         END IF;
3652       END IF;  -- Part Change
3653     END IF;  -- l_mapping_status
3654   END IF;  -- end path_position
3655 
3656  --ITEM ---------------------------------
3657 
3658  IF(p_disposition_rec.inventory_item_id IS NOT NULL) THEN
3659     --dbms_output.put_line(SubStr('In Validate_For_Create -- Check ITem  ', 1, 255));
3660     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3661       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Check Check Item');
3662     END IF;
3663     IF (l_position_empty = TRUE) THEN
3664       FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_POS_EMPTY_NO_ITM');    --Item does not belong to the item group
3665       FND_MSG_PUB.ADD;
3666     END IF;
3667 
3668     validate_item(p_disposition_rec.inventory_item_id, p_disposition_rec.item_org_id, p_disposition_rec.workorder_id);
3669 
3670     --item group exist requires item to exist
3671     IF(p_disposition_rec.item_group_id IS NOT NULL) THEN
3672       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3673         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Check ITem and item group relation');
3674       END IF;
3675       --dbms_output.put_line(SubStr('In Validate_For_Create -- Check ITem and item group relation ', 1, 255));
3676       OPEN item_in_itemgrp_csr( p_disposition_rec.inventory_item_id, p_disposition_rec.item_group_id);
3677       FETCH item_in_itemgrp_csr INTO l_exist;
3678         IF item_in_itemgrp_csr%NOTFOUND THEN
3679           FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_NOT_IN_ITMGRP');    --Item does not belong to the item group
3680           FND_MSG_PUB.ADD;
3681         END IF;
3682       CLOSE item_in_itemgrp_csr;
3683     END IF;  -- item_group_id is not null
3684 
3685      -- Bug#:4059944
3686      -- Forcing the user to select an instance if the item is Trackable
3687      OPEN item_is_ib_trackable (p_disposition_rec.inventory_item_id);
3688      FETCH item_is_ib_trackable INTO item_is_trackable;
3689      CLOSE item_is_ib_trackable;
3690      IF( item_is_trackable ='Y') THEN
3691         IF (p_disposition_rec.instance_id IS NULL) THEN
3692         -- validation to force the user to pick an instance if Disposition Item is Trackable in the IB
3693 	   FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_TR_ITEM_INST_MAND');    -- Invalid item group
3694 	   FND_MESSAGE.Set_Token('ITEM_NAME',p_disposition_rec.item_number);
3695 	   FND_MSG_PUB.ADD;
3696 	    END IF;
3697 	 ELSE   --start fix Bug#4075758 Item is non-tracked
3698 	  validate_Item_Control(p_disposition_rec.inventory_item_id , p_disposition_rec.item_org_id,
3699                                          p_disposition_rec.serial_number,
3700                                           p_disposition_rec.item_revision,
3701 										  p_disposition_rec.lot_number);
3702 		--end  Bug#4075758
3703 
3704     END IF;
3705   END IF;  -- item id is not null
3706 
3707   --ITEM GROUP-----------------------------
3708   IF(p_disposition_rec.item_group_id IS NOT NULL) THEN
3709     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3710       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Check ITem group ');
3711     END IF;
3712      --dbms_output.put_line(SubStr('In Validate_For_Create -- Check ITem Group ', 1, 255));
3713     OPEN val_item_group_csr(p_disposition_rec.item_group_id);
3714     FETCH val_item_group_csr INTO l_exist;
3715       IF (val_item_group_csr%NOTFOUND) THEN
3716          FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_ITEM_GRP');    -- Invalid item group
3717         FND_MSG_PUB.ADD;
3718       END IF;
3719     CLOSE val_item_group_csr;
3720 
3721     IF(p_disposition_rec.inventory_item_Id IS NULL) THEN
3722       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITMGRP_REQ_ITM');    --Since item group is present, item number needs to be entered.
3723       FND_MSG_PUB.ADD;
3724     END IF;
3725     --path position id exist then item group must be null
3726     IF(p_disposition_rec.path_position_id IS NOT NULL)THEN
3727       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_POS_ITMGRP');   -- Can only enter either position or item group but not both.
3728       FND_MSG_PUB.ADD;
3729     END IF;
3730   END IF;  -- item_group_id is not null
3731 
3732   --INSTANCE-----------------------------
3733   IF(p_disposition_rec.instance_id IS NOT NULL) THEN
3734     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3735       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Check Instance_id');
3736     END IF;
3737     --dbms_output.put_line(SubStr('In Validate_For_Create -- Check Instance Number', 1, 255));
3738     validate_instance(p_disposition_rec.instance_id,
3739                       p_disposition_rec.workorder_id,
3740                       p_disposition_rec.path_position_id,
3741                       p_disposition_rec.part_change_id);
3742 
3743     IF(p_disposition_rec.inventory_item_id IS NULL) THEN
3744       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_REQ');    -- Item number is required
3745       FND_MSG_PUB.ADD;
3746     ELSE
3747       OPEN get_item_id_csr(p_disposition_rec.instance_id);
3748       FETCH get_item_id_csr INTO l_item_id;
3749       IF l_item_id <> p_disposition_rec.inventory_item_id THEN
3750          FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_NO_MATCH');    -- Item does not match with instance's item.
3751          FND_MSG_PUB.ADD;
3752       END IF;
3753       CLOSE get_item_id_csr;
3754     END IF;
3755   END IF;
3756 
3757   --LOT NUMBER----------------------------------
3758   IF(p_disposition_rec.lot_number IS NOT NULL) THEN
3759      IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3760         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Check Lot_number');
3761       END IF;
3762     --dbms_output.put_line(SubStr('In Validate_For_Create -- Check Lot Number', 1, 255));
3763     IF(p_disposition_rec.inventory_item_id IS NULL) THEN
3764       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_REQ');    -- Item number is required
3765       FND_MSG_PUB.ADD;
3766     ELSE
3767       OPEN val_lot_number_csr(p_disposition_rec.lot_number, p_disposition_rec.inventory_item_id);
3768       FETCH val_lot_number_csr INTO l_exist;
3769       IF (val_lot_number_csr%NOTFOUND) THEN
3770         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_LOT');    -- Invalid lot_number and item combination
3771         FND_MSG_PUB.ADD;
3772       END IF;
3773       CLOSE val_lot_number_csr;
3774     END IF;
3775   END IF;
3776 
3777   --SERIAL NUMBER -----------------------------------
3778   IF(p_disposition_rec.serial_number IS NOT NULL) THEN
3779     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3780       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Check Serial_Number');
3781     END IF;
3782     --dbms_output.put_line(SubStr('In Validate_For_Create -- Check Serial Number', 1, 255));
3783     IF(p_disposition_rec.inventory_item_id IS NULL) THEN
3784       --dbms_output.put_line(SubStr('In Validate_For_Create -- Check Serial Number--check item is null', 1, 255));
3785       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_ITEM_REQ');    -- Item is required
3786       FND_MSG_PUB.ADD;
3787     ELSE
3788       --dbms_output.put_line(SubStr('In Validate_For_Create -- before open val_serial_number_csr', 1, 255));
3789       OPEN val_serial_number_csr(p_disposition_rec.serial_number, p_disposition_rec.inventory_item_id);
3790       FETCH val_serial_number_csr INTO l_exist;
3791       IF (val_serial_number_csr%NOTFOUND) THEN
3792         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_SERIAL');    -- Invalid serial number and item combination
3793         FND_MSG_PUB.ADD;
3794       END IF;
3795       CLOSE val_serial_number_csr;
3796     END IF;
3797     --dbms_output.put_line(SubStr('In Validate_For_Create --end check serial Number', 1, 255));
3798   END IF;
3799 
3800   --QUANTITY -----------------------------------
3801   IF (p_disposition_rec.quantity IS NULL AND l_position_empty = FALSE) THEN
3802     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_QTY_REQ');    -- Quantity cannot be null
3803     FND_MSG_PUB.ADD;
3804   ELSIF (p_disposition_rec.quantity IS NOT NULL) THEN
3805     IF p_disposition_rec.quantity <= 0 THEN
3806        FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_QTY_LESS_ZERO');    -- Quantity must be greater than zero
3807        FND_MSG_PUB.ADD;
3808     END IF;
3809     IF p_disposition_rec.instance_id IS NOT NULL THEN
3810       OPEN instance_quantity_csr(p_disposition_rec.instance_id);
3811       FETCH instance_quantity_csr into l_quantity;
3812       -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
3813       -- The quantity check should be modified from '<>' to '>'. Subsequently, the error has been modified to
3814       -- 'Quantity should not be greater than instance quantity'.
3815       IF (p_disposition_rec.quantity > l_quantity) THEN
3816         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_QTY_INST_QTY');    -- Quantity cannot be different from instance's quantity
3817         FND_MSG_PUB.ADD;
3818       END IF;
3819       CLOSE instance_quantity_csr;
3820     END IF;
3821   END IF;
3822 
3823   --UOM-------------------------------------------------------------
3824   IF( p_disposition_rec.uom IS NULL AND l_position_empty = FALSE )THEN
3825     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_UOM_REQ');    -- UOM cannot be null
3826     FND_MSG_PUB.ADD;
3827   ELSIF ( p_disposition_rec.uom IS NOT NULL) THEN
3828     OPEN val_uom_csr(p_disposition_rec.uom);
3829     FETCH val_uom_csr INTO l_exist;
3830     IF val_uom_csr%NOTFOUND THEN
3831       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_UOM');    -- Invalid UOM.
3832       FND_MSG_PUB.ADD;
3833     END IF;
3834     CLOSE val_uom_csr;
3835 
3836     IF p_disposition_rec.instance_id IS NOT NULL THEN
3837       OPEN instance_uom_csr(p_disposition_rec.instance_id);
3838       FETCH instance_uom_csr INTO l_uom;
3839       IF (p_disposition_rec.uom <> l_uom) THEN
3840         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_INST_UOM');    -- Invalid UOM.  UOM must be the same as instance's UOM.
3841         FND_MSG_PUB.ADD;
3842       END IF;
3843       CLOSE instance_uom_csr;
3844     END IF;
3845 
3846     IF p_disposition_rec.inventory_item_id IS NOT NULL THEN
3847       OPEN item_class_uom_csr(p_disposition_rec.uom, p_disposition_rec.inventory_item_id);
3848       FETCH item_class_uom_csr into l_exist;
3849       IF item_class_uom_csr%NOTFOUND THEN
3850         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_INV_ITEM_UOM');    -- Invalid UOM.  UOM must belong to the item's primary uom
3851         FND_MSG_PUB.ADD;
3852       END IF;
3853       CLOSE item_class_uom_csr;
3854     END IF;
3855   END IF;
3856 
3857   --COLLECTION ID-------------------------------------------------------------
3858   -- Added by jaramana on March 25, 2005 to fix bug 4243200
3859   -- First check if a QA Plan is defined in the workorder Org.
3860   AHL_QA_RESULTS_PVT.get_qa_plan( p_api_version   => 1.0,
3861                                   p_init_msg_list => FND_API.G_False,
3862                                   p_commit => FND_API.G_FALSE,
3863                                   p_validation_level => FND_API.G_VALID_LEVEL_FULL,
3864                                   p_default => FND_API.G_FALSE,
3865                                   p_organization_id => p_disposition_rec.item_org_id,
3866                                   p_transaction_number => 2004,  -- MRB_TRANSACTION_NUMBER
3867                                   p_col_trigger_value => fnd_profile.value('AHL_MRB_DISP_PLAN_TYPE'),
3868                                   x_return_status => l_return_status,
3869                                   x_msg_count => l_msg_count,
3870                                   x_msg_data => l_msg_data,
3871                                   x_plan_id  => l_plan_id);
3872   --IF p_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB') AND p_disposition_rec.instance_id IS NOT NULL THEN
3873   IF p_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB') AND
3874      p_disposition_rec.instance_id IS NOT NULL AND
3875      l_plan_id IS NOT NULL THEN
3876     IF p_disposition_rec.collection_id IS NULL THEN
3877       OPEN is_qa_coll_reqd(l_plan_id);
3878       FETCH is_qa_coll_reqd INTO l_dummy;
3879       IF(is_qa_coll_reqd%FOUND) THEN
3880         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_QA_RESULT_REQ');    --  QA Result Required
3881         FND_MSG_PUB.ADD;
3882       END IF;
3883       CLOSE is_qa_coll_reqd;
3884     ELSE
3885       validate_collection_id(p_disposition_rec.collection_id);
3886     END IF;
3887   END IF;
3888   -- End fix for bug 4243200
3889 
3890   IF ((p_disposition_rec.instance_id IS NULL  OR
3891 	   (nvl(p_disposition_rec.condition_id, -1) <> fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')
3892            AND nvl(p_disposition_rec.condition_id, -1) <> fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE')
3893 	   )
3894 	 )AND
3895 	 ( p_disposition_rec.summary IS NOT NULL OR p_disposition_rec.problem_code IS NOT NULL
3896 	       OR p_disposition_rec.severity_id IS NOT NULL
3897 	 )) THEN
3898        FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DIS_SR_NOT_REQ');      --Non Conformance (SR) information is not required
3899        FND_MSG_PUB.ADD;
3900   END IF;
3901 
3902   --OPERATION_ID--------------------------------------------------------
3903   IF (p_disposition_rec.wo_operation_id IS NOT NULL) THEN
3904     validate_wo_operation(p_disposition_rec.workorder_id, p_disposition_rec.wo_operation_id );
3905   END IF;
3906 
3907   --validate item revision--------------------------------------------------------
3908   IF (p_disposition_rec.item_revision IS NOT NULL) THEN
3909     IF p_disposition_rec.inventory_item_id IS NULL THEN
3910       FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_ITM_REV_REQ_ITM');    --Cannot enter an item revision without entering item
3911       FND_MSG_PUB.ADD;
3912     ELSE
3913       OPEN item_revisions_csr(p_disposition_rec.item_revision, p_disposition_rec.inventory_item_id, p_disposition_rec.item_org_id);
3914       FETCH item_revisions_csr INTO l_exist;
3915       IF item_revisions_csr%NOTFOUND THEN
3916         FND_MESSAGE.Set_Name(G_APP_NAME, 'AHL_PRD_DIS_INV_ITEM_REV');    --Invalid item revision
3917         FND_MSG_PUB.ADD;
3918       END IF;
3919       CLOSE item_revisions_csr;
3920     END IF;
3921   END IF;
3922 
3923   IF FND_MSG_PUB.count_msg > 0 THEN
3924     RAISE FND_API.G_EXC_ERROR;
3925   END IF;
3926 
3927   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
3928     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure');
3929    END IF;
3930 
3931   --dbms_output.put_line(SubStr('End Validate_For_Create', 1, 255));
3932 END validate_for_create;
3933 
3934 --------------------------------------------------------------------------------
3935 PROCEDURE convert_values_to_ids
3936 (
3937   p_x_prd_disposition_rec IN OUT NOCOPY AHL_PRD_DISPOSITION_PVT.disposition_rec_type
3938 ) IS
3939 
3940 CURSOR instance_id_csr(p_instance_number IN VARCHAR2) IS
3941     SELECT instance_id from csi_item_instances
3942     WHERE instance_number = p_instance_number;
3943 
3944 CURSOR item_group_id_csr(p_item_group_name IN VARCHAR2) IS
3945        SELECT item_group_id from ahl_item_groups_b
3946 	   WHERE name = p_item_group_name AND status_code = 'COMPLETE';
3947 
3948 CURSOR item_id_csr(p_item_number IN VARCHAR2) IS
3949        SELECT inventory_item_id FROM MTL_SYSTEM_ITEMS_KFV
3950        WHERE concatenated_segments = p_item_number;
3951 
3952 CURSOR condition_id_csr(p_condition_meaning IN VARCHAR2) IS
3953        SELECT status_id FROM mtl_material_statuses_vl
3954        WHERE status_code = p_condition_meaning;
3955 
3956 
3957 CURSOR wo_operation_id_csr(p_workorder_id IN NUMBER, p_operation_seq IN NUMBER) IS
3958        SELECT workorder_operation_id from ahl_workorder_operations
3959        WHERE workorder_id = p_workorder_id AND operation_sequence_num = p_operation_seq;
3960 
3961 CURSOR severity_id_csr(p_severity_name IN VARCHAR2) IS
3962        SELECT incident_severity_id from cs_incident_severities_vl
3963 	    WHERE name = p_severity_name
3964               AND incident_subtype = 'INC'
3965 	      AND trunc(sysdate) between trunc(nvl(start_date_active,sysdate))  and  trunc(nvl(end_date_active,sysdate));
3966 
3967 -- AVIKUKUM::PIE::FP::19-OCT-2010
3968 CURSOR service_type_code_csr (c_service_type VARCHAR2) IS
3969     SELECT lookup_code
3970           FROM pa_lookups
3971          WHERE lookup_type    = 'SERVICE TYPE'
3972            AND enabled_flag   = 'Y'
3973            AND meaning        = c_service_type
3974            AND TRUNC(SYSDATE) BETWEEN TRUNC(NVL(start_date_active,SYSDATE-1))
3975                                   AND TRUNC(NVL(end_date_active,SYSDATE));
3976 
3977 
3978 CURSOR problem_code_csr(p_problem_meaning IN VARCHAR2) IS
3979 /*
3980 SELECT fl.lookup_code  FROM fnd_lookup_values_vl FL
3981 	   WHERE fl.meaning = p_problem_meaning
3982 	     AND lookup_type = 'REQUEST_PROBLEM_CODE'
3983          AND trunc(sysdate) BETWEEN trunc(nvl(start_date_active,sysdate)) AND trunc(nvl(end_date_active,sysdate))
3984 		 AND (( NOT EXISTS (SELECT 1 FROM CS_SR_PROB_CODE_MAPPING_V WHERE INCIDENT_TYPE_ID = FND_PROFILE.Value('AHL_PRD_SR_TYPE')
3985 			   AND TRUNC(SYSDATE) BETWEEN TRUNC(NVL(START_DATE_ACTIVE,SYSDATE)) AND TRUNC(NVL(END_DATE_ACTIVE,SYSDATE))) )
3986 					OR ( EXISTS (SELECT 1 FROM CS_SR_PROB_CODE_MAPPING_V MAP WHERE MAP.INCIDENT_TYPE_ID    = FND_PROFILE.Value('AHL_PRD_SR_TYPE')
3987 					            AND MAP.INVENTORY_ITEM_ID IS NULL AND MAP.PROBLEM_CODE = FL.LOOKUP_CODE
3988 							   AND TRUNC(SYSDATE) BETWEEN TRUNC(NVL(MAP.START_DATE_ACTIVE,SYSDATE)) AND TRUNC(NVL(MAP.END_DATE_ACTIVE,SYSDATE)))));
3989 */
3990 --    AnRaj: Changed query, Perf Bug#4908609,Issue#6
3991 SELECT   fl.lookup_code
3992 FROM     fnd_lookup_values_vl FL
3993 WHERE    fl.meaning = p_problem_meaning
3994 AND      lookup_type = 'REQUEST_PROBLEM_CODE'
3995 AND      trunc(sysdate) BETWEEN trunc(nvl(start_date_active,sysdate))
3996 AND      trunc(nvl(end_date_active,sysdate)) ;
3997 
3998 L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'convert_values_to_ids';
3999 l_instance_id NUMBER;
4000 l_item_group_id NUMBER;
4001 BEGIN
4002 
4003   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4004     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin', 'Entering Procedure');
4005   END IF;
4006   --dbms_output.put_line(SubStr('Begin Convert_val_to_id', 1, 255));
4007   IF (p_x_prd_disposition_rec.instance_number IS NOT NULL AND  p_x_prd_disposition_rec.instance_number <> FND_API.G_MISS_CHAR) THEN
4008     OPEN instance_id_csr(p_x_prd_disposition_rec.instance_number);
4009     FETCH instance_id_csr INTO p_x_prd_disposition_rec.instance_id;
4010     IF(instance_id_csr%NOTFOUND) THEN
4011       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_INST_NUM');
4012       FND_MESSAGE.Set_Token('INTANCE_NUM', p_x_prd_disposition_rec.instance_number);
4013       FND_MSG_PUB.ADD;
4014     END IF;
4015     CLOSE instance_id_csr;
4016   ELSIF(p_x_prd_disposition_rec.instance_number = FND_API.G_MISS_CHAR) THEN
4017      p_x_prd_disposition_rec.instance_id := NULL;
4018   END IF;
4019 
4020   IF (p_x_prd_disposition_rec.item_group_name IS NOT NULL AND  p_x_prd_disposition_rec.item_group_name <> FND_API.G_MISS_CHAR) THEN
4021     OPEN item_group_id_csr(p_x_prd_disposition_rec.item_group_name);
4022     FETCH item_group_id_csr INTO p_x_prd_disposition_rec.item_group_id;
4023     IF(item_group_id_csr%NOTFOUND) THEN
4024       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_ITM_GRPNAME');
4025       FND_MESSAGE.Set_Token('ITEM_GROUP', p_x_prd_disposition_rec.item_group_name);
4026       FND_MSG_PUB.ADD;
4027     END IF;
4028     CLOSE item_group_id_csr;
4029     ELSIF(p_x_prd_disposition_rec.item_group_name = FND_API.G_MISS_CHAR) THEN
4030       p_x_prd_disposition_rec.item_group_id := NULL;
4031     END IF;
4032 
4033    IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4034       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Before convert Item Number: ' ||p_x_prd_disposition_rec.item_number);
4035    END IF;
4036    --dbms_output.put_line(SubStr('convert Item Number', 1, 255));
4037   IF (p_x_prd_disposition_rec.item_number IS NOT NULL AND  p_x_prd_disposition_rec.item_number <> FND_API.G_MISS_CHAR) THEN
4038     OPEN item_id_csr(p_x_prd_disposition_rec.item_number);
4039     FETCH item_id_csr INTO p_x_prd_disposition_rec.inventory_item_id;
4040     IF(item_id_csr%NOTFOUND) THEN
4041       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_ITEM_NUM');
4042       FND_MESSAGE.Set_Token('ITEM_NUM', p_x_prd_disposition_rec.item_number);
4043       FND_MSG_PUB.ADD;
4044     END IF;
4045     CLOSE item_id_csr;
4046   ELSIF(p_x_prd_disposition_rec.item_number = FND_API.G_MISS_CHAR) THEN
4047       p_x_prd_disposition_rec.inventory_item_id := NULL;
4048   END IF;
4049 
4050   IF (p_x_prd_disposition_rec.operation_sequence IS NOT NULL AND  p_x_prd_disposition_rec.operation_sequence <> FND_API.G_MISS_NUM) THEN
4051     OPEN wo_operation_id_csr(p_x_prd_disposition_rec.workorder_id, p_x_prd_disposition_rec.operation_sequence);
4052     FETCH wo_operation_id_csr INTO p_x_prd_disposition_rec.wo_operation_id;
4053     IF(wo_operation_id_csr%NOTFOUND) THEN
4054       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_OPER_SEQ');
4055       FND_MESSAGE.Set_Token('OPER_SEQ', p_x_prd_disposition_rec.operation_sequence);
4056       FND_MSG_PUB.ADD;
4057     END IF;
4058     CLOSE wo_operation_id_csr;
4059   ELSIF(p_x_prd_disposition_rec.operation_sequence = FND_API.G_MISS_NUM) THEN
4060       p_x_prd_disposition_rec.wo_operation_id := NULL;
4061   END IF;
4062 
4063   IF (p_x_prd_disposition_rec.condition_meaning IS NOT NULL AND  p_x_prd_disposition_rec.condition_meaning <> FND_API.G_MISS_CHAR) THEN
4064     OPEN condition_id_csr(p_x_prd_disposition_rec.condition_meaning);
4065     FETCH condition_id_csr INTO p_x_prd_disposition_rec.condition_id;
4066     IF(condition_id_csr%NOTFOUND) THEN
4067       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_CONDITION');
4068       FND_MESSAGE.Set_Token('CONDITION', p_x_prd_disposition_rec.condition_meaning);
4069       FND_MSG_PUB.ADD;
4070     END IF;
4071     CLOSE condition_id_csr;
4072   ELSIF(p_x_prd_disposition_rec.condition_meaning = FND_API.G_MISS_CHAR) THEN
4073       p_x_prd_disposition_rec.condition_id := NULL;
4074   END IF;
4075 
4076   IF (p_x_prd_disposition_rec.severity_name IS NOT NULL AND  p_x_prd_disposition_rec.severity_name <> FND_API.G_MISS_CHAR) THEN
4077     OPEN severity_id_csr( p_x_prd_disposition_rec.severity_name);
4078     FETCH severity_id_csr INTO p_x_prd_disposition_rec.severity_id;
4079     IF(severity_id_csr%NOTFOUND) THEN
4080       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_SEVERITY_NAME');
4081       FND_MESSAGE.Set_Token('NAME', p_x_prd_disposition_rec.severity_name);
4082       FND_MSG_PUB.ADD;
4083     END IF;
4084     CLOSE severity_id_csr;
4085   ELSIF(p_x_prd_disposition_rec.severity_name = FND_API.G_MISS_CHAR) THEN
4086       p_x_prd_disposition_rec.severity_id := NULL;
4087   END IF;
4088 
4089   IF (p_x_prd_disposition_rec.problem_meaning IS NOT NULL AND  p_x_prd_disposition_rec.problem_meaning <> FND_API.G_MISS_CHAR) THEN
4090     OPEN problem_code_csr( p_x_prd_disposition_rec.problem_meaning);
4091     FETCH problem_code_csr INTO p_x_prd_disposition_rec.problem_code;
4092     IF(problem_code_csr%NOTFOUND) THEN
4093       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_PROBLEM');
4094       FND_MESSAGE.Set_Token('PROBLEM', p_x_prd_disposition_rec.problem_meaning);
4095       FND_MSG_PUB.ADD;
4096     END IF;
4097     CLOSE problem_code_csr;
4098    ELSIF(p_x_prd_disposition_rec.problem_meaning = FND_API.G_MISS_CHAR) THEN
4099       p_x_prd_disposition_rec.problem_code := NULL;
4100    END IF;
4101 
4102 ---AVIKUKUM::PIE::FP ::19-OCT-2010:: Service Type
4103 --If Service Type is passed then derive the Service Type Code.
4104 -- If Service Type Code does not exists for Service Type, throw error.
4105 
4106   IF (p_x_prd_disposition_rec.service_type IS NOT NULL AND  p_x_prd_disposition_rec.service_type <> FND_API.G_MISS_CHAR) THEN
4107     OPEN service_type_code_csr( p_x_prd_disposition_rec.service_type);
4108     FETCH service_type_code_csr INTO p_x_prd_disposition_rec.service_type_code;
4109     IF(service_type_code_csr%NOTFOUND) THEN
4110       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_SERVICE_TYPE_INVALID');
4111       FND_MSG_PUB.ADD;
4112     END IF;
4113     CLOSE service_type_code_csr;
4114   ELSIF(p_x_prd_disposition_rec.service_type = FND_API.G_MISS_CHAR) THEN
4115       p_x_prd_disposition_rec.service_type_code := NULL;
4116   END IF;
4117 
4118    IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4119      FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end', 'Exiting Procedure');
4120    END IF;
4121 
4122 
4123  --dbms_output.put_line(SubStr('End Convert_val_to_id', 1, 255));
4124 
4125 END convert_values_to_ids;
4126 
4127 
4128 
4129 
4130 
4131 
4132 --------------------------------------------------------------------------------
4133 PROCEDURE validate_collection_id(p_collection_id IN NUMBER) IS
4134   CURSOR val_Collection_id_csr(p_collection_id IN NUMBER) IS
4135        SELECT 'x' FROM qa_results WHERE collection_id = p_collection_id;
4136 
4137 l_exist VARCHAR(1);
4138 
4139 BEGIN
4140   IF p_collection_id IS NOT NULL THEN
4141     OPEN val_collection_id_csr(p_collection_id);
4142     FETCH val_collection_id_csr into l_exist;
4143     IF val_collection_id_csr%NOTFOUND THEN
4144       FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_COLLECTION_ID');    --  Invalid collection Id
4145       FND_MESSAGE.Set_Token('COLL_ID', p_collection_id);
4146       FND_MSG_PUB.ADD;
4147     END IF;
4148   END IF;
4149 END validate_collection_id;
4150 
4151 
4152 --Validate_workorder----------------------------------------------------
4153 PROCEDURE validate_workorder(p_workorder_id IN NUMBER) IS
4154   CURSOR workorder_csr(p_workorder_id IN NUMBER) IS
4155     SELECT 'x' FROM AHL_WORKORDERS
4156     WHERE workorder_id = p_workorder_id;
4157 
4158 l_exist VARCHAR(1);
4159 
4160 BEGIN
4161   OPEN workorder_csr(p_workorder_id);
4162   FETCH workorder_csr INTO l_exist;
4163   IF workorder_csr%NOTFOUND THEN
4164     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_INV_WORKORDER_ID');    --  Invalid Workorder Id
4165     FND_MESSAGE.set_token('WORKORDER_ID', p_workorder_id);
4166     FND_MSG_PUB.ADD;
4167     CLOSE workorder_csr;
4168     RAISE FND_API.G_EXC_ERROR;
4169   ELSE
4170     CLOSE workorder_csr;
4171   END IF;
4172 
4173 END validate_workorder;
4174 
4175 
4176 --Validate_Path_Position---------------------------------------------
4177 PROCEDURE validate_path_position(p_path_position_id IN NUMBER) IS
4178   CURSOR path_position_csr(p_path_position_id IN NUMBER) IS
4179     SELECT 'x' FROM ahl_mc_path_positions
4180     WHERE path_position_id = p_path_position_id;
4181 
4182 l_exist VARCHAR(1);
4183 
4184 BEGIN
4185   OPEN path_position_csr(p_path_position_id);
4186   FETCH path_position_csr INTO l_exist;
4187   IF path_position_csr%NOTFOUND THEN
4188     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_PATH_POSITION');
4189     FND_MESSAGE.SET_TOKEN('PATH_POS_ID', p_path_position_id);
4190     FND_MSG_PUB.ADD;
4191     CLOSE path_position_csr;
4192     RAISE FND_API.G_EXC_ERROR;
4193   ELSE
4194     CLOSE path_position_csr;
4195   END IF;
4196 END validate_path_position;
4197 
4198 --Validate_item---------------------------------------------
4199 PROCEDURE validate_item(p_inventory_item_id IN NUMBER, p_organization_id IN NUMBER, p_workorder_id IN NUMBER) IS
4200 
4201   CURSOR get_wo_organization_csr(p_workorder_id NUMBER) IS
4202       SELECT vi.organization_id from  ahl_workorders wo, ahl_visits_b vi
4203        WHERE wo.workorder_id = p_workorder_id
4204 	     AND wo.visit_id = vi.visit_id;
4205 
4206   CURSOR val_item_csr(p_item_id NUMBER, p_organization_id NUMBER) IS
4207     SELECT 'x' FROM mtl_system_items_kfv
4208 	WHERE inventory_item_id = p_inventory_item_id
4209 	  AND organization_id = p_organization_id;
4210 
4211 
4212 l_exist VARCHAR(1);
4213 l_wo_organization_id NUMBER;
4214 
4215 BEGIN
4216 
4217 
4218   OPEN val_item_csr(p_inventory_item_id, p_organization_id);
4219   FETCH val_item_csr INTO l_exist;
4220   IF val_item_csr%NOTFOUND THEN
4221     CLOSE val_item_csr;   --Close cursor before raising exception
4222     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_ITEM_ID');
4223 	FND_MESSAGE.SET_TOKEN('ITEM_ID', p_inventory_item_id);
4224 	FND_MSG_PUB.ADD;
4225 	RAISE FND_API.G_EXC_ERROR;
4226   END IF;
4227   CLOSE val_item_csr;
4228 
4229 
4230   OPEN get_wo_organization_csr(p_workorder_id);
4231   FETCH get_wo_organization_csr INTO l_wo_organization_id;
4232   CLOSE get_wo_organization_csr;
4233 
4234   IF l_wo_organization_id <> p_organization_id THEN
4235     -- need to check whether if item is defined in workorder organization
4236     OPEN val_item_csr(p_inventory_item_id, l_wo_organization_id);
4237     FETCH val_item_csr INTO l_exist;
4238     IF val_item_csr%NOTFOUND THEN
4239       CLOSE val_item_csr;  --close cursor before raise an exception
4240       FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_ITEM_NOT_IN_WO_ORG');   --Item is not defined in workorder's organization
4241 	  FND_MESSAGE.SET_TOKEN('ITEM_ID', p_inventory_item_id);
4242 	  FND_MSG_PUB.ADD;
4243 	  RAISE FND_API.G_EXC_ERROR;
4244     END IF;
4245     CLOSE val_item_csr;
4246   END IF;
4247 
4248 END validate_item;
4249 
4250 --validate_Item_Control--------------------------------------
4251 --Check if items is serial control then require serial_number
4252 -- if item is lot control then requires lot_number
4253 -- if item is quantity revision control then requires revision number
4254 PROCEDURE validate_Item_Control(p_item_id IN NUMBER, p_org_id IN NUMBER,
4255                                           p_serial_number IN VARCHAR2,
4256                                           p_item_rev_number IN VARCHAR2,
4257 										  p_lot_number IN VARCHAR2) IS
4258 
4259 
4260 CURSOR item_control_csr(p_item_id IN NUMBER, p_org_id IN NUMBER) IS
4261   SELECT serial_number_control_code, revision_qty_control_code,  lot_control_code
4262   FROM MTL_SYSTEM_ITEMS_KFV
4263   WHERE inventory_item_id = p_item_id
4264   AND organization_id = p_org_id;
4265 
4266 l_item_crl_rec item_control_csr%ROWTYPE;
4267 l_serial_flag  VARCHAR2(1);
4268 l_rev_qty_flag VARCHAR2(1);
4269 l_lot_flag VARCHAR2(1);
4270 
4271 BEGIN
4272 
4273   OPEN item_control_csr(p_item_id, p_org_id);
4274   FETCH item_control_csr INTO l_item_crl_rec;
4275   IF item_control_csr%FOUND THEN
4276     IF l_item_crl_rec.lot_control_code = 2 THEN
4277       l_lot_flag:='Y';
4278     ELSE
4279       l_lot_flag:='N';
4280     END IF;
4281 
4282 	IF l_item_crl_rec.revision_qty_control_code = 2 THEN
4283       l_rev_qty_flag:='Y';
4284     ELSE
4285       l_rev_qty_flag:='N';
4286     END IF;
4287 
4288     IF l_item_crl_rec.serial_number_control_code = 1 THEN
4289       l_serial_flag:='N';
4290     ELSE
4291       l_serial_flag:='Y';
4292     END IF;
4293   END IF;
4294   CLOSE item_control_csr;
4295 
4296   IF l_serial_flag = 'Y' AND p_serial_number IS NULL THEN
4297     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_SERIAL_REQ');    --Serial Number is required
4298     FND_MSG_PUB.ADD;
4299   END IF;
4300 
4301   IF l_rev_qty_flag = 'Y' AND p_item_rev_number IS NULL THEN
4302     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_ITEM_REV_REQ');    --Item Revision Number is required
4303     FND_MSG_PUB.ADD;
4304   END IF;
4305 
4306   IF l_lot_flag = 'Y' AND p_lot_number IS NULL THEN
4307     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_LOT_NUM_REQ');    --Lot Number is required
4308     FND_MSG_PUB.ADD;
4309   END IF;
4310 
4311 END validate_Item_Control;
4312 
4313 
4314 
4315 
4316 --Validate Instance------------------------------------------------------------
4317 
4318 PROCEDURE validate_instance(p_instance_id IN NUMBER, p_workorder_id IN NUMBER, p_path_position_id IN NUMBER, p_part_change_id IN NUMBER) IS
4319 
4320   CURSOR instance_csr(p_instance_id IN NUMBER) IS
4321     SELECT 'x' from csi_item_instances
4322     where instance_id = p_instance_id;
4323 
4324   CURSOR instance_in_wip_csr(p_instance_id IN NUMBER, p_workorder_id IN NUMBER) IS
4325     SELECT 'x' from csi_item_instances csi, ahl_workorders wo
4326      WHERE instance_id = p_instance_id
4327        and wo.wip_entity_id = csi.wip_job_id
4328        and csi.location_type_code NOT IN ('PO','IN-TRANSIT','PROJECT','INVENTORY')
4329        and trunc(sysdate) between trunc(nvl(csi.active_start_date, sysdate)) and trunc(nvl(csi.active_end_date, sysdate));
4330 
4331   CURSOR instance_in_disp_csr(p_instance_id IN NUMBER, p_workorder_id IN NUMBER) IS
4332      SELECT 'x' from ahl_prd_dispositions_b WHERE
4333        workorder_id = p_workorder_id
4334        and instance_id = p_instance_id
4335        and nvl(status_code, ' ') NOT IN ('COMPLETE', 'TERMINATED');
4336 
4337 --Begin Performance Tuning
4338 CURSOR get_wo_instance_id(p_workorder_id IN NUMBER) IS
4339      SELECT nvl(VTS.INSTANCE_ID,VST.ITEM_INSTANCE_ID)
4340        FROM ahl_workorders wo, AHL_VISITS_VL VST, AHL_VISIT_TASKS_VL VTS
4341        WHERE workorder_id = p_workorder_id
4342          and  WO.VISIT_TASK_ID=VTS.VISIT_TASK_ID
4343          AND VST.VISIT_ID=VTS.VISIT_ID;
4344 --End Performance Tuning
4345 
4346 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
4347 -- Cursor to check whether the disposition item is serialized or not.
4348 CURSOR chk_non_serialized_csr(p_instance_id NUMBER) IS
4349      SELECT 'X'
4350      FROM   mtl_system_items_b mtl, csi_item_instances csi
4351      WHERE  csi.instance_id                                              = p_instance_id
4352      AND    csi.inventory_item_id                                        = mtl.inventory_item_id
4353      AND    NVL(csi.inv_organization_id, csi.inv_master_organization_id) = mtl.organization_id
4354      AND    mtl.serial_number_control_code                               = 1;
4355 
4356 l_wo_instance_id NUMBER;
4357 l_wo_root_instance_id NUMBER;        --Root Instance of workorder instance
4358 l_dis_root_instance_id NUMBER;      --Root Instance of disposition instance.
4359 l_exist VARCHAR(1);
4360 L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'validate_instance' ;
4361 
4362 -- Added by jaramana on August 7, 2007 to support IB Trees
4363 l_unit_config_id   NUMBER;
4364 l_unit_config_name ahl_unit_config_headers.name%TYPE;
4365 l_return_status    VARCHAR2(1);
4366 l_dummy            VARCHAR2(1);
4367 
4368 BEGIN
4369 
4370   OPEN instance_csr(p_instance_id);
4371   FETCH instance_csr INTO l_exist;
4372   IF instance_csr%NOTFOUND THEN
4373     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_INSTANT_ID');
4374     FND_MESSAGE.SET_TOKEN('INSTANT_ID', p_instance_id);
4375     FND_MSG_PUB.ADD;
4376   END IF;
4377   CLOSE instance_csr;
4378 
4379   -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
4380   -- Multiple dispositions for the same instance/position are allowed for non-serialized items.
4381   OPEN chk_non_serialized_csr(p_instance_id);
4382   FETCH chk_non_serialized_csr INTO l_dummy;
4383   IF (chk_non_serialized_csr%NOTFOUND) THEN
4384     OPEN instance_in_disp_csr(p_instance_id, p_workorder_id);
4385     FETCH instance_in_disp_csr INTO l_exist;
4386     IF instance_in_disp_csr%FOUND THEN
4387       -- Added by jaramana on August 7, 2007 to support IB Trees
4388       -- Allow duplicate instances for IB Trees when created from Part Change
4389       AHL_PRD_PARTS_CHANGE_PVT.Get_Unit_Config_Information(p_item_instance_id => NULL,
4390                                                            p_workorder_id     => p_workorder_id,
4391                                                            x_unit_config_id   => l_unit_config_id,
4392                                                            x_unit_config_name => l_unit_config_name,
4393                                                            x_return_status    => l_return_status);
4394       IF (l_unit_config_name IS NULL AND p_part_change_id IS NOT NULL) THEN
4395         -- IB Tree, Disposition created from Part Change UI: Allow duplicates
4396         NULL;
4397       ELSE
4398         FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_INST_IN_DISP');    --Instance already exist in another not-completed or not-terminated disposition.
4399         FND_MSG_PUB.ADD;
4400       END IF;
4401       -- End changes by jaramana on August 7, 2007 to support IB Trees
4402     END IF;
4403     CLOSE instance_in_disp_csr;
4404   END IF;
4405   CLOSE chk_non_serialized_csr;
4406 
4407   IF p_path_position_id IS NOT NULL THEN
4408     IF p_part_change_id IS NOT NULL THEN
4409       -- Called from Part Change UI
4410       -- Part Change (Removal or Swap) has already occurred
4411       -- Cannot verify if the disposition instance is in the same unit as the workorder
4412       -- since the disposition instance has already been removed
4413       NULL;
4414     ELSE
4415       --path position exists then need to check if the instance is in the same tree as workorder instance
4416       --Get Workorder Instance Id
4417       OPEN get_wo_instance_id(p_workorder_id);
4418       FETCH get_wo_instance_id INTO l_wo_instance_id;
4419       CLOSE get_wo_instance_id;
4420 
4421       IF l_wo_instance_id <> p_instance_id THEN
4422         --get root instance for workorder instance
4423         l_wo_root_instance_id := get_root_instance_id(l_wo_instance_id);
4424 
4425         --get root instance for disposition instance
4426         l_dis_root_instance_id := get_root_instance_id(p_instance_id);
4427 
4428         IF nvl(l_wo_root_instance_id, -1) <> nvl(l_dis_root_instance_id, -1) THEN
4429           --dbms_output.put_line(' before throw the error root instance are not the same');
4430           IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4431             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'l_wo_instance_id:' || l_wo_instance_id);
4432             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'l_wo_root_instance_id:' || l_wo_root_instance_id);
4433             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'l_dis_root_instance_id:' || l_dis_root_instance_id);
4434           END IF;
4435           FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_INST_IN_UC');   -- Instance is not in the same unit as workorder instance
4436           FND_MSG_PUB.ADD;
4437           RAISE FND_API.G_EXC_ERROR;
4438         END IF;  -- Root Instances are not the same
4439       END IF;  -- l_wo_instance_id <> p_instance_id
4440     END IF;  -- p_part_change_id is null
4441   ELSE    --then it is a stand alone instance need to check if instance is issued to the job
4442     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4443       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'Stand alone instance');
4444     END IF;
4445     -- Following lines commented out by jaramana on August 8, 2007
4446     -- In the case of IB Tree, it does not make sense to force the instance to be in the job.
4447     -- The instance may be currently installed on the IB Tree and creation of Disposition should be
4448     -- be allowed for it (1. From Part Change, the Installation Disposition is created after
4449     -- the instance is installed on the IB Tree. 2. While creating a disposition for removing,
4450     -- the instance is still on the IB Tree which may not have been issued to the job)
4451     /***
4452     OPEN instance_in_wip_csr(p_instance_id, p_workorder_id);
4453     FETCH instance_in_wip_csr INTO l_exist;
4454     IF instance_in_wip_csr%NOTFOUND THEN
4455       CLOSE instance_in_wip_csr;
4456       FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INST_NOT_ISSUED');   -- Instance is not issued to the job
4457       FND_MSG_PUB.ADD;
4458       RAISE FND_API.G_EXC_ERROR;
4459     END IF;
4460     CLOSE instance_in_wip_csr;
4461     ***/
4462   END IF;
4463 
4464   --dbms_output.put_line(SubStr('end validate_instance ', 1, 255));
4465 END validate_instance;
4466 
4467 -----validate workorder operation--------------------------------------
4468 
4469 PROCEDURE validate_wo_operation(p_workorder_id IN NUMBER, p_wo_operation_id IN NUMBER) IS
4470 
4471 CURSOR val_wo_operation_csr(p_workorder_id IN NUMBER, p_wo_operation_id IN NUMBER) IS
4472        SELECT 'x' FROM ahl_workorder_operations
4473        WHERE workorder_operation_id = p_wo_operation_id
4474          AND workorder_id = p_workorder_id;
4475 
4476 l_exist VARCHAR(1);
4477 
4478 BEGIN
4479   OPEN val_wo_operation_csr(p_workorder_id, p_wo_operation_id);
4480   FETCH val_wo_operation_csr INTO l_exist;
4481   IF val_wo_operation_csr%NOTFOUND THEN
4482     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_INV_OPERATION');    --Invalid operation id.
4483     FND_MESSAGE.SET_TOKEN('OPER_ID', p_wo_operation_id);
4484     FND_MSG_PUB.ADD;
4485   END IF;
4486   CLOSE val_wo_operation_csr;
4487 
4488 END validate_wo_operation;
4489 
4490 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
4491 -- Modified the API to accept the instance quantity, and modified the validations to accommodate: -
4492 -- 1) non-serialized items
4493 -- 2) disposition for empty positions
4494 PROCEDURE validate_part_change(p_part_change_id IN NUMBER, p_disp_instance_id IN NUMBER, p_disp_quantity IN NUMBER) IS
4495 
4496   -- Begin Changes made by jaramana on August 07, 2007 for the bug 6328554 (FP of 5948917)
4497   CURSOR part_change_csr IS
4498     SELECT removed_instance_id, installed_instance_id, NVL(part_change_type, 'X'), quantity
4499     FROM ahl_part_changes
4500     WHERE part_change_id = p_part_change_id;
4501 
4502   -- Cursor to get the disposition instance details.
4503   CURSOR get_inst_dtls_csr(c_instance_id IN NUMBER) IS
4504     SELECT SERIAL_NUMBER, INVENTORY_ITEM_ID, QUANTITY
4505     FROM CSI_ITEM_INSTANCES
4506     WHERE INSTANCE_ID = c_instance_id;
4507 
4508   l_removed_instance_id   NUMBER;
4509   l_installed_instance_id NUMBER;
4510   l_part_change_type      VARCHAR2(1);
4511   l_disp_inst_dtls        get_inst_dtls_csr%ROWTYPE;
4512   l_rem_inst_dtls         get_inst_dtls_csr%ROWTYPE;
4513   l_part_change_quantity  NUMBER;
4514   L_DEBUG_KEY             CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'validate_part_change';
4515 
4516 BEGIN
4517   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4518     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
4519                    L_DEBUG_KEY || '.begin ',
4520                    'At the start of the procedure.' ||
4521                    ' ,p_part_change_id  = ' || p_part_change_id ||
4522                    ' ,p_disp_instance_id = ' || p_disp_instance_id ||
4523                    ' ,p_disp_quantity = ' || p_disp_quantity );
4524   END IF;
4525 
4526   -- If the disposition is not for an empty position, then get the disposition instance details.
4527   IF p_disp_instance_id IS NOT NULL THEN
4528     OPEN get_inst_dtls_csr(p_disp_instance_id);
4529     FETCH get_inst_dtls_csr INTO l_disp_inst_dtls;
4530     CLOSE get_inst_dtls_csr;
4531   END IF;
4532 
4533   OPEN part_change_csr;
4534   FETCH part_change_csr INTO l_removed_instance_id, l_installed_instance_id, l_part_change_type, l_part_change_quantity;
4535   IF part_change_csr%NOTFOUND THEN
4536     FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_INV_PART_CHG_ID');    -- Invalid part change id
4537     FND_MESSAGE.SET_TOKEN('PART_CHNG_ID', p_part_change_id);
4538     FND_MSG_PUB.ADD;
4539   ELSIF (l_part_change_type IN ('R', 'S')) THEN  -- Remove or Swap
4540     -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
4541     -- Compare instances only if it is serialized.
4542     IF (l_disp_inst_dtls.SERIAL_NUMBER IS NOT NULL) THEN
4543       IF (NVL(p_disp_instance_id, -1) <> nvl(l_removed_instance_id, -1)) THEN
4544         FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_INV_REMOVE_INST');   -- Removed instance in part change is not the same as disposition instance
4545         FND_MESSAGE.SET_TOKEN('REMOVED_INST', l_removed_instance_id);
4546         FND_MESSAGE.SET_TOKEN('DISP_INST', p_disp_instance_id);
4547         FND_MSG_PUB.ADD;
4548       END IF;
4549     ELSE
4550       -- Non-serialized: Removed instance can be different from the Disposition Instance.
4551       -- Compare only item and quantity.
4552       IF (NVL(p_disp_instance_id, -1) <> nvl(l_removed_instance_id, -1)) THEN
4553         -- Get the removed instance details.
4554         OPEN get_inst_dtls_csr(l_removed_instance_id);
4555         FETCH get_inst_dtls_csr INTO l_rem_inst_dtls;
4556         CLOSE get_inst_dtls_csr;
4557 
4558         IF (l_disp_inst_dtls.inventory_item_id <> l_rem_inst_dtls.inventory_item_id OR
4559             nvl(p_disp_quantity,l_part_change_quantity) <> l_part_change_quantity) THEN
4560           IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4561             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'validate part change non serial item' ||
4562                            ', l_disp_inst_dtls.inventory_item_i ' || l_disp_inst_dtls.inventory_item_id ||
4563                            ', l_rem_inst_dtls.inventory_item_id ' || l_rem_inst_dtls.inventory_item_id  ||
4564                            ', p_disp_instance_id ' || p_disp_instance_id ||
4565                            ', p_removed_instance_id ' || l_removed_instance_id ||
4566                            ', p_disp_quantity ' || p_disp_quantity ||
4567                            ', l_part_change_quantity ' || l_part_change_quantity);
4568           END IF;
4569 
4570           -- The Message AHL_PRD_DIS_INV_REMOVE_INST is not accurate in this case, but is probably ok
4571           FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_INV_REMOVE_INST');   -- Removed instance in part change is not the same as disposition instance
4572           FND_MESSAGE.SET_TOKEN('REMOVED_INST', l_removed_instance_id);
4573           FND_MESSAGE.SET_TOKEN('DISP_INST', p_disp_instance_id);
4574           FND_MSG_PUB.ADD;
4575         END IF;  -- Item and Quantity Mismatch
4576       END IF;  -- Instances are different
4577     END IF;  -- Disp Instance's Serial Number is null or not
4578   ELSE
4579     -- Changed since the disposition instance will always
4580     -- (even after installation) be null for a disposition created against an empty position
4581     -- IF (NVL(p_disp_instance_id, nvl(l_installed_instance_id, -1)) <> nvl(l_installed_instance_id, -1)) THEN
4582     IF p_disp_instance_id IS NOT NULL AND l_installed_instance_id IS NOT NULL AND p_disp_instance_id <> l_installed_instance_id THEN
4583       FND_MESSAGE.SET_NAME(G_APP_NAME, 'AHL_PRD_DIS_INV_INSTALL_INST');   -- Installed instance in part change is not the same as disposition instance
4584       FND_MESSAGE.SET_TOKEN('INSTALLED_INST', l_installed_instance_id);
4585       FND_MESSAGE.SET_TOKEN('DISP_INST', p_disp_instance_id);
4586       FND_MSG_PUB.ADD;
4587     END IF;  -- Disposition Instance is not the same as the Installation Instance
4588   END IF;  -- Part Change Found, and Part Change Type Check
4589   CLOSE part_change_csr;
4590   -- End Changes made by jaramana on August 07, 2007 for the bug 6328554 (FP of 5948917)
4591 
4592   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4593       FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
4594                      L_DEBUG_KEY || '.end',
4595                      'At the end of the procedure ' );
4596   END IF;
4597 END validate_part_change;
4598 
4599 ------------------------------------------------------------------
4600 -- Start of Comments --
4601 --  Procedure name    : Calculate_Status
4602 --  Type        : Private
4603 --  Function    : Derives the status of the disposition
4604 --  Pre-reqs    :
4605 --  Parameters  :
4606 --
4607 --  Calculate_Status Parameters:
4608 --       p_disp_rec    IN  the final disposition record
4609 --	 x_status_code OUT NOCOPY the output of the disposition record
4610 --
4611 --  End of Comments.
4612 PROCEDURE Calculate_Status (
4613     p_disposition_Rec     IN  AHL_PRD_DISPOSITION_PVT.disposition_rec_type,
4614     x_status_code         OUT  NOCOPY   VARCHAR2)
4615 IS
4616 --
4617 CURSOR get_disposition_csr (p_disposition_id IN NUMBER) IS
4618 /*
4619 SELECT disp.status_code, disp.trackable_flag,
4620 pc.return_mtl_txn_id mtl_txn_id,
4621 pc.installed_part_change_id install_pc_id,
4622 AHL_PRD_DISP_MTL_TXN_PVT.calculate_txned_qty(disp.disposition_id) mtl_txn_qty
4623 FROM AHL_PRD_DISPOSITIONS_V disp, AHL_PART_CHANGES_V pc
4624 WHERE disp.disposition_id = p_disposition_id
4625 AND disp.part_change_id = pc.part_change_id (+);
4626 */
4627 -- AnRaj: Changed query, Perf Bug#4908609,Issue#5
4628 SELECT   disp.status_code,
4629          decode(disp.instance_id, null, decode(disp.path_position_id, null, 'N', 'Y'), 'Y') trackable_flag ,
4630          pc.return_mtl_txn_id mtl_txn_id,
4631          pc.installed_part_change_id install_pc_id,
4632          pc.part_change_type,
4633          AHL_PRD_DISP_MTL_TXN_PVT.calculate_txned_qty(disp.disposition_id) mtl_txn_qty
4634 FROM     AHL_PRD_DISPOSITIONS_B disp,
4635          AHL_PART_CHANGES_V pc
4636 WHERE    disp.disposition_id = p_disposition_id
4637 AND      disp.part_change_id = pc.part_change_id (+);
4638 
4639 --
4640 CURSOR get_trackable_csr (p_inv_item_id IN NUMBER,
4641                           p_inv_org_id IN NUMBER) IS
4642 SELECT NVL(MTL.comms_nl_trackable_flag, 'N')  trackable_flag
4643 FROM   MTL_SYSTEM_ITEMS_KFV MTL
4644 WHERE MTL.INVENTORY_ITEM_ID= p_inv_item_id
4645   AND MTL.organization_id =p_inv_org_id;
4646 --
4647 CURSOR get_part_change_type_csr (p_part_change_id IN NUMBER) IS
4648 SELECT part_change_type
4649   FROM AHL_PART_CHANGES
4650  WHERE part_change_id = p_part_change_id;
4651 --
4652 CURSOR get_pos_mandatory_csr(p_instance_id IN NUMBER) IS
4653 SELECT rel.position_necessity_code
4654 FROM AHL_MC_RELATIONSHIPS rel, CSI_II_RELATIONSHIPS CSI
4655 WHERE csi.subject_id = p_instance_id
4656     AND rel.relationship_id = TO_NUMBER(CSI.position_reference)
4657     AND CSI.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
4658     AND TRUNC(nvl(CSI.ACTIVE_START_DATE, sysdate-1)) < TRUNC(sysdate)
4659     AND TRUNC(nvl(CSI.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate);
4660 
4661 --For fixing bug 4085156, added by Jerry on 12/27/2004
4662 CURSOR get_pos_mandatory(c_path_position_id NUMBER) IS
4663 SELECT B.position_necessity_code
4664 FROM ahl_mc_path_position_nodes A,
4665      ahl_mc_relationships B,
4666      ahl_mc_headers_b C
4667 WHERE A.path_position_id = c_path_position_id
4668   and A.sequence = (select max(D.sequence)
4669                      from ahl_mc_path_position_nodes D
4670                     group by D.path_position_id
4671                     having D.path_position_id = c_path_position_id)
4672   and A.mc_id = C.mc_id
4673   and A.version_number = C.version_number
4674   and C.mc_header_id = B.mc_header_id
4675   and A.position_key = B.position_key;
4676 
4677 --
4678 l_disp_dtl_rec  get_disposition_csr%ROWTYPE;
4679 l_pos_mand_flag   VARCHAR2(30);
4680 L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'Calculate_Status';
4681 
4682 --
4683 BEGIN
4684 
4685   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4686     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
4687                    L_DEBUG_KEY || '.begin',
4688                    'At the start of the procedure. p_disposition_rec.disposition_id = ' || p_disposition_rec.disposition_id);
4689   END IF;
4690 
4691   --Fetch existing parameters.
4692   IF (p_disposition_rec.disposition_id IS NOT NULL) THEN
4693     OPEN get_disposition_csr(p_disposition_rec.disposition_id);
4694     FETCH get_disposition_csr into l_disp_dtl_rec;
4695     CLOSE get_disposition_csr;
4696   ELSE
4697      OPEN get_trackable_csr (p_disposition_rec.inventory_item_id,
4698                              p_disposition_rec.item_org_id);
4699      FETCH get_trackable_csr into l_disp_dtl_rec.trackable_flag;
4700      CLOSE get_trackable_csr;
4701   END IF;
4702 
4703   -- Added by jaramana on August 7, 2007
4704   IF (l_disp_dtl_rec.part_change_type IS NULL AND p_disposition_rec.part_change_id IS NOT NULL) THEN
4705     OPEN get_part_change_type_csr(p_disposition_rec.part_change_id);
4706     FETCH get_part_change_type_csr INTO l_disp_dtl_rec.part_change_type;
4707     CLOSE get_part_change_type_csr;
4708   END IF;
4709 
4710   --determine if instance position is mandatory.
4711   IF (p_disposition_rec.instance_id IS NOT NULL) THEN
4712     OPEN get_pos_mandatory_csr (p_disposition_rec.instance_id);
4713     FETCH get_pos_mandatory_csr INTO l_pos_mand_flag;
4714     CLOSE get_pos_mandatory_csr;
4715   --For fixing bug 4085156, this ELSIF section was added by Jerry on 12/27/2004
4716   ELSIF (p_disposition_rec.path_position_id IS NOT NULL) THEN
4717     OPEN get_pos_mandatory(p_disposition_rec.path_position_id);
4718     FETCH get_pos_mandatory INTO l_pos_mand_flag;
4719     CLOSE get_pos_mandatory;
4720   END IF;
4721 
4722   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4723     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'p_disposition_rec.immediate_disposition_code = ' || p_disposition_rec.immediate_disposition_code ||
4724                    ', p_disposition_rec.instance_id = ' || p_disposition_rec.instance_id ||
4725                    ', p_disposition_rec.part_change_id = ' || p_disposition_rec.part_change_id ||
4726                    ', l_disp_dtl_rec.part_change_type = ' || l_disp_dtl_rec.part_change_type ||
4727                    ', l_disp_dtl_rec.trackable_flag = ' || l_disp_dtl_rec.trackable_flag);
4728   END IF;
4729 
4730   ----dbms_output.put_line( l_disp_dtl_rec.trackable_flag);
4731   --dbms_output.put_line( p_disposition_rec.quantity||'<>'||l_disp_dtl_rec.mtl_txn_qty);
4732 
4733   --If terminated, can not change status.
4734   IF (p_disposition_rec.status_code = 'TERMINATED'
4735      OR l_disp_dtl_rec.status_code = 'TERMINATED') THEN
4736       x_status_code := 'TERMINATED';
4737 
4738   --secondary disposition required
4739   ELSIF ((p_disposition_rec.immediate_disposition_code = 'BFS' OR
4740           p_disposition_rec.immediate_disposition_code = 'NON_CONF') AND
4741           p_disposition_rec.secondary_disposition_code IS NULL) THEN
4742        x_status_code := 'SECONDARY_REQD';
4743 
4744   --Added by Jerry Li on 01/18/2005 for fixing bug 4095487 issue 1.
4745   ELSIF (p_disposition_rec.immediate_disposition_code IN ('NA','NOT_RECEIVED','NOT_REMOVED')
4746           AND p_disposition_rec.path_position_id IS NOT NULL
4747           AND l_disp_dtl_rec.trackable_flag = 'Y'
4748           AND p_disposition_rec.instance_id IS NOT NULL) THEN
4749         x_status_code := NULL;
4750 
4751   -- Added by jaramana on August 7, 2007 to set the Dispositions created only for
4752   -- the sake of installation to status COMPLETE as soon as the installation is done.
4753   ELSIF (p_disposition_rec.immediate_disposition_code NOT IN ('NA','NOT_REMOVED')
4754           -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 13-Dec-2007
4755           -- Check for path_position_id as well, so as to cater to disposition for empty position.
4756           AND (p_disposition_rec.instance_id IS NOT NULL OR p_disposition_rec.path_position_id IS NOT NULL)
4757           AND p_disposition_rec.part_change_id IS NOT NULL
4758           AND NVL(l_disp_dtl_rec.part_change_type, 'X') = 'I') THEN
4759         x_status_code := 'COMPLETE';
4760 
4761   ----Added by Jerry Li on 01/18/2005 for fixing bug 4095487 issue 2a.
4762   ELSIF (p_disposition_rec.immediate_disposition_code = 'NOT_RECEIVED'
4763          AND p_disposition_rec.path_position_id IS NULL
4764          AND l_disp_dtl_rec.trackable_flag <> 'Y'
4765          AND p_disposition_rec.quantity > NVL(l_disp_dtl_rec.mtl_txn_qty, 0)) THEN
4766         x_status_code := NULL;
4767 
4768   --Part Removal required, if path position is given and no part change has occurred
4769   ELSIF (p_disposition_rec.immediate_disposition_code NOT IN ('NA','NOT_RECEIVED','NOT_REMOVED')
4770           AND NVL(p_disposition_rec.secondary_disposition_code, 'NULL') <> 'REWORK_NR'
4771           AND p_disposition_rec.path_position_id IS NOT NULL
4772           AND p_disposition_rec.instance_id IS NOT NULL
4773           AND p_disposition_rec.part_change_id IS NULL) THEN
4774         x_status_code := 'PART_CHANGE_REQD';
4775 
4776   -- Non-conformance request required. When tracked instance is in non-serviceable condition
4777   ELSIF (p_disposition_rec.immediate_disposition_code NOT IN ('NA','NOT_RECEIVED','NOT_REMOVED')
4778          AND l_disp_dtl_rec.trackable_flag = 'Y'
4779          AND (p_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE')
4780             OR p_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'))
4781          AND p_disposition_rec.primary_service_request_id IS NULL) THEN
4782       x_status_code := 'NON_CONF_REQD';
4783 
4784   --Mtl_txn required
4785  ELSIF (p_disposition_rec.immediate_disposition_code NOT IN ('NA','NOT_REMOVED')
4786         AND nvl(p_disposition_rec.secondary_disposition_code,'NULL') <> 'HOLD'
4787         AND (( l_disp_dtl_rec.trackable_flag = 'Y'
4788               AND p_disposition_rec.part_change_id IS NOT NULL
4789               AND l_disp_dtl_rec.mtl_txn_id IS NULL)
4790            OR (l_disp_dtl_rec.trackable_flag = 'Y'
4791               AND p_disposition_rec.part_change_id IS NULL
4792               AND p_disposition_rec.quantity > NVL(l_disp_dtl_rec.mtl_txn_qty, 0))
4793            OR (l_disp_dtl_rec.trackable_flag <> 'Y'
4794                AND p_disposition_rec.quantity > NVL(l_disp_dtl_rec.mtl_txn_qty, 0)))) THEN
4795           x_status_code := 'MTL_TXN_REQD';
4796 
4797  --Removal Complete
4798  ELSIF (p_disposition_rec.immediate_disposition_code NOT IN ('NA','NOT_RECEIVED','NOT_REMOVED')
4799         AND l_disp_dtl_rec.trackable_flag = 'Y'
4800         AND p_disposition_rec.path_position_id IS NOT NULL
4801         AND p_disposition_rec.part_change_id IS NOT NULL
4802         AND l_disp_dtl_rec.install_pc_id IS NULL) THEN
4803          x_status_code := 'REMOVAL_COMP';
4804  --QA collection ID
4805  ELSIF (p_disposition_rec.immediate_disposition_code NOT IN ('NA','NOT_RECEIVED','NOT_REMOVED')
4806          AND p_disposition_rec.instance_id IS NOT NULL
4807          AND p_disposition_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')
4808          AND p_disposition_rec.collection_id IS NULL)THEN
4809         x_status_code := 'PENDING_MRB';
4810 
4811   --Install required
4812   ELSIF  (--p_disposition_rec.instance_id IS NOT NULL and
4813           --For fixing bug 4085156, the above condition was removed by Jerry on 12/27/2004
4814           p_disposition_rec.path_position_id IS NOT NULL and
4815           l_pos_mand_flag = 'MANDATORY' AND
4816           l_disp_dtl_rec.install_pc_id IS NULL) THEN
4817           x_status_code := 'INSTALL_REQD';
4818 
4819   --Complete status
4820   ELSIF (p_disposition_rec.immediate_disposition_code IN ('NA','NOT_REMOVED') OR
4821          (l_disp_dtl_rec.trackable_flag ='Y'--tracked
4822          AND ( p_disposition_rec.path_position_id IS NOT NULL    --part change
4823            AND l_disp_dtl_rec.install_pc_id IS NOT NULL
4824            AND (l_disp_dtl_rec.mtl_txn_id IS NOT NULL
4825              OR p_disposition_rec.secondary_disposition_code = 'HOLD')
4826             OR (p_disposition_rec.path_position_id IS NULL          --no part change
4827              AND NVL(l_disp_dtl_rec.mtl_txn_qty, 0) >= p_disposition_rec.quantity)))
4828           OR (l_disp_dtl_rec.trackable_flag <>'Y' -- non-tracked
4829            AND NVL(l_disp_dtl_rec.mtl_txn_qty, 0) >= p_disposition_rec.quantity
4830 		   AND get_issued_quantity(p_disposition_rec.disposition_id) >= p_disposition_rec.quantity   --add to fix bug 4077106
4831 		)) THEN
4832          x_status_code := 'COMPLETE';
4833 
4834   ELSE
4835         x_status_code := null;
4836   END IF;
4837 
4838   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
4839     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
4840                    L_DEBUG_KEY || '.end',
4841                    'At the end of the procedure, x_status_code = ' || x_status_code);
4842   END IF;
4843 
4844 END Calculate_Status;
4845 
4846 
4847 ------------------------------------------------------------------
4848 --  Function name    : Validate_Disposition_Types
4849 --  Type        : Private
4850 --  Function    : Validate the disposition type of the disposition record
4851 --  Pre-reqs    :
4852 --  Parameters  :
4853 --
4854 --  Validate_Disposition_Types parameters:
4855 --       p_disp_rec    IN  the final disposition record
4856 --  End of Comments.
4857 
4858 PROCEDURE Validate_Disposition_Types (
4859     x_return_status       OUT  NOCOPY    VARCHAR2,
4860     x_msg_count           OUT  NOCOPY    NUMBER,
4861     x_msg_data            OUT  NOCOPY    VARCHAR2,
4862     p_disposition_rec     IN  AHL_PRD_DISPOSITION_PVT.disposition_rec_type)
4863 IS
4864 --
4865 --
4866 CURSOR check_immed_disp_types_csr (p_disp_code IN VARCHAR2)IS
4867 SELECT 'X'
4868 FROM fnd_lookups
4869 WHERE  lookup_type = 'AHL_IMMED_DISP_TYPE'
4870 AND lookup_code = p_disp_code
4871 AND lookup_code <> 'NULL';
4872 --
4873 CURSOR check_second_disp_types_csr (p_disp_code IN VARCHAR2)IS
4874 SELECT 'X'
4875 FROM fnd_lookups
4876 WHERE  lookup_type = 'AHL_SECND_DISP_TYPE'
4877 AND lookup_code = p_disp_code
4878 AND lookup_code <> 'NULL';
4879 --
4880 CURSOR check_condition_csr (p_condition_id IN NUMBER) IS
4881 SELECT 'X'
4882 FROM mtl_material_statuses
4883 WHERE status_id = p_condition_id
4884 AND enabled_flag = 1;
4885 --
4886 CURSOR get_disp_rec_csr (p_disp_id IN NUMBER) IS
4887 /*
4888 SELECT *
4889 FROM AHL_PRD_DISPOSITIONS_V
4890 WHERE DISPOSITION_ID = p_disp_id;
4891 */
4892 --AnRaj: Changed query, Perf Bug#4908609,Issue#3
4893 select  B.condition_id,
4894          COND.STATUS_CODE CONDITION_CODE,
4895          B.immediate_disposition_code,
4896          FND1.MEANING IMMEDIATE_TYPE,
4897          B.secondary_disposition_code,
4898          FND2.MEANING SECONDARY_TYPE,
4899          B.part_change_id,
4900          decode(B.instance_id, null, decode(B.path_position_id, null, 'N', 'Y'), 'Y') TRACKABLE_FLAG
4901 from     AHL_PRD_DISPOSITIONS_B B,
4902          FND_LOOKUPS FND1,
4903          FND_LOOKUPS FND2,
4904          MTL_MATERIAL_STATUSES_VL COND
4905 where    FND1.LOOKUP_TYPE (+) = 'AHL_IMMED_DISP_TYPE'
4906 AND      B.immediate_disposition_code = FND1.LOOKUP_CODE (+)
4907 AND      FND2.LOOKUP_TYPE (+) = 'AHL_SECND_DISP_TYPE'
4908 AND      B.SECONDARY_DISPOSITION_CODE = FND2.LOOKUP_CODE (+)
4909 AND      B.condition_id = COND.status_id (+)
4910 AND      B.disposition_id = p_disp_id;
4911 
4912 --
4913 l_dummy VARCHAR2(1);
4914 --l_api_version      CONSTANT NUMBER       := 1.0;
4915 l_api_name         CONSTANT VARCHAR2(30) := 'Validate_Disp_Types';
4916 l_imm_disp_type_tbl   AHL_PRD_DISP_UTIL_PVT.Disp_Type_Tbl_Type;
4917 l_sec_disp_type_tbl   AHL_PRD_DISP_UTIL_PVT.Disp_Type_Tbl_Type;
4918 l_disp_rec      Get_Disp_Rec_Csr%ROWTYPE;
4919 l_match_flag boolean;
4920 l_trackable_flag VARCHAR2(1);
4921 --
4922 BEGIN
4923   -- Standard start of API savepoint
4924   SAVEPOINT Validate_Disp_Types_Pvt;
4925 
4926   -- Initialize Procedure return status to success
4927   x_return_status := FND_API.G_RET_STS_SUCCESS;
4928 
4929   --Validate that the immediate disposition type is valid
4930   OPEN check_immed_disp_types_csr (p_disposition_rec.immediate_disposition_code);
4931   FETCH check_immed_disp_types_csr into l_dummy;
4932   IF (check_immed_disp_types_csr%NOTFOUND) THEN
4933     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_IMMED_TYPE_INV');
4934     FND_MSG_PUB.ADD;
4935   END IF;
4936   CLOSE check_immed_disp_types_csr;
4937 
4938   --Validate that the secondary disposition type is valid
4939   IF (p_disposition_rec.secondary_disposition_code IS NOT NULL) THEN
4940    OPEN check_second_disp_types_csr (p_disposition_rec.secondary_disposition_code);
4941    FETCH check_second_disp_types_csr into l_dummy;
4942    IF (check_second_disp_types_csr%NOTFOUND) THEN
4943     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_SECND_TYPE_INV');
4944     FND_MSG_PUB.ADD;
4945    END IF;
4946    CLOSE check_second_disp_types_csr;
4947   END IF;
4948 
4949   OPEN check_condition_csr (p_disposition_rec.condition_id);
4950   FETCH check_condition_csr into l_dummy;
4951   IF (check_condition_csr%NOTFOUND) THEN
4952     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_CONDITION_INV');
4953     FND_MSG_PUB.ADD;
4954   END IF;
4955   CLOSE check_condition_csr;
4956 
4957 
4958 
4959   --Check that secondary disposition is null for all immediate except BFS,
4960   -- NonConf dispositions
4961   IF (p_disposition_rec.immediate_disposition_code = 'BFS' OR
4962       p_disposition_rec.immediate_disposition_code ='NON_CONF') THEN
4963 
4964       --If RTV/RTC/HOLD/REWORK_RR, condition has to be unserviceable or MRB
4965       IF (p_disposition_rec.secondary_disposition_code <> 'REWORK_NR' AND
4966           p_disposition_rec.secondary_disposition_code <> 'SCRAP' AND
4967           p_disposition_rec.condition_id <> fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE') AND
4968           p_disposition_rec.condition_id <> fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')) THEN
4969        FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_TYPE_COND_INV');
4970        FND_MSG_PUB.ADD;
4971       --If SCRAP, condition has to be MRB
4972       ELSIF (p_disposition_rec.secondary_disposition_code = 'SCRAP' AND
4973              p_disposition_rec.condition_id <> fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')) THEN
4974        FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_TYPE_COND_INV');
4975        FND_MSG_PUB.ADD;
4976       END IF;
4977 
4978   ELSE
4979     --Use_as_is means condition must be serviceable
4980      IF (p_disposition_rec.immediate_disposition_code = 'USE_AS_IS' AND
4981          (p_disposition_rec.condition_id=fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE') OR
4982           p_disposition_rec.condition_id=fnd_profile.value('AHL_MTL_MAT_STATUS_MRB'))) THEN
4983         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_TYPE_COND_INV');
4984         FND_MSG_PUB.ADD;
4985      END IF;
4986      --SCRAP means condition is MRB
4987      IF (p_disposition_rec.immediate_disposition_code = 'SCRAP' AND
4988          p_disposition_rec.condition_id <> fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')) THEN
4989        FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_TYPE_COND_INV');
4990        FND_MSG_PUB.ADD;
4991       END IF;
4992       --not BFS or NON_CONF, secondary must be null
4993       IF(p_disposition_rec.secondary_disposition_code IS NOT NULL) THEN
4994        FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_SECND_TYPE_INV');
4995        FND_MSG_PUB.ADD;
4996       END IF;
4997   END IF;
4998 
4999   --Jerry added the following validation on 02/17/2005 for fixing bug 4189553
5000   --To determine whether the disposition is for tracked item or non-tracked item
5001   IF p_disposition_rec.path_position_id IS NOT NULL THEN
5002     l_trackable_flag := 'Y';
5003   ELSIF p_disposition_rec.inventory_item_id IS NOT NULL THEN
5004     SELECT nvl(comms_nl_trackable_flag, 'N') INTO l_trackable_flag
5005       FROM mtl_system_items_kfv
5006      WHERE inventory_item_id = p_disposition_rec.inventory_item_id
5007        AND organization_id = p_disposition_rec.item_org_id;
5008   ELSIF p_disposition_rec.item_group_id IS NOT NULL THEN
5009     SELECT decode(type_code, 'TRACKED', 'Y', 'N') INTO l_trackable_flag
5010       FROM ahl_item_groups_b
5011      WHERE item_group_id = p_disposition_rec.item_group_id;
5012   ELSE
5013     l_trackable_flag := 'N';
5014   END IF;
5015 
5016   IF (p_disposition_rec.secondary_disposition_code IN ('REWORK_RR', 'REWORK_NR') AND
5017       l_trackable_flag = 'N') THEN
5018     FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_SECND_TYPE_INV');
5019     FND_MSG_PUB.ADD;
5020   END IF;
5021 
5022   --Validate against existing state in update case.
5023   IF (p_disposition_rec.operation_flag = G_OP_UPDATE AND
5024       p_disposition_rec.disposition_id IS NOT NULL) THEN
5025 
5026       --2a) Fetch the existing state.
5027       OPEN get_disp_rec_csr (p_disposition_rec.disposition_id);
5028       FETCH get_disp_rec_csr INTO l_disp_rec;
5029       IF (get_disp_rec_csr%NOTFOUND) THEN
5030         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_ID_INV');
5031         FND_MESSAGE.Set_Token('DISPOSITION_ID', p_disposition_rec.disposition_id);
5032         FND_MSG_PUB.ADD;
5033         RAISE FND_API.G_EXC_ERROR;
5034       END IF;
5035       CLOSE get_disp_rec_csr;
5036 
5037       --Validate that condition id flows only 1 way.
5038       --'MRB' must stay as MRB
5039       IF (l_disp_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')
5040         AND p_disposition_rec.condition_id <> fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')) THEN
5041            FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_COND_CHANGE_INV');
5042            FND_MESSAGE.Set_Token('OLD_CONDITION', l_disp_rec.condition_code);
5043            FND_MESSAGE.Set_Token('NEW_CONDITION', p_disposition_rec.condition_meaning);
5044            FND_MSG_PUB.ADD;
5045       --Unserviceable cannot become serviceable
5046       ELSIF (l_disp_rec.condition_id = fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE') AND
5047              p_disposition_rec.condition_id<>fnd_profile.value('AHL_MTL_MAT_STATUS_UNSERVICABLE') AND
5048              p_disposition_rec.condition_id<>fnd_profile.value('AHL_MTL_MAT_STATUS_MRB')) THEN
5049            FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_COND_CHANGE_INV');
5050            FND_MESSAGE.Set_Token('OLD_CONDITION', l_disp_rec.condition_code);
5051            FND_MESSAGE.Set_Token('NEW_CONDITION', p_disposition_rec.condition_meaning);
5052            FND_MSG_PUB.ADD;
5053       END IF;
5054 
5055      --Validate that Disposition Types are defined correctly
5056      --1) Check that Not Removed and NA are not mapped to Not Received
5057      IF (l_disp_rec.immediate_disposition_code IS NOT NULL) THEN
5058        IF ( l_disp_rec.immediate_disposition_code in ('NOT_REMOVED','NA')
5059          AND p_disposition_rec.immediate_disposition_code = 'NOT_RECEIVED') THEN
5060          FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_IMMED_CHANGE_ILL');
5061           FND_MESSAGE.Set_Token('OLD_DISP_TYPE', l_disp_rec.immediate_type);
5062           FND_MESSAGE.Set_Token('NEW_DISP_TYPE', p_disposition_rec.immediate_disposition);
5063           FND_MSG_PUB.ADD;
5064        END IF;
5065 
5066        --2) Check that Not Received, BFS, Non_Conf, SCRAP are not changed
5067        --IF ( l_disp_rec.immediate_disposition_code in ('NOT_RECEIVED','BFS','NON_CONF','SCRAP')
5068        --Jerry removed 'NOT_RECEIVED' on 01/17/2005 for fixing bug 4094927
5069        IF ( l_disp_rec.immediate_disposition_code in ('BFS','NON_CONF','SCRAP')
5070         AND p_disposition_rec.immediate_disposition_code <> l_disp_rec.immediate_disposition_code) THEN
5071           FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_IMMED_CHANGE_ILL');
5072           FND_MESSAGE.Set_Token('OLD_DISP_TYPE', l_disp_rec.immediate_type);
5073           FND_MESSAGE.Set_Token('NEW_DISP_TYPE', p_disposition_rec.immediate_disposition);
5074           FND_MSG_PUB.ADD;
5075        END IF;
5076 
5077      --3) Check that USE_AS_IS, RTV, RTC can not change to NOT_REMOVED,NA, NOT_RECEIVED
5078       IF ( l_disp_rec.immediate_disposition_code in ('USE_AS_IS','RTV','RTC')
5079          AND p_disposition_rec.immediate_disposition_code in ('NOT_REMOVED','NA','NOT_RECEIVED')) THEN
5080           FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_IMMED_CHANGE_ILL');
5081           FND_MESSAGE.Set_Token('OLD_DISP_TYPE', l_disp_rec.immediate_type);
5082           FND_MESSAGE.Set_Token('NEW_DISP_TYPE', p_disposition_rec.immediate_disposition);
5083           FND_MSG_PUB.ADD;
5084        END IF;
5085      END IF;
5086 
5087      --Validate secondary dispositions
5088      --4) Check if secondary is SCRAP then must stay SCRAP
5089      IF ( l_disp_rec.secondary_disposition_code = 'SCRAP'
5090         AND p_disposition_rec.secondary_disposition_code <> 'SCRAP') THEN
5091         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_SECND_CHANGE_ILL');
5092          FND_MESSAGE.Set_Token('OLD_DISP_TYPE', l_disp_rec.secondary_type);
5093          FND_MESSAGE.Set_Token('NEW_DISP_TYPE', p_disposition_rec.secondary_disposition);
5094         FND_MSG_PUB.ADD;
5095      END IF;
5096 
5097 
5098      --5) Check REWORK_NR means no part change has or is taking place.
5099      IF ( p_disposition_rec.secondary_disposition_code = 'REWORK_NR'
5100          and (l_disp_rec.part_change_id IS NOT NULL
5101              or p_disposition_rec.part_change_id IS NOT NULL)) THEN
5102         FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_SECND_CHANGE_ILL');
5103          FND_MESSAGE.Set_Token('OLD_DISP_TYPE', l_disp_rec.secondary_type);
5104          FND_MESSAGE.Set_Token('NEW_DISP_TYPE', p_disposition_rec.secondary_disposition);
5105         FND_MSG_PUB.ADD;
5106      END IF;
5107 
5108      -- Jerry added the following validation on 02/17/2005 for fixing bug 4189553
5109      IF ( p_disposition_rec.secondary_disposition_code IN ('REWORK_NR','REWORK_RR')
5110          AND l_disp_rec.trackable_flag = 'N') THEN
5111          FND_MESSAGE.Set_Name(G_APP_NAME,'AHL_PRD_DISP_SECND_CHANGE_ILL');
5112          FND_MESSAGE.Set_Token('OLD_DISP_TYPE', l_disp_rec.secondary_type);
5113          FND_MESSAGE.Set_Token('NEW_DISP_TYPE', p_disposition_rec.secondary_disposition);
5114         FND_MSG_PUB.ADD;
5115      END IF;
5116 
5117   END IF; --G_UPDATE
5118 
5119   IF FND_MSG_PUB.count_msg > 0 THEN
5120     RAISE FND_API.G_EXC_ERROR;
5121   END IF;
5122 
5123 EXCEPTION
5124  WHEN FND_API.G_EXC_ERROR THEN
5125    Rollback to Validate_Disp_Types_Pvt;
5126    x_return_status := FND_API.G_RET_STS_ERROR;
5127    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
5128                               p_data  => x_msg_data,
5129                               p_encoded => fnd_api.g_false);
5130  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
5131    Rollback to Validate_Disp_Types_Pvt;
5132    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5133    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
5134                               p_data  => x_msg_data,
5135                               p_encoded => fnd_api.g_false);
5136  WHEN OTHERS THEN
5137    Rollback to Validate_Disp_Types_Pvt;
5138    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
5139    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
5140                              p_procedure_name => l_api_name,
5141                              p_error_text     => SQLERRM);
5142     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
5143                               p_data  => x_msg_data,
5144                               p_encoded => fnd_api.g_false);
5145 
5146 END Validate_Disposition_Types;
5147 
5148 -------------------------------------------------------------------------
5149 
5150 
5151 
5152 FUNCTION workorder_Editable(p_workorder_id IN NUMBER) RETURN BOOLEAN
5153 IS
5154 
5155   CURSOR workorder_status_csr(p_workorder_id IN NUMBER) IS
5156        SELECT status_code from ahl_workorders where workorder_id = p_workorder_id;
5157 
5158   l_status_code VARCHAR(30);
5159 BEGIN
5160   OPEN workorder_status_csr(p_workorder_id);
5161   FETCH workorder_status_csr INTO l_status_code;
5162   CLOSE workorder_status_csr;
5163   -- Change made by jaramana on August 8, 2007 for bug 6326065 (FP of 6061600)
5164   -- Need to allow Disp Txn association for Complete workorders (code 4)
5165   -- update_disposition is called by AHL_PRD_DISP_MTL_TXN_PVT.Process_Disp_Mtl_Txn
5166   -- when the Transaction Qty is updated. So allow the Complete status as updateable.
5167   -- But note that from the Disposition UI, it will still not be possible to create or
5168   -- update the Disposition when the work order is in status Complete
5169   -- IF (l_status_code IN ('12', '4', '5', '7'))THEN --CLOSED, COMPLETE, COMPLETE NO CHARGE, CANCELLED
5170   IF (l_status_code IN ('12', '5', '7')) THEN --CLOSED, COMPLETE NO CHARGE, CANCELLED
5171      RETURN FALSE;
5172   END IF;
5173 
5174   RETURN TRUE;
5175 END workorder_editable;
5176 
5177 ----------------function get_unit_instance_id-------------------------
5178 -- retrieve the instance id of the unit for the job.
5179 ----------------------------------------------------------------------
5180 FUNCTION get_unit_instance_id(p_workorder_id IN NUMBER) RETURN NUMBER
5181 IS
5182   CURSOR task_instance_csr IS
5183     SELECT VTS.INSTANCE_ID, VTS.VISIT_ID
5184     FROM AHL_VISIT_TASKS_B VTS, AHL_WORKORDERS WO
5185     WHERE WO.VISIT_TASK_ID = VTS.VISIT_TASK_ID AND
5186     WO.WORKORDER_ID = p_workorder_id;
5187 
5188   CURSOR visit_instance_csr (c_visit_id IN NUMBER) IS
5189     SELECT VST.ITEM_INSTANCE_ID
5190     FROM AHL_VISITS_B VST
5191     WHERE VST.VISIT_ID = c_visit_id;
5192 
5193   CURSOR uc_header_instance_csr(p_uc_header_id IN NUMBER) IS
5194     SELECT csi_item_instance_id FROM ahl_unit_config_headers
5195     WHERE unit_config_header_id = p_uc_header_id;
5196 
5197   l_task_instance_id NUMBER;
5198   l_visit_id NUMBER;
5199   l_visit_instance_id NUMBER;
5200   l_wo_instance_id NUMBER;
5201   l_uc_header_id  NUMBER;
5202   l_unit_instance_id NUMBER;
5203 
5204   L_DEBUG_KEY      CONSTANT VARCHAR2(150) := G_LOG_PREFIX || 'get_unit_instance_id';
5205 
5206 
5207 BEGIN
5208   OPEN task_instance_csr;
5209   FETCH task_instance_csr into l_task_instance_id, l_visit_id;
5210   CLOSE task_instance_csr;
5211 
5212   OPEN visit_instance_csr(l_visit_id);
5213   FETCH visit_instance_csr into l_visit_instance_id;
5214   CLOSE visit_instance_csr;
5215 
5216   IF l_task_instance_id IS NULL THEN
5217     l_wo_instance_id := l_visit_instance_id;
5218   ELSE
5219     l_wo_instance_id := l_task_instance_id;
5220   END IF;
5221 
5222   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5223     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'For work order id ' || p_workorder_id || ', wo_instance_id = ' || l_wo_instance_id);
5224   END IF;
5225 
5226   -- Get the top most unit containing the wo instance
5227   l_uc_header_id := AHL_UTIL_UC_PKG.get_uc_header_id(l_wo_instance_id);
5228   IF (l_uc_header_id IS NULL) THEN
5229     -- The task instance may have been removed from the Unit already.
5230     -- So, try to get the UC from the visit instance
5231     IF (l_task_instance_id IS NOT NULL AND l_visit_instance_id IS NOT NULL) THEN
5232       -- WO instance is the task instance. So try with the visit instance
5233       l_uc_header_id := AHL_UTIL_UC_PKG.get_uc_header_id(l_visit_instance_id);
5234     ELSE
5235       -- WO instance is already the visit instance
5236       NULL;
5237     END IF;
5238   END IF;
5239 
5240   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5241     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'For work order id ' || p_workorder_id || ', uc_header_id = ' || l_uc_header_id);
5242   END IF;
5243 
5244   IF (l_uc_header_id IS NOT NULL) THEN
5245     OPEN uc_header_instance_csr(l_uc_header_id);
5246     FETCH uc_header_instance_csr INTO l_unit_instance_id;
5247     CLOSE uc_header_instance_csr;
5248     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5249       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY, 'For work order id ' || p_workorder_id || ', unit_instance_id = ' || l_unit_instance_id);
5250     END IF;
5251     RETURN l_unit_instance_id;
5252   ELSE
5253     -- IB Tree
5254     RETURN NULL;
5255   END IF;
5256 
5257 END get_unit_instance_id;
5258 
5259 --------------------------------------------------------------------
5260 
5261 --Retrieve root instance Id of an instance
5262 FUNCTION get_root_instance_id(p_instance_id IN NUMBER) RETURN NUMBER
5263 IS
5264 
5265  CURSOR get_root_instance_csr(p_instance_id IN NUMBER) IS
5266      SELECT object_id
5267       FROM csi_ii_relationships
5268        START WITH subject_id = p_instance_id
5269          AND relationship_type_code = 'COMPONENT-OF'
5270          AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
5271          AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
5272        CONNECT BY subject_id = PRIOR object_id
5273          AND relationship_type_code = 'COMPONENT-OF'
5274          AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
5275          AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
5276 
5277   CURSOR is_non_root_csr(p_instance_id NUMBER) IS
5278   SELECT 'x' FROM csi_ii_relationships
5279          WHERE subject_id = p_instance_id
5280          AND relationship_type_code = 'COMPONENT-OF'
5281          AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
5282          AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
5283 
5284   l_exist VARCHAR2(1);
5285   l_root_instance_id  NUMBER;
5286 BEGIN
5287   OPEN is_non_root_csr(p_instance_id);
5288   FETCH is_non_root_csr INTO l_exist;
5289   IF is_non_root_csr%NOTFOUND THEN   -- then it is a root instance
5290     l_root_instance_id := p_instance_id;
5291   ELSE
5292     OPEN get_root_instance_csr(p_instance_id);
5293     LOOP
5294       FETCH get_root_instance_csr INTO l_root_instance_id;
5295       EXIT when get_root_instance_csr%NOTFOUND;
5296     END LOOP;
5297     CLOSE get_root_instance_csr;
5298   END IF;
5299   CLOSE is_non_root_csr;
5300 
5301   RETURN l_root_instance_id;
5302 
5303 END get_root_instance_id;
5304 --------------------------------------------------------------------
5305 
5306 FUNCTION get_issued_quantity(p_disposition_id IN NUMBER) RETURN NUMBER
5307 IS
5308 Cursor get_issued_quantity_csr(p_disp_id IN NUMBER) IS
5309 SELECT sum (assoc.quantity)
5310   FROM  AHL_PRD_DISP_MTL_TXNS assoc,
5311   AHL_WORKORDER_MTL_TXNS mtxn
5312   WHERE assoc.disposition_id = p_disp_id
5313   AND assoc.workorder_mtl_txn_id = mtxn.workorder_mtl_txn_id
5314   AND mtxn.transaction_type_id = WIP_CONSTANTS.ISSCOMP_TYPE
5315   GROUP BY assoc.disposition_id;
5316 
5317 l_quantity NUMBER;
5318 BEGIN
5319 OPEN get_issued_quantity_csr(p_disposition_id);
5320 FETCH get_issued_quantity_csr INTO l_quantity;
5321 IF(get_issued_quantity_csr%NOTFOUND) THEN
5322   l_quantity := 0;
5323 END IF;
5324 CLOSE get_issued_quantity_csr;
5325 
5326 RETURN l_quantity;
5327 
5328 END get_issued_quantity;
5329 
5330 ------------------------------------------------------------------------
5331 -- Added function by rbhavsar on 09/27/2007 for Bug 6411059
5332 FUNCTION root_node_in_uc_headers(p_instance_id IN NUMBER) RETURN BOOLEAN
5333 IS
5334   CURSOR get_root_node(c_instance_id NUMBER) IS
5335     SELECT object_id
5336        FROM csi_ii_relationships
5337        START WITH subject_id = c_instance_id
5338        AND relationship_type_code = 'COMPONENT-OF'
5339        AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
5340        AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
5341 
5342        CONNECT BY subject_id = prior object_id
5343        AND relationship_type_code = 'COMPONENT-OF'
5344        AND trunc(nvl(active_start_date, SYSDATE)) <= trunc(SYSDATE)
5345        AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
5346 
5347    CURSOR check_in_headers(c_instance_id NUMBER) IS
5348    SELECT csi_item_instance_id
5349      FROM ahl_unit_config_headers
5350      WHERE csi_item_instance_id = c_instance_id
5351      AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
5352 
5353  TYPE objectid_tbl IS TABLE OF csi_ii_relationships.object_id%TYPE;
5354  l_object_id_tbl    objectid_tbl;
5355  l_instance_id      NUMBER;
5356  l_unit_instance_id NUMBER;
5357  l_api_name         CONSTANT VARCHAR2(30) := 'root_node_in_uc_headers';
5358 
5359 BEGIN
5360     IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5361        FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
5362                    G_LOG_PREFIX||l_api_name||'.begin',
5363                    'At the start of the function:  instance_id ='||p_instance_id);
5364     END IF;
5365 
5366     -- Get the root node instance for the given instance id
5367     OPEN get_root_node(p_instance_id);
5368     FETCH get_root_node BULK COLLECT INTO l_object_id_tbl;
5369     CLOSE get_root_node;
5370 
5371     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5372       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
5373                      G_LOG_PREFIX||l_api_name,
5374                      'Parent hierachy count ' || l_object_id_tbl.count);
5375     END IF;
5376 
5377     IF (l_object_id_tbl.count > 0) then
5378         l_instance_id := l_object_id_tbl(l_object_id_tbl.count);
5379     ELSE
5380         l_instance_id := p_instance_id;
5381     END IF;
5382 
5383     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5384       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
5385                      G_LOG_PREFIX||l_api_name,
5386                      'Root Instance is ' || l_instance_id);
5387     END IF;
5388 
5389     -- Check if the Root instance is in unit config headers
5390     OPEN check_in_headers(l_instance_id);
5391     FETCH check_in_headers INTO l_unit_instance_id;
5392     IF check_in_headers%NOTFOUND THEN
5393        IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5394          FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
5395                         G_LOG_PREFIX||l_api_name,
5396                        'Root Instance  ' || l_instance_id || ' is not in unit config headers ');
5397        END IF;
5398        CLOSE check_in_headers;
5399        IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5400               FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
5401                             G_LOG_PREFIX||l_api_name||'.end',
5402                             'At the end of the procedure returning FALSE');
5403        END IF;
5404        RETURN FALSE;
5405     ELSE
5406        IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5407          FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
5408                         G_LOG_PREFIX||l_api_name,
5409                        'Root Instance  ' || l_instance_id || ' is in unit config headers ');
5410        END IF;
5411        CLOSE check_in_headers;
5412        IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5413               FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
5414                             G_LOG_PREFIX||l_api_name||'.end',
5415                             'At the end of the procedure returning TRUE');
5416        END IF;
5417        RETURN TRUE;
5418     END IF;
5419 
5420 END root_node_in_uc_headers;
5421 
5422 --------------------------------------------------------------
5423 
5424 -- Procedure added by jaramana on October 8, 2007 for ER 5854667
5425 -- This procedure gets the WIP Entity Id of the Non-Master Work that is a child of the passed
5426 -- in Work order (Summary WO of the Non Routine)
5427 
5428 FUNCTION Get_NonMWO_WIP_Entity_Id(p_workorder_id IN NUMBER) RETURN NUMBER
5429 IS
5430 Cursor get_child_entities IS
5431 SELECT CHILD_OBJECT_ID
5432   FROM EAM_WO_RELATIONSHIPS
5433  WHERE PARENT_OBJECT_ID = (SELECT wip_entity_id FROM ahl_workorders WHERE workorder_id = p_workorder_id)
5434 AND PARENT_RELATIONSHIP_TYPE = 1
5435 ORDER BY CHILD_OBJECT_ID;
5436 
5437 Cursor get_matching_wo_dtls(c_wip_entity_id IN NUMBER) IS
5438 SELECT WO.WORKORDER_ID, WO.WIP_ENTITY_ID, WO.VISIT_TASK_ID
5439   FROM AHL_WORKORDERS WO, AHL_VISIT_TASKS_B TSK
5440  WHERE WIP_ENTITY_ID = c_wip_entity_id AND
5441        WO.VISIT_TASK_ID = TSK.VISIT_TASK_ID AND
5442        TSK.TASK_TYPE_CODE <> 'SUMMARY';
5443 
5444 Cursor get_non_summary_entity(c_wip_entity_id IN NUMBER) IS
5445 SELECT EAM.CHILD_OBJECT_ID
5446   FROM EAM_WO_RELATIONSHIPS EAM, AHL_WORKORDERS WO, AHL_VISIT_TASKS_B TSK
5447  WHERE EAM.CHILD_OBJECT_ID = WO.WIP_ENTITY_ID AND
5448        TSK.VISIT_TASK_ID = WO.VISIT_TASK_ID AND
5449        TSK.TASK_TYPE_CODE <> 'SUMMARY'
5450  START WITH EAM.CHILD_OBJECT_ID = c_wip_entity_id
5451  CONNECT BY PRIOR CHILD_OBJECT_ID = PARENT_OBJECT_ID AND
5452             PARENT_RELATIONSHIP_TYPE = 1
5453  ORDER BY LEVEL, EAM.CHILD_OBJECT_ID;
5454 
5455  l_child_entity_id NUMBER;
5456  l_first_child_id NUMBER := null;
5457  l_wo_dtls_rec get_matching_wo_dtls%ROWTYPE;
5458  l_full_name  CONSTANT VARCHAR2(60) := 'ahl.plsql.'||G_PKG_NAME||'.'||'Get_NonMWO_WIP_Entity_Id';
5459 
5460 BEGIN
5461   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5462     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, l_full_name, 'Entering Procedure. p_workorder_id = ' || p_workorder_id);
5463   END IF;
5464   OPEN get_child_entities;
5465   LOOP
5466     FETCH get_child_entities INTO l_child_entity_id;
5467     EXIT when get_child_entities%NOTFOUND;
5468     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5469       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'l_child_entity_id = ' || l_child_entity_id);
5470     END IF;
5471     OPEN get_matching_wo_dtls(l_child_entity_id);
5472     FETCH get_matching_wo_dtls INTO l_wo_dtls_rec;
5473     CLOSE get_matching_wo_dtls;
5474     IF (l_wo_dtls_rec.WIP_ENTITY_ID IS NOT NULL) THEN
5475       CLOSE get_child_entities;
5476       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5477         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'About to return ' || l_wo_dtls_rec.WIP_ENTITY_ID);
5478       END IF;
5479       RETURN l_wo_dtls_rec.WIP_ENTITY_ID;
5480     END IF;
5481     IF (l_first_child_id IS NULL) THEN
5482       l_first_child_id := l_child_entity_id;
5483     END IF;
5484   END LOOP;
5485   CLOSE get_child_entities;
5486   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5487     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'l_first_child_id = ' || l_first_child_id);
5488   END IF;
5489   IF (l_first_child_id IS NOT NULL) THEN
5490     OPEN get_non_summary_entity(l_first_child_id);
5491     FETCH get_non_summary_entity INTO l_child_entity_id;
5492     CLOSE get_non_summary_entity;
5493   END IF;
5494   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5495     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, l_full_name, 'Exiting Procedure. About to return ' || l_child_entity_id);
5496   END IF;
5497   RETURN l_child_entity_id;
5498 
5499 END Get_NonMWO_WIP_Entity_Id;
5500 
5501 --------------------------------------------------------------
5502 
5503 -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 12-Dec-2007
5504 -- The API update_item_location and its use has been commented out. Its functionality will
5505 -- now be handled in the API AHL_PRD_NONROUTINE_PVT.process_nonroutine_job.
5506 
5507 -- SURRKUMA :: ER 9213556 Ceate NR for next higher position flag
5508 -- The API update_item_location is needed now to move the non-serialized items to SR work order
5509 -- created for the parent position when the create NR for next higher position flag is checked.
5510 
5511 -- Procedure added by jaramana on February 14, 2007 for ER 5854667
5512 -- This procedure sets the instannce's location as the WIP Job passed in as parameter.
5513 PROCEDURE update_item_location(p_workorder_id  IN         NUMBER,
5514                                p_instance_id   IN         NUMBER,
5515                                x_return_status OUT NOCOPY Varchar2)
5516 IS
5517 
5518   l_wip_entity_id            NUMBER;
5519   l_instance_rec             csi_datastructures_pub.instance_rec;
5520   l_csi_transaction_rec      CSI_DATASTRUCTURES_PUB.transaction_rec;
5521   l_extend_attrib_values_tbl csi_datastructures_pub.extend_attrib_values_tbl;
5522   l_party_tbl                csi_datastructures_pub.party_tbl;
5523   l_account_tbl              csi_datastructures_pub.party_account_tbl;
5524   l_pricing_attrib_tbl       csi_datastructures_pub.pricing_attribs_tbl;
5525   l_org_assignments_tbl      csi_datastructures_pub.organization_units_tbl;
5526   l_asset_assignment_tbl     csi_datastructures_pub.instance_asset_tbl;
5527   l_instance_id_lst          csi_datastructures_pub.id_tbl;
5528   l_msg_count                NUMBER;
5529   l_msg_data                 VARCHAR2(2000);
5530 
5531   l_full_name  CONSTANT VARCHAR2(60) := 'ahl.plsql.'||G_PKG_NAME||'.'||'Update_item_location';
5532   l_transaction_type_id NUMBER;
5533   l_return_val          BOOLEAN;
5534   l_wo_status_code      AHL_WORKORDERS.STATUS_CODE%TYPE;
5535   l_temp_wo_id          NUMBER;
5536 
5537   -- For getting the status of the workorder from the wip_entity_id
5538   CURSOR ahl_wo_status_csr(c_wip_entity_id IN NUMBER) IS
5539     select workorder_id, status_code
5540     FROM ahl_workorders
5541     WHERE wip_entity_id = c_wip_entity_id;
5542 
5543   -- For getting the the updated object_version number from csi_item_isntances
5544   CURSOR ahl_obj_ver_csr IS
5545      select object_version_number
5546      from csi_item_instances
5547      where instance_id = p_instance_id;
5548 
5549   -- For getting the wip_location_id to populate csi_transaction record
5550   CURSOR ahl_wip_location_csr IS
5551      select wip_location_id
5552      from csi_install_parameters ;
5553 
5554 BEGIN
5555 
5556   --Initialize API return status to success
5557   x_return_status := FND_API.G_RET_STS_SUCCESS;
5558 
5559   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5560     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, l_full_name, 'Entering Procedure. p_workorder_id = ' || p_workorder_id || ', p_instance_id = ' || p_instance_id);
5561   END IF;
5562 
5563   -- Get the Non-Master Workorder's wip_entity_id
5564   l_wip_entity_id := Get_NonMWO_WIP_Entity_Id(p_workorder_id);
5565   IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5566     FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'Get_NonMWO_WIP_Entity_Id Returned ' || l_wip_entity_id);
5567   END IF;
5568   IF (l_wip_entity_id IS NULL) THEN
5569     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5570       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'Throwing Unexpected Error since Get_NonMWO_WIP_Entity_Id returned null');
5571     END IF;
5572     FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_WIP_ENTITY_MISSING');
5573     FND_MESSAGE.Set_Token('WOID', p_workorder_id);
5574     FND_MSG_PUB.ADD;
5575     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5576   ELSE
5577     -- Additional check added by jaramana on February 23, 2007 for ER 5854667
5578     -- Update the instance location only if the work order is in released status
5579     OPEN ahl_wo_status_csr(l_wip_entity_id);
5580     FETCH ahl_wo_status_csr INTO l_temp_wo_id, l_wo_status_code;
5581     CLOSE ahl_wo_status_csr;
5582     IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5583       FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'Status of Work order with id ' || l_temp_wo_id || ' is ' || l_wo_status_code);
5584     END IF;
5585     IF (l_wo_status_code <> G_WO_RELEASED_STATUS) THEN
5586       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5587         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'Not changing the location of the instance to the NR WO because the work order is not released.');
5588       END IF;
5589     ELSE
5590       -- Get the object_version number from csi_item_instances
5591       OPEN ahl_obj_ver_csr;
5592       FETCH ahl_obj_ver_csr INTO l_instance_rec.object_version_number;
5593       IF (ahl_obj_ver_csr%NOTFOUND) THEN
5594         FND_MESSAGE.Set_Name('AHL', 'AHL_PRD_REMOVED_INSTANCE_INVALID');
5595         FND_MESSAGE.Set_Token('INST', p_instance_id);
5596         FND_MSG_PUB.ADD;
5597         CLOSE ahl_obj_ver_csr;
5598         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5599       ELSE
5600         CLOSE ahl_obj_ver_csr;
5601       END IF;
5602       -- Populate l_instance_rec
5603       l_instance_rec.INSTANCE_ID        := p_instance_id;
5604       l_instance_rec.LOCATION_TYPE_CODE := 'WIP';
5605       l_instance_rec.WIP_JOB_ID         := l_wip_entity_id;
5606       l_instance_rec.instance_usage_code := 'IN_WIP';
5607 
5608       -- Get location id
5609       OPEN ahl_wip_location_csr;
5610       FETCH ahl_wip_location_csr INTO l_instance_rec.LOCATION_ID ;
5611       CLOSE ahl_wip_location_csr;
5612 
5613       -- get transaction_type_id .
5614       AHL_Util_UC_Pkg.GetCSI_Transaction_ID('UC_UPDATE', l_transaction_type_id, l_return_val);
5615       IF NOT(l_return_val) THEN
5616          RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
5617       END IF;
5618       l_csi_transaction_rec.transaction_type_id     := l_transaction_type_id;
5619       l_csi_transaction_rec.source_transaction_date := sysdate;
5620 
5621       -- Call the CSI API to actually do the update
5622       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5623         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'About to call CSI_ITEM_INSTANCE_PUB.UPDATE_ITEM_INSTANCE');
5624       END IF;
5625 
5626       CSI_ITEM_INSTANCE_PUB.UPDATE_ITEM_INSTANCE(p_api_version           => 1.0
5627                                                 ,p_commit                => fnd_api.g_false
5628                                                 ,p_init_msg_list         => fnd_api.g_false
5629                                                 ,p_validation_level      => fnd_api.g_valid_level_full
5630                                                 ,p_instance_rec          => l_instance_rec
5631                                                 ,p_ext_attrib_values_tbl => l_extend_attrib_values_tbl
5632                                                 ,p_party_tbl             => l_party_tbl
5633                                                 ,p_account_tbl           => l_account_tbl
5634                                                 ,p_pricing_attrib_tbl    => l_pricing_attrib_tbl
5635                                                 ,p_org_assignments_tbl   => l_org_assignments_tbl
5636                                                 ,p_asset_assignment_tbl  => l_asset_assignment_tbl
5637                                                 ,p_txn_rec               => l_csi_transaction_rec
5638                                                 ,x_instance_id_lst       => l_instance_id_lst
5639                                                 ,x_return_status         => x_return_status
5640                                                 ,x_msg_count             => l_msg_count
5641                                                 ,x_msg_data              => l_msg_data);
5642 
5643       IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5644         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name, 'Returned from CSI_ITEM_INSTANCE_PUB.UPDATE_ITEM_INSTANCE. x_return_status = ' || x_return_status);
5645       END IF;
5646     END IF;  -- Status is Released or not
5647   END IF;  -- WIP Entity Id is null or not
5648 
5649   -- Updated by jaramana on October 15, 2007 since the CSI API seems to nullify return params
5650   IF (x_return_status IS NULL AND NVL(l_msg_count, 0) = 0) THEN
5651     x_return_status := FND_API.G_RET_STS_SUCCESS;
5652   END IF;
5653 
5654   IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
5655     FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, l_full_name, 'Exiting Procedure. x_return_status = ' || x_return_status);
5656   END IF;
5657 
5658 END update_item_location;
5659 
5660 END AHL_PRD_DISPOSITION_PVT;