1 PACKAGE BODY wip_move_validator AS
2 /* $Header: wipmovvb.pls 120.14.12020000.2 2012/07/18 18:12:35 ankohli ship $ */
3 /*********************************************
4 * declare global variables for this package *
5 *********************************************/
6 g_group_id NUMBER;
7 enums txnID_list;
8
9 -- error handling procedure
10 PROCEDURE add_error(p_txn_id IN NUMBER,
11 p_err_col IN VARCHAR2,
12 p_err_msg IN VARCHAR2) IS
13 error_record request_error;
14 BEGIN
15 -- create error record
16 error_record.transaction_id := p_txn_id;
17 error_record.error_column := p_err_col;
18 error_record.error_message := substrb(p_err_msg,1,240);
19
20 -- add error record to error table (current_errors)
21 current_errors(current_errors.count + 1) := error_record;
22 END add_error;
23
24 -- error handling procedure
25 PROCEDURE add_error(p_txn_ids IN txnID_list,
26 p_err_col IN VARCHAR2,
27 p_err_msg IN VARCHAR2) IS
28
29 error_record request_error;
30
31 BEGIN
32 /* Bug#3123422 - Moved the invariable statements out of the loop
33 to optimize the code */
34 error_record.error_column := p_err_col;
35 error_record.error_message := substrb(p_err_msg,1,240);
36
37 FOR i IN 1..p_txn_ids.count LOOP
38 -- create error record
39 error_record.transaction_id := p_txn_ids(i);
40 -- add error record to error table (current_errors)
41 current_errors(current_errors.count + 1) := error_record;
42 END LOOP;
43 END add_error;
44
45 Procedure load_errors IS
46
47 n_errors NUMBER;
48 error_no NUMBER := 1;
49
50 BEGIN
51
52 n_errors := current_errors.count;
53
54 WHILE (error_no <= n_errors) LOOP
55
56 INSERT INTO wip_txn_interface_errors(
57 transaction_id,
58 error_message,
59 error_column,
60 last_update_date,
61 last_updated_by,
62 creation_date,
63 created_by,
64 last_update_login,
65 request_id,
66 program_application_id,
67 program_id,
68 program_update_date
69 )
70 SELECT current_errors(error_no).transaction_id, -- transaction_id
71 current_errors(error_no).error_message, -- error_message
72 current_errors(error_no).error_column, -- error_column
73 SYSDATE, -- last_update_date
74 NVL(last_updated_by, -1),
75 SYSDATE, -- creation_date
76 NVL(created_by, -1),
77 last_update_login,
78 request_id,
79 program_application_id,
80 program_id,
81 program_update_date
82 FROM wip_move_txn_interface
83 WHERE transaction_id = current_errors(error_no).transaction_id
84 AND group_id = g_group_id;
85
86 error_no := error_no + 1;
87 END LOOP;
88
89 -- cleare error table
90 current_errors.delete ;
91
92 END load_errors;
93 -- end error handling procedure
94
95 -- validate organization_id. The caller have an option to provide either
96 -- organization_id or organization_code. If the caller pass organization_id,
97 -- the id need to be valid. If the caller pass organization_code, we will
98 -- derive the organization_id. If the caller pass both, both value must be
99 -- consistent to each other.
100
101 /* Bug#2956953 - This procedure will be called only from wip move manager.
102 Call to this procedure from wip move worker code is commented
103 - Changes done as part of Wip Move Sequencing Project */
104
105 PROCEDURE organization_id(p_count_of_errored OUT NOCOPY NUMBER) IS
106 BEGIN
107 -- Derive ORGANIZATIOIN_ID if user provided only ORGANIZATION_CODE
108 UPDATE wip_move_txn_interface wmti
109 SET wmti.organization_id =
110 (SELECT mp.organization_id
111 FROM mtl_parameters mp
112 WHERE mp.organization_code = wmti.organization_code) --Fix by bug 9220479
113 WHERE wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
114 AND wmti.process_status = WIP_CONSTANTS.PENDING
115 AND wmti.organization_id IS NULL
116 AND wmti.organization_code IS NOT NULL;
117
118 -- reset enums table
119 enums.delete;
120
121 -- If cannot derive ORGANIZATION_ID or ORGANIZATION_ID not corresponding to
122 -- ORGANIZATION_CODE provided, error out.
123 UPDATE wip_move_txn_interface wmti
124 SET wmti.process_status = WIP_CONSTANTS.ERROR
125 WHERE wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
126 AND wmti.process_status = WIP_CONSTANTS.PENDING
127 AND ((wmti.organization_id IS NULL) -- cannot derive ORGANIZATION_ID
128 OR
129 (NOT EXISTS
130 (SELECT 'X'
131 FROM mtl_parameters mp
132 WHERE mp.organization_code = NVL(wmti.organization_code,
133 mp.organization_code)--Fix by bug 9220479
134 AND mp.organization_id = wmti.organization_id
135 )
136 ))
137 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
138
139 p_count_of_errored := sql%rowcount;
140
141 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
142 fnd_message.set_token('ENTITY1', 'ORGANIZATION_ID');
143 fnd_message.set_token('ENTITY2', 'ORGANIZATION_CODE');
144 add_error(p_txn_ids => enums,
145 p_err_col => 'ORGANIZATION_ID/CODE',
146 p_err_msg => fnd_message.get);
147
148 load_errors;
149
150 END organization_id;
151
152 -- validate wip_entity_id against wip_entities table. The caller have an
153 -- option to provide either wip_entity_id or wip_entity_name. If the caller
154 -- pass wip_entity_id, the id need to be valid. If the caller pass
155 -- wip_entity_name, we will derive the wip_entity_id. If the caller pass both,
156 -- both value must be consistent to each other. Moreover, the wip_entity_id
157 -- provided must have status that allow move transaction(3,4)
158 -- The wip_entity_id provided also need to have assembly associated with it.
159
160 -- Also validate line_id against wip_lines table. The caller have an option to
161 -- provide either line_id or line_code. If the caller pass line_id, the id
162 -- need to be valid. If the caller pass line_code, we will derive the
163 -- line_id. If the caller pass both, both value must be consistent to
164 -- each other. Only validate these values if the transaction type is
165 -- repetitive. If line_id and line_code are null, the caller need to pass
166 -- repetitive_schedule_id.
167 -- this routine will also derive the first transactable schedule if the
168 -- caller do not provide repetitive schedule id for repetitive transaction
169
170 -- Also Check that the job is not serilized. We do not support serialized
171 -- transaction for background.
172 PROCEDURE wip_entity_id IS
173 BEGIN
174 -- Derive WIP_ENTITY_ID if user provided only WIP_ENTITY_NAME
175 UPDATE wip_move_txn_interface wmti
176 SET wmti.wip_entity_id =
177 (SELECT we.wip_entity_id
178 FROM wip_entities we
179 WHERE we.wip_entity_name = wmti.wip_entity_name
180 AND we.organization_id = wmti.organization_id
181 AND entity_type IN (WIP_CONSTANTS.DISCRETE,
182 WIP_CONSTANTS.REPETITIVE,
183 WIP_CONSTANTS.LOTBASED))
184 WHERE wmti.group_id = g_group_id
185 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
186 AND wmti.process_status = WIP_CONSTANTS.RUNNING
187 AND wmti.wip_entity_id IS NULL
188 AND wmti.wip_entity_name IS NOT NULL;
189
190 -- reset enums table
191 enums.delete;
192 -- If unable to derive WIP_ENTITY_ID or WIP_ENTITY_ID not conresponding
193 -- to WIP_ENTITY_NAME specified, error out.
194 UPDATE wip_move_txn_interface wmti
195 SET wmti.process_status = WIP_CONSTANTS.ERROR
196 WHERE wmti.group_id = g_group_id
197 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
198 AND wmti.process_status = WIP_CONSTANTS.RUNNING
199 AND ((wmti.wip_entity_id IS NULL) -- cannot derive WIP_ENTITY_ID
200 OR
201 (NOT EXISTS
202 (SELECT 'X'
203 FROM wip_entities we
204 WHERE we.wip_entity_name = NVL(wmti.wip_entity_name,
205 we.wip_entity_name)
206 AND we.wip_entity_id = wmti.wip_entity_id
207 AND we.organization_id = wmti.organization_id
208 AND entity_type IN (WIP_CONSTANTS.DISCRETE,
209 WIP_CONSTANTS.REPETITIVE,
210 WIP_CONSTANTS.LOTBASED)
211 )
212 ))
213 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
214
215 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
216 fnd_message.set_token('ENTITY', 'WIP_ENTITY_ID - WIP_ENTITY_NAME');
217 add_error(p_txn_ids => enums,
218 p_err_col => 'WIP_ENTITY_ID/NAME',
219 p_err_msg => fnd_message.get);
220
221 -- Derive ENTITY_TYPE and PRIMARY_ITEM_ID from WIP_ENTITY_ID
222 UPDATE wip_move_txn_interface wmti
223 SET (wmti.entity_type, wmti.primary_item_id) =
224 (SELECT we.entity_type,
225 we.primary_item_id
226 FROM wip_entities we
227 WHERE we.wip_entity_id = wmti.wip_entity_id)
228 WHERE wmti.group_id = g_group_id
229 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
230 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
231
232 -- reset enums table
233 enums.delete;
234 -- If non-standard job and no assembly defined, error out
235 UPDATE wip_move_txn_interface wmti
236 SET wmti.process_status = WIP_CONSTANTS.ERROR
237 WHERE wmti.group_id = g_group_id
238 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
239 AND wmti.process_status = WIP_CONSTANTS.RUNNING
240 AND wmti.primary_item_id IS NULL
241 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
242
243 fnd_message.set_name('WIP', 'WIP_NO_ASSY_NO_TXN');
244 add_error(p_txn_ids => enums,
245 p_err_col => 'WIP_ENTITY_ID/NAME',
246 p_err_msg => fnd_message.get);
247
248 /************************
249 * Start Repetitive Check
250 ************************/
251 -- Derive LINE_ID if user provided only LINE_CODE.
252 UPDATE wip_move_txn_interface wmti
253 SET wmti.line_id =
254 (SELECT wl.line_id
255 FROM wip_lines wl
256 WHERE wl.line_code = wmti.line_code
257 AND wl.organization_id = wmti.organization_id
258 AND NVL(wl.disable_date, SYSDATE) >= SYSDATE)
259 WHERE wmti.group_id = g_group_id
260 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
261 AND wmti.process_status = WIP_CONSTANTS.RUNNING
262 AND wmti.entity_type = WIP_CONSTANTS.REPETITIVE
263 AND wmti.line_id IS NULL
264 AND wmti.line_code IS NOT NULL;
265
266 -- reset enums table
267 enums.delete;
268 -- If unable to derive LINE_ID or LINE_ID not conresponding to LINE_CODE
269 -- specified, error out.
270 UPDATE wip_move_txn_interface wmti
271 SET wmti.process_status = WIP_CONSTANTS.ERROR
272 WHERE wmti.group_id = g_group_id
273 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
274 AND wmti.process_status = WIP_CONSTANTS.RUNNING
275 AND wmti.entity_type = WIP_CONSTANTS.REPETITIVE
276 AND ((wmti.line_id IS NULL)
277 OR
278 (NOT EXISTS
279 (SELECT 'X'
280 FROM wip_lines wl
281 WHERE wl.line_code = NVL(wmti.line_code, wl.line_code)
282 AND wl.line_id = wmti.line_id
283 AND wl.organization_id = wmti.organization_id
284 AND NVL(wl.disable_date, SYSDATE) >= SYSDATE
285 )
286 ))
287 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
288
289 fnd_message.set_name('WIP', 'WIP_INVALID_LINE');
290 add_error(p_txn_ids => enums,
291 p_err_col => 'LINE_ID/CODE',
292 p_err_msg => fnd_message.get);
293
294 -- derive the first transactable schedule if REPETITIVE_SCHEDULE_ID is null
295 UPDATE wip_move_txn_interface wmti
296 SET wmti.repetitive_schedule_id =
297 (SELECT wrs1.repetitive_schedule_id
298 FROM wip_repetitive_schedules wrs1
299 WHERE wrs1.wip_entity_id = wmti.wip_entity_id
300 AND wrs1.organization_id = wmti.organization_id
301 AND wrs1.line_id = wmti.line_id
302 AND wrs1.status_type IN (WIP_CONSTANTS.RELEASED,
303 WIP_CONSTANTS.COMP_CHRG)
304 AND wrs1.first_unit_start_date =
305 (SELECT MIN(wrs2.first_unit_start_date)
306 FROM wip_repetitive_schedules wrs2
307 WHERE wrs2.wip_entity_id = wmti.wip_entity_id
308 AND wrs2.organization_id = wmti.organization_id
309 AND wrs2.line_id = wmti.line_id
310 AND wrs2.status_type IN (WIP_CONSTANTS.RELEASED,
311 WIP_CONSTANTS.COMP_CHRG)))
312 WHERE wmti.group_id = g_group_id
313 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
314 AND wmti.process_status = WIP_CONSTANTS.RUNNING
315 AND wmti.entity_type = WIP_CONSTANTS.REPETITIVE
316 AND wmti.repetitive_schedule_id IS NULL;
317
318 -- reset enums table
319 enums.delete;
320 -- By this time, all repetive transaction should have REPETITIVE_SCHEDULE_ID
321 -- Otherwise, error out
322 UPDATE wip_move_txn_interface wmti
323 SET wmti.process_status = WIP_CONSTANTS.ERROR
324 WHERE wmti.group_id = g_group_id
325 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
326 AND wmti.process_status = WIP_CONSTANTS.RUNNING
327 AND wmti.entity_type = WIP_CONSTANTS.REPETITIVE
328 AND wmti.repetitive_schedule_id IS NULL
329 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
330
331 fnd_message.set_name('WIP', 'WIP_INVALID_LINE');
332 add_error(p_txn_ids => enums,
333 p_err_col => 'LINE_ID/CODE',
334 p_err_msg => fnd_message.get);
335
336 /************************
337 * End Repetitive Check
338 ************************/
339
340 /************************
341 * Start Discrete Check
342 ************************/
343 -- reset enums table
344 enums.delete;
345 -- For Discrete and Lotbased, user should not provide these 3 values
346 UPDATE wip_move_txn_interface wmti
347 SET wmti.process_status = WIP_CONSTANTS.ERROR
348 WHERE wmti.group_id = g_group_id
349 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
350 AND wmti.process_status = WIP_CONSTANTS.RUNNING
351 AND wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
352 WIP_CONSTANTS.LOTBASED)
353 AND (wmti.line_id IS NOT NULL OR
354 wmti.line_code IS NOT NULL OR
355 wmti.repetitive_schedule_id IS NOT NULL)
356 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
357
358 fnd_message.set_name('WIP', 'WIP_NULL_LINE_ID');
359 add_error(p_txn_ids => enums,
360 p_err_col => 'WIP_ENTITY_ID/NAME',
361 p_err_msg => fnd_message.get);
362
363 /************************
364 * End Discrete Check
365 ************************/
366 -- reset enums table
367 enums.delete;
368 -- Check job status not either Complete or Release, error out.
369 UPDATE wip_move_txn_interface wmti
370 SET wmti.process_status = WIP_CONSTANTS.ERROR
371 WHERE wmti.group_id = g_group_id
372 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
373 AND wmti.process_status = WIP_CONSTANTS.RUNNING
374 AND ((wmti.entity_type = WIP_CONSTANTS.REPETITIVE
375 AND NOT EXISTS
376 (SELECT 'X'
377 FROM wip_repetitive_schedules wrs
378 WHERE wrs.wip_entity_id = wmti.wip_entity_id
379 AND wrs.organization_id = wmti.organization_id
380 AND wrs.line_id = wmti.line_id
381 AND wrs.status_type IN (WIP_CONSTANTS.RELEASED,
382 WIP_CONSTANTS.COMP_CHRG)))
383 OR
384 (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
385 WIP_CONSTANTS.LOTBASED)
386 AND NOT EXISTS
387 (SELECT 'X'
388 FROM wip_discrete_jobs wdj
389 WHERE wdj.wip_entity_id = wmti.wip_entity_id
390 AND wdj.organization_id = wmti.organization_id
391 AND wdj.status_type IN (WIP_CONSTANTS.RELEASED,
392 WIP_CONSTANTS.COMP_CHRG))))
393 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
394
395 fnd_message.set_name('WIP', 'WIP_NO_CHARGES_ALLOWED');
396 add_error(p_txn_ids => enums,
397 p_err_col => 'WIP_ENTITY_ID/NAME',
398 p_err_msg => fnd_message.get);
399
400 -- reset enums table
401 enums.delete;
402 -- If job/schedule specified has no routing, error out
403 UPDATE wip_move_txn_interface wmti
404 SET wmti.process_status = WIP_CONSTANTS.ERROR
405 WHERE wmti.group_id = g_group_id
406 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
407 AND wmti.process_status = WIP_CONSTANTS.RUNNING
408 AND NOT EXISTS
409 (SELECT 'X'
410 FROM wip_operations wo
411 WHERE wo.wip_entity_id = wmti.wip_entity_id
412 AND wo.organization_id = wmti.organization_id
413 AND NVL(wo.repetitive_schedule_id, -1) =
414 NVL(wmti.repetitive_schedule_id, -1))
415 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
416
417 fnd_message.set_name('WIP', 'WIP_ROUTING_NOT_FOUND');
418 fnd_message.set_token('ROUTINE', 'for Job/Schedule specified');
419 add_error(p_txn_ids => enums,
420 p_err_col => 'WIP_ENTITY_ID/NAME',
421 p_err_msg => fnd_message.get);
422
423 END wip_entity_id;
424
425 -- validate transaction_type. If the callers did not provide this info,
426 -- default to regular move. We do not support easy completion/return for
427 -- both discrete and repetitive if the assembly is under serial control.
428 -- We allow easy completion/return if the assembly is under lot control,
429 -- but the caller need to provide lot information when define a job.
430 -- However, we support only discrete and lotbased for this feature.
431 -- For repetitive, if the assembly is under lot control, it will error out.
432 PROCEDURE transaction_type IS
433 BEGIN
434 -- Default TRANSACTION_TYPE to Move if users do not provide one
435 UPDATE wip_move_txn_interface wmti
436 SET wmti.transaction_type = WIP_CONSTANTS.MOVE_TXN
437 WHERE wmti.group_id = g_group_id
438 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
439 AND wmti.process_status = WIP_CONSTANTS.RUNNING
440 AND wmti.transaction_type IS NULL;
441
442 -- reset enums table
443 enums.delete;
444 -- Errot out, if transaction type not either Move or EZ Complete or
445 -- EZ Return
446 UPDATE wip_move_txn_interface wmti
447 SET wmti.process_status = WIP_CONSTANTS.ERROR
448 WHERE wmti.group_id = g_group_id
449 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
450 AND wmti.process_status = WIP_CONSTANTS.RUNNING
451 AND wmti.transaction_type NOT IN (WIP_CONSTANTS.MOVE_TXN,
452 WIP_CONSTANTS.COMP_TXN,
453 WIP_CONSTANTS.RET_TXN)
454 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
455
456 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
457 fnd_message.set_token('ENTITY', 'TRANSACTION_TYPE');
458 add_error(p_txn_ids => enums,
459 p_err_col => 'TRANSACTION_TYPE',
460 p_err_msg => fnd_message.get);
461
462 -- reset enums table
463 enums.delete;
464 -- Error out if easy completion/return and the assembly is under serial
465 -- control because we cannot gather or derive serial number for background
466 -- txns
467 UPDATE wip_move_txn_interface wmti
468 SET wmti.process_status = WIP_CONSTANTS.ERROR
469 WHERE wmti.group_id = g_group_id
470 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
471 AND wmti.process_status = WIP_CONSTANTS.RUNNING
472 AND wmti.transaction_type IN (WIP_CONSTANTS.COMP_TXN,
473 WIP_CONSTANTS.RET_TXN)
474 AND EXISTS
475 (SELECT 'X'
476 FROM mtl_system_items msi,
477 wip_discrete_jobs wdj
478 WHERE wdj.wip_entity_id = wmti.wip_entity_id
479 AND msi.inventory_item_id = wmti.primary_item_id
480 AND msi.organization_id = wmti.organization_id
481 AND wdj.serialization_start_op IS NULL
482 AND msi.serial_number_control_code IN (WIP_CONSTANTS.FULL_SN,
483 WIP_CONSTANTS.DYN_RCV_SN))
484 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
485
486 fnd_message.set_name('WIP', 'WIP_EZ_NO_SERIAL_CONTROL2');
487 add_error(p_txn_ids => enums,
488 p_err_col => 'TRANSACTION_TYPE',
489 p_err_msg => fnd_message.get);
490
491 -- reset enums table
492 enums.delete;
493 -- Error out if easy completion/return and no default completion subinventory
494 -- locator defined for both Discrete and Repetitive Schedule
495 UPDATE wip_move_txn_interface wmti
496 SET wmti.process_status = WIP_CONSTANTS.ERROR
497 WHERE wmti.group_id = g_group_id
498 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
499 AND wmti.process_status = WIP_CONSTANTS.RUNNING
500 AND wmti.transaction_type IN (WIP_CONSTANTS.COMP_TXN,
501 WIP_CONSTANTS.RET_TXN)
502 AND ((wmti.entity_type = WIP_CONSTANTS.REPETITIVE
503 AND EXISTS
504 (SELECT 'X'
505 FROM wip_repetitive_items wri
506 WHERE wri.wip_entity_id = wmti.wip_entity_id
507 AND wri.organization_id = wmti.organization_id
508 AND wri.line_id = wmti.line_id
509 AND wri.completion_subinventory IS NULL))
510 OR
511 (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
512 WIP_CONSTANTS.LOTBASED)
513 AND EXISTS
514 (SELECT 'X'
515 FROM wip_discrete_jobs wdj
516 WHERE wdj.wip_entity_id = wmti.wip_entity_id
517 AND wdj.organization_id = wmti.organization_id
518 AND wdj.completion_subinventory IS NULL)))
519 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
520
521 fnd_message.set_name('WIP', 'WIP_EZ_NO_SUBINV_DEFAULT2');
522 add_error(p_txn_ids => enums,
523 p_err_col => 'TRANSACTION_TYPE',
524 p_err_msg => fnd_message.get);
525
526 -- reset enums table
527 enums.delete;
528 -- Error out if item revision does not exist as a BOM revision
529 UPDATE wip_move_txn_interface wmti
530 SET wmti.process_status = WIP_CONSTANTS.ERROR
531 WHERE wmti.group_id = g_group_id
532 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
533 AND wmti.process_status = WIP_CONSTANTS.RUNNING
534 AND wmti.transaction_type IN (WIP_CONSTANTS.COMP_TXN,
535 WIP_CONSTANTS.RET_TXN)
536 AND EXISTS
537 (SELECT 'X'
538 FROM mtl_system_items msi
539 WHERE msi.inventory_item_id = wmti.primary_item_id
540 AND msi.organization_id = wmti.organization_id
541 AND msi.revision_qty_control_code =
542 WIP_CONSTANTS.REVISION_CONTROLLED)
543 AND ((wmti.entity_type = WIP_CONSTANTS.REPETITIVE
544 AND NOT EXISTS
545 (SELECT 'X'
546 FROM wip_repetitive_schedules wrs,
547 mtl_item_revisions mir
548 WHERE wrs.organization_id = wmti.organization_id
549 AND wrs.repetitive_schedule_id = wmti.repetitive_schedule_id
550 AND mir.organization_id = wmti.organization_id
551 AND mir.inventory_item_id = wmti.primary_item_id
552 -- Fixed bug 2387630
553 AND (wrs.bom_revision IS NULL OR
554 mir.revision = wrs.bom_revision)))
555 OR
556 (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
557 WIP_CONSTANTS.LOTBASED)
558 AND NOT EXISTS
559 (SELECT 'X'
560 FROM wip_discrete_jobs wdj,
561 mtl_item_revisions mir
562 WHERE wdj.organization_id = wmti.organization_id
563 AND wdj.wip_entity_id = wmti.wip_entity_id
564 AND mir.organization_id = wmti.organization_id
565 AND mir.inventory_item_id = wmti.primary_item_id
566 -- Fixed bug 2387630
567 AND (wdj.bom_revision IS NULL OR
568 mir.revision = wdj.bom_revision))))
569 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
570
571 fnd_message.set_name('WIP', 'WIP_BOM_ITEM_REVISION');
572 add_error(p_txn_ids => enums,
573 p_err_col => 'TRANSACTION_TYPE',
574 p_err_msg => fnd_message.get);
575
576 -- reset enums table
577 enums.delete;
578 -- Error out if easy completion /return for repetitive schedule
579 -- and the assembly is under lot control
580 UPDATE wip_move_txn_interface wmti
581 SET wmti.process_status = WIP_CONSTANTS.ERROR
582 WHERE wmti.group_id = g_group_id
583 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
584 AND wmti.process_status = WIP_CONSTANTS.RUNNING
585 AND wmti.entity_type = WIP_CONSTANTS.REPETITIVE
586 AND wmti.transaction_type IN (WIP_CONSTANTS.COMP_TXN,
587 WIP_CONSTANTS.RET_TXN)
588 AND EXISTS
589 (SELECT 'X'
590 FROM mtl_system_items msi
591 WHERE msi.inventory_item_id = wmti.primary_item_id
592 AND msi.organization_id = wmti.organization_id
593 AND msi.lot_control_code = WIP_CONSTANTS.LOT)
594 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
595
596 fnd_message.set_name('WIP', 'WIP_EZ_NO_REP_LOT_CONTROL2');
597 add_error(p_txn_ids => enums,
598 p_err_col => 'TRANSACTION_TYPE',
599 p_err_msg => fnd_message.get);
600
601 -- reset enums table
602 enums.delete;
603 -- Error out if easy completion /return for Discrete job and the assembly
604 -- is under lot control and there is no default completion lot defined
605 UPDATE wip_move_txn_interface wmti
606 SET wmti.process_status = WIP_CONSTANTS.ERROR
607 WHERE wmti.group_id = g_group_id
608 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
609 AND wmti.process_status = WIP_CONSTANTS.RUNNING
610 AND wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
611 WIP_CONSTANTS.LOTBASED)
612 AND wmti.transaction_type IN (WIP_CONSTANTS.COMP_TXN,
613 WIP_CONSTANTS.RET_TXN)
614 AND EXISTS
615 (SELECT 'X'
616 FROM mtl_system_items msi
617 WHERE msi.inventory_item_id = wmti.primary_item_id
618 AND msi.organization_id = wmti.organization_id
619 AND msi.lot_control_code = WIP_CONSTANTS.LOT)
620 AND EXISTS
621 (SELECT 'X'
622 FROM wip_discrete_jobs wdj
623 WHERE wdj.organization_id = wmti.organization_id
624 AND wdj.wip_entity_id = wmti.wip_entity_id
625 AND wdj.lot_number IS NULL)
626 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
627
628 fnd_message.set_name('WIP', 'WIP_EZ_NO_JOB_LOT_DEFAULT2');
629 add_error(p_txn_ids => enums,
630 p_err_col => 'TRANSACTION_TYPE',
631 p_err_msg => fnd_message.get);
632
633 -- reset enums table
634 enums.delete;
635 -- Error out if easy completion to the new lot number and and either this
636 -- item or this item category requires "Lot Attributes".
637 UPDATE wip_move_txn_interface wmti
638 SET wmti.process_status = WIP_CONSTANTS.ERROR
639 WHERE wmti.group_id = g_group_id
640 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
641 AND wmti.process_status = WIP_CONSTANTS.RUNNING
642 AND wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
643 WIP_CONSTANTS.LOTBASED)
644 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
645 AND EXISTS -- lot control
646 (SELECT 'X'
647 FROM mtl_system_items msi
648 WHERE msi.inventory_item_id = wmti.primary_item_id
649 AND msi.organization_id = wmti.organization_id
650 AND msi.lot_control_code = WIP_CONSTANTS.LOT)
651 -- This is the first time to complete this assembly to this lot number
652 AND NOT EXISTS
653 (SELECT 'X'
654 FROM mtl_lot_numbers mln,
655 wip_discrete_jobs wdj
656 WHERE wdj.wip_entity_id = wmti.wip_entity_id
657 AND wdj.organization_id = wmti.organization_id
658 AND mln.inventory_item_id = wmti.primary_item_id
659 AND mln.organization_id = wmti.organization_id
660 AND mln.lot_number = wdj.lot_number)
661 -- This item or item category requires lot attributes
662 AND 2 = inv_lot_sel_attr.is_enabled(
663 'Lot Attributes', -- p_flex_name
664 wmti.organization_id, -- p_organization_id
665 wmti.primary_item_id) -- p_inventory_item_id
666 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
667
668 fnd_message.set_name('WIP', 'WIP_LOT_ATTR_NOT_ALLOW');
669 add_error(p_txn_ids => enums,
670 p_err_col => 'TRANSACTION_TYPE',
671 p_err_msg => fnd_message.get);
672
673 -- reset enums table
674 enums.delete;
675 -- Error out if easy completion to the new lot number and lot expiration date
676 -- was set to user-defined
677 UPDATE wip_move_txn_interface wmti
678 SET wmti.process_status = WIP_CONSTANTS.ERROR
679 WHERE wmti.group_id = g_group_id
680 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
681 AND wmti.process_status = WIP_CONSTANTS.RUNNING
682 AND wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
683 WIP_CONSTANTS.LOTBASED)
684 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
685 AND EXISTS -- lot control and expiration date is user-defined
686 (SELECT 'X'
687 FROM mtl_system_items msi
688 WHERE msi.inventory_item_id = wmti.primary_item_id
689 AND msi.organization_id = wmti.organization_id
690 AND msi.lot_control_code = WIP_CONSTANTS.LOT
691 AND msi.shelf_life_code = WIP_CONSTANTS.USER_DEFINED_EXP)
692 -- This is the first time to complete this assembly to this lot number
693 AND NOT EXISTS
694 (SELECT 'X'
695 FROM mtl_lot_numbers mln,
696 wip_discrete_jobs wdj
697 WHERE wdj.wip_entity_id = wmti.wip_entity_id
698 AND wdj.organization_id = wmti.organization_id
699 AND mln.inventory_item_id = wmti.primary_item_id
700 AND mln.organization_id = wmti.organization_id
701 AND mln.lot_number = wdj.lot_number)
702 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
703
704 fnd_message.set_name('WIP', 'WIP_USER_DEF_EXP_NOT_ALLOW');
705 add_error(p_txn_ids => enums,
706 p_err_col => 'TRANSACTION_TYPE',
707 p_err_msg => fnd_message.get);
708
709 END transaction_type;
710
711 -- validate transaction_date. Transaction date must be less than or equal
712 -- to SYSDATE, and greater than or equal to released date.
713 PROCEDURE transaction_date IS
714 BEGIN
715 -- reset enums table
716 enums.delete;
717 -- Error out if TRANSACTION_DATE is the future date
718 UPDATE wip_move_txn_interface wmti
719 SET wmti.process_status = WIP_CONSTANTS.ERROR
720 WHERE wmti.group_id = g_group_id
721 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
722 AND wmti.process_status = WIP_CONSTANTS.RUNNING
723 AND wmti.transaction_date > SYSDATE
724 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
725
726 fnd_message.set_name('WIP', 'WIP_NO_FORWARD_DATING');
727 add_error(p_txn_ids => enums,
728 p_err_col => 'TRANSACTION_DATE',
729 p_err_msg => fnd_message.get);
730
731 /* Fix for bug 5685099 : Validate if TRANSACTION_DATE falls in open accounting period. */
732 -- reset enums table
733 enums.delete;
734 -- Error out if TRANSACTION_DATE does not fall in open period
735 UPDATE wip_move_txn_interface wmti
736 SET wmti.process_status = WIP_CONSTANTS.ERROR
737 WHERE wmti.group_id = g_group_id
738 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
739 AND wmti.process_status = WIP_CONSTANTS.RUNNING
740 AND NOT EXISTS
741 (SELECT 'X'
742 FROM ORG_ACCT_PERIODS OAP
743 WHERE OAP.ORGANIZATION_ID = WMTI.ORGANIZATION_ID
744 AND OAP.PERIOD_CLOSE_DATE IS NULL
745 AND OAP.OPEN_FLAG = 'Y'
746 AND TRUNC(INV_LE_TIMEZONE_PUB.GET_LE_DAY_FOR_INV_ORG(
747 WMTI.TRANSACTION_DATE, -- p_trxn_date
748 WMTI.ORGANIZATION_ID -- p_inv_org_id
749 ))
750 BETWEEN OAP.PERIOD_START_DATE AND OAP.SCHEDULE_CLOSE_DATE)
751 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
752
753 fnd_message.set_name('WIP', 'WIP_DATE_IN_OPEN_PERIOD');
754 add_error(p_txn_ids => enums,
755 p_err_col => 'TRANSACTION_DATE',
756 p_err_msg => fnd_message.get);
757
758 /* end fix for bug 5685099 */
759
760 -- reset enums table
761 enums.delete;
762 -- Error out if TRANSACTION_DATE is before released date
763 UPDATE wip_move_txn_interface wmti
764 SET wmti.process_status = WIP_CONSTANTS.ERROR
765 WHERE wmti.group_id = g_group_id
766 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
767 AND wmti.process_status = WIP_CONSTANTS.RUNNING
768 AND ((wmti.entity_type = WIP_CONSTANTS.REPETITIVE
769 AND EXISTS
770 (SELECT 'X'
771 FROM wip_repetitive_schedules wrs
772 WHERE wrs.repetitive_schedule_id = wmti.repetitive_schedule_id
773 AND wrs.organization_id = wmti.organization_id
774 AND wrs.date_released > wmti.transaction_date))
775 OR
776 (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
777 WIP_CONSTANTS.LOTBASED)
778 AND EXISTS
779 (SELECT 'X'
780 FROM wip_discrete_jobs wdj
781 WHERE wdj.wip_entity_id = wmti.wip_entity_id
782 AND wdj.organization_id = wmti.organization_id
783 AND wdj.date_released > wmti.transaction_date)))
784 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
785
786 fnd_message.set_name('WIP', 'WIP_RELEASE_DATE');
787 add_error(p_txn_ids => enums,
788 p_err_col => 'TRANSACTION_DATE',
789 p_err_msg => fnd_message.get);
790
791 -- Derive ACCT_PERIOD_ID from TRANSACTION_DATE
792 UPDATE wip_move_txn_interface wmti
793 SET wmti.acct_period_id =
794 (SELECT oap.acct_period_id
795 FROM org_acct_periods oap
796 WHERE oap.organization_id = wmti.organization_id
797 -- modified the statement below for timezone project in J
798 AND TRUNC(inv_le_timezone_pub.get_le_day_for_inv_org(
799 wmti.transaction_date, -- p_trxn_date
800 wmti.organization_id -- p_inv_org_id
801 )) BETWEEN
802 oap.period_start_date AND oap.schedule_close_date)
803 WHERE wmti.group_id = g_group_id
804 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
805 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
806
807 -- reset enums table
808 enums.delete;
809 -- Error out if there is no open accout period for the TRANSACTION_DATE
810 -- specified or there is no WIP_PERIOD_BALANCES
811 UPDATE wip_move_txn_interface wmti
812 SET wmti.process_status = WIP_CONSTANTS.ERROR
813 WHERE wmti.group_id = g_group_id
814 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
815 AND wmti.process_status = WIP_CONSTANTS.RUNNING
816 AND (wmti.acct_period_id IS NULL
817 OR
818 NOT EXISTS
819 (SELECT 'X'
820 FROM wip_period_balances wpb
821 WHERE wpb.acct_period_id = wmti.acct_period_id
822 AND wpb.wip_entity_id = wmti.wip_entity_id
823 AND wpb.organization_id = wmti.organization_id
824 AND (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
825 WIP_CONSTANTS.LOTBASED)
826 OR (wmti.entity_type = WIP_CONSTANTS.REPETITIVE
827 AND repetitive_schedule_id IN
828 (SELECT wrs.repetitive_schedule_id
829 FROM wip_repetitive_schedules wrs
830 WHERE wrs.wip_entity_id = wmti.wip_entity_id
831 AND wrs.organization_id = wmti.organization_id
832 AND wrs.status_type IN (WIP_CONSTANTS.RELEASED,
833 WIP_CONSTANTS.COMP_CHRG))))))
834 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
835
836 fnd_message.set_name('WIP', 'WIP_NO_BALANCE');
837 add_error(p_txn_ids => enums,
838 p_err_col => 'TRANSACTION_DATE',
839 p_err_msg => fnd_message.get);
840
841 END transaction_date;
842
843 -- validate fm_operation_seq_num. From operation must be a valid operation.
844 -- For easy return transaction, from operation must be the last operation.
845 -- Callers always need to pass this value except for Return transactions.
846 -- If callers do not provide this info and it is return transaction, just
847 -- default fm_operation to last_op
848 PROCEDURE fm_operation IS
849 l_last_op NUMBER;
850 BEGIN
851 -- Set FM_OPERATION_SEQ_NUM to last_operation if TRANSACTION_TYPE is
852 -- EZ Return and FM_OPERATION_SEQ_NUM is null
853 UPDATE wip_move_txn_interface wmti
854 SET wmti.fm_operation_seq_num =
855 (SELECT wo.operation_seq_num
856 FROM wip_operations wo
857 WHERE wo.wip_entity_id = wmti.wip_entity_id
858 AND wo.organization_id = wmti.organization_id
859 AND NVL(wo.repetitive_schedule_id, -1) =
860 NVL(wmti.repetitive_schedule_id, -1)
861 AND wo.next_operation_seq_num IS NULL)
862 WHERE wmti.group_id = g_group_id
863 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
864 AND wmti.process_status = WIP_CONSTANTS.RUNNING
865 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
866 AND wmti.fm_operation_seq_num IS NULL;
867
868 -- reset enums table
869 enums.delete;
870 -- Error out if FM_OPERATION_SEQ_NUM is null or FM_OPERATION_SEQ_NUM
871 -- is invalid
872 UPDATE wip_move_txn_interface wmti
873 SET wmti.process_status = WIP_CONSTANTS.ERROR
874 WHERE wmti.group_id = g_group_id
875 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
876 AND wmti.process_status = WIP_CONSTANTS.RUNNING
877 AND (wmti.fm_operation_seq_num IS NULL
878 OR
879 (NOT EXISTS
880 (SELECT 'X'
881 FROM wip_operations wo
882 WHERE wo.wip_entity_id = wmti.wip_entity_id
883 AND wo.organization_id = wmti.organization_id
884 AND wo.operation_seq_num = wmti.fm_operation_seq_num
885 AND NVL(wo.repetitive_schedule_id, -1) =
886 NVL(wmti.repetitive_schedule_id, -1))))
887 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
888
889 fnd_message.set_name('WIP', 'WIP_INVALID_OPERATION');
890 add_error(p_txn_ids => enums,
891 p_err_col => 'FM_OPERATION_SEQ_NUM',
892 p_err_msg => fnd_message.get);
893
894 -- reset enums table
895 enums.delete;
896 -- Error out if TRANSACTION_TYPE is EZ Return and FM_OPERATION_SEQ_NUM
897 -- is not equal to the last operation.
898 UPDATE wip_move_txn_interface wmti
899 SET wmti.process_status = WIP_CONSTANTS.ERROR
900 WHERE wmti.group_id = g_group_id
901 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
902 AND wmti.process_status = WIP_CONSTANTS.RUNNING
903 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
904 AND wmti.fm_operation_seq_num <>
905 (SELECT wo.operation_seq_num
906 FROM wip_operations wo
907 WHERE wo.wip_entity_id = wmti.wip_entity_id
908 AND wo.organization_id = wmti.organization_id
909 AND NVL(wo.repetitive_schedule_id, -1) =
910 NVL(wmti.repetitive_schedule_id, -1)
911 AND wo.next_operation_seq_num IS NULL)
912 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
913
914 fnd_message.set_name('WIP', 'WIP_EZ_FM_LAST_OP');
915 add_error(p_txn_ids => enums,
916 p_err_col => 'FM_OPERATION_SEQ_NUM',
917 p_err_msg => fnd_message.get);
918 END fm_operation;
919
920 -- validate fm_intraoperation_step_type. From step must be valid.
921 -- If easy return transaction, from step must be "To move". If easy complete,
922 -- from step cannot be "To move" when from operation is the last operation.
923 -- You cannot move out of an operaion/step that has a No Move shop floor status
924 -- attached. If callers do not provide this info and it is return transaction,
925 -- just default fm_step to to move
926 PROCEDURE fm_step IS
927 l_sf_status VARCHAR2(100); /*Fix Bug 9758848*/
928 BEGIN
929 -- Set FM_INTRAOPERATION_STEP_TYPE to Tomove if TRANSACTION_TYPE is
930 -- EZ Return and FM_INTRAOPERATION_STEP_TYPE is null
931 UPDATE wip_move_txn_interface wmti
932 SET wmti.fm_intraoperation_step_type = WIP_CONSTANTS.TOMOVE
933 WHERE wmti.group_id = g_group_id
934 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
935 AND wmti.process_status = WIP_CONSTANTS.RUNNING
936 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
937 AND wmti.fm_intraoperation_step_type IS NULL;
938
939 -- reset enums table
940 enums.delete;
941 -- Error out if FM_INTRAOPERATION_STEP_TYPE is null or invalid
942 UPDATE wip_move_txn_interface wmti
943 SET wmti.process_status = WIP_CONSTANTS.ERROR
944 WHERE wmti.group_id = g_group_id
945 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
946 AND wmti.process_status = WIP_CONSTANTS.RUNNING
947 AND (wmti.fm_intraoperation_step_type IS NULL
948 OR
949 (NOT EXISTS
950 (SELECT 'X'
951 FROM wip_valid_intraoperation_steps wvis,
952 wip_operations wo
953 WHERE wvis.organization_id = wmti.organization_id
954 AND wvis.step_lookup_type = wmti.fm_intraoperation_step_type
955 AND wo.organization_id = wmti.organization_id
956 AND wo.wip_entity_id = wmti.wip_entity_id
957 AND wo.operation_seq_num = wmti.fm_operation_seq_num
958 AND NVL(wo.repetitive_schedule_id, -1) =
959 NVL(wmti.repetitive_schedule_id, -1)
960 AND ((wvis.record_creator = 'USER' OR
961 wvis.step_lookup_type = WIP_CONSTANTS.QUEUE)
962 OR
963 (wvis.record_creator = 'SYSTEM' AND
964 wo.next_operation_seq_num IS NULL)))))
965 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
966
967 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
968 fnd_message.set_token('ENTITY', 'FM_INTRAOPERATION_STEP_TYPE');
969 add_error(p_txn_ids => enums,
970 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
971 p_err_msg => fnd_message.get);
972
973 -- reset enums table
974 enums.delete;
975 -- Error out if FM_OPERATION_SEQ_NUM/FM_INTRAOPERATION_STEP_TYPE has
976 -- no move shop floor status attached
977 UPDATE wip_move_txn_interface wmti
978 SET wmti.process_status = WIP_CONSTANTS.ERROR
979 WHERE wmti.group_id = g_group_id
980 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
981 AND wmti.process_status = WIP_CONSTANTS.RUNNING
982 AND EXISTS
983 (SELECT 'X'
984 FROM wip_shop_floor_status_codes wsc,
985 wip_shop_floor_statuses ws
986 WHERE wsc.organization_id = wmti.organization_id
987 AND ws.organization_id = wmti.organization_id
988 AND ws.wip_entity_id = wmti.wip_entity_id
989 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
990 AND ws.operation_seq_num = wmti.fm_operation_seq_num
991 AND ws.intraoperation_step_type = wmti.fm_intraoperation_step_type
992 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
993 AND wsc.status_move_flag = WIP_CONSTANTS.NO
994 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
995 AND (wmti.source_code IS NULL OR
996 wmti.source_code <> 'RCV' OR
997 (wmti.source_code = 'RCV' AND
998 NOT EXISTS
999 (SELECT 'X'
1000 FROM wip_parameters wp
1001 WHERE wp.organization_id = wmti.organization_id
1002 AND wp.osp_shop_floor_status =
1003 wsc.shop_floor_status_code))))
1004 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1005
1006 /* Added the following for SUN enhancement in Bug 9758848*/
1007 if enums.count > 0 then
1008 for i in 1..enums.count loop
1009 SELECT ws.shop_floor_status_code
1010 into l_sf_status
1011 FROM wip_shop_floor_status_codes wsc,
1012 wip_shop_floor_statuses ws,
1013 wip_move_txn_interface wmti
1014 WHERE wsc.organization_id = wmti.organization_id
1015 AND ws.organization_id = wmti.organization_id
1016 AND ws.wip_entity_id = wmti.wip_entity_id
1017 AND wmti.transaction_id = enums(i)
1018 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
1019 AND ws.operation_seq_num = wmti.fm_operation_seq_num
1020 AND ws.intraoperation_step_type = wmti.fm_intraoperation_step_type
1021 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
1022 AND wsc.status_move_flag = WIP_CONSTANTS.NO
1023 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
1024 AND rownum = 1;
1025
1026 fnd_message.set_name('WIP', 'WIP_SF_STATUS_NO_TXN1');
1027 fnd_message.set_token('SF_STATUS', to_char(l_sf_status));
1028 add_error(p_txn_id => enums(i),
1029 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
1030 p_err_msg => fnd_message.get);
1031 end loop;
1032 end if;
1033
1034 -- reset enums table
1035 enums.delete;
1036 -- Error out if users try to perform easy completion from Tomove of the
1037 -- last operation
1038 UPDATE wip_move_txn_interface wmti
1039 SET wmti.process_status = WIP_CONSTANTS.ERROR
1040 WHERE wmti.group_id = g_group_id
1041 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1042 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1043 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1044 AND wmti.fm_intraoperation_step_type = WIP_CONSTANTS.TOMOVE
1045 AND wmti.fm_operation_seq_num =
1046 (SELECT wo.operation_seq_num
1047 FROM wip_operations wo
1048 WHERE wo.wip_entity_id = wmti.wip_entity_id
1049 AND wo.organization_id = wmti.organization_id
1050 AND NVL(wo.repetitive_schedule_id, -1) =
1051 NVL(wmti.repetitive_schedule_id, -1)
1052 AND wo.next_operation_seq_num IS NULL)
1053 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1054
1055 fnd_message.set_name('WIP', 'WIP_EZ_NO_CMP_LAST_OP2');
1056 add_error(p_txn_ids => enums,
1057 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
1058 p_err_msg => fnd_message.get);
1059
1060 -- reset enums table
1061 enums.delete;
1062 -- Error out if TRANSACTION_TYPE is EZ Return and
1063 -- FM_INTRAOPERATION_STEP_TYPE not equal to Tomove
1064 UPDATE wip_move_txn_interface wmti
1065 SET wmti.process_status = WIP_CONSTANTS.ERROR
1066 WHERE wmti.group_id = g_group_id
1067 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1068 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1069 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
1070 AND wmti.fm_intraoperation_step_type <> WIP_CONSTANTS.TOMOVE
1071 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1072
1073 fnd_message.set_name('WIP', 'WIP_EZ_FM_LAST_STEP');
1074 add_error(p_txn_ids => enums,
1075 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
1076 p_err_msg => fnd_message.get);
1077 END fm_step;
1078
1079 -- validate to_operation_seq_num. To operation must be a valid operation.
1080 -- For easy complete transaction, To operation must be the last operation.
1081 -- Callers always need to pass this value except for Easy complete
1082 -- transactions. If callers do not provide this info and it is complete
1083 -- transaction, just default to_operation to last_op
1084 PROCEDURE to_operation IS
1085 BEGIN
1086 -- Set TO_OPERATION_SEQ_NUM to last_operation if TRANSACTION_TYPE is
1087 -- EZ Completion and TO_OPERATION_SEQ_NUM is null
1088 UPDATE wip_move_txn_interface wmti
1089 SET wmti.to_operation_seq_num =
1090 (SELECT wo.operation_seq_num
1091 FROM wip_operations wo
1092 WHERE wo.wip_entity_id = wmti.wip_entity_id
1093 AND wo.organization_id = wmti.organization_id
1094 AND NVL(wo.repetitive_schedule_id, -1) =
1095 NVL(wmti.repetitive_schedule_id, -1)
1096 AND wo.next_operation_seq_num IS NULL)
1097 WHERE wmti.group_id = g_group_id
1098 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1099 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1100 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1101 AND wmti.to_operation_seq_num IS NULL;
1102
1103 /*Bug 4421485->Even for plain moves we will derive to_operation as
1104 next count point operation */
1105 UPDATE wip_move_txn_interface wmti
1106 SET wmti.to_operation_seq_num =
1107 (SELECT MIN(wo.operation_seq_num)
1108 FROM wip_operations wo
1109 WHERE wo.organization_id = wmti.organization_id
1110 AND wo.wip_entity_id = wmti.wip_entity_id
1111 AND NVL(wo.repetitive_schedule_id, -1) =
1112 NVL(wmti.repetitive_schedule_id, -1)
1113 AND wo.operation_seq_num > wmti.fm_operation_seq_num
1114 AND wo.count_point_type = 1)
1115 WHERE wmti.group_id = g_group_id
1116 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1117 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1118 AND wmti.transaction_type = WIP_CONSTANTS.MOVE_TXN
1119 AND wmti.to_operation_seq_num IS NULL;
1120
1121 -- reset enums table
1122 enums.delete;
1123 -- Error out if TO_OPERATION_SEQ_NUM is null or TO_OPERATION_SEQ_NUM
1124 -- is invalid
1125 UPDATE wip_move_txn_interface wmti
1126 SET wmti.process_status = WIP_CONSTANTS.ERROR
1127 WHERE wmti.group_id = g_group_id
1128 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1129 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1130 AND (wmti.to_operation_seq_num IS NULL
1131 OR
1132 (NOT EXISTS
1133 (SELECT 'X'
1134 FROM wip_operations wo
1135 WHERE wo.wip_entity_id = wmti.wip_entity_id
1136 AND wo.organization_id = wmti.organization_id
1137 AND wo.operation_seq_num = wmti.to_operation_seq_num
1138 AND NVL(wo.repetitive_schedule_id, -1) =
1139 NVL(wmti.repetitive_schedule_id, -1))))
1140 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1141
1142 fnd_message.set_name('WIP', 'WIP_INVALID_OPERATION');
1143 add_error(p_txn_ids => enums,
1144 p_err_col => 'TO_OPERATION_SEQ_NUM',
1145 p_err_msg => fnd_message.get);
1146
1147 -- reset enums table
1148 enums.delete;
1149 -- Error out if TRANSACTION_TYPE is EZ Ccmplete and TO_OPERATION_SEQ_NUM
1150 -- is not equal to the last operation.
1151 UPDATE wip_move_txn_interface wmti
1152 SET wmti.process_status = WIP_CONSTANTS.ERROR
1153 WHERE wmti.group_id = g_group_id
1154 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1155 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1156 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1157 AND wmti.to_operation_seq_num <>
1158 (SELECT wo.operation_seq_num
1159 FROM wip_operations wo
1160 WHERE wo.wip_entity_id = wmti.wip_entity_id
1161 AND wo.organization_id = wmti.organization_id
1162 AND NVL(wo.repetitive_schedule_id, -1) =
1163 NVL(wmti.repetitive_schedule_id, -1)
1164 AND wo.next_operation_seq_num IS NULL)
1165 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1166
1167 fnd_message.set_name('WIP', 'WIP_EZ_TO_LAST_OP');
1168 add_error(p_txn_ids => enums,
1169 p_err_col => 'TO_OPERATION_SEQ_NUM',
1170 p_err_msg => fnd_message.get);
1171 END to_operation;
1172
1173 -- validate to_intraoperation_step_type. To step must be valid.
1174 -- If easy complete transaction, to step must be "To move". If easy return,
1175 -- to step cannot be "To move" when to operation is the last operation.
1176 -- If callers do not provide this info and it is complete transaction,
1177 -- just default to_step to to move
1178 PROCEDURE to_step IS
1179 l_sf_status VARCHAR2(100); /*Fix Bug 9758848*/
1180 BEGIN
1181 -- Set TO_INTRAOPERATION_STEP_TYPE to Tomove if TRANSACTION_TYPE is
1182 -- EZ Complete and TO_INTRAOPERATION_STEP_TYPE is null
1183 UPDATE wip_move_txn_interface wmti
1184 /*Bug Bug 4421485*/
1185 SET wmti.to_intraoperation_step_type =
1186 DECODE(wmti.transaction_type,
1187 WIP_CONSTANTS.COMP_TXN,WIP_CONSTANTS.TOMOVE, WIP_CONSTANTS.QUEUE)
1188 WHERE wmti.group_id = g_group_id
1189 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1190 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1191 /*Bug Bug 4421485*/
1192 AND wmti.transaction_type IN (WIP_CONSTANTS.COMP_TXN,
1193 WIP_CONSTANTS.MOVE_TXN)
1194 AND wmti.to_intraoperation_step_type IS NULL;
1195
1196 -- reset enums table
1197 enums.delete;
1198 -- Error out if TO_INTRAOPERATION_STEP_TYPE is null or invalid
1199 UPDATE wip_move_txn_interface wmti
1200 SET wmti.process_status = WIP_CONSTANTS.ERROR
1201 WHERE wmti.group_id = g_group_id
1202 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1203 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1204 AND (wmti.to_intraoperation_step_type IS NULL
1205 OR
1206 (NOT EXISTS
1207 (SELECT 'X'
1208 FROM wip_valid_intraoperation_steps wvis,
1209 wip_operations wo
1210 WHERE wvis.organization_id = wmti.organization_id
1211 AND wvis.step_lookup_type = wmti.to_intraoperation_step_type
1212 AND wo.organization_id = wmti.organization_id
1213 AND wo.wip_entity_id = wmti.wip_entity_id
1214 AND wo.operation_seq_num = wmti.to_operation_seq_num
1215 AND NVL(wo.repetitive_schedule_id, -1) =
1216 NVL(wmti.repetitive_schedule_id, -1)
1217 -- Fixed bug 5059521. Since OSFM build routing as it goes, we cannot rely on
1218 -- wo.next_operation_seq_num IS NULL to determine that it is the last
1219 -- operation or not.
1220 AND (((wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
1221 WIP_CONSTANTS.REPETITIVE)
1222 OR
1223 (wmti.entity_type = WIP_CONSTANTS.LOTBASED AND
1224 wmti.transaction_type = WIP_CONSTANTS.COMP_TXN))
1225 AND
1226 ((wvis.record_creator = 'USER' OR
1227 wvis.step_lookup_type = WIP_CONSTANTS.QUEUE)
1228 OR
1229 (wvis.record_creator = 'SYSTEM' AND
1230 wo.next_operation_seq_num IS NULL)))
1231 OR
1232 (wmti.entity_type = WIP_CONSTANTS.LOTBASED AND
1233 wmti.transaction_type <> WIP_CONSTANTS.COMP_TXN AND
1234 (wvis.record_creator = 'USER' OR
1235 wvis.step_lookup_type = WIP_CONSTANTS.QUEUE))))))
1236
1237 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1238
1239 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
1240 fnd_message.set_token('ENTITY', 'TO_INTRAOPERATION_STEP_TYPE');
1241 add_error(p_txn_ids => enums,
1242 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1243 p_err_msg => fnd_message.get);
1244
1245 -- reset enums table
1246 enums.delete;
1247 -- Error out if users try to move to the same operation and step as the
1248 -- FM_OPERATION_SEQ_NUM and FM_INTRAOPERATION_STEP_TYPE
1249 UPDATE wip_move_txn_interface wmti
1250 SET wmti.process_status = WIP_CONSTANTS.ERROR
1251 WHERE wmti.group_id = g_group_id
1252 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1253 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1254 AND wmti.fm_operation_seq_num = wmti.to_operation_seq_num
1255 AND wmti.fm_intraoperation_step_type = wmti.to_intraoperation_step_type
1256 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1257
1258 fnd_message.set_name('WIP', 'WIP_SAME_OP_AND_STEP');
1259 add_error(p_txn_ids => enums,
1260 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1261 p_err_msg => fnd_message.get);
1262
1263 -- reset enums table
1264 enums.delete;
1265 -- Error out if TRANSACTION_TYPE is EZ Complete and
1266 -- TO_INTRAOPERATION_STEP_TYPE not equal to Tomove
1267 UPDATE wip_move_txn_interface wmti
1268 SET wmti.process_status = WIP_CONSTANTS.ERROR
1269 WHERE wmti.group_id = g_group_id
1270 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1271 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1272 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1273 AND wmti.to_intraoperation_step_type <> WIP_CONSTANTS.TOMOVE
1274 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1275
1276 fnd_message.set_name('WIP', 'WIP_EZ_TO_LAST_STEP');
1277 add_error(p_txn_ids => enums,
1278 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1279 p_err_msg => fnd_message.get);
1280
1281 -- reset enums table
1282 enums.delete;
1283 -- Error out if user try to easy complete job/schedule that has No Move shop
1284 -- floor status attached to Tomove of the last operation
1285 UPDATE wip_move_txn_interface wmti
1286 SET wmti.process_status = WIP_CONSTANTS.ERROR
1287 WHERE wmti.group_id = g_group_id
1288 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1289 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1290 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1291 AND EXISTS
1292 (SELECT 'X'
1293 FROM wip_shop_floor_status_codes wsc,
1294 wip_shop_floor_statuses ws
1295 WHERE wsc.organization_id = wmti.organization_id
1296 AND ws.organization_id = wmti.organization_id
1297 AND ws.wip_entity_id = wmti.wip_entity_id
1298 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
1299 AND ws.operation_seq_num = wmti.to_operation_seq_num
1300 AND ws.intraoperation_step_type = WIP_CONSTANTS.TOMOVE
1301 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
1302 AND wsc.status_move_flag = WIP_CONSTANTS.NO
1303 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE)
1304 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1305
1306 /* Added the following for SUN enhancement in Bug 9758848*/
1307 if enums.count > 0 then
1308 for i in 1..enums.count loop
1309 SELECT ws.shop_floor_status_code
1310 INTO l_sf_status
1311 FROM wip_shop_floor_status_codes wsc,
1312 wip_shop_floor_statuses ws,
1313 wip_move_txn_interface wmti
1314 WHERE wsc.organization_id = wmti.organization_id
1315 AND ws.organization_id = wmti.organization_id
1316 AND ws.wip_entity_id = wmti.wip_entity_id
1317 AND wmti.transaction_id = enums(i)
1318 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
1319 AND ws.operation_seq_num = wmti.to_operation_seq_num
1320 AND ws.intraoperation_step_type = WIP_CONSTANTS.TOMOVE
1321 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
1322 AND wsc.status_move_flag = WIP_CONSTANTS.NO
1323 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
1324 and rownum = 1;
1325
1326 fnd_message.set_name('WIP', 'WIP_SF_STATUS_NO_TXN2');
1327 fnd_message.set_token('SF_STATUS', to_char(l_sf_status));
1328 add_error(p_txn_id => enums(i),
1329 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1330 p_err_msg => fnd_message.get);
1331 end loop;
1332 end if;
1333
1334 -- reset enums table
1335 enums.delete;
1336 -- Error out if wip_parameter do not allow move over no_move shop floor
1337 -- status, and there are no_move status in between
1338 UPDATE wip_move_txn_interface wmti
1339 SET wmti.process_status = WIP_CONSTANTS.ERROR
1340 WHERE wmti.group_id = g_group_id
1341 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1342 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1343 AND wip_sf_status.count_no_move_statuses(
1344 wmti.organization_id, -- p_org_id
1345 wmti.wip_entity_id, -- p_wip_id
1346 wmti.line_id, -- p_line_id
1347 wmti.repetitive_schedule_id, -- p_sched_id
1348 wmti.fm_operation_seq_num, -- p_fm_op
1349 wmti.fm_intraoperation_step_type, -- p_fm_step
1350 wmti.to_operation_seq_num, -- p_to_op
1351 wmti.to_intraoperation_step_type, -- p_to_step
1352 -- Fixed bug 2121222
1353 wmti.source_code) > 0 -- p_source_code
1354 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1355
1356 /* Added the following for SUN enhancement in Bug 9758848*/
1357 if enums.count > 0 then
1358 for i in 1..enums.count loop
1359 select wip_sf_status.get_no_move_status(
1360 wmti.organization_id, -- p_org_id
1361 wmti.wip_entity_id, -- p_wip_id
1362 wmti.line_id, -- p_line_id
1363 wmti.repetitive_schedule_id, -- p_sched_id
1364 wmti.fm_operation_seq_num, -- p_fm_op
1365 wmti.fm_intraoperation_step_type, -- p_fm_step
1366 wmti.to_operation_seq_num, -- p_to_op
1367 wmti.to_intraoperation_step_type, -- p_to_step
1368 wmti.source_code)
1369 into l_sf_status
1370 from wip_move_txn_interface wmti
1371 where wmti.transaction_id = enums(i)
1372 and wmti.process_status = WIP_CONSTANTS.ERROR;
1373 fnd_message.set_name ('WIP', 'WIP_NO_MOVE_STATUS_BETWEEN');
1374 fnd_message.set_token('SF_STATUS', to_char(l_sf_status));
1375 add_error(p_txn_id => enums(i),
1376 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1377 p_err_msg => fnd_message.get);
1378 end loop;
1379 end if;
1380 END to_step;
1381
1382 -- transaction_quantity must be positive
1383 PROCEDURE transaction_qty IS
1384 BEGIN
1385 -- reset enums table
1386 enums.delete;
1387
1388 -- Error out if TRANSACTION_QUANTITY is negative or zero
1389 UPDATE wip_move_txn_interface wmti
1390 SET wmti.process_status = WIP_CONSTANTS.ERROR
1391 WHERE wmti.group_id = g_group_id
1392 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1393 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1394 AND wmti.transaction_quantity <= 0
1395 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1396
1397 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
1398 fnd_message.set_token('ENTITY1', 'TRANSACTION_QUANTITY');
1399 fnd_message.set_token('ENTITY2', 'zero');
1400 add_error(p_txn_ids => enums,
1401 p_err_col => 'TRANSACTION_QUANTITY',
1402 p_err_msg => fnd_message.get);
1403
1404 END transaction_qty;
1405
1406
1407 -- transaction_uom must be defined
1408 PROCEDURE transaction_uom IS
1409 BEGIN
1410 -- reset enums table
1411 enums.delete;
1412 -- Error out if TRANSACTION_UOM is invalid
1413 UPDATE wip_move_txn_interface wmti
1414 SET wmti.process_status = WIP_CONSTANTS.ERROR
1415 WHERE wmti.group_id = g_group_id
1416 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1417 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1418 AND NOT EXISTS
1419 (SELECT 'X'
1420 FROM mtl_item_uoms_view miuv
1421 WHERE miuv.organization_id = wmti.organization_id
1422 AND miuv.inventory_item_id = wmti.primary_item_id
1423 AND miuv.uom_code = wmti.transaction_uom)
1424 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1425
1426 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
1427 fnd_message.set_token('ENTITY', 'TRANSACTION_UOM');
1428 add_error(p_txn_ids => enums,
1429 p_err_col => 'TRANSACTION_UOM',
1430 p_err_msg => fnd_message.get);
1431
1432 END transaction_uom;
1433
1434 -- validate overcompletion_transaction_qty. This is an optional info.
1435 -- The caller need to provide this only for overmove/overcompletion txns.
1436 -- However, we do not allow overreturn, and over move for backward move.
1437 -- We also not allow overmove/overcomplete from scrap or reject step.
1438 -- This value cannot be zero or negative either.
1439 PROCEDURE ocpl_txn_qty IS
1440 BEGIN
1441 -- reset enums table
1442 enums.delete;
1443
1444 -- Error out if OVERCOMPLETION_TRANSACTION_QTY is negative or zero
1445 UPDATE wip_move_txn_interface wmti
1446 SET wmti.process_status = WIP_CONSTANTS.ERROR
1447 WHERE wmti.group_id = g_group_id
1448 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1449 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1450 AND wmti.overcompletion_transaction_qty IS NOT NULL
1451 AND wmti.overcompletion_transaction_qty <= 0
1452 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1453
1454 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
1455 fnd_message.set_token('ENTITY1', 'OVERCOMPLETION_TRANSACTION_QTY');
1456 fnd_message.set_token('ENTITY2', 'zero');
1457 add_error(p_txn_ids => enums,
1458 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1459 p_err_msg => fnd_message.get);
1460
1461 -- reset enums table
1462 enums.delete;
1463 -- Error out if OVERCOMPLETION_TRANSACTION_QTY is greater than
1464 -- TRANSACTION_QUANTITY
1465 UPDATE wip_move_txn_interface wmti
1466 SET wmti.process_status = WIP_CONSTANTS.ERROR
1467 WHERE wmti.group_id = g_group_id
1468 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1469 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1470 AND wmti.overcompletion_transaction_qty IS NOT NULL
1471 AND wmti.overcompletion_transaction_qty > wmti.transaction_quantity
1472 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1473
1474 fnd_message.set_name('MFG', 'MFG_GREATER_OR_EQUAL');
1475 fnd_message.set_token('ENTITY1', 'TRANSACTION_QUANTITY');
1476 fnd_message.set_token('ENTITY2', 'OVERCOMPLETION_TRANSACTION_QTY');
1477 add_error(p_txn_ids => enums,
1478 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1479 p_err_msg => fnd_message.get);
1480
1481 -- reset enums table
1482 enums.delete;
1483 -- Error out if user try to do over Return
1484 UPDATE wip_move_txn_interface wmti
1485 SET wmti.process_status = WIP_CONSTANTS.ERROR
1486 WHERE wmti.group_id = g_group_id
1487 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1488 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1489 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
1490 AND wmti.overcompletion_transaction_qty IS NOT NULL
1491 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1492
1493 fnd_message.set_name('WIP', 'WIP_NO_OC_RET');
1494 add_error(p_txn_ids => enums,
1495 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1496 p_err_msg => fnd_message.get);
1497
1498 -- reset enums table
1499 enums.delete;
1500 -- Error out if user try to do over Return from Scrap/Return from Reject
1501 UPDATE wip_move_txn_interface wmti
1502 SET wmti.process_status = WIP_CONSTANTS.ERROR
1503 WHERE wmti.group_id = g_group_id
1504 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1505 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1506 AND wmti.fm_intraoperation_step_type IN (WIP_CONSTANTS.SCRAP,
1507 WIP_CONSTANTS.REJECT)
1508 AND wmti.overcompletion_transaction_qty IS NOT NULL
1509 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1510
1511 fnd_message.set_name('WIP', 'WIP_NO_OC_SCR_REJ');
1512 add_error(p_txn_ids => enums,
1513 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1514 p_err_msg => fnd_message.get);
1515
1516 -- reset enums table
1517 enums.delete;
1518 -- Error out if OVERCOMPLETION_TRANSACTION_QTY is specified for backward
1519 -- move txns
1520 UPDATE wip_move_txn_interface wmti
1521 SET wmti.process_status = WIP_CONSTANTS.ERROR
1522 WHERE wmti.group_id = g_group_id
1523 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1524 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1525 AND (wmti.to_operation_seq_num < wmti.fm_operation_seq_num OR
1526 (wmti.to_operation_seq_num = wmti.fm_operation_seq_num AND
1527 wmti.to_intraoperation_step_type <
1528 wmti.fm_intraoperation_step_type))
1529 AND wmti.overcompletion_transaction_qty IS NOT NULL
1530 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1531
1532 fnd_message.set_name('WIP', 'WIP_NO_OC_REV_MOVE');
1533 add_error(p_txn_ids => enums,
1534 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1535 p_err_msg => fnd_message.get);
1536
1537 END ocpl_txn_qty;
1538
1539 -- validate transaction_id against the one in WIP_MOVE_TRANSACTIONS, and
1540 -- WIP_MOVE_TXN_INTERFACE. This value need to be unique.
1541 PROCEDURE transaction_id IS
1542 l_errMsg VARCHAR2(240);
1543 BEGIN
1544 -- Generate TRANSACTION_ID if user does not provide this value
1545 UPDATE wip_move_txn_interface wmti
1546 SET wmti.transaction_id = wip_transactions_s.nextval
1547 WHERE wmti.group_id = g_group_id
1548 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1549 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1550 AND wmti.transaction_id IS NULL;
1551
1552 -- Set Error Message
1553 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
1554 fnd_message.set_token('ENTITY', 'TRANSACTION_ID');
1555 l_errMsg := substrb(fnd_message.get, 1, 240);
1556
1557 INSERT INTO wip_txn_interface_errors(
1558 transaction_id,
1559 error_message,
1560 error_column,
1561 last_update_date,
1562 last_updated_by,
1563 creation_date,
1564 created_by,
1565 last_update_login,
1566 request_id,
1567 program_application_id,
1568 program_id,
1569 program_update_date
1570 )
1571 SELECT wmti1.transaction_id, -- transaction_id
1572 l_errMsg, -- error_message
1573 'TRANSACTION_ID', -- error_column
1574 SYSDATE, -- last_update_date
1575 NVL(wmti1.last_updated_by, -1),
1576 SYSDATE, -- creation_date
1577 NVL(wmti1.created_by, -1),
1578 wmti1.last_update_login,
1579 wmti1.request_id,
1580 wmti1.program_application_id,
1581 wmti1.program_id,
1582 wmti1.program_update_date
1583 FROM wip_move_txn_interface wmti1
1584 WHERE wmti1.group_id = g_group_id
1585 AND wmti1.process_phase = WIP_CONSTANTS.MOVE_VAL
1586 AND wmti1.process_status = WIP_CONSTANTS.RUNNING
1587 AND (EXISTS
1588 (SELECT 'X'
1589 FROM wip_move_transactions wmt
1590 WHERE wmt.transaction_id = wmti1.transaction_id)
1591 OR
1592 (1 <>
1593 (SELECT count(*)
1594 FROM wip_move_txn_interface wmti2
1595 WHERE wmti2.transaction_id = wmti1.transaction_id)));
1596
1597 END transaction_id;
1598
1599 -- derive primary_quantity from transaction_quantity and transaction_uom.
1600 -- you cannot easy return more than available quantity and organization do
1601 -- not allow negative balance
1602 PROCEDURE primary_qty IS
1603
1604 CURSOR c_availQty IS
1605 SELECT wmti.transaction_id txn_id,
1606 wmti.organization_id org_id,
1607 wmti.primary_item_id item_id,
1608 wmti.primary_quantity primary_qty,
1609 DECODE(msik.serial_number_control_code,
1610 WIP_CONSTANTS.FULL_SN, fnd_api.g_true,
1611 WIP_CONSTANTS.DYN_RCV_SN, fnd_api.g_true,
1612 fnd_api.g_false) is_ser_ctrl,
1613 DECODE(msik.lot_control_code,
1614 WIP_CONSTANTS.LOT, fnd_api.g_true,
1615 fnd_api.g_false) is_lot_ctrl,
1616 DECODE(msik.revision_qty_control_code,
1617 WIP_CONSTANTS.REV, fnd_api.g_true,
1618 fnd_api.g_false) is_rev_ctrl,
1619 DECODE(msik.revision_qty_control_code, -- revision
1620 WIP_CONSTANTS.REV, NVL(wdj.bom_revision,
1621 bom_revisions.get_item_revision_fn
1622 ('EXCLUDE_OPEN_HOLD', -- eco_status
1623 'ALL', -- examine_type
1624 wmti.organization_id, -- org_id
1625 wmti.primary_item_id, -- item_id
1626 wmti.transaction_date -- rev_date
1627 )),
1628 NULL) revision, -- revision
1629 wdj.lot_number lot,
1630 wmti.transaction_date txn_date,
1631 wdj.completion_subinventory subinv,
1632 wdj.completion_locator_id locID,
1633 mp.negative_inv_receipt_code negative_allow,
1634 msik.concatenated_segments assembly_name
1635 FROM wip_discrete_jobs wdj,
1636 mtl_system_items_kfv msik,
1637 mtl_parameters mp,
1638 wip_move_txn_interface wmti
1639 WHERE wdj.primary_item_id = msik.inventory_item_id
1640 AND wdj.organization_id = msik.organization_id
1641 AND wdj.organization_id = mp.organization_id
1642 AND wmti.wip_entity_id = wdj.wip_entity_id
1643 AND wmti.organization_id = wdj.organization_id
1644 AND wmti.entity_type <> WIP_CONSTANTS.REPETITIVE
1645 AND wmti.group_id = g_group_id
1646 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1647 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1648 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN;
1649
1650
1651 CURSOR c_repAvailQty IS
1652 SELECT wmti.transaction_id txn_id,
1653 wmti.organization_id org_id,
1654 wmti.primary_item_id item_id,
1655 wmti.primary_quantity primary_qty,
1656 DECODE(msik.serial_number_control_code,
1657 WIP_CONSTANTS.FULL_SN, fnd_api.g_true,
1658 WIP_CONSTANTS.DYN_RCV_SN, fnd_api.g_true,
1659 fnd_api.g_false) is_ser_ctrl,
1660 DECODE(msik.lot_control_code,
1661 WIP_CONSTANTS.LOT, fnd_api.g_true,
1662 fnd_api.g_false) is_lot_ctrl,
1663 DECODE(msik.revision_qty_control_code,
1664 WIP_CONSTANTS.REV, fnd_api.g_true,
1665 fnd_api.g_false) is_rev_ctrl,
1666 DECODE(msik.revision_qty_control_code, -- revision
1667 WIP_CONSTANTS.REV, NVL(wrs.bom_revision,
1668 bom_revisions.get_item_revision_fn
1669 ('EXCLUDE_OPEN_HOLD', -- eco_status
1670 'ALL', -- examine_type
1671 wmti.organization_id, -- org_id
1672 wmti.primary_item_id, -- item_id
1673 wmti.transaction_date -- rev_date
1674 )),
1675 NULL) revision, -- revision
1676 NULL lot,
1677 wmti.transaction_date txn_date,
1678 wri.completion_subinventory subinv,
1679 wri.completion_locator_id locID,
1680 mp.negative_inv_receipt_code negative_allow,
1681 msik.concatenated_segments assembly_name
1682 FROM wip_repetitive_schedules wrs,
1683 wip_repetitive_items wri,
1684 mtl_system_items_kfv msik,
1685 mtl_parameters mp,
1686 wip_move_txn_interface wmti
1687 WHERE wmti.primary_item_id = msik.inventory_item_id
1688 AND wmti.organization_id = msik.organization_id
1689 AND wmti.organization_id = mp.organization_id
1690 AND wrs.wip_entity_id = wmti.wip_entity_id
1691 AND wrs.organization_id = wmti.organization_id
1692 AND wrs.line_id = wmti.line_id
1693 AND wrs.repetitive_schedule_id = wmti.repetitive_schedule_id
1694 AND wri.organization_id = wmti.organization_id
1695 AND wri.wip_entity_id = wmti.wip_entity_id
1696 AND wri.line_id = wmti.line_id
1697 AND wmti.entity_type = WIP_CONSTANTS.REPETITIVE
1698 AND wmti.group_id = g_group_id
1699 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1700 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1701 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN;
1702
1703 l_availQty c_availQty%ROWTYPE;
1704 l_repAvailQty c_repAvailQty%ROWTYPE;
1705 l_returnStatus VARCHAR2(1);
1706 l_qoh NUMBER;
1707 l_rqoh NUMBER;
1708 l_qr NUMBER;
1709 l_qs NUMBER;
1710 l_att NUMBER;
1711 l_atr NUMBER;
1712 l_errMsg VARCHAR2(240);
1713 l_msg_count NUMBER;
1714 l_msg_data VARCHAR2(2000);
1715 BEGIN
1716 -- Derive PRIMARY_QUANTITY from TRANSACTION_QUANTITY and TRANSACTION_UOM
1717 -- if PRIMARY_QUANTITY is null
1718
1719 /** Bug fix 5000113. primary_quantity should be updated in sync with
1720 * transaction_quantity, and not just when primary_quantity is null.
1721 */
1722
1723 UPDATE wip_move_txn_interface wmti
1724 SET wmti.primary_quantity =
1725 (SELECT ROUND(wmti.transaction_quantity * mucv.conversion_rate,
1726 WIP_CONSTANTS.INV_MAX_PRECISION)
1727 FROM mtl_uom_conversions_view mucv
1728 WHERE mucv.organization_id = wmti.organization_id
1729 AND mucv.inventory_item_id = wmti.primary_item_id
1730 AND mucv.uom_code = wmti.transaction_uom)
1731 WHERE wmti.group_id = g_group_id
1732 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1733 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
1734 --AND wmti.primary_quantity IS NULL;
1735
1736 /* End of bug fix 5000113.
1737
1738 -- Set Error Message
1739 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
1740 fnd_message.set_token('ENTITY1', 'PRIMARY_QUANTITY');
1741 fnd_message.set_token('ENTITY2', 'zero');
1742 l_errMsg := substrb(fnd_message.get, 1, 240);
1743
1744 -- Error out if PRIMARY_QUANTITY is zero
1745 -- Insert error record into WIP_TXN_INTERFACE_ERRORS. Do not update
1746 -- WMTI.PROCESS_STATUS to Error because it is a minor issue. We will
1747 -- continue validating other values.
1748 INSERT INTO wip_txn_interface_errors(
1749 transaction_id,
1750 error_message,
1751 error_column,
1752 last_update_date,
1753 last_updated_by,
1754 creation_date,
1755 created_by,
1756 last_update_login,
1757 request_id,
1758 program_application_id,
1759 program_id,
1760 program_update_date
1761 )
1762 SELECT wmti.transaction_id, -- transaction_id
1763 l_errMsg, -- error_message
1764 'PRIMARY_QUANTITY', -- error_column
1765 SYSDATE, -- last_update_date
1766 NVL(wmti.last_updated_by, -1),
1767 SYSDATE, -- creation_date
1768 NVL(wmti.created_by, -1),
1769 wmti.last_update_login,
1770 wmti.request_id,
1771 wmti.program_application_id,
1772 wmti.program_id,
1773 wmti.program_update_date
1774 FROM wip_move_txn_interface wmti
1775 WHERE wmti.group_id = g_group_id
1776 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1777 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1778 AND wmti.primary_quantity = 0;
1779
1780 -- Set Error Message
1781 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
1782 fnd_message.set_token('ENTITY1', 'PRIMARY_QUANTITY');
1783 fnd_message.set_token('ENTITY2', 'TRANSACTION_QUANTITY');
1784 l_errMsg := substrb(fnd_message.get, 1, 240);
1785
1786 -- Error out if PRIMARY_QUANTITY is not consistent with TRANSACTION_QUANTITY
1787 -- Insert error record into WIP_TXN_INTERFACE_ERRORS. Do not update
1788 -- WMTI.PROCESS_STATUS to Error because it is a minor issue. We will
1789 -- continue validating other values.
1790 INSERT INTO wip_txn_interface_errors(
1791 transaction_id,
1792 error_message,
1793 error_column,
1794 last_update_date,
1795 last_updated_by,
1796 creation_date,
1797 created_by,
1798 last_update_login,
1799 request_id,
1800 program_application_id,
1801 program_id,
1802 program_update_date
1803 )
1804 SELECT wmti.transaction_id, -- transaction_id
1805 l_errMsg, -- error_message
1806 'PRIMARY_QUANTITY', -- error_column
1807 SYSDATE, -- last_update_date
1808 NVL(wmti.last_updated_by, -1),
1809 SYSDATE, -- creation_date
1810 NVL(wmti.created_by, -1),
1811 wmti.last_update_login,
1812 wmti.request_id,
1813 wmti.program_application_id,
1814 wmti.program_id,
1815 wmti.program_update_date
1816 FROM wip_move_txn_interface wmti,
1817 mtl_uom_conversions_view mucv
1818 WHERE mucv.organization_id = wmti.organization_id
1819 AND mucv.inventory_item_id = wmti.primary_item_id
1820 AND mucv.uom_code = wmti.transaction_uom
1821 AND wmti.group_id = g_group_id
1822 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1823 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1824 -- Fixed bug 4900010. Round both transaction_quantity and
1825 -- primary_quantity before making comparison.
1826 AND ROUND(wmti.transaction_quantity * mucv.conversion_rate,
1827 WIP_CONSTANTS.INV_MAX_PRECISION) <>
1828 ROUND(wmti.primary_quantity, WIP_CONSTANTS.INV_MAX_PRECISION);
1829
1830 -- Set Error Message
1831 /* Fix for Bug#4192541. Removed following check as this is only warning
1832 condition
1833 */
1834
1835 /*
1836 fnd_message.set_name('WIP', 'WIP_MIN_XFER_QTY');
1837 l_errMsg := substrb(fnd_message.get, 1, 240);
1838
1839 -- Error out if PRIMARY_QUANTITY less than MININUM_TRANSFER_QUANTITY
1840 -- defined at FM_OPERATION_SEQ_NUM and transactions are not Scrap/Reject
1841 INSERT INTO wip_txn_interface_errors(
1842 transaction_id,
1843 error_message,
1844 error_column,
1845 last_update_date,
1846 last_updated_by,
1847 creation_date,
1848 created_by,
1849 last_update_login,
1850 request_id,
1851 program_application_id,
1852 program_id,
1853 program_update_date
1854 )
1855 SELECT wmti.transaction_id, -- transaction_id
1856 l_errMsg, -- error_message
1857 'PRIMARY_QUANTITY', -- error_column
1858 SYSDATE, -- last_update_date
1859 NVL(wmti.last_updated_by, -1),
1860 SYSDATE, -- creation_date
1861 NVL(wmti.created_by, -1),
1862 wmti.last_update_login,
1863 wmti.request_id,
1864 wmti.program_application_id,
1865 wmti.program_id,
1866 wmti.program_update_date
1867 FROM wip_move_txn_interface wmti,
1868 wip_operations wo
1869 WHERE wo.organization_id = wmti.organization_id
1870 AND wo.wip_entity_id = wmti.wip_entity_id
1871 AND NVL(wo.repetitive_schedule_id, -1) =
1872 NVL(wmti.repetitive_schedule_id, -1)
1873 AND wo.operation_seq_num = wmti.fm_operation_seq_num
1874 AND wmti.fm_intraoperation_step_type NOT IN (WIP_CONSTANTS.SCRAP,
1875 WIP_CONSTANTS.REJECT)
1876 AND wmti.to_intraoperation_step_type NOT IN (WIP_CONSTANTS.SCRAP,
1877 WIP_CONSTANTS.REJECT)
1878 AND wmti.group_id = g_group_id
1879 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1880 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1881 AND wo.minimum_transfer_quantity > wmti.primary_quantity;
1882
1883
1884 */
1885 -- Set Error Message
1886 fnd_message.set_name ('INV', 'INV_NO_NEG_BALANCES');
1887 l_errMsg := substrb(fnd_message.get, 1, 240);
1888
1889 -- User cannot do easy return more than available quantity if
1890 -- organization do not allow negative balance. (Discrete/OSFM)
1891 FOR l_availQty IN c_availQty
1892 LOOP
1893 inv_quantity_tree_pub.query_quantities(
1894 p_api_version_number => 1.0,
1895 p_init_msg_lst => 'T',
1896 p_onhand_source => inv_quantity_tree_pvt.g_all_subs,
1897 p_organization_id => l_availQty.org_id,
1898 p_inventory_item_id => l_availQty.item_id,
1899 p_tree_mode => inv_quantity_tree_pvt.g_loose_only_mode,
1900 p_is_revision_control => fnd_api.to_boolean(l_availQty.is_rev_ctrl),
1901 p_is_lot_control => fnd_api.to_boolean(l_availQty.is_lot_ctrl),
1902 p_is_serial_control => fnd_api.to_boolean(l_availQty.is_ser_ctrl),
1903 p_demand_source_type_id => 5, -- WIP
1904 p_revision => l_availQty.revision,
1905 p_lot_number => l_availQty.lot,
1906 p_lot_expiration_date => l_availQty.txn_date,
1907 p_subinventory_code => l_availQty.subinv,
1908 p_locator_id => l_availQty.locID,
1909 x_return_status => l_returnStatus,
1910 x_msg_count => l_msg_count,
1911 x_msg_data => l_msg_data,
1912 x_qoh => l_qoh,
1913 x_rqoh => l_rqoh,
1914 x_qr => l_qr,
1915 x_qs => l_qs,
1916 x_att => l_att,
1917 x_atr => l_atr);
1918
1919 IF(l_returnStatus <> 'S')THEN
1920 add_error(p_txn_id => l_availQty.txn_id,
1921 p_err_col => 'PRIMARY_QUANTITY',
1922 p_err_msg => l_msg_data);
1923 ELSE
1924 IF(l_availQty.negative_allow = WIP_CONSTANTS.NO AND
1925 l_att < l_availQty.primary_qty) THEN
1926 add_error(p_txn_id => l_availQty.txn_id,
1927 p_err_col => 'PRIMARY_QUANTITY',
1928 p_err_msg => l_availQty.assembly_name||':'||l_errMsg);
1929 END IF;
1930 END IF;
1931 END LOOP; -- Only for EZ Return transactions (Discrete/OSFM)
1932
1933 -- User cannot do easy return more than available quantity if
1934 -- organization do not allow negative balance (Repetitive)
1935 FOR l_repAvailQty IN c_repAvailQty
1936 LOOP
1937 inv_quantity_tree_pub.query_quantities(
1938 p_api_version_number => 1.0,
1939 p_init_msg_lst => 'T',
1940 p_onhand_source => inv_quantity_tree_pvt.g_all_subs,
1941 p_organization_id => l_repAvailQty.org_id,
1942 p_inventory_item_id => l_repAvailQty.item_id,
1943 p_tree_mode => inv_quantity_tree_pvt.g_loose_only_mode,
1944 p_is_revision_control => fnd_api.to_boolean(l_repAvailQty.is_rev_ctrl),
1945 p_is_lot_control => fnd_api.to_boolean(l_repAvailQty.is_lot_ctrl),
1946 p_is_serial_control => fnd_api.to_boolean(l_repAvailQty.is_ser_ctrl),
1947 p_demand_source_type_id => 5, -- WIP
1948 p_revision => l_repAvailQty.revision,
1949 p_lot_number => l_repAvailQty.lot,
1950 p_lot_expiration_date => l_repAvailQty.txn_date,
1951 p_subinventory_code => l_repAvailQty.subinv,
1952 p_locator_id => l_repAvailQty.locID,
1953 x_return_status => l_returnStatus,
1954 x_msg_count => l_msg_count,
1955 x_msg_data => l_msg_data,
1956 x_qoh => l_qoh,
1957 x_rqoh => l_rqoh,
1958 x_qr => l_qr,
1959 x_qs => l_qs,
1960 x_att => l_att,
1961 x_atr => l_atr);
1962
1963 IF(l_returnStatus <> 'S')THEN
1964 add_error(p_txn_id => l_repAvailQty.txn_id,
1965 p_err_col => 'PRIMARY_QUANTITY',
1966 p_err_msg => l_msg_data);
1967 ELSE
1968 IF(l_repAvailQty.negative_allow = WIP_CONSTANTS.NO AND
1969 l_att < l_repAvailQty.primary_qty) THEN
1970 add_error(p_txn_id => l_repAvailQty.txn_id,
1971 p_err_col => 'PRIMARY_QUANTITY',
1972 p_err_msg => l_repAvailQty.assembly_name||':'||l_errMsg);
1973 END IF;
1974 END IF;
1975 END LOOP; -- Only for EZ Return transactions(Repetitive)
1976 END primary_qty;
1977
1978 -- derive primary_uom from primary_item_id
1979 PROCEDURE primary_uom IS
1980 l_errMsg VARCHAR2(240);
1981 BEGIN
1982 -- Derive PRIMARY_UOM from PRIMARY_ITEM_ID provided if PRIMARY_UOM is null
1983 UPDATE wip_move_txn_interface wmti
1984 SET wmti.primary_uom =
1985 (SELECT msi.primary_uom_code
1986 FROM mtl_system_items msi
1987 WHERE msi.organization_id = wmti.organization_id
1988 AND msi.inventory_item_id = wmti.primary_item_id)
1989 WHERE wmti.group_id = g_group_id
1990 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1991 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1992 AND wmti.primary_uom IS NULL;
1993
1994 -- Set Error Message
1995 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
1996 fnd_message.set_token('ENTITY1', 'PRIMARY_UOM');
1997 fnd_message.set_token('ENTITY2', 'PRIMARY_ITEM_ID');
1998 l_errMsg := substrb(fnd_message.get, 1, 240);
1999
2000 -- If caller provide PRIMARY_UOM, it must be consistent with
2001 -- primary_item_id provided
2002 INSERT INTO wip_txn_interface_errors(
2003 transaction_id,
2004 error_message,
2005 error_column,
2006 last_update_date,
2007 last_updated_by,
2008 creation_date,
2009 created_by,
2010 last_update_login,
2011 request_id,
2012 program_application_id,
2013 program_id,
2014 program_update_date
2015 )
2016 SELECT wmti.transaction_id, -- transaction_id
2017 l_errMsg, -- error_message
2018 'PRIMARY_UOM', -- error_column
2019 SYSDATE, -- last_update_date
2020 NVL(wmti.last_updated_by, -1),
2021 SYSDATE, -- creation_date
2022 NVL(wmti.created_by, -1),
2023 wmti.last_update_login,
2024 wmti.request_id,
2025 wmti.program_application_id,
2026 wmti.program_id,
2027 wmti.program_update_date
2028 FROM wip_move_txn_interface wmti,
2029 mtl_system_items msi
2030 WHERE msi.organization_id = wmti.organization_id
2031 AND msi.inventory_item_id = wmti.primary_item_id
2032 AND wmti.group_id = g_group_id
2033 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2034 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2035 AND msi.primary_uom_code <> wmti.primary_uom;
2036
2037 END primary_uom;
2038
2039 -- derive overcomplete_primary_quantity from overcomplete_transaction_quantity
2040 -- and transaction_uom provided.
2041 PROCEDURE ocpl_primary_qty IS
2042 l_errMsg VARCHAR2(240);
2043 BEGIN
2044 -- Derive OVERCOMPLETE_PRIMARY_QUANTITY from
2045 -- OVERCOMPLETE_TRANSACTION_QUANTITY and TRANSACTION_UOM provided.
2046
2047 /** Bug fix 5000113. overcompletion_primary_qty should be updated in sync with
2048 * transaction_quantity, and not just when overcompletion_quantity is null.
2049 */
2050
2051 UPDATE wip_move_txn_interface wmti
2052 SET wmti.overcompletion_primary_qty =
2053 (SELECT ROUND(wmti.overcompletion_transaction_qty *
2054 mucv.conversion_rate, WIP_CONSTANTS.INV_MAX_PRECISION)
2055 FROM mtl_uom_conversions_view mucv
2056 WHERE mucv.organization_id = wmti.organization_id
2057 AND mucv.inventory_item_id = wmti.primary_item_id
2058 AND mucv.uom_code = wmti.transaction_uom)
2059 WHERE wmti.group_id = g_group_id
2060 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2061 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2062 AND wmti.overcompletion_transaction_qty IS NOT NULL;
2063 --AND wmti.overcompletion_primary_qty IS NULL;
2064
2065 -- End of bug fix 5000113.
2066
2067 -- Set Error Message
2068 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
2069 fnd_message.set_token('ENTITY1', 'OVERCOMPLETION_PRIMARY_QTY');
2070 fnd_message.set_token('ENTITY2', 'zero');
2071 l_errMsg := substrb(fnd_message.get, 1, 240);
2072
2073 -- Error out if OVERCOMPLETION_PRIMARY_QTY is zero
2074 -- Insert error record into WIP_TXN_INTERFACE_ERRORS. Do not update
2075 -- WMTI.PROCESS_STATUS to Error because it is a minor issue. We will
2076 -- continue validating other values.
2077 INSERT INTO wip_txn_interface_errors(
2078 transaction_id,
2079 error_message,
2080 error_column,
2081 last_update_date,
2082 last_updated_by,
2083 creation_date,
2084 created_by,
2085 last_update_login,
2086 request_id,
2087 program_application_id,
2088 program_id,
2089 program_update_date
2090 )
2091 SELECT wmti.transaction_id, -- transaction_id
2092 l_errMsg, -- error_message
2093 'OVERCOMPLETION_PRIMARY_QTY', -- error_column
2094 SYSDATE, -- last_update_date
2095 NVL(wmti.last_updated_by, -1),
2096 SYSDATE, -- creation_date
2097 NVL(wmti.created_by, -1),
2098 wmti.last_update_login,
2099 wmti.request_id,
2100 wmti.program_application_id,
2101 wmti.program_id,
2102 wmti.program_update_date
2103 FROM wip_move_txn_interface wmti
2104 WHERE wmti.group_id = g_group_id
2105 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2106 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2107 AND wmti.overcompletion_primary_qty = 0;
2108
2109 -- Set Error Message
2110 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2111 fnd_message.set_token('ENTITY1', 'OVERCOMPLETION_PRIMARY_QTY');
2112 fnd_message.set_token('ENTITY2', 'OVERCOMPLETION_TRANSACTION_QTY');
2113 l_errMsg := substrb(fnd_message.get, 1, 240);
2114
2115 -- If caller provide this info, it must be consistent with
2116 -- overcompletion_transaction_qty provided
2117 INSERT INTO wip_txn_interface_errors(
2118 transaction_id,
2119 error_message,
2120 error_column,
2121 last_update_date,
2122 last_updated_by,
2123 creation_date,
2124 created_by,
2125 last_update_login,
2126 request_id,
2127 program_application_id,
2128 program_id,
2129 program_update_date
2130 )
2131 SELECT wmti.transaction_id, -- transaction_id
2132 l_errMsg, -- error_message
2133 'OVERCOMPLETION_PRIMARY_QTY', -- error_column
2134 SYSDATE, -- last_update_date
2135 NVL(wmti.last_updated_by, -1),
2136 SYSDATE, -- creation_date
2137 NVL(wmti.created_by, -1),
2138 wmti.last_update_login,
2139 wmti.request_id,
2140 wmti.program_application_id,
2141 wmti.program_id,
2142 wmti.program_update_date
2143 FROM wip_move_txn_interface wmti,
2144 mtl_uom_conversions_view mucv
2145 WHERE mucv.organization_id = wmti.organization_id
2146 AND mucv.inventory_item_id = wmti.primary_item_id
2147 AND mucv.uom_code = wmti.transaction_uom
2148 AND wmti.group_id = g_group_id
2149 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2150 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2151 AND wmti.overcompletion_transaction_qty IS NOT NULL
2152 -- Fixed bug 4900010. Round both transaction_quantity and
2153 -- primary_quantity before making comparison.
2154 AND ROUND(wmti.overcompletion_transaction_qty * mucv.conversion_rate,
2155 WIP_CONSTANTS.INV_MAX_PRECISION) <>
2156 ROUND(wmti.overcompletion_primary_qty,
2157 WIP_CONSTANTS.INV_MAX_PRECISION);
2158 END ocpl_primary_qty;
2159
2160 -- This value must be null. The move processor will be the one who insert
2161 -- child record and link it with parent record
2162 PROCEDURE ocpl_txn_id IS
2163 l_errMsg VARCHAR2(240);
2164 BEGIN
2165 -- Set Error Message
2166 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
2167 fnd_message.set_token('ENTITY', 'OVERCOMPLETION_TRANSACTION_ID');
2168 l_errMsg := substrb(fnd_message.get, 1, 240);
2169
2170 -- This value must be null because New Move Processor will be the one
2171 -- who insert child record and populate this value
2172 INSERT INTO wip_txn_interface_errors(
2173 transaction_id,
2174 error_message,
2175 error_column,
2176 last_update_date,
2177 last_updated_by,
2178 creation_date,
2179 created_by,
2180 last_update_login,
2181 request_id,
2182 program_application_id,
2183 program_id,
2184 program_update_date
2185 )
2186 SELECT wmti.transaction_id, -- transaction_id
2187 l_errMsg, -- error_message
2188 'OVERCOMPLETION_TRANSACTION_ID', -- error_column
2189 SYSDATE, -- last_update_date
2190 NVL(wmti.last_updated_by, -1),
2191 SYSDATE, -- creation_date
2192 NVL(wmti.created_by, -1),
2193 wmti.last_update_login,
2194 wmti.request_id,
2195 wmti.program_application_id,
2196 wmti.program_id,
2197 wmti.program_update_date
2198 FROM wip_move_txn_interface wmti
2199 WHERE wmti.group_id = g_group_id
2200 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2201 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2202 AND wmti.overcompletion_transaction_id IS NOT NULL;
2203
2204 END ocpl_txn_id;
2205
2206 -- This is an optional info. However, if the caller provided some values,
2207 -- it must be valid. If the caller pass reason_name, we will derive the
2208 -- reason_id. If the caller pass both, both value must be consistent to
2209 -- each other.
2210 PROCEDURE reason_id IS
2211 l_errMsg VARCHAR2(240);
2212 BEGIN
2213 -- Derive REASON_ID from REASON_NAME provided
2214 UPDATE wip_move_txn_interface wmti
2215 SET wmti.reason_id =
2216 (SELECT mtr.reason_id
2217 FROM mtl_transaction_reasons mtr
2218 WHERE mtr.reason_name = wmti.reason_name
2219 AND NVL(mtr.disable_date, SYSDATE) >= SYSDATE)
2220 WHERE wmti.group_id = g_group_id
2221 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2222 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2223 AND wmti.reason_id IS NULL
2224 AND wmti.reason_name IS NOT NULL;
2225
2226 -- Set Error Message
2227 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2228 fnd_message.set_token('ENTITY1', 'REASON_ID');
2229 fnd_message.set_token('ENTITY2', 'REASON_NAME');
2230 l_errMsg := substrb(fnd_message.get, 1, 240);
2231
2232 -- If caller provide REASON_ID, it must be consistent with
2233 -- REASON_NAME provided
2234 INSERT INTO wip_txn_interface_errors(
2235 transaction_id,
2236 error_message,
2237 error_column,
2238 last_update_date,
2239 last_updated_by,
2240 creation_date,
2241 created_by,
2242 last_update_login,
2243 request_id,
2244 program_application_id,
2245 program_id,
2246 program_update_date
2247 )
2248 SELECT wmti.transaction_id, -- transaction_id
2249 l_errMsg, -- error_message
2250 'REASON_ID/NAME', -- error_column
2251 SYSDATE, -- last_update_date
2252 NVL(wmti.last_updated_by, -1),
2253 SYSDATE, -- creation_date
2254 NVL(wmti.created_by, -1),
2255 wmti.last_update_login,
2256 wmti.request_id,
2257 wmti.program_application_id,
2258 wmti.program_id,
2259 wmti.program_update_date
2260 FROM wip_move_txn_interface wmti
2261 WHERE wmti.group_id = g_group_id
2262 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2263 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2264 AND (wmti.reason_id IS NOT NULL OR wmti.reason_name IS NOT NULL)
2265 AND NOT EXISTS
2266 (SELECT 'X'
2267 FROM mtl_transaction_reasons mtr
2268 WHERE mtr.reason_id = NVL(wmti.reason_id, mtr.reason_id)
2269 AND mtr.reason_name = NVL(wmti.reason_name, mtr.reason_name)
2270 AND NVL(mtr.disable_date, SYSDATE) >= SYSDATE);
2271
2272 END reason_id;
2273
2274 -- validate scrap_account_id. This value can be either required or optional
2275 -- info for the discrete and repetitive scrap transaction. It depends on the
2276 -- value setup in WIP_PARAMETERS. However it is always an optional info for
2277 -- OSFM txns. If the caller provided this info, it must be valid account_id
2278 PROCEDURE scrap_account_id IS
2279 l_scrap_flag NUMBER;
2280 l_errMsg VARCHAR2(240);
2281 BEGIN
2282 -- Set Error Message
2283 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
2284 fnd_message.set_token('ENTITY', 'SCRAP_ACCOUNT_ID');
2285 l_errMsg := substrb(fnd_message.get, 1, 240);
2286
2287 INSERT INTO wip_txn_interface_errors(
2288 transaction_id,
2289 error_message,
2290 error_column,
2291 last_update_date,
2292 last_updated_by,
2293 creation_date,
2294 created_by,
2295 last_update_login,
2296 request_id,
2297 program_application_id,
2298 program_id,
2299 program_update_date
2300 )
2301 SELECT wmti.transaction_id, -- transaction_id
2302 l_errMsg, -- error_message
2303 'SCRAP_ACCOUNT_ID', -- error_column
2304 SYSDATE, -- last_update_date
2305 NVL(wmti.last_updated_by, -1),
2306 SYSDATE, -- creation_date
2307 NVL(wmti.created_by, -1),
2308 wmti.last_update_login,
2309 wmti.request_id,
2310 wmti.program_application_id,
2311 wmti.program_id,
2312 wmti.program_update_date
2313 FROM wip_move_txn_interface wmti,
2314 wip_parameters wp
2315 WHERE wp.organization_id = wmti.organization_id
2316 AND wmti.group_id = g_group_id
2317 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2318 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2319 AND (wmti.fm_intraoperation_step_type = WIP_CONSTANTS.SCRAP OR
2320 wmti.to_intraoperation_step_type = WIP_CONSTANTS.SCRAP)
2321 AND ((wmti.scrap_account_id IS NULL
2322 AND wp.mandatory_scrap_flag = WIP_CONSTANTS.YES
2323 AND wmti.entity_type NOT IN(WIP_CONSTANTS.LOTBASED,
2324 WIP_CONSTANTS.CLOSED_OSFM))
2325 OR
2326 (wmti.scrap_account_id IS NOT NULL AND
2327 NOT EXISTS
2328 (SELECT 'X'
2329 FROM hr_organization_information hoi,
2330 gl_sets_of_books gsob,
2331 gl_code_combinations gcc
2332 WHERE gcc.chart_of_accounts_id = gsob.chart_of_accounts_id
2333 and gsob.set_of_books_id =
2334 to_number(decode(rtrim(translate(
2335 hoi.org_information1,'0123456789',' ')),
2336 null, hoi.org_information1,
2337 -99999))
2338 and (hoi.org_information_context || '') =
2339 'Accounting Information'
2340 AND hoi.organization_id = wmti.organization_id
2341 AND gcc.code_combination_id = wmti.scrap_account_id
2342 AND gcc.detail_posting_allowed_flag = 'Y'
2343 AND gcc.summary_flag = 'N'
2344 and gcc.enabled_flag = 'Y'
2345 AND TRUNC(wmti.transaction_date) BETWEEN
2346 NVL(gcc.start_date_active,
2347 TRUNC(wmti.transaction_date))
2348 AND NVL(gcc.end_date_active,
2349 TRUNC(wmti.transaction_date)))));
2350
2351 END scrap_account_id;
2352
2353 -- validate last_updated_by against fnd_user table. The caller have an option
2354 -- to provide either last_updated_by or last_updated_by_name. If the caller
2355 -- pass last_updated_by, the id need to be valid. If the caller pass
2356 -- last_updated_by_name, we will derive the ID. If the caller pass both
2357 -- both value must be consistent to each other.
2358 PROCEDURE last_updated_by IS
2359 l_errMsg VARCHAR2(240);
2360 BEGIN
2361 -- Derive LAST_UPDATED_BY if user provided only LAST_UPDATED_BY_NAME
2362 UPDATE wip_move_txn_interface wmti
2363 SET wmti.last_updated_by =
2364 (SELECT fu.user_id
2365 FROM fnd_user fu
2366 WHERE fu.user_name = wmti.last_updated_by_name
2367 AND SYSDATE BETWEEN fu.start_date AND NVL(fu.end_date, SYSDATE))
2368 WHERE wmti.group_id = g_group_id
2369 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2370 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2371 AND wmti.last_updated_by IS NULL
2372 AND wmti.last_updated_by_name IS NOT NULL;
2373
2374 -- Set Error Message
2375 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2376 fnd_message.set_token('ENTITY1', 'LAST_UPDATED_BY');
2377 fnd_message.set_token('ENTITY2', 'LAST_UPDATED_BY_NAME');
2378 l_errMsg := substrb(fnd_message.get, 1, 240);
2379
2380 -- Error out if LAST_UPDATED_BY is not consistent with LAST_UPDATED_BY_NAME
2381 INSERT INTO wip_txn_interface_errors(
2382 transaction_id,
2383 error_message,
2384 error_column,
2385 last_update_date,
2386 last_updated_by,
2387 creation_date,
2388 created_by,
2389 last_update_login,
2390 request_id,
2391 program_application_id,
2392 program_id,
2393 program_update_date
2394 )
2395 SELECT wmti.transaction_id, -- transaction_id
2396 l_errMsg, -- error_message
2397 'LAST_UPDATED_BY/BY_NAME', -- error_column
2398 SYSDATE, -- last_update_date
2399 NVL(wmti.last_updated_by, -1),
2400 SYSDATE, -- creation_date
2401 NVL(wmti.created_by, -1),
2402 wmti.last_update_login,
2403 wmti.request_id,
2404 wmti.program_application_id,
2405 wmti.program_id,
2406 wmti.program_update_date
2407 FROM wip_move_txn_interface wmti
2408 WHERE wmti.group_id = g_group_id
2409 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2410 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2411 AND wmti.last_updated_by IS NULL; -- cannot derive LAST_UPDATED_BY
2412
2413 END last_updated_by;
2414
2415 -- validate created_by against fnd_user table. The caller have an option
2416 -- to provide either created_by or created_by_name. If the caller
2417 -- pass created_by, the id need to be valid. If the caller pass
2418 -- created_by_name, we will derive the ID. If the caller pass both
2419 -- both value must be consistent to each other.
2420 PROCEDURE created_by IS
2421 l_errMsg VARCHAR2(240);
2422 BEGIN
2423 -- Derive CREATED_BY if user provided only CREATED_BY_NAME
2424 UPDATE wip_move_txn_interface wmti
2425 SET wmti.created_by =
2426 (SELECT fu.user_id
2427 FROM fnd_user fu
2428 WHERE fu.user_name = wmti.created_by_name
2429 AND SYSDATE BETWEEN fu.start_date AND NVL(fu.end_date, SYSDATE))
2430 WHERE wmti.group_id = g_group_id
2431 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2432 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2433 AND wmti.created_by IS NULL
2434 AND wmti.created_by_name IS NOT NULL;
2435
2436 -- Set Error Message
2437 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2438 fnd_message.set_token('ENTITY1', 'CREATED_BY');
2439 fnd_message.set_token('ENTITY2', 'CREATED_BY_NAME');
2440 l_errMsg := substrb(fnd_message.get, 1, 240);
2441
2442 -- Error out if CREATED_BY is not consistent with CREATED_BY_NAME
2443 INSERT INTO wip_txn_interface_errors(
2444 transaction_id,
2445 error_message,
2446 error_column,
2447 last_update_date,
2448 last_updated_by,
2449 creation_date,
2450 created_by,
2451 last_update_login,
2452 request_id,
2453 program_application_id,
2454 program_id,
2455 program_update_date
2456 )
2457 SELECT wmti.transaction_id, -- transaction_id
2458 l_errMsg, -- error_message
2459 'CREATED_BY/BY_NAME', -- error_column
2460 SYSDATE, -- last_update_date
2461 NVL(wmti.last_updated_by, -1),
2462 SYSDATE, -- creation_date
2463 NVL(wmti.created_by, -1),
2464 wmti.last_update_login,
2465 wmti.request_id,
2466 wmti.program_application_id,
2467 wmti.program_id,
2468 wmti.program_update_date
2469 FROM wip_move_txn_interface wmti
2470 WHERE wmti.group_id = g_group_id
2471 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2472 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2473 AND ((wmti.created_by IS NULL) -- cannot derive LAST_UPDATED_BY
2474 OR
2475 (NOT EXISTS
2476 (SELECT 'X'
2477 FROM fnd_user fu
2478 WHERE fu.user_name = NVL(wmti.created_by_name,
2479 fu.user_name)
2480 AND fu.user_id = wmti.created_by
2481 AND SYSDATE BETWEEN fu.start_date AND
2482 NVL(fu.end_date, SYSDATE))));
2483 END created_by;
2484
2485 -- This procedure is used to validate osp transactions. User cannot move into
2486 -- a queue of OSP operation unless the department associated to that operation
2487 -- has a location for PO_RECEIVE. For PO_MOVE the department associated with
2488 -- the next operation after to_op must have location. If to_op is the last op
2489 -- , the department associated to that operation must have location.
2490 -- The user must be a valid employee to perform osp transactions.
2491 PROCEDURE osp_validation IS
2492 l_errMsg VARCHAR2(240);
2493 BEGIN
2494 -- Set Error Message
2495 fnd_message.set_name('WIP', 'WIP_PO_MOVE_LOCATION');
2496 l_errMsg := substrb(fnd_message.get, 1, 240);
2497
2498 -- Error out if user try to move into a queue of OSP operation and the
2499 -- department associated to that operation does not have a location
2500 -- for PO_RECEIVE. For PO_MOVE the department associated with
2501 -- the next operation after to_op must have location. If to_op is the last op
2502 -- the department associated to that operation must have location.
2503 INSERT INTO wip_txn_interface_errors(
2504 transaction_id,
2505 error_message,
2506 error_column,
2507 last_update_date,
2508 last_updated_by,
2509 creation_date,
2510 created_by,
2511 last_update_login,
2512 request_id,
2513 program_application_id,
2514 program_id,
2515 program_update_date
2516 )
2517 SELECT wmti.transaction_id, -- transaction_id
2518 l_errMsg, -- error_message
2519 'TO_OP_SEQ_NUM/CREATED_BY', -- error_column
2520 SYSDATE, -- last_update_date
2521 NVL(wmti.last_updated_by, -1),
2522 SYSDATE, -- creation_date
2523 NVL(wmti.created_by, -1),
2524 wmti.last_update_login,
2525 wmti.request_id,
2526 wmti.program_application_id,
2527 wmti.program_id,
2528 wmti.program_update_date
2529 FROM wip_move_txn_interface wmti
2530 WHERE wmti.group_id = g_group_id
2531 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2532 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2533 AND EXISTS
2534 (SELECT 'X'
2535 FROM bom_departments bd,
2536 wip_operation_resources wor,
2537 wip_operations wo1,
2538 wip_operations wo2
2539 WHERE wor.organization_id = wmti.organization_id
2540 AND wor.wip_entity_id = wmti.wip_entity_id
2541 AND wor.operation_seq_num = wmti.to_operation_seq_num
2542 AND wmti.fm_operation_seq_num < wmti.to_operation_seq_num
2543 AND wmti.to_intraoperation_step_type = WIP_CONSTANTS.QUEUE
2544 AND (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
2545 WIP_CONSTANTS.LOTBASED)
2546 OR
2547 (wmti.entity_type = WIP_CONSTANTS.REPETITIVE AND
2548 wor.repetitive_schedule_id IN
2549 (SELECT wrs.repetitive_schedule_id
2550 FROM wip_repetitive_schedules wrs
2551 WHERE wrs.wip_entity_id = wmti.wip_entity_id
2552 AND wrs.organization_id = wmti.organization_id
2553 AND wrs.line_id = wmti.line_id
2554 AND wrs.status_type IN (WIP_CONSTANTS.RELEASED,
2555 WIP_CONSTANTS.COMP_CHRG))))
2556 AND wo1.organization_id = wor.organization_id
2557 AND wo1.wip_entity_id = wor.wip_entity_id
2558 AND NVL(wo1.repetitive_schedule_id,-1) =
2559 NVL(wor.repetitive_schedule_id,-1)
2560 AND wo1.operation_seq_num = wor.operation_seq_num
2561 AND wo2.organization_id = wo1.organization_id
2562 AND wo2.wip_entity_id = wo1.wip_entity_id
2563 AND NVL(wo2.repetitive_schedule_id,-1) =
2564 NVL(wo1.repetitive_schedule_id,-1)
2565 AND ((wor.autocharge_type = WIP_CONSTANTS.PO_RECEIPT AND
2566 wo2.operation_seq_num = wor.operation_seq_num)
2567 OR
2568 (wor.autocharge_type = WIP_CONSTANTS.PO_MOVE AND
2569 ((wo1.next_operation_seq_num IS NOT NULL AND
2570 wo1.next_operation_seq_num = wo2.operation_seq_num)
2571 OR
2572 (wo1.next_operation_seq_num IS NULL AND
2573 wo2.operation_seq_num = wor.operation_seq_num))))
2574 AND bd.organization_id = wmti.organization_id
2575 AND wo2.department_id = bd.department_id
2576 AND bd.location_id IS NULL);
2577
2578 -- Set Error Message
2579 fnd_message.set_name('WIP', 'WIP_VALID_EMPLOYEE');
2580 l_errMsg := substrb(fnd_message.get, 1, 240);
2581
2582 -- Error out if the user who try to do OSP transaction is not an employee
2583 INSERT INTO wip_txn_interface_errors(
2584 transaction_id,
2585 error_message,
2586 error_column,
2587 last_update_date,
2588 last_updated_by,
2589 creation_date,
2590 created_by,
2591 last_update_login,
2592 request_id,
2593 program_application_id,
2594 program_id,
2595 program_update_date
2596 )
2597 SELECT wmti.transaction_id, -- transaction_id
2598 l_errMsg, -- error_message
2599 'TO_OP_SEQ_NUM/CREATED_BY', -- error_column
2600 SYSDATE, -- last_update_date
2601 NVL(wmti.last_updated_by, -1),
2602 SYSDATE, -- creation_date
2603 NVL(wmti.created_by, -1),
2604 wmti.last_update_login,
2605 wmti.request_id,
2606 wmti.program_application_id,
2607 wmti.program_id,
2608 wmti.program_update_date
2609 FROM wip_move_txn_interface wmti
2610 WHERE wmti.group_id = g_group_id
2611 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2612 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2613 AND EXISTS
2614 (SELECT 'Outside processing resources exist'
2615 FROM wip_operation_resources wor
2616 WHERE wor.organization_id = wmti.organization_id
2617 AND wor.wip_entity_id = wmti.wip_entity_id
2618 AND wor.operation_seq_num = wmti.to_operation_seq_num
2619 AND wmti.fm_operation_seq_num < wmti.to_operation_seq_num
2620 AND wmti.to_intraoperation_step_type = WIP_CONSTANTS.QUEUE
2621 AND wor.autocharge_type IN (WIP_CONSTANTS.PO_RECEIPT,
2622 WIP_CONSTANTS.PO_MOVE)
2623 AND (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
2624 WIP_CONSTANTS.LOTBASED)
2625 OR
2626 (wmti.entity_type = WIP_CONSTANTS.REPETITIVE AND
2627 wor.repetitive_schedule_id IN
2628 (SELECT wrs.repetitive_schedule_id
2629 FROM wip_repetitive_schedules wrs
2630 WHERE wrs.organization_id = wmti.organization_id
2631 AND wrs.wip_entity_id = wmti.wip_entity_id
2632 AND wrs.line_id = wmti.line_id
2633 AND wrs.status_type IN (WIP_CONSTANTS.RELEASED,
2634 WIP_CONSTANTS.COMP_CHRG)))))
2635 AND NOT EXISTS
2636 (SELECT 'Current user is an employee'
2637 FROM fnd_user fu,
2638 per_people_f ppf
2639 WHERE fu.user_id = wmti.created_by
2640 AND fu.employee_id = ppf.person_id);
2641
2642 END osp_validation;
2643
2644 -- validate serial related information. This validation is only useful if
2645 -- user try to do background serialized txns.
2646 PROCEDURE serial_validation IS
2647 BEGIN
2648 -- reset enums table
2649 enums.delete;
2650 -- Users cannot move cross 'Queue' of serialization start op. User need to
2651 -- move 2 step. The first time move to Queue of serialization start op, then
2652 -- serial move. For backward move, do serial move first.
2653 UPDATE wip_move_txn_interface wmti
2654 SET wmti.process_status = WIP_CONSTANTS.ERROR
2655 WHERE wmti.group_id = g_group_id
2656 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2657 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2658 AND EXISTS -- serialized job
2659 (SELECT 'X'
2660 FROM wip_discrete_jobs wdj
2661 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2662 AND wdj.serialization_start_op IS NOT NULL
2663 AND (-- Forward move
2664 (wmti.fm_operation_seq_num < wdj.serialization_start_op AND
2665 (wmti.to_operation_seq_num > wdj.serialization_start_op
2666 OR
2667 (wmti.to_operation_seq_num = wdj.serialization_start_op AND
2668 wmti.to_intraoperation_step_type <> WIP_CONSTANTS.QUEUE)))
2669 OR
2670 -- Backward move
2671 (wmti.to_operation_seq_num < wdj.serialization_start_op AND
2672 (wmti.fm_operation_seq_num > wdj.serialization_start_op
2673 OR
2674 (wmti.fm_operation_seq_num = wdj.serialization_start_op AND
2675 wmti.fm_intraoperation_step_type <> WIP_CONSTANTS.QUEUE)))))
2676 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2677
2678 fnd_message.set_name('WIP', 'WIP_MOVE_CROSS_START_OP');
2679 add_error(p_txn_ids => enums,
2680 p_err_col => 'FM/TO_STEP, FM/TO_OP',
2681 p_err_msg => fnd_message.get);
2682
2683 -- Comment out the validation below because Express Move can be done for more
2684 -- then one quantity. Moreover, this validation was already done through the
2685 -- UI(mobile and MES), and we do not support serilized move in the background.
2686 /*
2687 -- reset enums table
2688 enums.delete;
2689 -- If user try to do serialized transaction, primary_quantity must be 1.
2690 -- This validation is only for serialized discrete job. For serialized
2691 -- OSFM job, primary_quantity can be more than 1.
2692 UPDATE wip_move_txn_interface wmti
2693 SET wmti.process_status = WIP_CONSTANTS.ERROR
2694 WHERE wmti.group_id = g_group_id
2695 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2696 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2697 AND EXISTS -- serialized discrete job and serialized transaction
2698 (SELECT 'X'
2699 FROM wip_discrete_jobs wdj,
2700 wip_entities we
2701 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2702 AND wdj.wip_entity_id = we.wip_entity_id
2703 AND we.entity_type = WIP_CONSTANTS.DISCRETE
2704 AND wdj.serialization_start_op IS NOT NULL
2705 AND wmti.fm_operation_seq_num >= wdj.serialization_start_op
2706 AND wmti.to_operation_seq_num >= wdj.serialization_start_op
2707 AND wmti.primary_quantity <> 1)
2708 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2709
2710 fnd_message.set_name('WIP', 'WIP_INVALID_SERIAL_QTY');
2711 add_error(p_txn_ids => enums,
2712 p_err_col => 'TRANSACTION/PRIMARY_QUANTITY',
2713 p_err_msg => fnd_message.get);
2714 */
2715
2716 -- reset enums table
2717 enums.delete;
2718 -- if user provide serial number information for non-serialized job, or
2719 -- serialized job with non-serialized move, error out.
2720 UPDATE wip_move_txn_interface wmti
2721 SET wmti.process_status = WIP_CONSTANTS.ERROR
2722 WHERE wmti.group_id = g_group_id
2723 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2724 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2725 AND EXISTS -- regular job
2726 (SELECT 'X'
2727 FROM wip_discrete_jobs wdj
2728 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2729 AND (wdj.serialization_start_op IS NULL -- non-serialized job
2730 OR -- serialized job with non-serialized move
2731 (wdj.serialization_start_op IS NOT NULL
2732 AND
2733 (wmti.fm_operation_seq_num < wdj.serialization_start_op OR
2734 (wmti.fm_operation_seq_num = wdj.serialization_start_op AND
2735 wmti.fm_intraoperation_step_type = WIP_CONSTANTS.QUEUE))
2736 AND
2737 (wmti.to_operation_seq_num < wdj.serialization_start_op OR
2738 (wmti.to_operation_seq_num = wdj.serialization_start_op AND
2739 wmti.to_intraoperation_step_type = WIP_CONSTANTS.QUEUE))))
2740 )
2741 AND EXISTS
2742 (SELECT 'X'
2743 FROM wip_serial_move_interface wsmi
2744 WHERE wsmi.transaction_id = wmti.transaction_id)
2745 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2746
2747 fnd_message.set_name('WIP', 'WIP_SERIAL_INFO_NOT_ALLOW');
2748 add_error(p_txn_ids => enums,
2749 p_err_col => 'WSMI.ASSEMBLY_SERIAL_NUMBER',
2750 p_err_msg => fnd_message.get);
2751
2752
2753 -- reset enums table
2754 enums.delete;
2755 -- if user try to do serialized transaction, number of serial records must be
2756 -- equal to wmti.primary_quantity
2757 UPDATE wip_move_txn_interface wmti
2758 SET wmti.process_status = WIP_CONSTANTS.ERROR
2759 WHERE wmti.group_id = g_group_id
2760 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2761 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2762 AND EXISTS -- serialized job and serialized transaction
2763 (SELECT 'X'
2764 FROM wip_discrete_jobs wdj
2765 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2766 AND wdj.serialization_start_op IS NOT NULL
2767 AND wmti.fm_operation_seq_num >= wdj.serialization_start_op
2768 AND wmti.to_operation_seq_num >= wdj.serialization_start_op)
2769 AND wmti.primary_quantity <>
2770 (SELECT COUNT(*)
2771 FROM wip_serial_move_interface wsmi,
2772 mtl_serial_numbers msn
2773 WHERE wsmi.transaction_id = wmti.transaction_id
2774 AND wsmi.assembly_serial_number = msn.serial_number
2775 AND wmti.organization_id = msn.current_organization_id
2776 AND wmti.primary_item_id = msn.inventory_item_id
2777 AND msn.wip_entity_id IS NOT NULL
2778 AND msn.wip_entity_id = wmti.wip_entity_id)
2779 AND wmti.primary_quantity <>
2780 (SELECT COUNT(*)
2781 FROM wip_serial_move_interface wsmi,
2782 wip_entities we,
2783 mtl_serial_numbers msn,
2784 mtl_object_genealogy mog
2785 WHERE wsmi.transaction_id = wmti.transaction_id
2786 AND wsmi.assembly_serial_number = msn.serial_number
2787 AND wmti.organization_id = msn.current_organization_id
2788 AND wmti.primary_item_id = msn.inventory_item_id
2789 AND msn.current_status = WIP_CONSTANTS.IN_STORES
2790 AND wmti.wip_entity_id = we.wip_entity_id
2791 AND ((mog.genealogy_origin = 1 AND
2792 mog.parent_object_id = we.gen_object_id AND
2793 mog.object_id = msn.gen_object_id)
2794 OR
2795 (mog.genealogy_origin = 2 AND
2796 mog.parent_object_id = msn.gen_object_id AND
2797 mog.object_id = we.gen_object_id))
2798 AND mog.end_date_active IS NULL)
2799 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2800
2801 fnd_message.set_name('WIP', 'WIP_SERIAL_QTY_MISSMATCH');
2802 add_error(p_txn_ids => enums,
2803 p_err_col => 'WSMI.ASSEMBLY_SERIAL_NUMBER',
2804 p_err_msg => fnd_message.get);
2805
2806 -- reset enums table
2807 enums.delete;
2808 -- if user try to do serialized transaction, the status of the serial
2809 -- must correspond to the transaction type.
2810 UPDATE wip_move_txn_interface wmti
2811 SET wmti.process_status = WIP_CONSTANTS.ERROR
2812 WHERE wmti.group_id = g_group_id
2813 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2814 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2815 AND EXISTS -- serialized job and serialized transaction
2816 (SELECT 'X'
2817 FROM wip_discrete_jobs wdj
2818 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2819 AND wdj.serialization_start_op IS NOT NULL
2820 AND wmti.fm_operation_seq_num >= wdj.serialization_start_op
2821 AND wmti.to_operation_seq_num >= wdj.serialization_start_op)
2822 AND NOT EXISTS
2823 (SELECT 'X'
2824 FROM wip_serial_move_interface wsmi,
2825 mtl_serial_numbers msn
2826 WHERE wsmi.transaction_id = wmti.transaction_id
2827 AND wsmi.assembly_serial_number = msn.serial_number
2828 AND wmti.organization_id = msn.current_organization_id
2829 AND wmti.primary_item_id = msn.inventory_item_id
2830 AND msn.line_mark_id IS NULL
2831 AND ((wmti.transaction_type = WIP_CONSTANTS.RET_TXN AND
2832 msn.group_mark_id IS NULL AND
2833 msn.wip_entity_id IS NULL AND
2834 msn.current_status = WIP_CONSTANTS.IN_STORES)
2835 OR
2836 (wmti.transaction_type IN (WIP_CONSTANTS.MOVE_TXN,
2837 WIP_CONSTANTS.COMP_TXN) AND
2838 msn.group_mark_id IS NOT NULL AND
2839 msn.wip_entity_id IS NOT NULL AND
2840 wmti.wip_entity_id = msn.wip_entity_id AND
2841 -- Define but not use or Issue out of store.
2842 msn.current_status IN (WIP_CONSTANTS.DEF_NOT_USED,
2843 WIP_CONSTANTS.OUT_OF_STORES))))
2844 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2845
2846 fnd_message.set_name('WIP', 'WIP_INVALID_SERIAL_STATUS');
2847 add_error(p_txn_ids => enums,
2848 p_err_col => 'WSMI.ASSEMBLY_SERIAL_NUMBER',
2849 p_err_msg => fnd_message.get);
2850
2851 END serial_validation;
2852
2853 -- If there are some errors occur, this routine will set
2854 -- PROCESS_STATUS to WIP_CONSTANTS.ERROR. Then it will insert all the errors
2855 -- into WIP_TXN_INTERFACE_ERRORS
2856 PROCEDURE update_interface_tbl IS
2857 BEGIN
2858 -- there are some errors occur, so set the process_status to error so that
2859 -- move processor will not pick up this record
2860 UPDATE wip_move_txn_interface wmti
2861 SET wmti.process_status = WIP_CONSTANTS.ERROR
2862 WHERE wmti.group_id = g_group_id
2863 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2864 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2865 AND EXISTS
2866 (SELECT 'X'
2867 FROM wip_txn_interface_errors wtie
2868 WHERE wtie.transaction_id = wmti.transaction_id);
2869
2870 -- insert error message to WIP_TXN_INTERFACE_ERRORS, and clear error table
2871 load_errors;
2872 END update_interface_tbl;
2873
2874 /* Fixed bug 5056289. Added more validation for assembly to prevent the whole
2875 batch error out when assembly fail inventory validation.
2876 */
2877 -- Validate assembly related information to prevent the whole batch failing
2878 -- if there is something wrong with the assembly like assembly is not
2879 -- transactable, or assembly is not an inventory item. This check is only for
2880 -- EZ Completion and EZ Return.
2881 PROCEDURE assembly_validation IS
2882 BEGIN
2883 -- reset enums table
2884 enums.delete;
2885 -- Users cannot do EZ Completion/EZ Return if an assembly is not transactable
2886 -- or an assembly is not an inventory item.
2887 UPDATE wip_move_txn_interface wmti
2888 SET wmti.process_status = WIP_CONSTANTS.ERROR
2889 WHERE wmti.group_id = g_group_id
2890 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2891 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2892 AND wmti.transaction_type IN (WIP_CONSTANTS.RET_TXN,
2893 WIP_CONSTANTS.COMP_TXN)
2894 AND EXISTS -- Item flag was not set properly.
2895 (SELECT 'X'
2896 FROM mtl_system_items msi
2897 WHERE msi.inventory_item_id = wmti.primary_item_id
2898 AND msi.organization_id = wmti.organization_id
2899 AND (msi.inventory_item_flag = 'N' OR
2900 msi.mtl_transactions_enabled_flag = 'N'))
2901 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2902
2903 fnd_message.set_name('INV', 'INV_INT_ITMEXP');
2904 add_error(p_txn_ids => enums,
2905 p_err_col => 'PRIMARY_ITEM_ID',
2906 p_err_msg => fnd_message.get);
2907
2908 END assembly_validation;
2909
2910
2911 -- If pass all the validation, and there is no error, this routine will
2912 -- derive all the rest info (fm_operation_code, fm_department_id,
2913 -- fm_department_code, to_operation_code, to_department_id, to_department_code)
2914 -- , then update PROCESS_PHASE to WIP_CONSTANTS.MOVE_PROC. This routine
2915 -- should be called after we called all the validation code and
2916 -- update_interface_tbl
2917 PROCEDURE derive IS
2918 l_PrevOpSeq NUMBER;
2919 l_NextOpSeq NUMBER;
2920 l_OpExists BOOLEAN;
2921 BEGIN
2922
2923 UPDATE wip_move_txn_interface wmti
2924 SET (wmti.fm_operation_code,
2925 wmti.fm_department_id,
2926 wmti.fm_department_code,
2927 wmti.to_operation_code,
2928 wmti.to_department_id,
2929 wmti.to_department_code,
2930 wmti.process_phase) =
2931 (SELECT bso1.operation_code,
2932 wo1.department_id,
2933 bd1.department_code,
2934 bso2.operation_code,
2935 wo2.department_id,
2936 bd2.department_code,
2937 WIP_CONSTANTS.MOVE_PROC
2938 FROM bom_standard_operations bso1,
2939 bom_standard_operations bso2,
2940 bom_departments bd1,
2941 bom_departments bd2,
2942 wip_operations wo1,
2943 wip_operations wo2
2944 WHERE wo1.organization_id = wmti.organization_id
2945 AND wo1.wip_entity_id = wmti.wip_entity_id
2946 AND wo1.operation_seq_num = wmti.fm_operation_seq_num
2947 AND wo2.organization_id = wmti.organization_id
2948 AND wo2.wip_entity_id = wmti.wip_entity_id
2949 AND wo2.operation_seq_num = wmti.to_operation_seq_num
2950 /* Standard operation ID is optional, so we should use outer join */
2951 AND bso1.standard_operation_id(+) = wo1.standard_operation_id
2952 AND bso2.standard_operation_id(+) = wo2.standard_operation_id
2953 AND wo1.department_id = bd1.department_id
2954 AND wo2.department_id = bd2.department_id
2955 AND (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
2956 WIP_CONSTANTS.LOTBASED)
2957 OR
2958 (wmti.entity_type = WIP_CONSTANTS.REPETITIVE AND
2959 wo1.repetitive_schedule_id = wmti.repetitive_schedule_id AND
2960 wo2.repetitive_schedule_id = wmti.repetitive_schedule_id)))
2961 WHERE wmti.group_id = g_group_id
2962 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2963 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
2964
2965 END derive;
2966
2967 PROCEDURE validate(p_group_id IN NUMBER,
2968 p_initMsgList IN VARCHAR2) IS
2969 l_params wip_logger.param_tbl_t;
2970 l_returnStatus VARCHAR2(1);
2971 l_logLevel NUMBER ;
2972
2973 BEGIN
2974 l_logLevel := fnd_log.g_current_runtime_level;
2975 IF(fnd_api.to_boolean(p_initMsgList)) THEN
2976 fnd_msg_pub.initialize;
2977 END IF;
2978
2979 -- write parameter value to log file
2980 if (l_logLevel <= wip_constants.trace_logging) then
2981 l_params(1).paramName := 'p_group_id';
2982 l_params(1).paramValue := p_group_id;
2983 wip_logger.entryPoint(p_procName => 'wip_move_validator.validate',
2984 p_params => l_params,
2985 x_returnStatus => l_returnStatus);
2986 end if;
2987
2988 -- reset global_variable everytime this routine is called
2989 g_group_id := p_group_id;
2990 enums.delete;
2991 -- Call last_updatd_by and created_by first even if it is a low priority
2992 -- validation because we want to insert last_updated_by and created_by
2993 -- into WIP_TXN_INTERFACE_ERRORS
2994 last_updated_by;
2995 created_by;
2996 /*****************************
2997 * Start critical validation *
2998 *****************************/
2999 -- If any of the procedure below error out, set WMTI.PROCESS_STATUS to
3000 -- Error and stop validation.
3001 /* Bug#2956953 - commented call to organization_id procedure as the validation
3002 for organization_id/organization_code are called from wip move manager code
3003 - Changes done as part of the Wip Move Sequencing Project */
3004 -- organization_id;
3005 wip_entity_id;
3006 transaction_type;
3007 transaction_date;
3008 fm_operation;
3009 fm_step;
3010 to_operation;
3011 to_step;
3012 transaction_qty;
3013 transaction_uom;
3014 ocpl_txn_qty;
3015 /*****************************
3016 * End critical validation *
3017 *****************************/
3018
3019 /*********************************
3020 * Start low priority validation *
3021 *********************************/
3022 -- If any of the procedure below error out, continue validating other
3023 -- low priority validation because we support multiple error message
3024 -- for one record.
3025 transaction_id;
3026 primary_qty;
3027 primary_uom;
3028 ocpl_primary_qty;
3029 ocpl_txn_id;
3030 reason_id;
3031 scrap_account_id;
3032
3033 -- need to call this routine before osp_validation because use
3034 -- created_by as a user_id to validate OSP
3035 osp_validation;
3036 serial_validation;
3037 /* Fixed bug 5056289. */
3038 -- Add more validation for assembly to prevent the whole batch failing if
3039 -- there is something wrong with the assembly. This check is only for
3040 -- EZ Completion and EZ Return.
3041 assembly_validation;
3042 /*******************************
3043 * End low priority validation *
3044 *******************************/
3045 -- set WMTI.PROCESS_STATUS to error if there is an error from any
3046 -- validation and insert error message into WIP_TXN_INTERFACE_ERRORS
3047 update_interface_tbl;
3048 -- derive the rest nessary info
3049 derive;
3050 -- write to the log file
3051 if (l_logLevel <= wip_constants.trace_logging) then
3052 wip_logger.exitPoint(p_procName => 'wip_move_validator.validate',
3053 p_procReturnStatus => fnd_api.g_ret_sts_success,
3054 p_msg => 'procedure complete',
3055 x_returnStatus => l_returnStatus);
3056 end if;
3057 EXCEPTION
3058 WHEN others THEN
3059 if (l_logLevel <= wip_constants.trace_logging) then
3060 wip_logger.exitPoint(p_procName => 'wip_move_validator.validate',
3061 p_procReturnStatus => fnd_api.g_ret_sts_unexp_error,
3062 p_msg => 'Unexpected Errors: ' || SQLERRM,
3063 x_returnStatus => l_returnStatus);
3064 end if;
3065
3066 END validate;
3067
3068 PROCEDURE get_move_txn_type(p_move_id IN NUMBER,
3069 p_org_id IN NUMBER DEFAULT NULL,
3070 p_wip_entity_id IN NUMBER DEFAULT NULL,
3071 p_assm_item_id IN NUMBER DEFAULT NULL,
3072 p_txn_type OUT NOCOPY VARCHAR2)
3073 IS
3074 BEGIN
3075 p_txn_type := move_txn_type(p_move_id => p_move_id,
3076 p_org_id => p_org_id,
3077 p_wip_entity_id => p_wip_entity_id,
3078 p_assm_item_id => p_assm_item_id);
3079 END get_move_txn_type;
3080
3081
3082 FUNCTION move_txn_type(p_move_id IN NUMBER,
3083 p_org_id IN NUMBER DEFAULT NULL,
3084 p_wip_entity_id IN NUMBER DEFAULT NULL,
3085 p_assm_item_id IN NUMBER DEFAULT NULL) return VARCHAR2
3086 IS
3087 p_txn_type VARCHAR2(80);
3088 l_org_id NUMBER ;
3089 l_wip_entity_id NUMBER ;
3090 l_assm_item_id NUMBER ;
3091 BEGIN
3092 l_org_id := p_org_id;
3093 l_wip_entity_id := p_wip_entity_id;
3094 l_assm_item_id := p_assm_item_id;
3095
3096
3097 if (l_org_id is NULL or l_wip_entity_id is NULL) then
3098 select organization_id,
3099 wip_entity_id
3100 into l_org_id,
3101 l_wip_entity_id
3102 from wip_move_transactions
3103 where transaction_id = p_move_id;
3104 end if;
3105
3106 if (l_assm_item_id is NULL) then
3107 select wdj.primary_item_id
3108 into l_assm_item_id
3109 from wip_discrete_jobs wdj
3110 where wdj.organization_id = l_org_id
3111 and wdj.wip_entity_id = l_wip_entity_id;
3112 end if;
3113
3114 begin
3115 -- Should have at most one match
3116 select distinct lu.meaning
3117 into p_txn_type
3118 from mfg_lookups lu,
3119 mtl_material_transactions mmt
3120 where mmt.move_transaction_id = p_move_id
3121 and mmt.organization_id = l_org_id
3122 and mmt.transaction_source_id = l_wip_entity_id
3123 and mmt.inventory_item_id = l_assm_item_id
3124 and mmt.transaction_type_id in (wip_constants.CPLASSY_TYPE, wip_constants.RETASSY_TYPE)
3125 and lu.lookup_type = 'WIP_MOVE_TRANSACTION_TYPE'
3126 and lu.lookup_code = decode(mmt.transaction_type_id, wip_constants.CPLASSY_TYPE, wip_constants.comp_txn, wip_constants.RETASSY_TYPE, wip_constants.ret_txn);
3127 exception
3128 -- no inv txn involved; just a plain move txn
3129 when no_data_found then
3130 select meaning
3131 into p_txn_type
3132 from mfg_lookups
3133 where lookup_type = 'WIP_MOVE_TRANSACTION_TYPE'
3134 and lookup_code = wip_constants.move_txn;
3135 when others then
3136 p_txn_type := -1;
3137 end;
3138
3139 return p_txn_type;
3140 END move_txn_type;
3141
3142 PROCEDURE validateOATxn(p_group_id IN NUMBER) IS
3143 l_params wip_logger.param_tbl_t;
3144 l_returnStatus VARCHAR2(1);
3145 l_logLevel NUMBER ;
3146 l_sf_status VARCHAR2(100); /*Fix Bug 9758848*/
3147
3148 BEGIN
3149 l_logLevel := fnd_log.g_current_runtime_level;
3150
3151 -- write parameter value to log file
3152 if (l_logLevel <= wip_constants.trace_logging) then
3153 l_params(1).paramName := 'p_group_id';
3154 l_params(1).paramValue := p_group_id;
3155 wip_logger.entryPoint(p_procName => 'wip_move_validator.validateOATxn',
3156 p_params => l_params,
3157 x_returnStatus => l_returnStatus);
3158 end if;
3159
3160 -- reset global_variable everytime this routine is called
3161 g_group_id := p_group_id;
3162 enums.delete;
3163
3164 -- Derive ACCT_PERIOD_ID from TRANSACTION_DATE
3165 UPDATE wip_move_txn_interface wmti
3166 SET wmti.acct_period_id =
3167 (SELECT oap.acct_period_id
3168 FROM org_acct_periods oap
3169 WHERE oap.organization_id = wmti.organization_id
3170 -- modified the statement below for timezone project in J
3171 AND TRUNC(inv_le_timezone_pub.get_le_day_for_inv_org(
3172 wmti.transaction_date, -- p_trxn_date
3173 wmti.organization_id -- p_inv_org_id
3174 )) BETWEEN
3175 oap.period_start_date AND oap.schedule_close_date)
3176 WHERE wmti.group_id = g_group_id
3177 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3178 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
3179
3180 -- reset enums table
3181 enums.delete;
3182 -- Error out if there is no open accout period for the TRANSACTION_DATE
3183 -- specified or there is no WIP_PERIOD_BALANCES
3184 UPDATE wip_move_txn_interface wmti
3185 SET wmti.process_status = WIP_CONSTANTS.ERROR
3186 WHERE wmti.group_id = g_group_id
3187 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3188 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3189 AND (wmti.acct_period_id IS NULL
3190 OR
3191 NOT EXISTS
3192 (SELECT 'X'
3193 FROM wip_period_balances wpb
3194 WHERE wpb.acct_period_id = wmti.acct_period_id
3195 AND wpb.wip_entity_id = wmti.wip_entity_id
3196 AND wpb.organization_id = wmti.organization_id))
3197 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3198
3199 fnd_message.set_name('WIP', 'WIP_NO_BALANCE');
3200 add_error(p_txn_ids => enums,
3201 p_err_col => 'TRANSACTION_DATE',
3202 p_err_msg => fnd_message.get);
3203
3204 -- Fixed bug 5310474
3205 -- reset enums table
3206 enums.delete;
3207 -- Error out if FM_OPERATION_SEQ_NUM/FM_INTRAOPERATION_STEP_TYPE has
3208 -- no move shop floor status attached
3209 UPDATE wip_move_txn_interface wmti
3210 SET wmti.process_status = WIP_CONSTANTS.ERROR
3211 WHERE wmti.group_id = g_group_id
3212 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3213 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3214 AND EXISTS
3215 (SELECT 'X'
3216 FROM wip_shop_floor_status_codes wsc,
3217 wip_shop_floor_statuses ws
3218 WHERE wsc.organization_id = wmti.organization_id
3219 AND ws.organization_id = wmti.organization_id
3220 AND ws.wip_entity_id = wmti.wip_entity_id
3221 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
3222 AND ws.operation_seq_num = wmti.fm_operation_seq_num
3223 AND ws.intraoperation_step_type = wmti.fm_intraoperation_step_type
3224 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
3225 AND wsc.status_move_flag = WIP_CONSTANTS.NO
3226 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
3227 AND (wmti.source_code IS NULL OR
3228 wmti.source_code <> 'RCV' OR
3229 (wmti.source_code = 'RCV' AND
3230 NOT EXISTS
3231 (SELECT 'X'
3232 FROM wip_parameters wp
3233 WHERE wp.organization_id = wmti.organization_id
3234 AND wp.osp_shop_floor_status =
3235 wsc.shop_floor_status_code))))
3236 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3237
3238 /* Added the following for SUN enhancement in Bug 9758848*/
3239 if enums.count > 0 then
3240 for i in 1..enums.count loop
3241 SELECT ws.shop_floor_status_code
3242 INTO l_sf_status
3243 FROM wip_shop_floor_status_codes wsc,
3244 wip_shop_floor_statuses ws,
3245 wip_move_txn_interface wmti
3246 WHERE wsc.organization_id = wmti.organization_id
3247 AND ws.organization_id = wmti.organization_id
3248 AND ws.wip_entity_id = wmti.wip_entity_id
3249 AND wmti.transaction_id = enums(i)
3250 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
3251 AND ws.operation_seq_num = wmti.fm_operation_seq_num
3252 AND ws.intraoperation_step_type = wmti.fm_intraoperation_step_type
3253 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
3254 AND wsc.status_move_flag = WIP_CONSTANTS.NO
3255 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
3256 AND rownum = 1;
3257
3258 fnd_message.set_name('WIP', 'WIP_SF_STATUS_NO_TXN1');
3259 fnd_message.set_token('SF_STATUS', to_char(l_sf_status));
3260 add_error(p_txn_id => enums(i),
3261 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
3262 p_err_msg => fnd_message.get);
3263 end loop;
3264 end if;
3265 -- reset enums table
3266 enums.delete;
3267 -- Error out if user try to easy complete job/schedule that has No Move shop
3268 -- floor status attached to Tomove of the last operation
3269 UPDATE wip_move_txn_interface wmti
3270 SET wmti.process_status = WIP_CONSTANTS.ERROR
3271 WHERE wmti.group_id = g_group_id
3272 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3273 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3274 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
3275 AND EXISTS
3276 (SELECT 'X'
3277 FROM wip_shop_floor_status_codes wsc,
3278 wip_shop_floor_statuses ws
3279 WHERE wsc.organization_id = wmti.organization_id
3280 AND ws.organization_id = wmti.organization_id
3281 AND ws.wip_entity_id = wmti.wip_entity_id
3282 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
3283 AND ws.operation_seq_num = wmti.to_operation_seq_num
3284 AND ws.intraoperation_step_type = WIP_CONSTANTS.TOMOVE
3285 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
3286 AND wsc.status_move_flag = WIP_CONSTANTS.NO
3287 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE)
3288 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3289
3290 /* Added the following for SUN enhancement in Bug 9758848*/
3291 if enums.count > 0 then
3292 for i in 1..enums.count loop
3293 SELECT ws.shop_floor_status_code
3294 INTO l_sf_status
3295 FROM wip_shop_floor_status_codes wsc,
3296 wip_shop_floor_statuses ws,
3297 wip_move_txn_interface wmti
3298 WHERE wsc.organization_id = wmti.organization_id
3299 AND ws.organization_id = wmti.organization_id
3300 AND ws.wip_entity_id = wmti.wip_entity_id
3301 AND wmti.transaction_id = enums(i)
3302 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
3303 AND ws.operation_seq_num = wmti.to_operation_seq_num
3304 AND ws.intraoperation_step_type = WIP_CONSTANTS.TOMOVE
3305 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
3306 AND wsc.status_move_flag = WIP_CONSTANTS.NO
3307 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
3308 and rownum = 1;
3309
3310 fnd_message.set_name('WIP', 'WIP_SF_STATUS_NO_TXN2');
3311 fnd_message.set_token('SF_STATUS', to_char(l_sf_status));
3312 add_error(p_txn_id => enums(i),
3313 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
3314 p_err_msg => fnd_message.get);
3315 end loop;
3316 -- End of fix for bug 5310474
3317 end if;
3318
3319 -- Validate whether there is no move shopfloor status in between or not.
3320 -- reset enums table
3321 enums.delete;
3322 -- Error out if wip_parameter do not allow move over no_move shop floor
3323 -- status, and there are no_move status in between
3324 UPDATE wip_move_txn_interface wmti
3325 SET wmti.process_status = WIP_CONSTANTS.ERROR
3326 WHERE wmti.group_id = g_group_id
3327 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3328 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3329 AND wip_sf_status.count_no_move_statuses(
3330 wmti.organization_id, -- p_org_id
3331 wmti.wip_entity_id, -- p_wip_id
3332 wmti.line_id, -- p_line_id
3333 wmti.repetitive_schedule_id, -- p_sched_id
3334 wmti.fm_operation_seq_num, -- p_fm_op
3335 wmti.fm_intraoperation_step_type, -- p_fm_step
3336 wmti.to_operation_seq_num, -- p_to_op
3337 wmti.to_intraoperation_step_type, -- p_to_step
3338 -- Fixed bug 2121222
3339 wmti.source_code) > 0 -- p_source_code
3340 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3341
3342 /* Added the following for SUN enhancement in Bug 9758848*/
3343 if enums.count > 0 then
3344 for i in 1..enums.count loop
3345 select wip_sf_status.get_no_move_status(
3346 wmti.organization_id, -- p_org_id
3347 wmti.wip_entity_id, -- p_wip_id
3348 wmti.line_id, -- p_line_id
3349 wmti.repetitive_schedule_id, -- p_sched_id
3350 wmti.fm_operation_seq_num, -- p_fm_op
3351 wmti.fm_intraoperation_step_type, -- p_fm_step
3352 wmti.to_operation_seq_num, -- p_to_op
3353 wmti.to_intraoperation_step_type, -- p_to_step
3354 wmti.source_code)
3355 into l_sf_status
3356 from wip_move_txn_interface wmti
3357 where wmti.transaction_id = enums(i)
3358 and wmti.process_status = WIP_CONSTANTS.ERROR;
3359 fnd_message.set_name ('WIP', 'WIP_NO_MOVE_STATUS_BETWEEN');
3360 fnd_message.set_token('SF_STATUS', to_char(l_sf_status));
3361 add_error(p_txn_id => enums(i),
3362 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
3363 p_err_msg => fnd_message.get);
3364 end loop;
3365 end if;
3366
3367 -- Do OSP related validation.
3368 osp_validation;
3369
3370 -- Set WMTI.PROCESS_STATUS to error if there is an error from any
3371 -- validation and insert error message into WIP_TXN_INTERFACE_ERRORS
3372 update_interface_tbl;
3373
3374 -- Set WMTI.PROCESS_PHASE to WIP_CONSTANTS.MOVE_PROC so that move processing
3375 -- code can process these records.
3376 UPDATE wip_move_txn_interface wmti
3377 SET process_phase = WIP_CONSTANTS.MOVE_PROC
3378 WHERE wmti.group_id = g_group_id
3379 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3380 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
3381
3382 -- write to the log file
3383 if (l_logLevel <= wip_constants.trace_logging) then
3384 wip_logger.exitPoint(p_procName => 'wip_move_validator.validateOATxn',
3385 p_procReturnStatus => fnd_api.g_ret_sts_success,
3386 p_msg => 'procedure complete',
3387 x_returnStatus => l_returnStatus);
3388 end if;
3389 EXCEPTION
3390 WHEN others THEN
3391 if (l_logLevel <= wip_constants.trace_logging) then
3392 wip_logger.exitPoint(p_procName => 'wip_move_validator.validateOATxn',
3393 p_procReturnStatus => fnd_api.g_ret_sts_unexp_error,
3394 p_msg => 'Unexpected Errors: ' || SQLERRM,
3395 x_returnStatus => l_returnStatus);
3396 end if;
3397
3398 END validateOATxn;
3399
3400 END wip_move_validator;