1 package body BOM_DIAGUNITTEST_ITMHLCHK as
2 /* $Header: BOMDGITB.pls 120.1.12020000.2 2012/11/14 08:28:17 leizhzha ship $ */
3 PROCEDURE init is
4 BEGIN
5 null;
6 END init;
7
8 PROCEDURE cleanup IS
9 BEGIN
10 -- test writer could insert special cleanup code here
11 NULL;
12 END cleanup;
13
14 PROCEDURE runtest(inputs IN JTF_DIAG_INPUTTBL,
15 report OUT NOCOPY JTF_DIAG_REPORT,
16 reportClob OUT NOCOPY CLOB) IS
17 reportStr LONG; -- REPORT
18 sqltxt VARCHAR2(9999); -- SQL select statement
19 c_username VARCHAR2(50); -- accept input for username
20 statusStr VARCHAR2(50); -- SUCCESS or FAILURE
21 errStr VARCHAR2(4000); -- error message
22 fixInfo VARCHAR2(4000); -- fix tip
23 isFatal VARCHAR2(50); -- TRUE or FALSE
24 num_rows NUMBER;
25 dummy_num NUMBER;
26 row_limit NUMBER;
27 l_item_id NUMBER;
28 l_org_id NUMBER;
29 Value_link VARCHAR2(4000);
30 l_org_exists NUMBER;
31 l_script VARCHAR2(20);
32 l_index_match NUMBER;
33 l_seg_count NUMBER;
34 l_org_col_exists NUMBER;
35 l_where_clause VARCHAR2(500);
36 l_count NUMBER;
37 ln_cursor Integer;
38 sql_stmt VARCHAR2(4000);
39 ln_rows_proc INTEGER :=0;
40 l_ret_status BOOLEAN;
41 l_status VARCHAR2 (1);
42 l_industry VARCHAR2 (1);
43 l_oracle_schema VARCHAR2 (30);
44
45 Cursor c_item_status_codes is
46 select inventory_item_status_code status
47 from mtl_item_status_tl
48 order by inventory_item_status_code;
49
50 Cursor c_item_status_attr_val(l_item_status_code VARCHAR2) Is
51 select inventory_item_status_code,substr(attribute_name,18) attribute_name,attribute_value
52 from mtl_stat_attrib_values_all_v
53 where status_code_ndb = 1
54 and inventory_item_status_code=l_item_status_code
55 order by attribute_name;
56
57 Cursor list_of_unique_indexes(l_owner VARCHAR2) Is
58 select index_name
59 from all_indexes
60 where table_name = 'MTL_SYSTEM_ITEMS_B'
61 and owner = l_owner
62 and UNIQUENESS = 'UNIQUE';
63
64 BEGIN
65 JTF_DIAGNOSTIC_ADAPTUTIL.setUpVars;
66 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport('@html');
67 JTF_DIAGNOSTIC_COREAPI.insert_style_sheet;
68
69 /* Set Row Limit to 1000 (i.e.) Max Number of records to be fetched by each sql*/
70 row_limit :=1000;
71 l_org_exists :=0; /* Initialize to zero */
72
73 -- accept input
74 l_org_id := JTF_DIAGNOSTIC_ADAPTUTIL.getInputValue('OrgId',inputs);
75 l_script := nvl(upper(JTF_DIAGNOSTIC_ADAPTUTIL.getInputValue('Script',inputs)),'ALL');
76
77 -- JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Script Selected: '||l_script);
78
79
80 /* l_script is NOT a mandatory input. If it is not entered, then run all the scripts.
81 However if a script name is entered, then validate it for existence. */
82
83 If l_script not in ('DUP_ITEM','UNIQ_INDEX','IVGL_ACC','MISSING_TL','COST_ENABLED',
84 'SECONDARY_UOM','BUYER_ID','PLANNER_INACT',
85 'ATTR_DEPEND','STATTR_MISMATCH','ACTDATE_NN','ALL') Then
86
87 JTF_DIAGNOSTIC_COREAPI.errorprint('Invalid Script Name');
88 JTF_DIAGNOSTIC_COREAPI.ActionErrorPrint('Please choose a Script Name from the Lov or leave the field blank.');
89 statusStr := 'FAILURE';
90 isFatal := 'TRUE';
91 fixInfo := ' Please review the error message below and take corrective action.';
92 errStr := ' Invalid value for input field Script ';
93
94 report := JTF_DIAGNOSTIC_ADAPTUTIL.constructReport(statusStr,errStr,fixInfo,isFatal);
95 reportClob := JTF_DIAGNOSTIC_ADAPTUTIL.getReportClob;
96 Return;
97 End If;
98 /* End of script name validation*/
99
100 /* l_org_id is NOT a mandatory input. If it is not entered, then run the scripts for all orgs.
101 However if a value is entered for org_id, then validate it for existence. */
102
103 If l_org_id is not null Then /* validate if input org_id exists*/
104 Begin
105 select 1 into l_org_exists
106 from mtl_parameters
107 where organization_id = l_org_id;
108 Exception
109 When others Then
110 l_org_exists :=0;
111 JTF_DIAGNOSTIC_COREAPI.errorprint('Invalid Organization Id');
112 JTF_DIAGNOSTIC_COREAPI.ActionErrorPrint(' Please either provide a valid value for the Organization Id or leave it blank.');
113 statusStr := 'FAILURE';
114 isFatal := 'TRUE';
115 fixInfo := ' Please review the error message below and take corrective action. ';
116 errStr := ' Invalid value for input field Organization Id ';
117
118 report := JTF_DIAGNOSTIC_ADAPTUTIL.constructReport(statusStr,errStr,fixInfo,isFatal);
119 reportClob := JTF_DIAGNOSTIC_ADAPTUTIL.getReportClob;
120 End;
121 End If; /* End of l_org_id is not null */
122
123 If (l_org_id is null) or (l_org_exists = 1) Then
124 /* Health Check scripts start */
125
126 /* Get the application installation info. References to Data Dictionary Objects without schema name
127 included in WHERE predicate are not allowed (GSCC Check: file.sql.47). Schema name has to be passed
128 as an input parameter to JTF_DIAGNOSTIC_COREAPI.Column_Exists API. */
129
130 l_ret_status := fnd_installation.get_app_info ('INV'
131 , l_status
132 , l_industry
133 , l_oracle_schema
134 );
135
136 /*JTF_DIAGNOSTIC_COREAPI.Line_Out(' l_oracle_schema: '||l_oracle_schema);*/
137
138 If l_script in ('ALL','DUP_ITEM') Then
139 /* Script 1 - Duplicate Item Names */
140 sqltxt := 'SELECT mif.PADDED_ITEM_NUMBER "Item Number", '||
141 ' mp.organization_code "Org Code", '||
142 ' mif.inventory_item_id "Item Id", '||
143 ' mif.organization_id "Org Id" '||
144 ' FROM mtl_item_flexfields mif , mtl_parameters mp '||
145 ' WHERE (mif.organization_id,PADDED_ITEM_NUMBER) in '||
146 ' (select organization_id , padded_item_number '||
147 ' from mtl_item_flexfields '||
148 ' group by organization_Id, PADDED_ITEM_NUMBER '||
149 ' having count(*) > 1 ) '||
150 ' AND mif.organization_id = mp.organization_id ';
151
152 if l_org_id is not null then
153 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
154 end if;
155 sqltxt := sqltxt || ' and rownum< '||row_limit;
156 sqltxt := sqltxt || ' order by mif.PADDED_ITEM_NUMBER, mp.organization_code';
157 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Duplicate Item Names ');
158
159 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
160 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
161 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
162 If (num_rows = row_limit -1 ) Then
163 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
164 <BR/> to prevent an excessively big output file <BR/>');
165 End If;
166 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/><u>IMPACT:</u>
167 <BR/>Querying these items in Items form , transactions form , sales order form etc.
168 <BR/>will error thus making these items unusable.');
169
170 reportStr := '<BR/>
171 <BR/><u>ACTION</u>:
172 <BR/>If Duplicate Rows are returned:
173 <BR/> Case 1: Master Item duplicates:
174 <BR/> If Duplicate Item is present only in the Master org, then user needs to
175 <BR/> rename the Master Item which is not assigned to any child org.
176 <BR/> To rename the Master Item, make use of the below mentioned update script.
177 <BR/> Case 2: Both Child and Master org duplicates:
178 <BR/> If the Duplicate Item is present in both Master and Child orgs , then user can
179 <BR/> choose any one of the duplicated items and rename the same in the Master org.
180 <BR/> To rename the Master Item, make use of the below mentioned update script.
181 <BR/> Please use the below update statements to rename the Master Item.
182 <BR/> <BR/>Important: Please try these scripts on a TEST instance first.
183 <pre>
184 The below update statement can be used to correct a specific item.
185 Substitute the bind variables orgid and itemid with the appropriate values.
186
187 update mtl_system_items_b
188 set segment1 = ''segment1'' || ''_DUP''
189 where organization_id = :orgid
190 and inventory_item_id = :itemid;
191 </pre>
192 <BR/> Use ''Delete Items'' form to delete the renamed item.
193 <BR/>';
194 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
195 End If; /* End of Impact and Action */
196
197 statusStr := 'SUCCESS';
198 isFatal := 'FALSE';
199 JTF_DIAGNOSTIC_COREAPI.BRPrint;
200 End If; /* End of l_script */
201 /* End of Script 1 - Duplicate Item Names */
202
203 /* Script for Unique Index suggestion for Item Number segments in MSIB */
204
205 /* Get the application installation info. References to Data Dictionary Objects without schema name
206 included in WHERE predicate are not allowed (GSCC Check: file.sql.47). For accessing all_indexes
207 in cursor list_of_unique_indexes and all_ind_columns in the query below we need to pass the schema name*/
208
209 l_ret_status := fnd_installation.get_app_info ('INV'
210 , l_status
211 , l_industry
212 , l_oracle_schema
213 );
214
215 /*JTF_DIAGNOSTIC_COREAPI.Line_Out(' l_oracle_schema: '||l_oracle_schema);*/
216
217 If l_script in ('ALL','UNIQ_INDEX') Then
218
219 /* Logic of the script:
220 Let SetA = all the enabled segments for MSTK kff
221 SetB = all the columns in a particular index on table MTL_SYSTEM_ITEMS_B
222
223 If SetA - SetB = SetB - SetA Then SetA = SetB
224 */
225
226 Begin
227 /*Fetch Enabled System Items Segments */
228
229 sqltxt := 'select segment_num "Segment Number", segment_name "Segment Name", '||
230 ' application_column_name "Column Name", required_flag "Required Flag" '||
231 ' from fnd_id_flex_segments_vl '||
232 ' where application_id = 401 '||
233 ' and id_flex_code = ''MSTK'' '||
234 ' and id_flex_num = 101 '||
235 ' and enabled_flag = ''Y'' '||
236 ' order by segment_num ';
237
238 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Unique Index suggestion for Enabled Item Number Segments in mtl_system_items_b Table.');
239 statusStr := 'SUCCESS';
240 isFatal := 'FALSE';
241 /*End of Script to fetch Enabled System Items Segments */
242
243 If (num_rows = 0) Then
244 JTF_DIAGNOSTIC_COREAPI.Line_Out('None of the Item Number Segments are enabled. <BR/>');
245 Elsif (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
246 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Listed above are the enabled system items segments.
247 <BR/> Users are suggested to create an Unique Index on MTL_SYSTEM_ITEMS_B table
248 <BR/> containing all the enabled segments plus the organization_id column.
249 <BR/> For further details on creating such an index please refer to
250 <BR/> ''Oracle Manufacturing APIs and Open Interfaces Manual'' (Part No. A95955-03),
251 <BR/> Chapter 7 - ''Oracle Inventory Open Interfaces and APIs'',
252 <BR/> Section ''Open Item Interface'', SubSection ''Setting Up the Item Interface''.
253 <BR/> <BR/><u>IMPACT:</u> Presence of such an Index will improve the performance
254 <BR/> while querying up Items and will also avoid Duplicate Items from getting created.
255 <BR/><BR/> Verifying whether such an index exists....
256 <BR/> <u>Result:</u>');
257 l_index_match:=0;
258
259 For l_index in list_of_unique_indexes(l_oracle_schema) Loop
260 l_index_match:=0; /* reset to does not match*/
261 l_org_col_exists :=0;
262 l_seg_count :=0;
263
264 Begin
265
266 Select 1 into l_seg_count from dual
267 where not exists (
268 (select APPLICATION_COLUMN_NAME "Column_Name"
269 from FND_ID_FLEX_SEGMENTS
270 where ID_FLEX_CODE = 'MSTK'
271 and enabled_flag = 'Y'
272 MINUS
273 select ori.logical_column_name "Column_Name" from (select * from (select
274 tab.owner
275 , tab.table_name
276 , col.table_name real_table_name
277 , decode(ev.view_name, NULL, col.column_name, evc.view_column_name) logical_column_name
278 , col.column_name real_column_name
279 from
280 dba_tables tab
281 , dba_tab_columns col
282 , dba_editioning_views ev
283 , dba_editioning_view_cols evc
284 WHERE tab.table_name = 'MTL_SYSTEM_ITEMS_B'
285 and col.owner = tab.owner
286 and col.table_name = tab.table_name
287 and ev.owner(+) = tab.owner
288 and ev.table_name(+) = tab.table_name
289 and evc.owner(+) = ev.owner
290 AND evc.view_name(+) = ev.view_name
291 AND (ev.view_name IS NULL OR evc.table_column_name = col.column_name)) WHERE logical_column_name LIKE 'SEGMENT%') ori, all_ind_columns aic
292 WHERE ori.real_column_name = aic.column_name
293 and ori.real_table_name = aic.table_name
294 AND aic.index_name =l_index.index_name
295 AND aic.index_owner=l_oracle_schema)
296 UNION
297 (
298 select ori.logical_column_name "Column_Name" from (select * from (select
299 tab.owner
300 , tab.table_name
301 , col.table_name real_table_name
302 , decode(ev.view_name, NULL, col.column_name, evc.view_column_name) logical_column_name
303 , col.column_name real_column_name
304 from
305 dba_tables tab
306 , dba_tab_columns col
307 , dba_editioning_views ev
308 , dba_editioning_view_cols evc
309 WHERE tab.table_name = 'MTL_SYSTEM_ITEMS_B'
310 and col.owner = tab.owner
311 and col.table_name = tab.table_name
312 and ev.owner(+) = tab.owner
313 and ev.table_name(+) = tab.table_name
314 and evc.owner(+) = ev.owner
315 AND evc.view_name(+) = ev.view_name
316 AND (ev.view_name IS NULL OR evc.table_column_name = col.column_name)) WHERE logical_column_name LIKE 'SEGMENT%') ori, all_ind_columns aic
317 WHERE ori.real_column_name = aic.column_name
318 and ori.real_table_name = aic.table_name
319 AND aic.index_name =l_index.index_name
320 AND aic.index_owner=l_oracle_schema
321 MINUS
322 select APPLICATION_COLUMN_NAME "Column_Name"
323 from FND_ID_FLEX_SEGMENTS
324 where ID_FLEX_CODE = 'MSTK'
325 and enabled_flag = 'Y')
326 );
327
328 If l_seg_count = 1 Then /* Segment Match Found*/
329 Begin
330 select 1 into l_org_col_exists
331 from (select * from (select
332 tab.owner
333 , tab.table_name
334 , col.table_name real_table_name
335 , decode(ev.view_name, NULL, col.column_name, evc.view_column_name) logical_column_name
336 , col.column_name real_column_name
337 from
338 dba_tables tab
339 , dba_tab_columns col
340 , dba_editioning_views ev
341 , dba_editioning_view_cols evc
342 WHERE tab.table_name = 'MTL_SYSTEM_ITEMS_B'
343 and col.owner = tab.owner
344 and col.table_name = tab.table_name
345 and ev.owner(+) = tab.owner
346 and ev.table_name(+) = tab.table_name
347 and evc.owner(+) = ev.owner
348 AND evc.view_name(+) = ev.view_name
349 AND (ev.view_name IS NULL OR evc.table_column_name = col.column_name)) WHERE logical_column_name = 'ORGANIZATION_ID') ori, all_ind_columns aic
350 WHERE ori.real_column_name = aic.column_name
351 and ori.real_table_name = aic.table_name
352 AND aic.index_name =l_index.index_name
353 AND aic.index_owner=l_oracle_schema;
354 Exception
355 When Others Then
356 Null;
357 End;
358 End If;
359
360 If l_seg_count=1 and l_org_col_exists=1 Then
361 l_index_match :=1; /* Matching Index Exists */
362 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Unique Index '||l_index.index_name||' matches the Enabled System Items Segments + Organization_Id columns. <BR/>');
363 Exit;
364 End If;
365
366 Exception
367 When Others Then
368 null;
369 End;
370 End Loop;
371
372 If l_index_match=0 Then /* Match Not Found*/
373 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> No Unique Index as described above exists.
374 <BR/> <BR/><u>ACTION:</u> Please create a Unique Index on MTL_SYSTEM_ITEMS_B table
375 <BR/> containing all the enabled segments plus the organization_id column. <BR/>');
376 End If;
377 End If; /* End of Impact and Action */
378 End;
379 JTF_DIAGNOSTIC_COREAPI.BRPrint;
380 End If; /* End of l_script */
381 /* End of Script for Unique Index suggestion for Item Number segments in MSIB */
382
383 /* Script for fetching items with invalid GL accounts. */
384 If l_script in ('ALL','IVGL_ACC') Then
385 sqltxt := ' SELECT glcc.PADDED_CONCATENATED_SEGMENTS "Code Combination", '||
386 ' mif.PADDED_ITEM_NUMBER "Item Number", '||
387 ' mp.organization_code "Org Code", '||
388 ' glcc.code_combination_id "Code Combination Id", '||
389 ' mif.inventory_item_id "Item Id", '||
390 ' mp.organization_id "Org Id", '||
391 ' decode(mif.cost_of_sales_account,glcc.code_combination_Id,''X'') "Cost Of Sales Account", '||
392 ' decode(mif.sales_account,glcc.code_combination_Id,''X'') "Sales Account", '||
393 ' decode(mif.expense_account,glcc.code_combination_Id,''X'') "Expense Account", '||
394 ' decode(mif.encumbrance_account,glcc.code_combination_Id,''X'') "Encumbrance Account" '||
395 ' FROM gl_code_combinations_kfv glcc, mtl_item_flexfields mif , mtl_parameters mp '||
396 ' WHERE glcc.code_combination_id in (mif.cost_of_sales_account, mif.SALES_ACCOUNT, '||
397 ' mif.EXPENSE_ACCOUNT, mif.ENCUMBRANCE_ACCOUNT) '||
398 ' AND nvl(glcc.END_DATE_ACTIVE,sysdate) < sysdate '||
399 ' AND DETAIL_POSTING_ALLOWED = ''Y'' '||
400 ' AND CHART_OF_ACCOUNTS_ID in (select chart_of_accounts_id '||
401 ' from ORG_ORGANIZATION_DEFINITIONS ood '||
402 ' where ood.organization_id = mif.organization_id and rownum = 1) '||
403 ' AND mif.organization_id = mp.organization_id ';
404
405 if l_org_id is not null then
406 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
407 end if;
408 sqltxt := sqltxt || ' and rownum< '||row_limit;
409 sqltxt := sqltxt || ' order by glcc.PADDED_CONCATENATED_SEGMENTS, mif.PADDED_ITEM_NUMBER, mp.organization_code';
410
411 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Items with Invalid GL Accounts');
412
413 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
414 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
415 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
416 If (num_rows = row_limit -1 ) Then
417 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
418 <BR/> to prevent an excessively big output file <BR/>');
419 End If;
420 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/>Account Columns marked with ''X'' correspond to invalid GL Accounts.');
421 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/><u>IMPACT:</u>
422 <BR/> Downstream applications using these items might refer to
423 <BR/> these invalid GL accounts thus causing data corruption. ');
424
425 reportStr :=
426 '<BR/> <BR/><u>ACTION</u>:
427 <BR/> Please follow the below steps to correct each of the items with invalid GL Accounts.
428 <BR/> 1) Open (N) Inventory > Items form (Master Items/Organization Items).
429 <BR/> 2) Query for that Item.
430 <BR/> 3) Go to the respective invalid GL Account Code field.
431 <BR/> (T) Costing > ''Cost of Goods Sold Account'', (T) Invoicing > ''Sales Account'',
432 <BR/> (T) Purchasing > ''Expense Account'', (T) Purchasing > ''Encumbrance Account''.
433 <BR/> 4) Choose an appropriate valid GL Account from the Lov attached.
434 <BR/> 5) Save changes to this item.
435 <BR/> <u>Note</u>: If the number of items to corrected are huge, then Item Import functionality
436 <BR/> can also be used for correcting the GL Account fields.
437 <BR/> For details on Item Import, please refer to
438 <BR/> ''Oracle Manufacturing APIs and Open Interfaces Manual'' (Part No. A95955-03),
439 <BR/> Chapter 7 - ''Oracle Inventory Open Interfaces and APIs'', Section ''Open Item Interface''.
440 <BR/>';
441 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
442 End If; /* End of Impact and Action */
443
444 statusStr := 'SUCCESS';
445 isFatal := 'FALSE';
446
447 JTF_DIAGNOSTIC_COREAPI.BRPrint;
448 End If; /* End of l_script */
449 /* End of script for fetching items with invalid GL accounts. */
450
451 /* Script to identify items present in mtl_system_items_b but missing in mtl_system_items_tl */
452 If l_script in ('ALL','MISSING_TL') Then
453 sqltxt := 'SELECT mif.PADDED_ITEM_NUMBER "Item Number", '||
454 ' mp.Organization_code "Org Code", '||
455 ' mif.inventory_item_id "Item Id", '||
456 ' mif.organization_id "Org Id" '||
457 ' FROM mtl_item_flexfields mif , mtl_parameters mp '||
458 ' WHERE Not Exists (SELECT ''x'' '||
459 ' FROM mtl_system_items_tl msitl '||
460 ' WHERE msitl.organization_id = mif.organization_id '||
461 ' AND msitl.inventory_item_id = mif.inventory_item_id) '||
462 ' AND mif.organization_id = mp.organization_id ';
463
464 if l_org_id is not null then
465 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
466 end if;
467 sqltxt := sqltxt || ' and rownum< '||row_limit;
468 sqltxt := sqltxt || ' order by mif.PADDED_ITEM_NUMBER, mp.organization_code';
469
470 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' List of Items present in mtl_system_items_b table but missing in mtl_system_items_tl table');
471
472 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
473 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
474 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
475 If (num_rows = row_limit -1 ) Then
476 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
477 <BR/> to prevent an excessively big output file <BR/>');
478 End If;
479 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/><u>IMPACT:</u>
480 <BR/> These items cannot be queried and used in multiple forms across the application .
481 <BR/> For e.g. Items , Purchasing, Transactions, Sales order form etc. <BR/><BR/>');
482
483 JTF_DIAGNOSTIC_COREAPI.ActionErrorLink('<BR/> If Rows are returned with missing data in translations table,
484 <BR/> then please refer to metalink note : ' , '388325.1', '' );
485 End If; /* End of Impact and Action */
486
487 statusStr := 'SUCCESS';
488 isFatal := 'FALSE';
489
490 JTF_DIAGNOSTIC_COREAPI.BRPrint;
491 End If; /* End of l_script */
492 /* End of Script to identiy items present in mtl_system_items_b but missing in mtl_system_items_tl */
493
494
495 /* Script to Identify costing enabled items with missing data in costing tables */
496 If l_script in ('ALL','COST_ENABLED') Then
497 sqltxt := ' select '||
498 ' mif.padded_item_number "PADDED ITEM NUMBER", '||
499 ' mp.organization_code "ORGANIZATION CODE", '||
500 ' mif.costing_enabled_flag "COSTING ENABLED FLAG", '||
501 ' mif.inventory_asset_flag "INVENTORY ASSET FLAG", '||
502 ' mif.inventory_item_id "INVENTORY ITEM ID", '||
503 ' mp.organization_id "ORGANIZATION ID" '||
504 ' from mtl_item_flexfields mif, mtl_parameters mp '||
505 ' where mif.organization_id = mp.organization_id '||
506 ' and mif.costing_enabled_flag = ''Y'' '||
507 ' and not exists (select null '||
508 ' from cst_item_costs cic '||
509 ' where cic.organization_id = mif.organization_id '||
510 ' and cic.inventory_item_id = mif.inventory_item_id) ';
511
512 if l_org_id is not null then
513 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
514 end if;
515 sqltxt := sqltxt || ' and rownum< '||row_limit;
516 sqltxt :=sqltxt||' order by mif.padded_item_number, mp.organization_code';
517
518 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Costing Enabled Items with missing data in costing tables. ');
519
520 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
521 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
522 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
523 If (num_rows = row_limit -1 ) Then
524 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
525 <BR/> to prevent an excessively big output file <BR/>');
526 End If;
527 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/><u>IMPACT:</u>
528 <BR/>These items cannot be costed which will cause data corruption in Costing module. ');
529
530 reportStr :=
531 ' <BR/><BR/><u>ACTION</u>:
532 <BR/> Please follow the below steps to create the missing data in costing tables
533 <BR/> for each item returned above.
534 <BR/> Case 1: (On Hand Quantity does not exist for the item in the corresponding organization)
535 <BR/> 1) Open (N) Inventory > Items form (Master Items/Organization Items).
536 <BR/> 2) Query for that Item.
537 <BR/> 3) Go to (T) Costing.
538 <BR/> 4) Select ''Costing Enabled'' checkbox. Select ''Inventory Asset Value'' checkbox if required.
539 <BR/> If these checkboxes are already checked, then uncheck them first and then check again.
540 <BR/> 5) Save changes to this item.
541 <BR/>
542 <BR/> Case 2:(On Hand Quantity exists for the item in the corresponding organization)
543 <BR/> 1) Issue out the on hand quantity for this item.
544 <BR/> Now <b><u>NO</u></b> On Hand Quantity exists for this item.
545 <BR/> 2) Follow the steps in case 1 to enable the costing flags.
546 <BR/> 3) Receive the quantity back into the organization.
547 <BR/>
548 <BR/> Caution:Costing Flags should be flipped only when NO On Hand Qty exists for an Item.
549 <BR/> Otherwise it will lead to severe data corruption.
550 <BR/> <u>Note</u>: If the number of items to corrected are huge, then Item Import functionality
551 <BR/> can also be used for flipping the costing flags.
552 <BR/> For details on Item Import, please refer to
553 <BR/> ''Oracle Manufacturing APIs and Open Interfaces Manual'' (Part No. A95955-03),
554 <BR/> Chapter 7 - ''Oracle Inventory Open Interfaces and APIs'', Section ''Open Item Interface''.
555 <BR/>';
556
557 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
558 End If; /* End of Impact and Action */
559
560 statusStr := 'SUCCESS';
561 isFatal := 'FALSE';
562
563 JTF_DIAGNOSTIC_COREAPI.BRPrint;
564 End If; /* End of l_script */
565 /* End of costing enabled items with missing data in costing tables. */
566
567
568 /* Script to identify items whose tracking and pricing UOMs are set to Primary but
569 Secondary UOM has a non null value. So we check for the existence of the columns ont_pricing_qty_source,tracking_quantity_ind
570 in table mtl_system_items_b */
571
572 If l_script in ('ALL','SECONDARY_UOM') Then
573
574 sqltxt := ' select '||
575 ' mif.padded_item_number "item number", '||
576 ' mp.organization_code "org code", '||
577 ' mif.tracking_quantity_ind "tracking quantity ind", '||
578 ' mif.ont_pricing_qty_source "ont pricing qty source", '||
579 ' mif.secondary_uom_code "secondary uom code", '||
580 ' mif.inventory_item_id "inventory item id", '||
581 ' mif.organization_id "organization id" '||
582 ' from mtl_item_flexfields mif, mtl_parameters mp '||
583 ' where mif.organization_id=mp.organization_id '||
584 ' and nvl(mif.tracking_quantity_ind,''P'') = ''P'' '||
585 ' and nvl(mif.ont_pricing_qty_source,''P'') = ''P'' '||
586 ' and mif.secondary_uom_code is not null ';
587
588 if l_org_id is not null then
589 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
590 end if;
591 sqltxt := sqltxt || ' and rownum< '||row_limit;
592 sqltxt :=sqltxt||' order by mif.padded_item_number, mp.organization_code';
593
594 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Items whose Tracking or Pricing fields (Items -> Main tab) set to Primary but Secondary UOM has a Non Null value.');
595
596 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
597 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
598 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
599 If (num_rows = row_limit -1 ) Then
600 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
601 <BR/> to prevent an excessively big output file <BR/>');
602 End If;
603 JTF_DIAGNOSTIC_COREAPI.Line_Out(' <BR/> When an item''s Tracking or Pricing field (Items -> main tab)
604 <BR/> is set to Primary, then its Secondary UOM should not be populated.');
605
606 JTF_DIAGNOSTIC_COREAPI.Line_Out(' <BR/><u>IMPACT:</u>
607 <BR/> Item import process cannot be run to update any of the Item attributes
608 <BR/> as users will receive the following error message.
609 <BR/> ''If tracking and pricing are set to Primary,
610 <BR/> then Secondary Unit of measure can only have a null value. '' ');
611
612 reportStr := '<BR/><BR/><u>ACTION</u>:
613 <BR/> Use Item Import in UPDATE mode to update the column SECONDARY_UOM_CODE
614 <BR/> as NULL for these Items.
615 <BR/> To null out varchar attributes through Item Import, the value ''!'' (exclamation mark)
616 <BR/> has to be populated for the corresponding column in the interface record.
617 <BR/> For details on Item Import, please refer to
618 <BR/> ''Oracle Manufacturing APIs and Open Interfaces Manual'' (Part No. A95955-03),
619 <BR/> Chapter 7 - ''Oracle Inventory Open Interfaces and APIs'', Section ''Open Item Interface''.
620 <BR/>';
621 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
622 End If; /* End of Impact and Action */
623
624 statusStr := 'SUCCESS';
625 isFatal := 'FALSE';
626
627 JTF_DIAGNOSTIC_COREAPI.BRPrint;
628 End If; /* End of l_script */
629 /* End of script to identify items whose tracking and pricing UOMs are set to Primary but
630 Secondary UOM has a non null value.*/
631
632 /* Script to identify items attached with inactive buyers*/
633 If l_script in ('ALL','BUYER_ID') Then
634 sqltxt := ' select '||
635 ' mif.padded_item_number "Item Number", '||
636 ' mp.organization_code "Organization Code", '||
637 ' pav.agent_name "Default Buyer", '||
638 ' to_char(pav.start_date_active,''DD-MON-YYYY HH24:MI:SS'') "Start Date Active", '||
639 ' to_char(pav.end_date_active,''DD-MON-YYYY HH24:MI:SS'') "End Date Active", '||
640 ' mif.inventory_item_id "Inventory Item Id", '||
641 ' mif.organization_id "Organization Id", '||
642 ' mif.buyer_id "Default Buyer Id" '||
643 ' from mtl_item_flexfields mif, mtl_parameters mp, po_agents_v pav '||
644 ' where mif.organization_id=mp.organization_id '||
645 ' and mif.buyer_id=pav.agent_id '||
646 ' and sysdate not between nvl(pav.start_date_active, sysdate-1) '||
647 ' and nvl(pav.end_date_active, sysdate+1) ';
648
649 if l_org_id is not null then
650 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
651 end if;
652 sqltxt := sqltxt || ' and rownum< '||row_limit;
653 sqltxt := sqltxt ||' order by mif.padded_item_number, mp.organization_code';
654
655 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Items whose buyer_id corresponds to Inactive Buyers');
656
657 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
658 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
659 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
660 If (num_rows = row_limit -1 ) Then
661 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
662 <BR/> to prevent an excessively big output file <BR/>');
663 End If;
664 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/><u>IMPACT:</u>
665 <BR/> Item import process cannot be run to update any of the Item attributes as users
666 <BR/> will receive error messages corresponding to inactive buyers. ');
667
668 reportStr := '<BR/><BR/><u>ACTION</u>:
669 <BR/> If records are fetched with inactive buyer_id,
670 <BR/> then please follow the below steps to correct them.
671 <BR/> 1) Open (N) Inventory > Items > Items form.
672 <BR/> If attribute ''Default Buyer'' is Master Controlled, then use Master Items form,
673 <BR/> Else if it is Org Controlled, then use Organization Items form.
674 <BR/> 2) Query for an item fetched above.
675 <BR/> 3) Go to (T) Purchasing > ''Default Buyer'' field.
676 <BR/> 4) Currently it will be blank.
677 <BR/> 5) Click on this field and tab out without entering any value for it.
678 <BR/> This will clear the buyer_id column.
679 <BR/> 6) Save the changes to the form.
680 <BR/>';
681 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
682
683
684 /*<BR/><BR/> Note: If the number of items to be corrected are huge, then use Item Import in UPDATE mode to null out the buyer_id column.
685 <BR/> For nulling out numeric attributes through IOI the value -999999 has to be populated for the corresponding column in the interface record.
686 */
687 End If; /* End of Impact and Action */
688
689 statusStr := 'SUCCESS';
690 isFatal := 'FALSE';
691
692 JTF_DIAGNOSTIC_COREAPI.BRPrint;
693 End If; /* End of l_script */
694 /* End of Script to identify items attached with inactive buyers*/
695
696 /* Script to identify items attached with inactive planners*/
697
698 If l_script in ('ALL','PLANNER_INACT') Then
699 sqltxt := ' select '||
700 ' mif.padded_item_number "Item Number", '||
701 ' mp.organization_code "Organization Code", '||
702 ' mpl.planner_code "Planner", '||
703 ' to_char(mpl.disable_date,''DD-MON-YYYY HH24:MI:SS'') "Planner Disable Date", '||
704 ' mif.inventory_item_id "Inventory Item Id", '||
705 ' mif.organization_id "Organization Id" '||
706 ' from mtl_item_flexfields mif, mtl_parameters mp, mtl_planners mpl '||
707 ' where mif.organization_id=mp.organization_id '||
708 ' and mif.organization_id=mpl.organization_id '||
709 ' and mif.planner_code=mpl.planner_code '||
710 ' and nvl(mpl.disable_date, sysdate+1) < sysdate ';
711
712 if l_org_id is not null then
713 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
714 end if;
715 sqltxt := sqltxt || ' and rownum< '||row_limit;
716 sqltxt := sqltxt ||' order by mif.padded_item_number, mp.organization_code, mpl.planner_code';
717
718 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Items with Inactive Planners ');
719
720 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
721 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
722 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
723 If (num_rows = row_limit -1 ) Then
724 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
725 <BR/> to prevent an excessively big output file <BR/>');
726 End If;
727
728 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/><u>IMPACT:</u>
729 <BR/> Item import process cannot be run to update any of the Item attributes as users
730 <BR/> will receive error messages corresponding to invalid planners. ');
731
732 reportStr := '<BR/><BR/><u>ACTION</u>:
733 <BR/> If records are fetched with inactive planners,
734 <BR/> then please follow the below steps to correct them.
735 <BR/> 1) Open (N) Inventory > Items > Items form.
736 <BR/> If attribute ''Planner'' is Master Controlled, then use Master Items form,
737 <BR/> Else if it is Org Controlled, then use Organization Items form.
738 <BR/> 2) Query for an item fetched above.
739 <BR/> 3) Go to (T) General Planning > Planner field.
740 <BR/> 4) Currently it will show the inactive planner.
741 <BR/> 5) Either clear this field or choose a valid planner from the lov.
742 <BR/> 6) Save the changes to the form. <BR/>
743 <BR/> <U>Note:</U> If the number of items to be corrected are huge, then
744 <BR/> use Item Import in UPDATE mode to update the column PLANNER_CODE
745 <BR/> for these Items to either a NULL value or a valid Planner.
746 <BR/> To null out varchar attributes through Item Import, the value ''!'' (exclamation mark)
747 <BR/> has to be populated for the corresponding column in the interface record.
748 <BR/> For details on Item Import, please refer to
749 <BR/> ''Oracle Manufacturing APIs and Open Interfaces Manual'' (Part No. A95955-03),
750 <BR/> Chapter 7 - ''Oracle Inventory Open Interfaces and APIs'', Section ''Open Item Interface''.
751 <BR/>';
752 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
753
754
755 End If; /* End of Impact and Action */
756
757 statusStr := 'SUCCESS';
758 isFatal := 'FALSE';
759
760 JTF_DIAGNOSTIC_COREAPI.BRPrint;
761 End If; /* End of l_script */
762 /* End of Script to identify items with inactive planners*/
763
764
765 /* Script to identify items that fail the Interdependencies betweem Status Attributes. */
766 If l_script in ('ALL','ATTR_DEPEND') Then
767 sqltxt := ' Select '||
768 ' mif.padded_item_number "Item Number", '||
769 ' mp.organization_code "Org Code", '||
770 ' mif.inventory_item_flag "INVENTORY ITEM FLAG", '||
771 ' mif.purchasing_item_flag "PURCHASING ITEM FLAG", '||
772 ' mif.customer_order_flag "CUSTOMER ORDER FLAG", '||
773 ' mif.internal_order_flag "INTERNAL ORDER FLAG", '||
774 ' mif.invoiceable_item_flag "INVOICEABLE ITEM FLAG", '||
775 ' decode(mif.bom_item_type,1,''Model'',2,''Option Class'',3,''Planning'',4,''Standard'',5,''Product Family'') "BOM ITEM TYPE", '||
776 ' decode(stock_enabled_flag,inventory_item_flag,null,''N'',null,''Y'',stock_enabled_flag) "STOCK ENABLED FLAG", '||
777 ' decode(mtl_transactions_enabled_flag,stock_enabled_flag,null,''N'',null,''Y'',mtl_transactions_enabled_flag) "MTL TRANSACTIONS ENABLED FLAG", '||
778 ' decode(purchasing_enabled_flag,purchasing_item_flag,null,''N'',null,''Y'',purchasing_enabled_flag) "PURCHASING ENABLED FLAG", '||
779 ' decode(customer_order_enabled_flag,customer_order_flag,null,''N'',null,''Y'',customer_order_enabled_flag) "CUSTOMER ORDER ENABLED FLAG", '||
780 ' decode(internal_order_enabled_flag,internal_order_flag,null,''N'',null,''Y'',internal_order_enabled_flag) "INTERNAL ORDER ENABLED FLAG", '||
781 ' decode(invoice_enabled_flag,invoiceable_item_flag,null,''N'',null,''Y'',invoice_enabled_flag) "INVOICE ENABLED FLAG", '||
782 ' decode(build_in_wip_flag,inventory_item_flag,decode(build_in_wip_flag,decode(bom_item_type,1,''N'',2,''N'',3,''N'',5,''N'',build_in_wip_flag),null,build_in_wip_flag), '||
783 ' ''N'',decode(build_in_wip_flag,decode(bom_item_type,1,''N'',2,''N'',3,''N'',5,''N'',build_in_wip_flag),null,build_in_wip_flag),'||
784 ' ''Y'',build_in_wip_flag) "BUILD IN WIP FLAG", '||
785 ' mif.inventory_item_id "Inventory Item Id",mif.organization_id "Org Id" '||
786 ' from mtl_item_flexfields mif, mtl_parameters mp '||
787 ' where '||
788 ' mif.organization_id=mp.organization_id '||
789 ' and '||
790 ' ( '||
791 ' ( mif.inventory_item_flag=''N'' and mif.stock_enabled_flag=''Y'') '||
792 ' or (mif.inventory_item_flag=''N'' and mif.mtl_transactions_enabled_flag=''Y'') '||
793 ' or (mif.purchasing_item_flag=''N'' and mif.purchasing_enabled_flag=''Y'') '||
794 ' or (mif.customer_order_flag=''N'' and mif.customer_order_enabled_flag=''Y'') '||
795 ' or (mif.internal_order_flag=''N'' and mif.internal_order_enabled_flag=''Y'') '||
796 ' or (mif.invoiceable_item_flag=''N'' and mif.invoice_enabled_flag=''Y'') '||
797 ' or ( (mif.inventory_item_flag=''N'' or mif.bom_item_type <> 4) and mif.build_in_wip_flag=''Y'') '||
798 ' ) ';
799
800 If l_org_id is not null then
801 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
802 End if;
803 sqltxt := sqltxt || ' and rownum< '||row_limit;
804 sqltxt := sqltxt ||' order by mif.padded_item_number, mp.organization_code';
805
806 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Items that fail the Interdependencies between Status Attributes.');
807
808 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
809 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
810 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
811 If (num_rows = row_limit -1 ) Then
812 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
813 <BR/> to prevent an excessively big output file <BR/>');
814 End If;
815 reportStr := '<BR/> Listed below are the interdependencies for the Item Status Attributes.
816 <BR/><BR/> 1. Stockable (stock_enabled_flag) Must be set to No
817 <BR/> If Inventory Item (inventory_item_flag) is set to No.
818 <BR/> 2. Transactable (mtl_transactions_enabled_flag) Must be set to No
819 <BR/> If Stockable (stock_enabled_flag) is set to No.
820 <BR/> 3. Purchasable (purchasing_enabled_flag) Must be set to No
821 <BR/> If Purchased (purchasing_item_flag) is set to No.
822 <BR/> 4. Build in WIP (build_in_wip_flag) Must be set to No
823 <BR/> If Inventory Item (inventory_item_flag) is set to No
824 <BR/> OR BOM Item Type (bom_item_type) is NOT set to Standard.
825 <BR/> 5. Customer Orders Enabled (customer_order_enabled_flag) Must be set to No
826 <BR/> If Customer Ordered Item (customer_order_flag) is set to No.
827 <BR/> 6. Internal Orders Enabled (internal_order_enabled_flag) Must be set to No
828 <BR/> If Internal Ordered Item (internal_order_flag) is set to No.
829 <BR/> 7. Invoice Enabled (invoice_enabled_flag) Must be set to No
830 <BR/> If Invoiceable Item (invoiceable_item_flag) is set to No.
831 <BR/><BR/> Note 1: In the output above, the Item Status Attributes
832 <BR/> successfully meeting the interdepencies are indicated with a null value.
833 <BR/> The ones showing ''Y'' indicate the failed status attributes.
834 <BR/> The current values (''Y'' or ''N'') of the Independent attributes are always shown.
835 <BR/> Note 2: For an item, if either Stockable or Transactable attributes are wrong
836 <BR/> then please verify and correct both.
837 <BR/><BR/><u>ACTION</u>:
838 <BR/> If records are fetched above,then please use Item Import in UPDATE mode
839 <BR/> to correct the respective Item Status Attribute value.
840 <BR/> For details on Item Import, please refer to
841 <BR/> ''Oracle Manufacturing APIs and Open Interfaces Manual'' (Part No. A95955-03),
842 <BR/> Chapter 7 - ''Oracle Inventory Open Interfaces and APIs'', Section ''Open Item Interface''.
843 <BR/>';
844 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
845 End If; /* End of Impact and Action */
846
847 statusStr := 'SUCCESS';
848 isFatal := 'FALSE';
849
850 JTF_DIAGNOSTIC_COREAPI.BRPrint;
851 End If; /* End of l_script */
852 /* End of Script to identify items that fail the Interdependencies betweem Status Attributes. */
853
854
855 /* Script to identify Items violating validations between status code and status control attributes . */
856 If l_script in ('ALL','STATTR_MISMATCH') Then
857 Begin
858 delete from bom_diag_temp_tab; -- Clear the temporary tables
859 For l_item_st_rec in c_item_status_codes loop
860 l_where_clause :='';
861 l_where_clause :=l_where_clause ||' and mif.INVENTORY_ITEM_STATUS_CODE = '''||l_item_st_rec.status||''' and ( 1=2 ';
862 for l_st_attr_rec in c_item_status_attr_val(l_item_st_rec.status) loop
863 l_where_clause := l_where_clause||' or mif.'||l_st_attr_rec.attribute_name||' <> '''||l_st_attr_rec.attribute_value||'''';
864 end loop;
865 l_where_clause :=l_where_clause ||' ) '; /* append closing brace */
866
867 /* Insert the fetched records into temporary table bom_diag_temp_tab */
868 sql_stmt := '';
869 sql_stmt := ' Insert into bom_diag_temp_tab (Inventory_item_id, organization_id, '||
870 ' char_col1,char_col2,char_col3,char_col4,char_col5,char_col6,char_col7,char_col8,char_col9) '||
871 ' Select mif.inventory_item_id , '||
872 ' mif.organization_Id, '||
873 ' MIF.INVENTORY_ITEM_STATUS_CODE, '||
874 ' MIF.BOM_ENABLED_FLAG, '||
875 ' MIF.BUILD_IN_WIP_FLAG, '||
876 ' MIF.CUSTOMER_ORDER_ENABLED_FLAG, '||
877 ' MIF.INTERNAL_ORDER_ENABLED_FLAG, '||
878 ' MIF.INVOICE_ENABLED_FLAG, '||
879 ' MIF.MTL_TRANSACTIONS_ENABLED_FLAG, '||
880 ' MIF.PURCHASING_ENABLED_FLAG, '||
881 ' MIF.STOCK_ENABLED_FLAG '||
882 ' From mtl_item_flexfields mif '||
883 ' Where 1=1 '||l_where_clause;
884 if l_org_id is not null then
885 sql_stmt :=sql_stmt||' and mif.organization_id = '||l_org_id;
886 end if;
887 /*sql_stmt := sql_stmt || ' and rownum< 5'; -- temporarily limiting the records to 5 */
888
889 ln_cursor := dbms_sql.open_cursor;
890 DBMS_SQL.PARSE(ln_cursor,sql_stmt,dbms_sql.native);
891 ln_rows_proc := DBMS_SQL.EXECUTE(ln_cursor);
892 DBMS_SQL.CLOSE_CURSOR(ln_cursor);
893
894 End Loop;
895
896 /* Display the records stored in temporary table bom_diag_temp_tab */
897 sqltxt := ' Select Inventory_Item_Id "Inventory Item Id", '||
898 ' Organization_id "Organization id", '||
899 ' Char_Col1 "Inventory Item Status Code", '||
900 ' Char_Col2 "BOM ENABLED FLAG", '||
901 ' Char_Col3 "BUILD IN WIP FLAG", '||
902 ' Char_Col4 "CUSTOMER ORDER ENABLED FLAG", '||
903 ' Char_Col5 "INTERNAL ORDER ENABLED FLAG", '||
904 ' Char_Col6 "INVOICE ENABLED FLAG", '||
905 ' Char_Col7 "MTL TRANSACTIONS ENABLED FLAG", '||
906 ' Char_Col8 "PURCHASING ENABLED FLAG", '||
907 ' Char_Col9 "STOCK ENABLED FLAG" '||
908 ' From bom_diag_temp_tab where 1=1 ';
909
910 sqltxt := sqltxt || ' and rownum< '||row_limit;
911 sqltxt :=sqltxt||' order by inventory_item_id, organization_id';
912
913 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Items violating validations between status code and status control attributes ');
914
915 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
916 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
917 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
918 If (num_rows = row_limit -1 ) Then
919 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
920 <BR/> to prevent an excessively big output file <BR/>');
921 End If;
922 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/>
923 The values of the Status Control Attributes that use ''Sets Value'' status setting should
924 <BR/> always be in sync with their corresponding values of the Item Status Code chosen.
925 <BR/> Listed above are the items that violate this validation.
926 <BR/> The values of all their Status Control Attributes
927 <BR/> along with the Item Status Code are also listed.
928 <BR/> Please refer to the below table that lists the Status Control Attributes
929 <BR/> using ''Sets Value'' status setting. If no rows are fetched,
930 <BR/> it implies that none of the Status Control Attributes use ''Sets Value''.
931 <BR/>');
932
933 sqltxt := ' select attribute_name "Attribute Name" '||
934 ' from mtl_item_attributes '||
935 ' where status_control_code = 1 ';
936 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt,'');
937
938 reportStr := ('<BR/><u>ACTION</u>:
939 <BR/>If records are fetched above listing items that violate this validation, then
940 <BR/>1) Please use Item Import in UPDATE mode to modify the Item Status Code
941 <BR/>which will in turn set the values of all Status Control Attributes.
942 <BR/>2) If required, the values of the Status Controlled Attributes that
943 <BR/>do NOT use ''Sets Value'' setting, can then be changed.
944 <BR/> For details on Item Import, please refer to
945 <BR/> ''Oracle Manufacturing APIs and Open Interfaces Manual'' (Part No. A95955-03),
946 <BR/> Chapter 7 - ''Oracle Inventory Open Interfaces and APIs'', Section ''Open Item Interface''.
947 <BR/>');
948
949 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
950 End If; /* End of Impact and Action */
951
952 statusStr := 'SUCCESS';
953 isFatal := 'FALSE';
954
955 End;
956
957 JTF_DIAGNOSTIC_COREAPI.BRPrint;
958 End If; /* End of l_script */
959 /* End of Script to identify Items violating validations between status code and status control attributes . */
960
961 /* Script to fetch items whose start_date_active, end_date_active columns are not null */
962 If l_script in ('ALL','ACTDATE_NN') Then
963 sqltxt := ' SELECT mif.padded_item_number "Item Number", '||
964 ' mp.organization_code "Org Code", '||
965 ' to_char(mif.start_date_active,''DD-MON-YYYY HH24:MI:SS'') "Start Date Active", '||
966 ' to_char(mif.end_date_active,''DD-MON-YYYY HH24:MI:SS'') "End Date Active", '||
967 ' mif.inventory_item_id "Item Id", '||
968 ' mp.organization_id "Org Id" '||
969 ' FROM mtl_item_flexfields mif , mtl_parameters mp '||
970 ' WHERE 1=1 '||
971 ' AND mif.organization_id=mp.organization_id '||
972 ' AND ( mif.end_date_active IS NOT NULL OR mif.start_date_active IS NOT NULL ) ';
973
974 if l_org_id is not null then
975 sqltxt :=sqltxt||' and mif.organization_id = '||l_org_id;
976 end if;
977 sqltxt := sqltxt || ' and rownum< '||row_limit;
978 sqltxt := sqltxt || ' order by mif.PADDED_ITEM_NUMBER, mp.organization_code';
979
980 num_rows:= JTF_DIAGNOSTIC_COREAPI.display_sql(sqltxt, ' Items whose start_date_active, end_date_active columns are populated ');
981
982 If (num_rows = 0) Then /* Corrupt Data Found for this case*/
983 JTF_DIAGNOSTIC_COREAPI.Line_Out('No corrupt data found for this case. <BR/>');
984 ElsIf (num_rows > 0) Then /* Show Impact and Action only if rows are returned */
985 If (num_rows = row_limit -1 ) Then
986 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> Output of the above table is limited to the first '||(row_limit-1)||' rows
987 <BR/> to prevent an excessively big output file <BR/>');
988 End If;
989 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/> start_date_active and end_date_active date fields
990 <BR/> are NOT used to determine the effectivity of an item.
991 <BR/> The effectivity of an item is determined by its Item Status Code.
992 <BR/><BR/><u>IMPACT:</u>
993 <BR/> None of the attributes of these items can be updated.
994 <BR/> FRM-40654 error may also occur while trying to
995 <BR/> update these items through the Items form.
996 <BR/>');
997
998 reportStr := '<BR/><u>ACTION</u>:
999 <BR/> These two date fields have to be nulled out.
1000 <BR/> Nulling them out will not effect any standard functionality in Items form.
1001 <BR/> Please use the below update statements to null out these two date fields.
1002 <BR/> <BR/>Important: Please try these scripts on a TEST instance first.
1003 <pre>
1004 The below update statement can be used to correct a specific item.
1005 Substitute the bind variables orgid and itemid
1006 with the appropriate values.
1007
1008 update mtl_system_items_b
1009 set start_date_active = null
1010 ,end_date_active = null
1011 where organization_id = :orgid
1012 and inventory_item_id = :itemid;
1013
1014 The below two update statements can be used
1015 to collectively correct all the problematic items.
1016
1017 update mtl_system_items_b
1018 set start_date_active = null
1019 where start_date_active is not null;
1020
1021 update mtl_system_items_b
1022 set end_date_active = null
1023 where end_date_active is not null; </pre>
1024 <BR/>';
1025 JTF_DIAGNOSTIC_ADAPTUTIL.addStringToReport(reportClob,reportStr);
1026 End If; /* End of Impact and Action */
1027
1028 statusStr := 'SUCCESS';
1029 isFatal := 'FALSE';
1030
1031 JTF_DIAGNOSTIC_COREAPI.BRPrint;
1032 End If; /* End of l_script */
1033 /* End of Script to fetch items whose start_date_active, end_date_active columns are not null */
1034
1035 ----------------
1036 <<l_test_end>>
1037 JTF_DIAGNOSTIC_COREAPI.Line_Out('<BR/><BR/>This Health Check Test completed as expected <BR/>');
1038 report := JTF_DIAGNOSTIC_ADAPTUTIL.constructReport(statusStr,errStr,fixInfo,isFatal);
1039 reportClob := JTF_DIAGNOSTIC_ADAPTUTIL.getReportClob;
1040
1041 End If; /* End of l_org_id is null or l_org_exists=1 */
1042
1043 EXCEPTION
1044 when others then
1045 JTF_DIAGNOSTIC_COREAPI.errorprint('Error: '||sqlerrm);
1046 JTF_DIAGNOSTIC_COREAPI.ActionErrorPrint('If this error repeats, please contact Oracle Support Services');
1047 statusStr := 'FAILURE';
1048 errStr := sqlerrm ||' occurred in script. ';
1049 fixInfo := 'Unexpected Exception in BOMDGITB.pls';
1050 isFatal := 'FALSE';
1051 report := JTF_DIAGNOSTIC_ADAPTUTIL.constructReport(statusStr,errStr,fixInfo,isFatal);
1052 reportClob := JTF_DIAGNOSTIC_ADAPTUTIL.getReportClob;
1053
1054 END runTest;
1055
1056 PROCEDURE getComponentName(name OUT NOCOPY VARCHAR2) IS
1057 BEGIN
1058 name := 'Items Data Health Check Details';
1059 END getComponentName;
1060
1061 PROCEDURE getTestDesc(descStr OUT NOCOPY VARCHAR2) IS
1062 BEGIN
1063 descStr := 'This diagnostic test performs a variety of health checks against Items <BR/>
1064 and provides suggestions on how to solve possible issues.<BR/>
1065 It is recommended to run this health check periodically.';
1066 END getTestDesc;
1067
1068 PROCEDURE getTestName(name OUT NOCOPY VARCHAR2) IS
1069 BEGIN
1070 name := 'Items Data Health Check';
1071 END getTestName;
1072
1073 PROCEDURE getDependencies (package_names OUT NOCOPY JTF_DIAG_DEPENDTBL) IS
1074 tempDependencies JTF_DIAG_DEPENDTBL;
1075
1076 BEGIN
1077 package_names := JTF_DIAGNOSTIC_ADAPTUTIL.initDependencyTable;
1078 END getDependencies;
1079
1080 PROCEDURE isDependencyPipelined (str OUT NOCOPY VARCHAR2) IS
1081 BEGIN
1082 str := 'FALSE';
1083 END isDependencyPipelined;
1084
1085
1086 PROCEDURE getOutputValues(outputValues OUT NOCOPY JTF_DIAG_OUTPUTTBL) IS
1087 tempOutput JTF_DIAG_OUTPUTTBL;
1088 BEGIN
1089 tempOutput := JTF_DIAGNOSTIC_ADAPTUTIL.initOutputTable;
1090 outputValues := tempOutput;
1091 EXCEPTION
1092 when others then
1093 outputValues := JTF_DIAGNOSTIC_ADAPTUTIL.initOutputTable;
1094 END getOutputValues;
1095
1096
1097 PROCEDURE getDefaultTestParams(defaultInputValues OUT NOCOPY JTF_DIAG_INPUTTBL) IS
1098 tempInput JTF_DIAG_INPUTTBL;
1099 BEGIN
1100 tempInput := JTF_DIAGNOSTIC_ADAPTUTIL.initinputtable;
1101 tempInput := JTF_DIAGNOSTIC_ADAPTUTIL.addInput(tempInput,'OrgId','LOV-oracle.apps.bom.diag.lov.OrganizationLov');-- Lov name modified to OrgId for bug 6412260
1102 tempInput := JTF_DIAGNOSTIC_ADAPTUTIL.addInput(tempInput,'Script','LOV-oracle.apps.bom.diag.lov.ItemHealthLov');
1103 defaultInputValues := tempInput;
1104 EXCEPTION
1105 when others then
1106 defaultInputValues := JTF_DIAGNOSTIC_ADAPTUTIL.initinputtable;
1107 END getDefaultTestParams;
1108
1109 Function getTestMode return INTEGER IS
1110 BEGIN
1111 return JTF_DIAGNOSTIC_ADAPTUTIL.ADVANCED_MODE;
1112
1113 END getTestMode;
1114
1115 END BOM_DIAGUNITTEST_ITMHLCHK;