[Home] [Help]
PACKAGE BODY: APPS.WIP_UTILITIES
Source
1 PACKAGE BODY WIP_UTILITIES AS
2 /* $Header: wiputilb.pls 120.13.12020000.2 2012/11/27 23:32:28 hliew ship $ */
3
4 procedure do_sql(p_sql_stmt in varchar2) is
5 cursor_id integer;
6 return_val integer;
7 sql_stmt varchar2(8192);
8 begin
9 -- set sql statement
10 sql_stmt := p_sql_stmt;
11
12 -- open a cursor
13 cursor_id := dbms_sql.open_cursor;
14
15 -- parse sql statement
16 dbms_sql.parse(cursor_id, sql_stmt, DBMS_SQL.V7);
17
18 -- execute statement
19 return_val := dbms_sql.execute(cursor_id);
20
21 -- close cursor
22 dbms_sql.close_cursor(cursor_id);
23 end do_sql;
24
25 Function is_status_applicable(p_trx_status_enabled IN NUMBER :=NULL,
26 p_trx_type_id IN NUMBER :=NULL,
27 p_lot_status_enabled IN VARCHAR2 :=NULL,
28 p_serial_status_enabled IN VARCHAR2 :=NULL,
29 p_organization_id IN NUMBER :=NULL,
30 p_inventory_item_id IN NUMBER :=NULL,
31 p_sub_code IN VARCHAR2 :=NULL,
32 p_locator_id IN NUMBER :=NULL,
33 p_lot_number IN VARCHAR2 :=NULL,
34 p_serial_number IN VARCHAR2 :=NULL,
35 p_object_type IN VARCHAR2 :=NULL)
36 return varchar2 is
37 l_return_status VARCHAR2(1);
38 l_msg_count NUMBER;
39 l_msg_data VARCHAR2(256);
40
41 BEGIN
42 IF not wms_install.check_install(l_return_status,
43 l_msg_count,
44 l_msg_data,
45 NULL ) then
46 return 'Y';
47 END IF;
48
49 return INV_MATERIAL_STATUS_GRP.is_status_applicable('TRUE', p_trx_status_enabled, p_trx_type_id,
50 p_lot_status_enabled, p_serial_status_enabled, p_organization_id, p_inventory_item_id,
51 p_sub_code, p_locator_id, p_lot_number, p_serial_number, p_object_type);
52
53 exception
54 when others then
55 return 'Y';
56 END is_status_applicable;
57
58 /*******************************************************************
59 * This is the wrapper to call the WMS label printing routine
60 * This one should be used instead of the print_label if called from
61 * java. The p_err_msg basically is a concatenated version of all
62 * the error message on the stack if an error is returned from WMS.
63 ******************************************************************/
64 procedure print_label_java(p_txn_id IN NUMBER,
65 p_table_type IN NUMBER, -- 1 MTI, 2 MMTT
66 p_ret_status OUT NOCOPY VARCHAR2,
67 p_err_msg OUT NOCOPY VARCHAR2,
68 p_business_flow_code IN NUMBER) IS
69 l_msg_count number;
70 l_label_status varchar2(30);
71 l_msg_data varchar2(240);
72 l_params wip_logger.param_tbl_t;
73 l_returnStatus varchar2(1);
74 l_logLevel NUMBER := fnd_log.g_current_runtime_level;
75 begin
76 p_ret_status := fnd_api.g_ret_sts_success;
77
78 if (l_logLevel <= wip_constants.trace_logging) then
79 l_params(1).paramName := 'p_txn_id';
80 l_params(1).paramValue := p_txn_id;
81 l_params(2).paramName := 'p_table_type';
82 l_params(2).paramValue := p_table_type;
83 l_params(3).paramName := 'p_business_flow_code';
84 l_params(3).paramValue := p_business_flow_code;
85 -- Fix bug 15904090 ,should not use p_ret_status as the output
86 -- parameter for wip_logger.entryPoint.
87 wip_logger.entryPoint(p_procName => 'wip_utils.print_label_java',
88 p_params => l_params,
89 x_returnStatus => l_returnStatus);
90 if(l_returnStatus <> fnd_api.g_ret_sts_success) then
91 -- Fix bug 15904090, only if l_returnStatus <> fnd_api.g_ret_sts_success,
92 -- we set p_ret_status := l_returnStatus
93 p_ret_status := l_returnStatus;
94 raise fnd_api.g_exc_unexpected_error;
95 end if;
96 end if;
97
98 print_label(p_txn_id => p_txn_id,
99 p_table_type => p_table_type,
100 p_ret_status => p_ret_status,
101 p_msg_count => l_msg_count,
102 p_msg_data => l_msg_data,
103 p_label_status => l_label_status,
104 p_business_flow_code => p_business_flow_code);
105
106 -- if error, pack the message into p_err_msg for java
107 if (p_ret_status <> 'S') then
108 get_message_stack(p_msg => p_err_msg);
109 end if;
110
111 if (l_logLevel <= wip_constants.trace_logging) then
112 wip_logger.exitPoint(p_procName => 'wip_utils.print_label_java',
113 p_procReturnStatus => p_ret_status,
114 p_msg => p_err_msg,
115 x_returnStatus => l_returnStatus); --discard logging return status
116 end if;
117 end print_label_java;
118
119 /*******************************************************************
120 * This is the wrapper to call the WMS label printing routine
121 ******************************************************************/
122 procedure print_label(p_txn_id IN NUMBER,
123 p_table_type IN NUMBER, -- 1 MTI, 2 MMTT
124 p_ret_status OUT NOCOPY VARCHAR2,
125 p_msg_count OUT NOCOPY NUMBER,
126 p_msg_data OUT NOCOPY VARCHAR2,
127 p_label_status OUT NOCOPY VARCHAR2,
128 p_business_flow_code IN NUMBER) IS
129 -- only want to retrieve the assembly completion records
130 -- no label printing for return
131 cursor get_mmtt(x_txn_header_id number) is
132 select transaction_temp_id, rowid
133 from mtl_material_transactions_temp
134 where transaction_header_id = x_txn_header_id
135 and transaction_source_type_id = 5
136 and transaction_action_id = WIP_CONSTANTS.CPLASSY_ACTION;
137 cursor get_mti(x_txn_header_id number) is
138 select transaction_interface_id, rowid
139 from mtl_transactions_interface
140 where transaction_header_id = x_txn_header_id
141 and transaction_source_type_id = 5
142 and transaction_action_id = WIP_CONSTANTS.CPLASSY_ACTION;
143 l_temp_id number;
144
145 l_params wip_logger.param_tbl_t;
146 l_returnStatus varchar2(1);
147 l_logLevel NUMBER := fnd_log.g_current_runtime_level;
148 begin
149 p_ret_status := fnd_api.g_ret_sts_success;
150
151 if (l_logLevel <= wip_constants.trace_logging) then
152 l_params(1).paramName := 'p_txn_id';
153 l_params(1).paramValue := p_txn_id;
154 l_params(2).paramName := 'p_table_type';
155 l_params(2).paramValue := p_table_type;
156 l_params(3).paramName := 'p_business_flow_code';
157 l_params(3).paramValue := p_business_flow_code;
158 --Fix bug 15904090, should not use p_ret_status as an output for wip_logger.entryPoint
159 wip_logger.entryPoint(p_procName => 'wip_utils.print_label',
160 p_params => l_params,
161 x_returnStatus => l_returnStatus);
162 if(l_returnStatus <> fnd_api.g_ret_sts_success) then
163 -- Fix bug 15904090, only if l_returnStatus <> fnd_api.g_ret_sts_success,
164 -- we set p_ret_status := l_returnStatus
165 p_ret_status := l_returnStatus;
166 raise fnd_api.g_exc_unexpected_error;
167 end if;
168 end if;
169
170 if (p_table_type = 1) then -- mti
171 for inv_rec in get_mti(p_txn_id) loop
172 if (inv_rec.transaction_interface_id is null) then
173 -- transaction interface id not assigned to mti, probably no lot/serial
174 -- generate one
175
176 select mtl_material_transactions_s.nextval into l_temp_id
177 from sys.dual;
178 update mtl_transactions_interface
179 set transaction_interface_id = l_temp_id
180 where rowid = inv_rec.rowid;
181 else
182 l_temp_id := inv_rec.transaction_interface_id;
183 end if;
184 if (l_logLevel <= wip_constants.trace_logging) then
185 wip_logger.log(p_msg => 'Calling INV_LABEL.print_label_wrap',
186 x_returnStatus => l_returnStatus);
187 wip_logger.log(p_msg => 'p_label_status:'||p_label_status,
188 x_returnStatus => l_returnStatus);
189 wip_logger.log(p_msg => 'p_ret_status:'||p_ret_status,
190 x_returnStatus => l_returnStatus);
191 wip_logger.log(p_msg => 'l_temp_id:'||l_temp_id,
192 x_returnStatus => l_returnStatus);
193 wip_logger.log(p_msg => 'p_business_flow_code:'||p_business_flow_code,
194 x_returnStatus => l_returnStatus);
195 end if;
196
197 -- the p_txn_identifier is defined in INVLA10B.pls
198 -- 1 is MMTT, 2 is MTI, 3 MTRL, 4 WFS
199 INV_LABEL.print_label_wrap(x_return_status => p_ret_status,
200 x_msg_count => p_msg_count,
201 x_msg_data => p_msg_data,
202 x_label_status => p_label_status,
203 p_business_flow_code => p_business_flow_code,
204 p_transaction_id => l_temp_id,
205 p_transaction_identifier => 2); -- interface
206 if (l_logLevel <= wip_constants.trace_logging) then
207 wip_logger.log(p_msg => 'After Calling INV_LABEL.print_label_wrap',
208 x_returnStatus => l_returnStatus);
209 wip_logger.log(p_msg => 'After Calling INV_LABEL p_label_status:'||p_label_status,
210 x_returnStatus => l_returnStatus);
211 wip_logger.log(p_msg => 'After Calling INV_LABEL p_ret_status:'||p_ret_status,
212 x_returnStatus => l_returnStatus);
213 wip_logger.log(p_msg => 'After Calling INV_LABEL p_msg_data:'||p_msg_data,
214 x_returnStatus => l_returnStatus);
215 end if;
216 end loop;
217 elsif (p_table_type = 2) then -- mmtt
218 for inv_rec in get_mmtt(p_txn_id) loop
219 if (inv_rec.transaction_temp_id is null) then
220 -- temp id not assigned to mmtt record (probably no lot/serial),
221 -- generate one
222 select mtl_material_transactions_s.nextval into l_temp_id
223 from sys.dual;
224 update mtl_material_transactions_temp
225 set transaction_temp_id = l_temp_id
226 where rowid = inv_rec.rowid;
227 else
228 l_temp_id := inv_rec.transaction_temp_id;
229 end if;
230 if (l_logLevel <= wip_constants.trace_logging) then
231 wip_logger.log(p_msg => 'Calling2 INV_LABEL.print_label_wrap',
232 x_returnStatus => l_returnStatus);
233 wip_logger.log(p_msg => 'p_label_status:'||p_label_status,
234 x_returnStatus => l_returnStatus);
235 wip_logger.log(p_msg => 'p_ret_status:'||p_ret_status,
236 x_returnStatus => l_returnStatus);
237 wip_logger.log(p_msg => 'l_temp_id:'||l_temp_id,
238 x_returnStatus => l_returnStatus);
239 wip_logger.log(p_msg => 'p_business_flow_code:'||p_business_flow_code,
240 x_returnStatus => l_returnStatus);
241 end if;
242 INV_LABEL.print_label_wrap(x_return_status => p_ret_status,
243 x_msg_count => p_msg_count,
244 x_msg_data => p_msg_data,
245 x_label_status => p_label_status,
246 p_business_flow_code => p_business_flow_code,
247 p_transaction_id => l_temp_id,
248 p_transaction_identifier => 1); -- MMTT
249 if (l_logLevel <= wip_constants.trace_logging) then
250 wip_logger.log(p_msg => 'After Calling2 INV_LABEL.print_label_wrap',
251 x_returnStatus => l_returnStatus);
252 wip_logger.log(p_msg => 'After Calling INV_LABEL p_label_status:'||p_label_status,
253 x_returnStatus => l_returnStatus);
254 wip_logger.log(p_msg => 'After Calling INV_LABEL p_ret_status:'||p_ret_status,
255 x_returnStatus => l_returnStatus);
256 wip_logger.log(p_msg => 'After Calling INV_LABEL p_msg_data:'||p_msg_data,
257 x_returnStatus => l_returnStatus);
258 end if;
259 end loop;
260 end if;
261
262 if (l_logLevel <= wip_constants.trace_logging) then
263 wip_logger.exitPoint(p_procName => 'wip_utils.print_label',
264 p_procReturnStatus => p_ret_status,
265 p_msg => p_msg_data,
266 x_returnStatus => l_returnStatus); --discard logging return status
267 end if;
268
269 END print_label;
270
271 procedure print_label(p_business_flow_code IN NUMBER := NULL,
272 p_label_type_id IN NUMBER := NULL,
273 p_organization_id IN NUMBER := NULL,
274 p_inventory_item_id IN NUMBER := NULL,
275 p_revision IN VARCHAR2 := NULL,
276 p_lot_number IN VARCHAR2 := NULL,
277 p_fm_serial_number IN VARCHAR2 := NULL,
278 p_to_serial_number IN VARCHAR2 := NULL,
279 p_lpn_id IN NUMBER := NULL,
280 p_subinventory_code IN VARCHAR2 := NULL,
281 p_locator_id IN NUMBER := NULL,
282 p_delivery_id IN NUMBER := NULL,
283 p_quantity IN NUMBER := NULL,
284 p_uom IN VARCHAR2 := NULL,
285 p_no_of_copies IN NUMBER := NULL,
286 p_ret_status OUT NOCOPY VARCHAR2,
287 p_msg_count OUT NOCOPY NUMBER,
288 p_msg_data OUT NOCOPY VARCHAR2,
289 p_label_status OUT NOCOPY VARCHAR2) is
290 l_params wip_logger.param_tbl_t;
291 l_returnStatus varchar2(1);
292 l_logLevel NUMBER := fnd_log.g_current_runtime_level;
293 begin
294 p_ret_status := fnd_api.g_ret_sts_success;
295
296 if (l_logLevel <= wip_constants.trace_logging) then
297 l_params(1).paramName := 'p_business_flow_code';
298 l_params(1).paramValue := p_business_flow_code;
299 l_params(2).paramName := 'p_label_type_id';
300 l_params(2).paramValue := p_label_type_id;
301 l_params(3).paramName := 'p_organization_id';
302 l_params(3).paramValue := p_organization_id;
303 l_params(4).paramName := 'p_inventory_item_id';
304 l_params(4).paramValue := p_inventory_item_id;
305 l_params(5).paramName := 'p_revision';
306 l_params(5).paramValue := p_revision;
307 l_params(6).paramName := 'p_lot_number';
308 l_params(6).paramValue := p_lot_number;
309 l_params(7).paramName := 'p_fm_serial_number';
310 l_params(7).paramValue := p_fm_serial_number;
311 l_params(8).paramName := 'p_to_serial_number';
312 l_params(8).paramValue := p_to_serial_number;
313 l_params(9).paramName := 'p_lpn_id';
314 l_params(9).paramValue := p_lpn_id;
315 l_params(10).paramName := 'p_subinventory_code';
316 l_params(10).paramValue := p_subinventory_code;
317 l_params(11).paramName := 'p_locator_id';
318 l_params(11).paramValue := p_locator_id;
319 l_params(12).paramName := 'p_delivery_id';
320 l_params(12).paramValue := p_delivery_id;
321 l_params(13).paramName := 'p_quantity';
322 l_params(13).paramValue := p_quantity;
323 l_params(14).paramName := 'p_uom';
324 l_params(14).paramValue := p_uom;
325 l_params(15).paramName := 'p_no_of_copies';
326 l_params(15).paramValue := p_no_of_copies;
327 --Fix bug 15904090, should not use p_ret_status as an output for wip_logger.entryPoint
328 wip_logger.entryPoint(p_procName => 'wip_utils.print_label',
329 p_params => l_params,
330 x_returnStatus => l_returnStatus);
331 if(l_returnStatus <> fnd_api.g_ret_sts_success) then
332 -- Fix bug 15904090, only if l_returnStatus <> fnd_api.g_ret_sts_success,
333 -- we set p_ret_status := l_returnStatus
334 p_ret_status := l_returnStatus;
335 raise fnd_api.g_exc_unexpected_error;
336 end if;
337 end if;
338
339 inv_label.print_label_manual_wrap(p_business_flow_code => p_business_flow_code,
340 p_label_type => p_label_type_id,
341 p_organization_id => p_organization_id,
342 p_inventory_item_id => p_inventory_item_id,
343 p_revision => p_revision,
344 p_lot_number => p_lot_number,
345 p_fm_serial_number => p_fm_serial_number,
346 p_to_serial_number => p_to_serial_number,
347 p_lpn_id => p_lpn_id,
348 p_subinventory_code => p_subinventory_code,
349 p_locator_id => p_locator_id,
350 p_delivery_id => p_delivery_id,
351 p_quantity => p_quantity,
352 p_uom => p_uom,
353 p_no_of_copies => p_no_of_copies,
354 x_return_status => p_ret_status,
355 x_msg_count => p_msg_count,
356 x_msg_data => p_msg_data,
357 x_label_status => p_label_status);
358
359 if (l_logLevel <= wip_constants.trace_logging) then
360 wip_logger.exitPoint(p_procName => 'wip_utils.print_label',
361 p_procReturnStatus => p_ret_status,
362 p_msg => p_msg_data,
363 x_returnStatus => l_returnStatus); --discard logging return status
364 end if;
365 end print_label;
366
367 procedure get_message_stack(p_delete_stack in varchar2 := null,
368 p_separator in varchar2 := null,
369 p_msg OUT NOCOPY VARCHAR2) is
370 l_curMsg VARCHAR2(2000) := '';
371 l_msgCount NUMBER;
372 l_separator VARCHAR2(30) := nvl(p_separator,' ');
373 begin
374 fnd_msg_pub.Count_And_Get(p_encoded => fnd_api.g_false,
375 p_count => l_msgCount,
376 p_data => p_msg);
377
378 IF(l_msgCount > 1) THEN
379 FOR i IN 1..l_msgCount LOOP
380 l_curMsg := fnd_msg_pub.get(p_msg_index => l_msgCount - i + 1,
381 p_encoded => FND_API.g_false);
382 if(nvl(length(p_msg), 0) + length(l_curMsg) + length(l_separator) < 2000) then
383 p_msg := p_msg || l_separator || l_curMsg;
384 end if;
385 END LOOP;
386 END IF;
387
388 if(fnd_api.to_boolean(nvl(p_delete_stack,fnd_api.g_true))) then
389 fnd_msg_pub.delete_msg;
390 end if;
391
392 EXCEPTION
393 WHEN OTHERS THEN
394 fnd_msg_pub.add_exc_msg(p_pkg_name => 'wip_utilities',
395 p_procedure_name => 'get_message_stack',
396 p_error_text => SQLERRM);
397 p_msg := fnd_msg_pub.get(p_encoded => fnd_api.g_false);
398 if(fnd_api.to_boolean(nvl(p_delete_stack,fnd_api.g_true))) then
399 fnd_msg_pub.delete_msg;
400 end if;
401 END get_message_stack;
402
403 /* Deletes transaction records from the mtl temp tables */
404 procedure delete_temp_records(p_header_id IN NUMBER) is
405 begin
406 -- Delete all serial numbers tied to lots
407 delete from mtl_serial_numbers_temp
408 where transaction_temp_id in
409 ( select msnt.transaction_temp_id
410 from mtl_serial_numbers_temp msnt,
411 mtl_transaction_lots_temp mtlt,
412 mtl_material_transactions_temp mmtt
413 where mmtt.transaction_header_id = p_header_id
414 and mtlt.transaction_temp_id = mmtt.transaction_temp_id
415 and mtlt.serial_transaction_temp_id = msnt.transaction_temp_id
416 );
417
418 -- Delete all serial numbers (sn control only)
419 delete from mtl_serial_numbers_temp
420 where transaction_temp_id in
421 ( select msnt.transaction_temp_id
422 from mtl_serial_numbers_temp msnt,
423 mtl_material_transactions_temp mmtt
424 where mmtt.transaction_header_id = p_header_id
425 and mmtt.transaction_temp_id = msnt.transaction_temp_id
426 );
427
428 -- Delete all lots
429 delete from mtl_transaction_lots_temp
430 where transaction_temp_id in
431 ( select mtlt.transaction_temp_id
432 from mtl_material_transactions_temp mmtt,
433 mtl_transaction_lots_temp mtlt
434 where mmtt.transaction_header_id = p_header_id
435 and mtlt.transaction_temp_id = mmtt.transaction_temp_id
436 );
437
438 -- Finally, delete all records in mmtt for this transaction
439 delete from mtl_material_transactions_temp
440 where transaction_header_id = p_header_id;
441
442 end delete_temp_records;
443
444 /* Deletes transaction records from the mtl temp tables */
445 procedure delete_temp_records(p_temp_id IN NUMBER) is
446 begin
447 -- Delete all serial numbers tied to lots
448 delete from mtl_serial_numbers_temp msnt
449 where transaction_temp_id in
450 (select mtlt.serial_transaction_temp_id
451 from mtl_transaction_lots_temp mtlt
452 where mtlt.transaction_temp_id = p_temp_id
453 );
454
455 -- Delete all serial numbers (sn control only)
456 delete from mtl_serial_numbers_temp
457 where transaction_temp_id = p_temp_id;
458
459 -- Delete all lots
460 delete from mtl_transaction_lots_temp
461 where transaction_temp_id = p_temp_id;
462
463 -- Finally, delete all records in mmtt for this transaction
464 delete from mtl_material_transactions_temp
465 where transaction_header_id = p_temp_id;
466 end delete_temp_records;
467
468 procedure update_serial(p_serial_number in VARCHAR2,
469 p_inventory_item_id in number,
470 p_organization_id in number,
471 p_wip_entity_id in number,
472 p_line_mark_id in number := null,
473 p_operation_seq_num in number,
474 p_intraoperation_step_type in number,
475 x_return_status OUT NOCOPY VARCHAR2) is
476 l_objID NUMBER;
477 l_msg_data VARCHAR2(2000);
478 l_msg_count VARCHAR2(2000);
479 l_current_status NUMBER;
480 l_initialization_date DATE;
481 l_completion_date DATE;
482 l_ship_date DATE;
483 l_revision VARCHAR2(3);
484 /* ER 4378835: Increased length of lot_number from 30 to 80 to support OPM Lot-model changes */
485 l_lot_number VARCHAR2(80);
486 l_group_mark_id NUMBER;
487 l_lot_line_mark_id NUMBER;
488 l_current_organization_id NUMBER;
489 l_current_locator_id NUMBER;
490 l_current_subinventory_code VARCHAR2(30);
491 l_original_wip_entity_id NUMBER;
492 l_original_unit_vendor_id NUMBER;
493 l_vendor_lot_number VARCHAR2(80);
494 l_vendor_serial_number VARCHAR2(30);
495 l_last_receipt_issue_type NUMBER;
496 l_last_txn_source_id NUMBER;
497 l_last_txn_source_type_id NUMBER;
498 --Bug 12960198 Modified the size limit of variable per requirement from Inv
499 l_last_txn_source_name MTL_SERIAL_NUMBERS.LAST_TXN_SOURCE_NAME%TYPE;
500 l_parent_item_id NUMBER;
501 l_parent_serial_number VARCHAR2(30);
502 l_dummy VARCHAR2(1);
503 l_last_status NUMBER;
504 begin
505 savepoint wipupdserial0;
506 --check for existence of serial number while locking it
507 select current_status,
508 initialization_date,
509 completion_date,
510 ship_date,
511 revision,
512 lot_number,
513 group_mark_id,
514 lot_line_mark_id,
515 current_organization_id,
516 current_locator_id,--10
517 current_subinventory_code,
518 original_wip_entity_id,
519 original_unit_vendor_id,
520 vendor_lot_number,
521 vendor_serial_number,
522 last_receipt_issue_type,
523 last_txn_source_id,
524 last_txn_source_type_id,
525 last_txn_source_name,
526 parent_item_id,--20
527 parent_serial_number
528 into l_current_status,
529 l_initialization_date,
530 l_completion_date,
531 l_ship_date,
532 l_revision,
533 l_lot_number,
534 l_group_mark_id,
535 l_lot_line_mark_id,
536 l_current_organization_id,
537 l_current_locator_id,--10
538 l_current_subinventory_code,
539 l_original_wip_entity_id,
540 l_original_unit_vendor_id,
541 l_vendor_lot_number,
542 l_vendor_serial_number,
543 l_last_receipt_issue_type,
544 l_last_txn_source_id,
545 l_last_txn_source_type_id,
546 l_last_txn_source_name,
547 l_parent_item_id,--20
548 l_parent_serial_number
549 from mtl_serial_numbers
550 where serial_number = p_serial_number
551 and inventory_item_id = p_inventory_item_id
552 and current_organization_id = p_organization_id
553 for update nowait;
554
555 if(l_current_status = 6) then
556 l_last_status := 1;
557 else
558 l_last_status := l_current_status;
559 end if;
560
561 inv_serial_number_pub.updateserial(p_api_version => 1.0,
562 p_inventory_item_id => p_inventory_item_id,
563 p_organization_id => p_organization_id,
564 p_serial_number => p_serial_number,
565 p_initialization_date => l_initialization_date,
566 p_completion_date => l_completion_date,
567 p_ship_date => l_ship_date,
568 p_revision => l_revision,
569 p_lot_number => l_lot_number,
570 p_current_locator_id => l_current_locator_id,
571 p_subinventory_code => l_current_subinventory_code,
572 p_trx_src_id => l_original_wip_entity_id,
573 p_unit_vendor_id => l_original_unit_vendor_id,
574 p_vendor_lot_number => l_vendor_lot_number,
575 p_vendor_serial_number => l_vendor_serial_number,
576 p_receipt_issue_type => l_last_receipt_issue_type,
577 p_txn_src_id => l_last_txn_source_id,
578 p_txn_src_name => l_last_txn_source_name,
579 p_txn_src_type_id => l_last_txn_source_type_id,
580 p_current_status => l_current_status,
581 p_parent_item_id => l_parent_item_id,
582 p_parent_serial_number => l_parent_serial_number,
583 p_serial_temp_id => null,
584 p_last_status => l_last_status,
585 p_status_id => null,
586 x_object_id => l_objID,
587 x_return_status => x_return_status,
588 x_msg_count => l_msg_count,
589 x_msg_data => l_msg_data,
590 p_wip_entity_id => p_wip_entity_id,
591 p_operation_seq_num => p_operation_seq_num,
592 p_intraoperation_step_type => p_intraoperation_step_type,
593 p_line_mark_id => p_line_mark_id);
594
595 if(x_return_status <> fnd_api.g_ret_sts_success) then
596 raise fnd_api.g_exc_unexpected_error;
597 end if;
598 exception
599 when wip_constants.records_locked then
600 rollback to wipupdserial0;
601 x_return_status := fnd_api.g_ret_sts_unexp_error;
602 fnd_message.set_name('WIP', 'SERIAL_NUMBERS_LOCKED');
603 fnd_msg_pub.add;
604 when fnd_api.g_exc_unexpected_error then
605 rollback to wipupdserial0;
606 --status and message should have been set by inv api. set status
607 --just in case.
608 x_return_status := fnd_api.g_ret_sts_unexp_error;
609
610 when others then
611 rollback to wipupdserial0;
612 x_return_status := fnd_api.g_ret_sts_unexp_error;
613 fnd_msg_pub.add_exc_msg(p_pkg_name => 'wip_utilities',
614 p_procedure_name => 'update_serial',
615 p_error_text => SQLERRM);
616 end update_serial;
617
618 procedure generate_serials(p_org_id in NUMBER,
619 p_item_id in NUMBER,
620 p_qty IN NUMBER,
621 p_wip_entity_id IN NUMBER,
622 p_revision in VARCHAR2,
623 p_lot in varchar2,
624 x_start_serial IN OUT NOCOPY VARCHAR2,
625 x_end_serial OUT NOCOPY VARCHAR2,
626 x_return_status OUT NOCOPY VARCHAR2,
627 x_err_msg OUT NOCOPY VARCHAR2) is
628 l_status NUMBER;
629 l_qty NUMBER := p_qty;
630 begin
631 x_return_status := fnd_api.g_ret_sts_success;
632 if(x_start_serial is null) then
633 l_status := inv_serial_number_pub.generate_serials(p_org_id => p_org_id,
634 p_item_id => p_item_id,
635 p_qty => p_qty,
636 p_wip_id => p_wip_entity_id,
637 p_group_mark_id => p_wip_entity_id,
638 p_line_mark_id => null,
639 p_rev => p_revision,
640 p_lot => p_lot,
641 p_skip_serial => wip_constants.yes,
642 x_start_ser => x_start_serial,
643 x_end_ser => x_end_serial,
644 x_proc_msg => x_err_msg);
645 else
646 l_qty := p_qty;
647 l_status := inv_serial_number_pub.validate_serials(p_org_id => p_org_id,
648 p_item_id => p_item_id,
649 p_qty => l_qty,
650 p_wip_entity_id => p_wip_entity_id,
651 p_group_mark_id => p_wip_entity_id,
652 p_line_mark_id => null,
653 p_rev => p_revision,
654 p_lot => p_lot,
655 p_start_ser => x_start_serial,
656 p_trx_src_id => null,
657 p_trx_action_id => null,
658 p_subinventory_code => null,
659 p_locator_id => null,
660 x_end_ser => x_end_serial,
661 x_proc_msg => x_err_msg);
662 if(l_qty <> p_qty AND
663 l_status = 0) then
664 fnd_message.set_name('INV', 'INVALID_SERIAL_NUMBER');
665 fnd_msg_pub.add;
666 get_message_stack(p_msg => x_err_msg,
667 p_delete_stack => fnd_api.g_false,
668 p_separator => ' ');
669 end if;
670 end if;
671 /* For Bug 5860709 : Returning 'W' for status 2-Warning*/
672 if(l_status = 2 ) then
673 x_return_status := WIP_CONSTANTS.WARN;
674 --if(l_status <> 0) then
675 elsif(l_status <> 0) then
676 x_return_status := fnd_api.g_ret_sts_error;
677 end if;
678 exception
679 when others then
680 x_return_status := fnd_api.g_ret_sts_unexp_error;
681 x_err_msg := SQLERRM;
682 end generate_serials;
683
684 FUNCTION require_lot_attributes(p_org_id IN NUMBER,
685 p_item_id IN NUMBER,
686 p_lot_number IN VARCHAR2)
687 RETURN NUMBER IS
688
689 l_require_lot_attr NUMBER;
690 BEGIN
691 SELECT inv_lot_sel_attr.is_enabled(
692 'Lot Attributes',
693 p_org_id,
694 p_item_id)
695 INTO l_require_lot_attr
696 FROM dual
697 WHERE NOT EXISTS -- new lot
698 (SELECT 'X'
699 FROM mtl_lot_numbers mln
700 WHERE mln.organization_id = p_org_id
701 AND mln.inventory_item_id = p_item_id
702 AND mln.lot_number = p_lot_number);
703
704 IF(l_require_lot_attr = 2) THEN
705 RETURN WIP_CONSTANTS.YES;
706 ELSE
707 RETURN WIP_CONSTANTS.NO;
708 END IF;
709
710 EXCEPTION
711 WHEN others THEN -- include NO_DATA_FOUND exception too
712 RETURN WIP_CONSTANTS.NO;
713 END require_lot_attributes;
714
715 PROCEDURE get_locator(p_locator_id IN NUMBER,
716 p_org_id IN NUMBER,
717 p_locator OUT NOCOPY VARCHAR2)
718 IS
719 BEGIN
720 p_locator := inv_project.get_locator(p_locator_id, p_org_id);
721 END get_locator;
722
723 FUNCTION is_user_defined_lot_exp(p_org_id IN NUMBER,
724 p_item_id IN NUMBER,
725 p_lot_number IN VARCHAR2)
726 RETURN NUMBER IS
727
728 l_shelf_life_code NUMBER;
729 BEGIN
730 SELECT msi.shelf_life_code
731 INTO l_shelf_life_code
732 FROM mtl_system_items msi
733 WHERE msi.inventory_item_id = p_item_id
734 AND msi.organization_id = p_org_id
735 AND NOT EXISTS -- new lot
736 (SELECT 'X'
737 FROM mtl_lot_numbers mln
738 WHERE mln.organization_id = p_org_id
739 AND mln.inventory_item_id = p_item_id
740 AND mln.lot_number = p_lot_number);
741
742 IF(l_shelf_life_code = WIP_CONSTANTS.USER_DEFINED_EXP) THEN
743 RETURN WIP_CONSTANTS.YES;
744 ELSE
745 RETURN WIP_CONSTANTS.NO;
746 END IF;
747
748 EXCEPTION
749 WHEN others THEN -- include NO_DATA_FOUND exception too
750 RETURN WIP_CONSTANTS.NO;
751 END is_user_defined_lot_exp;
752
753 FUNCTION is_dff_required(p_application_id IN NUMBER,
754 p_dff_name IN VARCHAR2)
755 RETURN VARCHAR2 IS
756
757 l_dff_required BOOLEAN;
758 BEGIN
759 l_dff_required := fnd_flex_apis.is_descr_required(
760 x_application_id => p_application_id,
761 x_desc_flex_name => p_dff_name);
762
763 IF(l_dff_required) THEN
764 RETURN fnd_api.g_true;
765 ELSE
766 RETURN fnd_api.g_false;
767 END IF;
768 END is_dff_required;
769
770 FUNCTION is_dff_setup(p_application_id IN NUMBER,
771 p_dff_name IN VARCHAR2)
772 RETURN VARCHAR2 IS
773
774 l_dff_setup BOOLEAN;
775 BEGIN
776 l_dff_setup := fnd_flex_apis.is_descr_setup(
777 x_application_id => p_application_id,
778 x_desc_flex_name => p_dff_name);
779
780 IF(l_dff_setup) THEN
781 RETURN fnd_api.g_true;
782 ELSE
783 RETURN fnd_api.g_false;
784 END IF;
785 END is_dff_setup;
786
787 /*Added the following function for bug 7138983(FP 7028072)*/
788 FUNCTION validate_scrap_account_id ( scrap_account_id IN NUMBER,
789 chart_of_accounts_id IN NUMBER )
790 RETURN VARCHAR2 IS
791 x_flex_result boolean;
792 BEGIN
793
794 x_flex_result := fnd_flex_keyval.validate_ccid(appl_short_name => 'SQLGL',
795 key_flex_code => 'GL#',
796 structure_number => chart_of_accounts_id,
797 combination_id => scrap_account_id,
798 security => 'ENFORCE'
799 );
800
801 if x_flex_result then
802 return 'Y';
803 else
804 return 'N';
805 end if;
806 EXCEPTION
807 WHEN OTHERS THEN
808 RETURN 'N';
809 END validate_scrap_account_id;
810
811
812
813
814
815
816 /**************************************************************************/
817 --VJ: Label Printing - Start
818
819 PROCEDURE print_job_labels(p_wip_entity_id IN NUMBER,
820 -- p_op_seq_num IN NUMBER,
821 x_status IN OUT NOCOPY VARCHAR2,
822 x_msg_count IN OUT NOCOPY NUMBER,
823 x_msg IN OUT NOCOPY VARCHAR2
824 )
825 IS
826 l_org_id NUMBER;
827 l_item_id NUMBER;
828 l_label_status VARCHAR2(30);
829 l_returnStatus VARCHAR2(1);
830 l_logLevel NUMBER := fnd_log.g_current_runtime_level;
831 l_params wip_logger.param_tbl_t;
832 l_msg_data VARCHAR2(100);
833
834 CURSOR job_serials (p_org_id NUMBER, p_we_id NUMBER, p_item_id NUMBER)
835 IS
836 SELECT serial_number
837 FROM mtl_serial_numbers
838 WHERE current_organization_id = p_org_id
839 and wip_entity_id = p_we_id
840 AND inventory_item_id = p_item_id;
841
842 BEGIN
843 x_status := fnd_api.g_ret_sts_success;
844
845 if (l_logLevel <= wip_constants.trace_logging) then
846 l_params(1).paramName := 'p_wip_entity_id';
847 l_params(1).paramValue := p_wip_entity_id;
848 -- l_params(2).paramName := 'p_op_seq_num';
849 -- l_params(2).paramValue := p_op_seq_num;
850 l_params(2).paramName := 'x_status';
851 l_params(2).paramValue := x_status;
852 l_params(3).paramName := 'x_msg_count';
853 l_params(3).paramValue := x_msg_count;
854 l_params(4).paramName := 'x_msg';
855 l_params(4).paramValue := x_msg;
856 wip_logger.entryPoint(p_procName => 'wip_utils.print_job_labels',
857 p_params => l_params,
858 x_returnStatus => x_status);
859 if(x_status <> fnd_api.g_ret_sts_success) then
860 raise fnd_api.g_exc_unexpected_error;
861 end if;
862 end if;
863
864 select organization_id, primary_item_id
865 into l_org_id, l_item_id
866 from wip_discrete_jobs
867 where wip_entity_id = p_wip_entity_id;
868
869 INV_LABEL.PRINT_LABEL_MANUAL_WRAP (
870 P_BUSINESS_FLOW_CODE => NULL,
871 P_LABEL_TYPE => 9,
872 P_ORGANIZATION_ID => l_org_id,
873 P_INVENTORY_ITEM_ID => NULL,
874 P_REVISION => NULL,
875 P_LOT_NUMBER => NULL,
876 P_FM_SERIAL_NUMBER => NULL,
877 P_TO_SERIAL_NUMBER => NULL,
878 P_LPN_ID => NULL,
879 P_SUBINVENTORY_CODE => NULL,
880 P_LOCATOR_ID => NULL,
881 P_DELIVERY_ID => NULL,
882 P_QUANTITY => NULL,
883 P_UOM => NULL,
884 P_WIP_ENTITY_ID => p_wip_entity_id,
885 P_NO_OF_COPIES => NULL,
886 X_RETURN_STATUS => x_status,
887 X_MSG_COUNT => x_msg_count,
888 X_MSG_DATA => l_msg_data,
889 X_LABEL_STATUS => l_label_status);
890 if (l_logLevel <= wip_constants.trace_logging) then
891 wip_logger.log(p_msg => 'INV_LABEL.PRINT_LABEL_MANUAL_WRAP results',
892 x_returnStatus => l_returnStatus); --discard logging return status
893 wip_logger.log(p_msg => x_status,
894 x_returnStatus => l_returnStatus); --discard logging return status
895 wip_logger.log(p_msg => l_msg_data,
896 x_returnStatus => l_returnStatus); --discard logging return status
897 end if;
898
899
900 FOR serial_num in job_serials(l_org_id,p_wip_entity_id,l_item_id) LOOP
901
902 -- Start : Changes to fix bug #6860138 --
903 /***********
904 INV_LABEL.PRINT_LABEL_MANUAL_WRAP (
905 P_BUSINESS_FLOW_CODE => NULL,
906 P_LABEL_TYPE => 2,
907 P_ORGANIZATION_ID => l_org_id,
908 P_INVENTORY_ITEM_ID => l_item_id,
909 P_REVISION => NULL,
910 P_LOT_NUMBER => NULL,
911 P_FM_SERIAL_NUMBER => serial_num.serial_number,
912 P_TO_SERIAL_NUMBER => serial_num.serial_number,
913 P_LPN_ID => NULL,
914 P_SUBINVENTORY_CODE => NULL,
915 P_LOCATOR_ID => NULL,
916 P_DELIVERY_ID => NULL,
917 P_QUANTITY => NULL,
918 P_UOM => NULL,
919 P_WIP_ENTITY_ID => p_wip_entity_id,
920 P_NO_OF_COPIES => NULL,
921 X_RETURN_STATUS => x_status,
922 X_MSG_COUNT => x_msg_count,
923 X_MSG_DATA => l_msg_data,
924 X_LABEL_STATUS => l_label_status);
925 ***********/
926
927 print_serial_label(p_org_id => l_org_id,
928 p_serial_number => serial_num.serial_number,
929 p_item_id => l_item_id,
930 x_status => x_status,
931 x_msg_count => x_msg_count,
932 x_msg => l_msg_data
933 );
934 -- End : Changes to fix bug #6860138 --
935
936 if (l_logLevel <= wip_constants.trace_logging) then
937 wip_logger.log(p_msg => 'INV_LABEL.PRINT_LABEL_MANUAL_WRAP results for serial '||serial_num.serial_number,
938 x_returnStatus => l_returnStatus); --discard logging return status
939 wip_logger.log(p_msg => x_status,
940 x_returnStatus => l_returnStatus); --discard logging return status
941 wip_logger.log(p_msg => l_msg_data,
942 x_returnStatus => l_returnStatus); --discard logging return status
943 end if;
944
945 END LOOP;
946
947 if (l_logLevel <= wip_constants.trace_logging) then
948 wip_logger.exitPoint(p_procName => 'wip_utils.print_job_labels',
949 p_procReturnStatus => x_status,
950 p_msg => l_msg_data,
951 x_returnStatus => l_returnStatus); --discard logging return status
952 end if;
953 END print_job_labels;
954
955 /**************************************************************************/
956
957 PROCEDURE print_serial_label(p_org_id IN NUMBER,
958 p_serial_number IN VARCHAR2,
959 p_item_id IN NUMBER,
960 x_status IN OUT NOCOPY VARCHAR2,
961 x_msg_count IN OUT NOCOPY NUMBER,
962 x_msg IN OUT NOCOPY VARCHAR2
963 )
964 IS
965 l_wip_entity_id NUMBER;
966 l_item_id NUMBER;
967 l_label_status VARCHAR2(30);
968 l_msg_data VARCHAR2(100);
969 l_returnStatus VARCHAR2(1);
970 l_logLevel NUMBER := fnd_log.g_current_runtime_level;
971 l_params wip_logger.param_tbl_t;
972
973 -- Start : Changes to fix bug #6860138 --
974 l_lot_number VARCHAR2(80);
975 l_sch_st_date DATE;
976 l_item_rev VARCHAR2(3);
977 -- End : Changes to fix bug #6860138 --
978
979 BEGIN
980 x_status := fnd_api.g_ret_sts_success;
981
982 if (l_logLevel <= wip_constants.trace_logging) then
983 l_params(1).paramName := 'p_org_id';
984 l_params(1).paramValue := p_org_id;
985 l_params(2).paramName := 'p_serial_number';
986 l_params(2).paramValue := p_serial_number;
987 l_params(3).paramName := 'p_item_id';
988 l_params(3).paramValue := p_item_id;
989 l_params(4).paramName := 'x_status';
990 l_params(4).paramValue := x_status;
991 l_params(5).paramName := 'x_msg_count';
992 l_params(5).paramValue := x_msg_count;
993 l_params(6).paramName := 'x_msg';
994 l_params(6).paramValue := x_msg;
995 wip_logger.entryPoint(p_procName => 'wip_utils.print_serial_label',
996 p_params => l_params,
997 x_returnStatus => x_status);
998 if(x_status <> fnd_api.g_ret_sts_success) then
999 raise fnd_api.g_exc_unexpected_error;
1000 end if;
1001 end if;
1002
1003 l_item_id := p_item_id;
1004
1005 SELECT wip_entity_id, inventory_item_id
1006 INTO l_wip_entity_id, l_item_id
1007 FROM mtl_serial_numbers
1008 WHERE current_organization_id = p_org_id
1009 AND serial_number = p_serial_number
1010 AND inventory_item_id = nvl(l_item_id, inventory_item_id);
1011
1012 -- For completed serial number, wip_entity_id in mtl_serial_numbers will
1013 -- be null. Link mtl_object_genealogy to get wip_entity_id
1014 if(l_wip_entity_id is null) then
1015 SELECT we.wip_entity_id
1016 INTO l_wip_entity_id
1017 FROM mtl_serial_numbers msn,
1018 wip_entities we,
1019 mtl_object_genealogy mog
1020 WHERE
1021 ((mog.genealogy_origin = 1 and
1022 mog.parent_object_id = we.gen_object_id and
1023 mog.object_id = msn.gen_object_id)
1024 or
1025 (mog.genealogy_origin = 2 and
1026 mog.parent_object_id = msn.gen_object_id and
1027 mog.object_id = we.gen_object_id))
1028 and mog.end_date_active is null
1029 and msn.serial_number = p_serial_number
1030 and msn.current_organization_id = p_org_id;
1031 end if;
1032
1033 -- Start : Changes to fix bug #6860138 --
1034 SELECT wdj.lot_number,
1035 wdj.scheduled_start_date,
1036 DECODE(msi.revision_qty_control_code,
1037 WIP_CONSTANTS.REV,
1038 NVL(wdj.bom_revision,
1039 BOM_revisions.GET_ITEM_REVISION_FN
1040 ('EXCLUDE_OPEN_HOLD',-- eco_status
1041 'ALL', -- examine_type
1042 p_org_id, -- org_id
1043 l_item_id, -- item_id
1044 l_sch_st_date) -- rev_date
1045 ),
1046 NULL
1047 )
1048 INTO l_lot_number,
1049 l_sch_st_date,
1050 l_item_rev
1051 FROM mtl_system_items msi,
1052 wip_discrete_jobs wdj
1053 WHERE wdj.wip_entity_id = l_wip_entity_id
1054 AND msi.organization_id = wdj.organization_id
1055 AND msi.inventory_item_id = wdj.primary_item_id;
1056 -- End : Changes to fix bug #6860138 --
1057
1058 INV_LABEL.PRINT_LABEL_MANUAL_WRAP (
1059 P_BUSINESS_FLOW_CODE => NULL,
1060 P_LABEL_TYPE => 2,
1061 P_ORGANIZATION_ID => p_org_id,
1062 P_INVENTORY_ITEM_ID => l_item_id,
1063 P_REVISION => l_item_rev, --Fixed bug#6860138 --NULL,
1064 P_LOT_NUMBER => l_lot_number, --Fixed bug#6860138 --NULL,
1065 P_FM_SERIAL_NUMBER => p_serial_number,
1066 P_TO_SERIAL_NUMBER => p_serial_number,
1067 P_LPN_ID => NULL,
1068 P_SUBINVENTORY_CODE => NULL,
1069 P_LOCATOR_ID => NULL,
1070 P_DELIVERY_ID => NULL,
1071 P_QUANTITY => NULL,
1072 P_UOM => NULL,
1073 P_WIP_ENTITY_ID => l_wip_entity_id,
1074 P_NO_OF_COPIES => NULL,
1075 X_RETURN_STATUS => x_status,
1076 X_MSG_COUNT => x_msg_count,
1077 X_MSG_DATA => l_msg_data,
1078 X_LABEL_STATUS => l_label_status);
1079
1080 if (l_logLevel <= wip_constants.trace_logging) then
1081 wip_logger.exitPoint(p_procName => 'wip_utils.print_serial_label',
1082 p_procReturnStatus => x_status,
1083 p_msg => l_msg_data,
1084 x_returnStatus => l_returnStatus); --discard logging return status
1085 end if;
1086 END print_serial_label;
1087
1088 /**************************************************************************/
1089
1090 PROCEDURE print_move_txn_label(p_txn_id IN NUMBER,
1091 x_status IN OUT NOCOPY VARCHAR2,
1092 x_msg_count IN OUT NOCOPY NUMBER,
1093 x_msg IN OUT NOCOPY VARCHAR2
1094 )
1095 IS
1096 l_label_status VARCHAR2(30);
1097 l_returnStatus VARCHAR2(1);
1098 l_logLevel NUMBER := fnd_log.g_current_runtime_level;
1099 l_params wip_logger.param_tbl_t;
1100 l_msg_data VARCHAR2(100);
1101
1102 BEGIN
1103 x_status := fnd_api.g_ret_sts_success;
1104
1105 if (l_logLevel <= wip_constants.trace_logging) then
1106 l_params(1).paramName := 'p_txn_id';
1107 l_params(1).paramValue := p_txn_id;
1108 l_params(2).paramName := 'x_status';
1109 l_params(2).paramValue := x_status;
1110 l_params(3).paramName := 'x_msg_count';
1111 l_params(3).paramValue := x_msg_count;
1112 l_params(4).paramName := 'x_msg';
1113 l_params(4).paramValue := x_msg;
1114 wip_logger.entryPoint(p_procName => 'wip_utils.print_move_txn_label',
1115 p_params => l_params,
1116 x_returnStatus => x_status);
1117 if(x_status <> fnd_api.g_ret_sts_success) then
1118 raise fnd_api.g_exc_unexpected_error;
1119 end if;
1120 end if;
1121
1122 INV_LABEL.PRINT_LABEL_WRAP (
1123 X_RETURN_STATUS => x_status,
1124 X_MSG_COUNT => x_msg_count,
1125 X_MSG_DATA => x_msg,
1126 X_LABEL_STATUS => l_label_status,
1127 P_BUSINESS_FLOW_CODE => 41,
1128 P_TRANSACTION_ID => p_txn_id, -- from WMT
1129 P_TRANSACTION_IDENTIFIER => 9);
1130
1131 if (l_logLevel <= wip_constants.trace_logging) then
1132 wip_logger.exitPoint(p_procName => 'wip_utils.print_move_txn_label',
1133 p_procReturnStatus => x_status,
1134 p_msg => l_msg_data,
1135 x_returnStatus => l_returnStatus); --discard logging return status
1136 end if;
1137 END print_move_txn_label;
1138
1139
1140
1141 --VJ: Label Printing - End
1142 /**************************************************************************/
1143
1144
1145
1146
1147 END WIP_UTILITIES;