1 PACKAGE BODY wip_move_validator AS
2 /* $Header: wipmovvb.pls 120.12 2007/09/17 21:19:06 kboonyap 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 = UPPER(wmti.organization_code))
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 = UPPER(NVL(wmti.organization_code,
133 mp.organization_code))
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
381 AND wrs.status_type IN (WIP_CONSTANTS.RELEASED,
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
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;
496 SET wmti.process_status = WIP_CONSTANTS.ERROR
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
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
611 WIP_CONSTANTS.LOTBASED)
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,
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
727 add_error(p_txn_ids => enums,
724 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
725
726 fnd_message.set_name('WIP', 'WIP_NO_FORWARD_DATING');
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
844 -- For easy return transaction, from operation must be the last operation.
841 END transaction_date;
842
843 -- validate fm_operation_seq_num. From operation must be a valid 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 BEGIN
928 -- Set FM_INTRAOPERATION_STEP_TYPE to Tomove if TRANSACTION_TYPE is
929 -- EZ Return and FM_INTRAOPERATION_STEP_TYPE is null
930 UPDATE wip_move_txn_interface wmti
931 SET wmti.fm_intraoperation_step_type = WIP_CONSTANTS.TOMOVE
932 WHERE wmti.group_id = g_group_id
933 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
934 AND wmti.process_status = WIP_CONSTANTS.RUNNING
935 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
936 AND wmti.fm_intraoperation_step_type IS NULL;
937
938 -- reset enums table
939 enums.delete;
940 -- Error out if FM_INTRAOPERATION_STEP_TYPE is null or invalid
941 UPDATE wip_move_txn_interface wmti
942 SET wmti.process_status = WIP_CONSTANTS.ERROR
943 WHERE wmti.group_id = g_group_id
944 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
945 AND wmti.process_status = WIP_CONSTANTS.RUNNING
946 AND (wmti.fm_intraoperation_step_type IS NULL
947 OR
948 (NOT EXISTS
949 (SELECT 'X'
950 FROM wip_valid_intraoperation_steps wvis,
951 wip_operations wo
952 WHERE wvis.organization_id = wmti.organization_id
953 AND wvis.step_lookup_type = wmti.fm_intraoperation_step_type
954 AND wo.organization_id = wmti.organization_id
958 NVL(wmti.repetitive_schedule_id, -1)
955 AND wo.wip_entity_id = wmti.wip_entity_id
956 AND wo.operation_seq_num = wmti.fm_operation_seq_num
957 AND NVL(wo.repetitive_schedule_id, -1) =
959 AND ((wvis.record_creator = 'USER' OR
960 wvis.step_lookup_type = WIP_CONSTANTS.QUEUE)
961 OR
962 (wvis.record_creator = 'SYSTEM' AND
963 wo.next_operation_seq_num IS NULL)))))
964 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
965
966 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
967 fnd_message.set_token('ENTITY', 'FM_INTRAOPERATION_STEP_TYPE');
968 add_error(p_txn_ids => enums,
969 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
970 p_err_msg => fnd_message.get);
971
972 -- reset enums table
973 enums.delete;
974 -- Error out if FM_OPERATION_SEQ_NUM/FM_INTRAOPERATION_STEP_TYPE has
975 -- no move shop floor status attached
976 UPDATE wip_move_txn_interface wmti
977 SET wmti.process_status = WIP_CONSTANTS.ERROR
978 WHERE wmti.group_id = g_group_id
979 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
980 AND wmti.process_status = WIP_CONSTANTS.RUNNING
981 AND EXISTS
982 (SELECT 'X'
983 FROM wip_shop_floor_status_codes wsc,
984 wip_shop_floor_statuses ws
985 WHERE wsc.organization_id = wmti.organization_id
986 AND ws.organization_id = wmti.organization_id
987 AND ws.wip_entity_id = wmti.wip_entity_id
988 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
989 AND ws.operation_seq_num = wmti.fm_operation_seq_num
990 AND ws.intraoperation_step_type = wmti.fm_intraoperation_step_type
991 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
992 AND wsc.status_move_flag = WIP_CONSTANTS.NO
993 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
994 AND (wmti.source_code IS NULL OR
995 wmti.source_code <> 'RCV' OR
996 (wmti.source_code = 'RCV' AND
997 NOT EXISTS
998 (SELECT 'X'
999 FROM wip_parameters wp
1000 WHERE wp.organization_id = wmti.organization_id
1001 AND wp.osp_shop_floor_status =
1002 wsc.shop_floor_status_code))))
1003 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1004
1005 fnd_message.set_name('WIP', 'WIP_STATUS_NO_TXN1');
1006 add_error(p_txn_ids => enums,
1007 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
1008 p_err_msg => fnd_message.get);
1009
1010 -- reset enums table
1011 enums.delete;
1012 -- Error out if users try to perform easy completion from Tomove of the
1013 -- last operation
1014 UPDATE wip_move_txn_interface wmti
1015 SET wmti.process_status = WIP_CONSTANTS.ERROR
1016 WHERE wmti.group_id = g_group_id
1017 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1018 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1019 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1020 AND wmti.fm_intraoperation_step_type = WIP_CONSTANTS.TOMOVE
1021 AND wmti.fm_operation_seq_num =
1022 (SELECT wo.operation_seq_num
1023 FROM wip_operations wo
1024 WHERE wo.wip_entity_id = wmti.wip_entity_id
1025 AND wo.organization_id = wmti.organization_id
1026 AND NVL(wo.repetitive_schedule_id, -1) =
1027 NVL(wmti.repetitive_schedule_id, -1)
1028 AND wo.next_operation_seq_num IS NULL)
1029 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1030
1031 fnd_message.set_name('WIP', 'WIP_EZ_NO_CMP_LAST_OP2');
1032 add_error(p_txn_ids => enums,
1033 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
1034 p_err_msg => fnd_message.get);
1035
1036 -- reset enums table
1037 enums.delete;
1038 -- Error out if TRANSACTION_TYPE is EZ Return and
1039 -- FM_INTRAOPERATION_STEP_TYPE not equal to Tomove
1040 UPDATE wip_move_txn_interface wmti
1041 SET wmti.process_status = WIP_CONSTANTS.ERROR
1042 WHERE wmti.group_id = g_group_id
1043 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1044 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1045 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
1046 AND wmti.fm_intraoperation_step_type <> WIP_CONSTANTS.TOMOVE
1047 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1048
1049 fnd_message.set_name('WIP', 'WIP_EZ_FM_LAST_STEP');
1050 add_error(p_txn_ids => enums,
1051 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
1052 p_err_msg => fnd_message.get);
1053 END fm_step;
1054
1055 -- validate to_operation_seq_num. To operation must be a valid operation.
1056 -- For easy complete transaction, To operation must be the last operation.
1057 -- Callers always need to pass this value except for Easy complete
1058 -- transactions. If callers do not provide this info and it is complete
1059 -- transaction, just default to_operation to last_op
1060 PROCEDURE to_operation IS
1061 BEGIN
1062 -- Set TO_OPERATION_SEQ_NUM to last_operation if TRANSACTION_TYPE is
1063 -- EZ Completion and TO_OPERATION_SEQ_NUM is null
1064 UPDATE wip_move_txn_interface wmti
1065 SET wmti.to_operation_seq_num =
1066 (SELECT wo.operation_seq_num
1070 AND NVL(wo.repetitive_schedule_id, -1) =
1067 FROM wip_operations wo
1068 WHERE wo.wip_entity_id = wmti.wip_entity_id
1069 AND wo.organization_id = wmti.organization_id
1071 NVL(wmti.repetitive_schedule_id, -1)
1072 AND wo.next_operation_seq_num IS NULL)
1073 WHERE wmti.group_id = g_group_id
1074 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1075 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1076 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1077 AND wmti.to_operation_seq_num IS NULL;
1078
1079 /*Bug 4421485->Even for plain moves we will derive to_operation as
1080 next count point operation */
1081 UPDATE wip_move_txn_interface wmti
1082 SET wmti.to_operation_seq_num =
1083 (SELECT MIN(wo.operation_seq_num)
1084 FROM wip_operations wo
1085 WHERE wo.organization_id = wmti.organization_id
1086 AND wo.wip_entity_id = wmti.wip_entity_id
1087 AND NVL(wo.repetitive_schedule_id, -1) =
1088 NVL(wmti.repetitive_schedule_id, -1)
1089 AND wo.operation_seq_num > wmti.fm_operation_seq_num
1090 AND wo.count_point_type = 1)
1091 WHERE wmti.group_id = g_group_id
1092 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1093 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1094 AND wmti.transaction_type = WIP_CONSTANTS.MOVE_TXN
1095 AND wmti.to_operation_seq_num IS NULL;
1096
1097 -- reset enums table
1098 enums.delete;
1099 -- Error out if TO_OPERATION_SEQ_NUM is null or TO_OPERATION_SEQ_NUM
1100 -- is invalid
1101 UPDATE wip_move_txn_interface wmti
1102 SET wmti.process_status = WIP_CONSTANTS.ERROR
1103 WHERE wmti.group_id = g_group_id
1104 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1105 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1106 AND (wmti.to_operation_seq_num IS NULL
1107 OR
1108 (NOT EXISTS
1109 (SELECT 'X'
1110 FROM wip_operations wo
1111 WHERE wo.wip_entity_id = wmti.wip_entity_id
1112 AND wo.organization_id = wmti.organization_id
1113 AND wo.operation_seq_num = wmti.to_operation_seq_num
1114 AND NVL(wo.repetitive_schedule_id, -1) =
1115 NVL(wmti.repetitive_schedule_id, -1))))
1116 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1117
1118 fnd_message.set_name('WIP', 'WIP_INVALID_OPERATION');
1119 add_error(p_txn_ids => enums,
1120 p_err_col => 'TO_OPERATION_SEQ_NUM',
1121 p_err_msg => fnd_message.get);
1122
1123 -- reset enums table
1124 enums.delete;
1125 -- Error out if TRANSACTION_TYPE is EZ Ccmplete and TO_OPERATION_SEQ_NUM
1126 -- is not equal to the last operation.
1127 UPDATE wip_move_txn_interface wmti
1128 SET wmti.process_status = WIP_CONSTANTS.ERROR
1129 WHERE wmti.group_id = g_group_id
1130 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1131 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1132 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1133 AND wmti.to_operation_seq_num <>
1134 (SELECT wo.operation_seq_num
1135 FROM wip_operations wo
1136 WHERE wo.wip_entity_id = wmti.wip_entity_id
1137 AND wo.organization_id = wmti.organization_id
1138 AND NVL(wo.repetitive_schedule_id, -1) =
1139 NVL(wmti.repetitive_schedule_id, -1)
1140 AND wo.next_operation_seq_num IS NULL)
1141 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1142
1143 fnd_message.set_name('WIP', 'WIP_EZ_TO_LAST_OP');
1144 add_error(p_txn_ids => enums,
1145 p_err_col => 'TO_OPERATION_SEQ_NUM',
1146 p_err_msg => fnd_message.get);
1147 END to_operation;
1148
1149 -- validate to_intraoperation_step_type. To step must be valid.
1150 -- If easy complete transaction, to step must be "To move". If easy return,
1151 -- to step cannot be "To move" when to operation is the last operation.
1152 -- If callers do not provide this info and it is complete transaction,
1153 -- just default to_step to to move
1154 PROCEDURE to_step IS
1155 BEGIN
1156 -- Set TO_INTRAOPERATION_STEP_TYPE to Tomove if TRANSACTION_TYPE is
1157 -- EZ Complete and TO_INTRAOPERATION_STEP_TYPE is null
1158 UPDATE wip_move_txn_interface wmti
1159 /*Bug Bug 4421485*/
1160 SET wmti.to_intraoperation_step_type =
1161 DECODE(wmti.transaction_type,
1162 WIP_CONSTANTS.COMP_TXN,WIP_CONSTANTS.TOMOVE, WIP_CONSTANTS.QUEUE)
1163 WHERE wmti.group_id = g_group_id
1164 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1165 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1166 /*Bug Bug 4421485*/
1167 AND wmti.transaction_type IN (WIP_CONSTANTS.COMP_TXN,
1168 WIP_CONSTANTS.MOVE_TXN)
1169 AND wmti.to_intraoperation_step_type IS NULL;
1170
1171 -- reset enums table
1172 enums.delete;
1173 -- Error out if TO_INTRAOPERATION_STEP_TYPE is null or invalid
1174 UPDATE wip_move_txn_interface wmti
1175 SET wmti.process_status = WIP_CONSTANTS.ERROR
1176 WHERE wmti.group_id = g_group_id
1177 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1178 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1179 AND (wmti.to_intraoperation_step_type IS NULL
1180 OR
1181 (NOT EXISTS
1182 (SELECT 'X'
1186 AND wvis.step_lookup_type = wmti.to_intraoperation_step_type
1183 FROM wip_valid_intraoperation_steps wvis,
1184 wip_operations wo
1185 WHERE wvis.organization_id = wmti.organization_id
1187 AND wo.organization_id = wmti.organization_id
1188 AND wo.wip_entity_id = wmti.wip_entity_id
1189 AND wo.operation_seq_num = wmti.to_operation_seq_num
1190 AND NVL(wo.repetitive_schedule_id, -1) =
1191 NVL(wmti.repetitive_schedule_id, -1)
1192 -- Fixed bug 5059521. Since OSFM build routing as it goes, we cannot rely on
1193 -- wo.next_operation_seq_num IS NULL to determine that it is the last
1194 -- operation or not.
1195 AND (((wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
1196 WIP_CONSTANTS.REPETITIVE)
1197 OR
1198 (wmti.entity_type = WIP_CONSTANTS.LOTBASED AND
1199 wmti.transaction_type = WIP_CONSTANTS.COMP_TXN))
1200 AND
1201 ((wvis.record_creator = 'USER' OR
1202 wvis.step_lookup_type = WIP_CONSTANTS.QUEUE)
1203 OR
1204 (wvis.record_creator = 'SYSTEM' AND
1205 wo.next_operation_seq_num IS NULL)))
1206 OR
1207 (wmti.entity_type = WIP_CONSTANTS.LOTBASED AND
1208 wmti.transaction_type <> WIP_CONSTANTS.COMP_TXN AND
1209 (wvis.record_creator = 'USER' OR
1210 wvis.step_lookup_type = WIP_CONSTANTS.QUEUE))))))
1211
1212 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1213
1214 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
1215 fnd_message.set_token('ENTITY', 'TO_INTRAOPERATION_STEP_TYPE');
1216 add_error(p_txn_ids => enums,
1217 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1218 p_err_msg => fnd_message.get);
1219
1220 -- reset enums table
1221 enums.delete;
1222 -- Error out if users try to move to the same operation and step as the
1223 -- FM_OPERATION_SEQ_NUM and FM_INTRAOPERATION_STEP_TYPE
1224 UPDATE wip_move_txn_interface wmti
1225 SET wmti.process_status = WIP_CONSTANTS.ERROR
1226 WHERE wmti.group_id = g_group_id
1227 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1228 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1229 AND wmti.fm_operation_seq_num = wmti.to_operation_seq_num
1230 AND wmti.fm_intraoperation_step_type = wmti.to_intraoperation_step_type
1231 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1232
1233 fnd_message.set_name('WIP', 'WIP_SAME_OP_AND_STEP');
1234 add_error(p_txn_ids => enums,
1235 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1236 p_err_msg => fnd_message.get);
1237
1238 -- reset enums table
1239 enums.delete;
1240 -- Error out if TRANSACTION_TYPE is EZ Complete and
1241 -- TO_INTRAOPERATION_STEP_TYPE not equal to Tomove
1242 UPDATE wip_move_txn_interface wmti
1243 SET wmti.process_status = WIP_CONSTANTS.ERROR
1244 WHERE wmti.group_id = g_group_id
1245 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1246 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1247 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1248 AND wmti.to_intraoperation_step_type <> WIP_CONSTANTS.TOMOVE
1249 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1250
1251 fnd_message.set_name('WIP', 'WIP_EZ_TO_LAST_STEP');
1252 add_error(p_txn_ids => enums,
1253 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1254 p_err_msg => fnd_message.get);
1255
1256 -- reset enums table
1257 enums.delete;
1258 -- Error out if user try to easy complete job/schedule that has No Move shop
1259 -- floor status attached to Tomove of the last operation
1260 UPDATE wip_move_txn_interface wmti
1261 SET wmti.process_status = WIP_CONSTANTS.ERROR
1262 WHERE wmti.group_id = g_group_id
1263 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1264 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1265 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
1266 AND EXISTS
1267 (SELECT 'X'
1268 FROM wip_shop_floor_status_codes wsc,
1269 wip_shop_floor_statuses ws
1270 WHERE wsc.organization_id = wmti.organization_id
1271 AND ws.organization_id = wmti.organization_id
1272 AND ws.wip_entity_id = wmti.wip_entity_id
1273 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
1274 AND ws.operation_seq_num = wmti.to_operation_seq_num
1275 AND ws.intraoperation_step_type = WIP_CONSTANTS.TOMOVE
1276 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
1277 AND wsc.status_move_flag = WIP_CONSTANTS.NO
1278 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE)
1279 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1280
1281 fnd_message.set_name('WIP', 'WIP_STATUS_NO_TXN2');
1282 add_error(p_txn_ids => enums,
1283 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1284 p_err_msg => fnd_message.get);
1285
1286 -- reset enums table
1287 enums.delete;
1288 -- Error out if wip_parameter do not allow move over no_move shop floor
1289 -- status, and there are no_move status in between
1290 UPDATE wip_move_txn_interface wmti
1294 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1291 SET wmti.process_status = WIP_CONSTANTS.ERROR
1292 WHERE wmti.group_id = g_group_id
1293 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1295 AND wip_sf_status.count_no_move_statuses(
1296 wmti.organization_id, -- p_org_id
1297 wmti.wip_entity_id, -- p_wip_id
1298 wmti.line_id, -- p_line_id
1299 wmti.repetitive_schedule_id, -- p_sched_id
1300 wmti.fm_operation_seq_num, -- p_fm_op
1301 wmti.fm_intraoperation_step_type, -- p_fm_step
1302 wmti.to_operation_seq_num, -- p_to_op
1303 wmti.to_intraoperation_step_type, -- p_to_step
1304 -- Fixed bug 2121222
1305 wmti.source_code) > 0 -- p_source_code
1306 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1307
1308 fnd_message.set_name ('WIP', 'WIP_NO_MOVE_SF_STATUS_BETWEEN');
1309 add_error(p_txn_ids => enums,
1310 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
1311 p_err_msg => fnd_message.get);
1312 END to_step;
1313
1314 -- transaction_quantity must be positive
1315 PROCEDURE transaction_qty IS
1316 BEGIN
1317 -- reset enums table
1318 enums.delete;
1319
1320 -- Error out if TRANSACTION_QUANTITY is negative or zero
1321 UPDATE wip_move_txn_interface wmti
1322 SET wmti.process_status = WIP_CONSTANTS.ERROR
1323 WHERE wmti.group_id = g_group_id
1324 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1325 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1326 AND wmti.transaction_quantity <= 0
1327 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1328
1329 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
1330 fnd_message.set_token('ENTITY1', 'TRANSACTION_QUANTITY');
1331 fnd_message.set_token('ENTITY2', 'zero');
1332 add_error(p_txn_ids => enums,
1333 p_err_col => 'TRANSACTION_QUANTITY',
1334 p_err_msg => fnd_message.get);
1335
1336 END transaction_qty;
1337
1338
1339 -- transaction_uom must be defined
1340 PROCEDURE transaction_uom IS
1341 BEGIN
1342 -- reset enums table
1343 enums.delete;
1344 -- Error out if TRANSACTION_UOM is invalid
1345 UPDATE wip_move_txn_interface wmti
1346 SET wmti.process_status = WIP_CONSTANTS.ERROR
1347 WHERE wmti.group_id = g_group_id
1348 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1349 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1350 AND NOT EXISTS
1351 (SELECT 'X'
1352 FROM mtl_item_uoms_view miuv
1353 WHERE miuv.organization_id = wmti.organization_id
1354 AND miuv.inventory_item_id = wmti.primary_item_id
1355 AND miuv.uom_code = wmti.transaction_uom)
1356 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1357
1358 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
1359 fnd_message.set_token('ENTITY', 'TRANSACTION_UOM');
1360 add_error(p_txn_ids => enums,
1361 p_err_col => 'TRANSACTION_UOM',
1362 p_err_msg => fnd_message.get);
1363
1364 END transaction_uom;
1365
1366 -- validate overcompletion_transaction_qty. This is an optional info.
1367 -- The caller need to provide this only for overmove/overcompletion txns.
1368 -- However, we do not allow overreturn, and over move for backward move.
1369 -- We also not allow overmove/overcomplete from scrap or reject step.
1370 -- This value cannot be zero or negative either.
1371 PROCEDURE ocpl_txn_qty IS
1372 BEGIN
1373 -- reset enums table
1374 enums.delete;
1375
1376 -- Error out if OVERCOMPLETION_TRANSACTION_QTY is negative or zero
1377 UPDATE wip_move_txn_interface wmti
1378 SET wmti.process_status = WIP_CONSTANTS.ERROR
1379 WHERE wmti.group_id = g_group_id
1380 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1381 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1382 AND wmti.overcompletion_transaction_qty IS NOT NULL
1383 AND wmti.overcompletion_transaction_qty <= 0
1384 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1385
1386 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
1387 fnd_message.set_token('ENTITY1', 'OVERCOMPLETION_TRANSACTION_QTY');
1388 fnd_message.set_token('ENTITY2', 'zero');
1389 add_error(p_txn_ids => enums,
1390 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1391 p_err_msg => fnd_message.get);
1392
1393 -- reset enums table
1394 enums.delete;
1395 -- Error out if OVERCOMPLETION_TRANSACTION_QTY is greater than
1396 -- TRANSACTION_QUANTITY
1397 UPDATE wip_move_txn_interface wmti
1398 SET wmti.process_status = WIP_CONSTANTS.ERROR
1399 WHERE wmti.group_id = g_group_id
1400 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1401 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1402 AND wmti.overcompletion_transaction_qty IS NOT NULL
1403 AND wmti.overcompletion_transaction_qty > wmti.transaction_quantity
1404 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1405
1406 fnd_message.set_name('MFG', 'MFG_GREATER_OR_EQUAL');
1407 fnd_message.set_token('ENTITY1', 'TRANSACTION_QUANTITY');
1408 fnd_message.set_token('ENTITY2', 'OVERCOMPLETION_TRANSACTION_QTY');
1409 add_error(p_txn_ids => enums,
1410 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1411 p_err_msg => fnd_message.get);
1412
1413 -- reset enums table
1414 enums.delete;
1415 -- Error out if user try to do over Return
1419 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1416 UPDATE wip_move_txn_interface wmti
1417 SET wmti.process_status = WIP_CONSTANTS.ERROR
1418 WHERE wmti.group_id = g_group_id
1420 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1421 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN
1422 AND wmti.overcompletion_transaction_qty IS NOT NULL
1423 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1424
1425 fnd_message.set_name('WIP', 'WIP_NO_OC_RET');
1426 add_error(p_txn_ids => enums,
1427 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1428 p_err_msg => fnd_message.get);
1429
1430 -- reset enums table
1431 enums.delete;
1432 -- Error out if user try to do over Return from Scrap/Return from Reject
1433 UPDATE wip_move_txn_interface wmti
1434 SET wmti.process_status = WIP_CONSTANTS.ERROR
1435 WHERE wmti.group_id = g_group_id
1436 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1437 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1438 AND wmti.fm_intraoperation_step_type IN (WIP_CONSTANTS.SCRAP,
1439 WIP_CONSTANTS.REJECT)
1440 AND wmti.overcompletion_transaction_qty IS NOT NULL
1441 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1442
1443 fnd_message.set_name('WIP', 'WIP_NO_OC_SCR_REJ');
1444 add_error(p_txn_ids => enums,
1445 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1446 p_err_msg => fnd_message.get);
1447
1448 -- reset enums table
1449 enums.delete;
1450 -- Error out if OVERCOMPLETION_TRANSACTION_QTY is specified for backward
1451 -- move txns
1452 UPDATE wip_move_txn_interface wmti
1453 SET wmti.process_status = WIP_CONSTANTS.ERROR
1454 WHERE wmti.group_id = g_group_id
1455 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1456 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1457 AND (wmti.to_operation_seq_num < wmti.fm_operation_seq_num OR
1458 (wmti.to_operation_seq_num = wmti.fm_operation_seq_num AND
1459 wmti.to_intraoperation_step_type <
1460 wmti.fm_intraoperation_step_type))
1461 AND wmti.overcompletion_transaction_qty IS NOT NULL
1462 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
1463
1464 fnd_message.set_name('WIP', 'WIP_NO_OC_REV_MOVE');
1465 add_error(p_txn_ids => enums,
1466 p_err_col => 'OVERCOMPLETION_TRANSACTION_QTY',
1467 p_err_msg => fnd_message.get);
1468
1469 END ocpl_txn_qty;
1470
1471 -- validate transaction_id against the one in WIP_MOVE_TRANSACTIONS, and
1472 -- WIP_MOVE_TXN_INTERFACE. This value need to be unique.
1473 PROCEDURE transaction_id IS
1474 l_errMsg VARCHAR2(240);
1475 BEGIN
1476 -- Generate TRANSACTION_ID if user does not provide this value
1477 UPDATE wip_move_txn_interface wmti
1478 SET wmti.transaction_id = wip_transactions_s.nextval
1479 WHERE wmti.group_id = g_group_id
1480 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1481 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1482 AND wmti.transaction_id IS NULL;
1483
1484 -- Set Error Message
1485 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
1486 fnd_message.set_token('ENTITY', 'TRANSACTION_ID');
1487 l_errMsg := substrb(fnd_message.get, 1, 240);
1488
1489 INSERT INTO wip_txn_interface_errors(
1490 transaction_id,
1491 error_message,
1492 error_column,
1493 last_update_date,
1494 last_updated_by,
1495 creation_date,
1496 created_by,
1497 last_update_login,
1498 request_id,
1499 program_application_id,
1500 program_id,
1501 program_update_date
1502 )
1503 SELECT wmti1.transaction_id, -- transaction_id
1504 l_errMsg, -- error_message
1505 'TRANSACTION_ID', -- error_column
1506 SYSDATE, -- last_update_date
1507 NVL(wmti1.last_updated_by, -1),
1508 SYSDATE, -- creation_date
1509 NVL(wmti1.created_by, -1),
1510 wmti1.last_update_login,
1511 wmti1.request_id,
1512 wmti1.program_application_id,
1513 wmti1.program_id,
1514 wmti1.program_update_date
1515 FROM wip_move_txn_interface wmti1
1516 WHERE wmti1.group_id = g_group_id
1517 AND wmti1.process_phase = WIP_CONSTANTS.MOVE_VAL
1518 AND wmti1.process_status = WIP_CONSTANTS.RUNNING
1519 AND (EXISTS
1520 (SELECT 'X'
1521 FROM wip_move_transactions wmt
1522 WHERE wmt.transaction_id = wmti1.transaction_id)
1523 OR
1524 (1 <>
1525 (SELECT count(*)
1526 FROM wip_move_txn_interface wmti2
1527 WHERE wmti2.transaction_id = wmti1.transaction_id)));
1528
1529 END transaction_id;
1530
1531 -- derive primary_quantity from transaction_quantity and transaction_uom.
1532 -- you cannot easy return more than available quantity and organization do
1533 -- not allow negative balance
1534 PROCEDURE primary_qty IS
1535
1536 CURSOR c_availQty IS
1537 SELECT wmti.transaction_id txn_id,
1538 wmti.organization_id org_id,
1539 wmti.primary_item_id item_id,
1540 wmti.primary_quantity primary_qty,
1541 DECODE(msik.serial_number_control_code,
1545 DECODE(msik.lot_control_code,
1542 WIP_CONSTANTS.FULL_SN, fnd_api.g_true,
1543 WIP_CONSTANTS.DYN_RCV_SN, fnd_api.g_true,
1544 fnd_api.g_false) is_ser_ctrl,
1546 WIP_CONSTANTS.LOT, fnd_api.g_true,
1547 fnd_api.g_false) is_lot_ctrl,
1548 DECODE(msik.revision_qty_control_code,
1549 WIP_CONSTANTS.REV, fnd_api.g_true,
1550 fnd_api.g_false) is_rev_ctrl,
1551 DECODE(msik.revision_qty_control_code, -- revision
1552 WIP_CONSTANTS.REV, NVL(wdj.bom_revision,
1553 bom_revisions.get_item_revision_fn
1554 ('EXCLUDE_OPEN_HOLD', -- eco_status
1555 'ALL', -- examine_type
1556 wmti.organization_id, -- org_id
1557 wmti.primary_item_id, -- item_id
1558 wmti.transaction_date -- rev_date
1559 )),
1560 NULL) revision, -- revision
1561 wdj.lot_number lot,
1562 wmti.transaction_date txn_date,
1563 wdj.completion_subinventory subinv,
1564 wdj.completion_locator_id locID,
1565 mp.negative_inv_receipt_code negative_allow,
1566 msik.concatenated_segments assembly_name
1567 FROM wip_discrete_jobs wdj,
1568 mtl_system_items_kfv msik,
1569 mtl_parameters mp,
1570 wip_move_txn_interface wmti
1571 WHERE wdj.primary_item_id = msik.inventory_item_id
1572 AND wdj.organization_id = msik.organization_id
1573 AND wdj.organization_id = mp.organization_id
1574 AND wmti.wip_entity_id = wdj.wip_entity_id
1575 AND wmti.organization_id = wdj.organization_id
1576 AND wmti.entity_type <> WIP_CONSTANTS.REPETITIVE
1577 AND wmti.group_id = g_group_id
1578 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1579 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1580 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN;
1581
1582
1583 CURSOR c_repAvailQty IS
1584 SELECT wmti.transaction_id txn_id,
1585 wmti.organization_id org_id,
1586 wmti.primary_item_id item_id,
1587 wmti.primary_quantity primary_qty,
1588 DECODE(msik.serial_number_control_code,
1589 WIP_CONSTANTS.FULL_SN, fnd_api.g_true,
1590 WIP_CONSTANTS.DYN_RCV_SN, fnd_api.g_true,
1591 fnd_api.g_false) is_ser_ctrl,
1592 DECODE(msik.lot_control_code,
1593 WIP_CONSTANTS.LOT, fnd_api.g_true,
1594 fnd_api.g_false) is_lot_ctrl,
1595 DECODE(msik.revision_qty_control_code,
1596 WIP_CONSTANTS.REV, fnd_api.g_true,
1597 fnd_api.g_false) is_rev_ctrl,
1598 DECODE(msik.revision_qty_control_code, -- revision
1599 WIP_CONSTANTS.REV, NVL(wrs.bom_revision,
1600 bom_revisions.get_item_revision_fn
1601 ('EXCLUDE_OPEN_HOLD', -- eco_status
1602 'ALL', -- examine_type
1603 wmti.organization_id, -- org_id
1604 wmti.primary_item_id, -- item_id
1605 wmti.transaction_date -- rev_date
1606 )),
1607 NULL) revision, -- revision
1608 NULL lot,
1609 wmti.transaction_date txn_date,
1610 wri.completion_subinventory subinv,
1611 wri.completion_locator_id locID,
1612 mp.negative_inv_receipt_code negative_allow,
1613 msik.concatenated_segments assembly_name
1614 FROM wip_repetitive_schedules wrs,
1615 wip_repetitive_items wri,
1616 mtl_system_items_kfv msik,
1617 mtl_parameters mp,
1618 wip_move_txn_interface wmti
1619 WHERE wmti.primary_item_id = msik.inventory_item_id
1620 AND wmti.organization_id = msik.organization_id
1621 AND wmti.organization_id = mp.organization_id
1622 AND wrs.wip_entity_id = wmti.wip_entity_id
1623 AND wrs.organization_id = wmti.organization_id
1624 AND wrs.line_id = wmti.line_id
1625 AND wrs.repetitive_schedule_id = wmti.repetitive_schedule_id
1626 AND wri.organization_id = wmti.organization_id
1627 AND wri.wip_entity_id = wmti.wip_entity_id
1628 AND wri.line_id = wmti.line_id
1629 AND wmti.entity_type = WIP_CONSTANTS.REPETITIVE
1630 AND wmti.group_id = g_group_id
1631 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1632 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1633 AND wmti.transaction_type = WIP_CONSTANTS.RET_TXN;
1634
1635 l_availQty c_availQty%ROWTYPE;
1636 l_repAvailQty c_repAvailQty%ROWTYPE;
1637 l_returnStatus VARCHAR2(1);
1638 l_qoh NUMBER;
1639 l_rqoh NUMBER;
1640 l_qr NUMBER;
1641 l_qs NUMBER;
1642 l_att NUMBER;
1643 l_atr NUMBER;
1644 l_errMsg VARCHAR2(240);
1645 l_msg_count NUMBER;
1646 l_msg_data VARCHAR2(2000);
1647 BEGIN
1648 -- Derive PRIMARY_QUANTITY from TRANSACTION_QUANTITY and TRANSACTION_UOM
1649 -- if PRIMARY_QUANTITY is null
1650
1651 /** Bug fix 5000113. primary_quantity should be updated in sync with
1652 * transaction_quantity, and not just when primary_quantity is null.
1653 */
1654
1655 UPDATE wip_move_txn_interface wmti
1656 SET wmti.primary_quantity =
1657 (SELECT ROUND(wmti.transaction_quantity * mucv.conversion_rate,
1661 AND mucv.inventory_item_id = wmti.primary_item_id
1658 WIP_CONSTANTS.INV_MAX_PRECISION)
1659 FROM mtl_uom_conversions_view mucv
1660 WHERE mucv.organization_id = wmti.organization_id
1662 AND mucv.uom_code = wmti.transaction_uom)
1663 WHERE wmti.group_id = g_group_id
1664 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1665 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
1666 --AND wmti.primary_quantity IS NULL;
1667
1668 /* End of bug fix 5000113.
1669
1670 -- Set Error Message
1671 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
1672 fnd_message.set_token('ENTITY1', 'PRIMARY_QUANTITY');
1673 fnd_message.set_token('ENTITY2', 'zero');
1674 l_errMsg := substrb(fnd_message.get, 1, 240);
1675
1676 -- Error out if PRIMARY_QUANTITY is zero
1677 -- Insert error record into WIP_TXN_INTERFACE_ERRORS. Do not update
1678 -- WMTI.PROCESS_STATUS to Error because it is a minor issue. We will
1679 -- continue validating other values.
1680 INSERT INTO wip_txn_interface_errors(
1681 transaction_id,
1682 error_message,
1683 error_column,
1684 last_update_date,
1685 last_updated_by,
1686 creation_date,
1687 created_by,
1688 last_update_login,
1689 request_id,
1690 program_application_id,
1691 program_id,
1692 program_update_date
1693 )
1694 SELECT wmti.transaction_id, -- transaction_id
1695 l_errMsg, -- error_message
1696 'PRIMARY_QUANTITY', -- error_column
1697 SYSDATE, -- last_update_date
1698 NVL(wmti.last_updated_by, -1),
1699 SYSDATE, -- creation_date
1700 NVL(wmti.created_by, -1),
1701 wmti.last_update_login,
1702 wmti.request_id,
1703 wmti.program_application_id,
1704 wmti.program_id,
1705 wmti.program_update_date
1706 FROM wip_move_txn_interface wmti
1707 WHERE wmti.group_id = g_group_id
1708 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1709 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1710 AND wmti.primary_quantity = 0;
1711
1712 -- Set Error Message
1713 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
1714 fnd_message.set_token('ENTITY1', 'PRIMARY_QUANTITY');
1715 fnd_message.set_token('ENTITY2', 'TRANSACTION_QUANTITY');
1716 l_errMsg := substrb(fnd_message.get, 1, 240);
1717
1718 -- Error out if PRIMARY_QUANTITY is not consistent with TRANSACTION_QUANTITY
1719 -- Insert error record into WIP_TXN_INTERFACE_ERRORS. Do not update
1720 -- WMTI.PROCESS_STATUS to Error because it is a minor issue. We will
1721 -- continue validating other values.
1722 INSERT INTO wip_txn_interface_errors(
1723 transaction_id,
1724 error_message,
1725 error_column,
1726 last_update_date,
1727 last_updated_by,
1728 creation_date,
1729 created_by,
1730 last_update_login,
1731 request_id,
1732 program_application_id,
1733 program_id,
1734 program_update_date
1735 )
1736 SELECT wmti.transaction_id, -- transaction_id
1737 l_errMsg, -- error_message
1738 'PRIMARY_QUANTITY', -- error_column
1739 SYSDATE, -- last_update_date
1740 NVL(wmti.last_updated_by, -1),
1741 SYSDATE, -- creation_date
1742 NVL(wmti.created_by, -1),
1743 wmti.last_update_login,
1744 wmti.request_id,
1745 wmti.program_application_id,
1746 wmti.program_id,
1747 wmti.program_update_date
1748 FROM wip_move_txn_interface wmti,
1749 mtl_uom_conversions_view mucv
1750 WHERE mucv.organization_id = wmti.organization_id
1751 AND mucv.inventory_item_id = wmti.primary_item_id
1752 AND mucv.uom_code = wmti.transaction_uom
1753 AND wmti.group_id = g_group_id
1754 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1755 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1756 -- Fixed bug 4900010. Round both transaction_quantity and
1757 -- primary_quantity before making comparison.
1758 AND ROUND(wmti.transaction_quantity * mucv.conversion_rate,
1759 WIP_CONSTANTS.INV_MAX_PRECISION) <>
1760 ROUND(wmti.primary_quantity, WIP_CONSTANTS.INV_MAX_PRECISION);
1761
1762 -- Set Error Message
1763 /* Fix for Bug#4192541. Removed following check as this is only warning
1764 condition
1765 */
1766
1767 /*
1768 fnd_message.set_name('WIP', 'WIP_MIN_XFER_QTY');
1769 l_errMsg := substrb(fnd_message.get, 1, 240);
1770
1771 -- Error out if PRIMARY_QUANTITY less than MININUM_TRANSFER_QUANTITY
1772 -- defined at FM_OPERATION_SEQ_NUM and transactions are not Scrap/Reject
1773 INSERT INTO wip_txn_interface_errors(
1774 transaction_id,
1775 error_message,
1776 error_column,
1777 last_update_date,
1778 last_updated_by,
1779 creation_date,
1780 created_by,
1781 last_update_login,
1782 request_id,
1783 program_application_id,
1784 program_id,
1785 program_update_date
1786 )
1790 SYSDATE, -- last_update_date
1787 SELECT wmti.transaction_id, -- transaction_id
1788 l_errMsg, -- error_message
1789 'PRIMARY_QUANTITY', -- error_column
1791 NVL(wmti.last_updated_by, -1),
1792 SYSDATE, -- creation_date
1793 NVL(wmti.created_by, -1),
1794 wmti.last_update_login,
1795 wmti.request_id,
1796 wmti.program_application_id,
1797 wmti.program_id,
1798 wmti.program_update_date
1799 FROM wip_move_txn_interface wmti,
1800 wip_operations wo
1801 WHERE wo.organization_id = wmti.organization_id
1802 AND wo.wip_entity_id = wmti.wip_entity_id
1803 AND NVL(wo.repetitive_schedule_id, -1) =
1804 NVL(wmti.repetitive_schedule_id, -1)
1805 AND wo.operation_seq_num = wmti.fm_operation_seq_num
1806 AND wmti.fm_intraoperation_step_type NOT IN (WIP_CONSTANTS.SCRAP,
1807 WIP_CONSTANTS.REJECT)
1808 AND wmti.to_intraoperation_step_type NOT IN (WIP_CONSTANTS.SCRAP,
1809 WIP_CONSTANTS.REJECT)
1810 AND wmti.group_id = g_group_id
1811 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1812 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1813 AND wo.minimum_transfer_quantity > wmti.primary_quantity;
1814
1815
1816 */
1817 -- Set Error Message
1818 fnd_message.set_name ('INV', 'INV_NO_NEG_BALANCES');
1819 l_errMsg := substrb(fnd_message.get, 1, 240);
1820
1821 -- User cannot do easy return more than available quantity if
1822 -- organization do not allow negative balance. (Discrete/OSFM)
1823 FOR l_availQty IN c_availQty
1824 LOOP
1825 inv_quantity_tree_pub.query_quantities(
1826 p_api_version_number => 1.0,
1827 p_init_msg_lst => 'T',
1828 p_onhand_source => inv_quantity_tree_pvt.g_all_subs,
1829 p_organization_id => l_availQty.org_id,
1830 p_inventory_item_id => l_availQty.item_id,
1831 p_tree_mode => inv_quantity_tree_pvt.g_loose_only_mode,
1832 p_is_revision_control => fnd_api.to_boolean(l_availQty.is_rev_ctrl),
1833 p_is_lot_control => fnd_api.to_boolean(l_availQty.is_lot_ctrl),
1834 p_is_serial_control => fnd_api.to_boolean(l_availQty.is_ser_ctrl),
1835 p_demand_source_type_id => 5, -- WIP
1836 p_revision => l_availQty.revision,
1837 p_lot_number => l_availQty.lot,
1838 p_lot_expiration_date => l_availQty.txn_date,
1839 p_subinventory_code => l_availQty.subinv,
1840 p_locator_id => l_availQty.locID,
1841 x_return_status => l_returnStatus,
1842 x_msg_count => l_msg_count,
1843 x_msg_data => l_msg_data,
1844 x_qoh => l_qoh,
1845 x_rqoh => l_rqoh,
1846 x_qr => l_qr,
1847 x_qs => l_qs,
1848 x_att => l_att,
1849 x_atr => l_atr);
1850
1851 IF(l_returnStatus <> 'S')THEN
1852 add_error(p_txn_id => l_availQty.txn_id,
1853 p_err_col => 'PRIMARY_QUANTITY',
1854 p_err_msg => l_msg_data);
1855 ELSE
1856 IF(l_availQty.negative_allow = WIP_CONSTANTS.NO AND
1857 l_att < l_availQty.primary_qty) THEN
1858 add_error(p_txn_id => l_availQty.txn_id,
1859 p_err_col => 'PRIMARY_QUANTITY',
1860 p_err_msg => l_availQty.assembly_name||':'||l_errMsg);
1861 END IF;
1862 END IF;
1863 END LOOP; -- Only for EZ Return transactions (Discrete/OSFM)
1864
1865 -- User cannot do easy return more than available quantity if
1866 -- organization do not allow negative balance (Repetitive)
1867 FOR l_repAvailQty IN c_repAvailQty
1868 LOOP
1869 inv_quantity_tree_pub.query_quantities(
1870 p_api_version_number => 1.0,
1871 p_init_msg_lst => 'T',
1872 p_onhand_source => inv_quantity_tree_pvt.g_all_subs,
1873 p_organization_id => l_repAvailQty.org_id,
1874 p_inventory_item_id => l_repAvailQty.item_id,
1875 p_tree_mode => inv_quantity_tree_pvt.g_loose_only_mode,
1876 p_is_revision_control => fnd_api.to_boolean(l_repAvailQty.is_rev_ctrl),
1877 p_is_lot_control => fnd_api.to_boolean(l_repAvailQty.is_lot_ctrl),
1878 p_is_serial_control => fnd_api.to_boolean(l_repAvailQty.is_ser_ctrl),
1879 p_demand_source_type_id => 5, -- WIP
1880 p_revision => l_repAvailQty.revision,
1881 p_lot_number => l_repAvailQty.lot,
1882 p_lot_expiration_date => l_repAvailQty.txn_date,
1883 p_subinventory_code => l_repAvailQty.subinv,
1884 p_locator_id => l_repAvailQty.locID,
1885 x_return_status => l_returnStatus,
1886 x_msg_count => l_msg_count,
1887 x_msg_data => l_msg_data,
1888 x_qoh => l_qoh,
1889 x_rqoh => l_rqoh,
1890 x_qr => l_qr,
1891 x_qs => l_qs,
1892 x_att => l_att,
1893 x_atr => l_atr);
1894
1895 IF(l_returnStatus <> 'S')THEN
1896 add_error(p_txn_id => l_repAvailQty.txn_id,
1900 IF(l_repAvailQty.negative_allow = WIP_CONSTANTS.NO AND
1897 p_err_col => 'PRIMARY_QUANTITY',
1898 p_err_msg => l_msg_data);
1899 ELSE
1901 l_att < l_repAvailQty.primary_qty) THEN
1902 add_error(p_txn_id => l_repAvailQty.txn_id,
1903 p_err_col => 'PRIMARY_QUANTITY',
1904 p_err_msg => l_repAvailQty.assembly_name||':'||l_errMsg);
1905 END IF;
1906 END IF;
1907 END LOOP; -- Only for EZ Return transactions(Repetitive)
1908 END primary_qty;
1909
1910 -- derive primary_uom from primary_item_id
1911 PROCEDURE primary_uom IS
1912 l_errMsg VARCHAR2(240);
1913 BEGIN
1914 -- Derive PRIMARY_UOM from PRIMARY_ITEM_ID provided if PRIMARY_UOM is null
1915 UPDATE wip_move_txn_interface wmti
1916 SET wmti.primary_uom =
1917 (SELECT msi.primary_uom_code
1918 FROM mtl_system_items msi
1919 WHERE msi.organization_id = wmti.organization_id
1920 AND msi.inventory_item_id = wmti.primary_item_id)
1921 WHERE wmti.group_id = g_group_id
1922 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1923 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1924 AND wmti.primary_uom IS NULL;
1925
1926 -- Set Error Message
1927 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
1928 fnd_message.set_token('ENTITY1', 'PRIMARY_UOM');
1929 fnd_message.set_token('ENTITY2', 'PRIMARY_ITEM_ID');
1930 l_errMsg := substrb(fnd_message.get, 1, 240);
1931
1932 -- If caller provide PRIMARY_UOM, it must be consistent with
1933 -- primary_item_id provided
1934 INSERT INTO wip_txn_interface_errors(
1935 transaction_id,
1936 error_message,
1937 error_column,
1938 last_update_date,
1939 last_updated_by,
1940 creation_date,
1941 created_by,
1942 last_update_login,
1943 request_id,
1944 program_application_id,
1945 program_id,
1946 program_update_date
1947 )
1948 SELECT wmti.transaction_id, -- transaction_id
1949 l_errMsg, -- error_message
1950 'PRIMARY_UOM', -- error_column
1951 SYSDATE, -- last_update_date
1952 NVL(wmti.last_updated_by, -1),
1953 SYSDATE, -- creation_date
1954 NVL(wmti.created_by, -1),
1955 wmti.last_update_login,
1956 wmti.request_id,
1957 wmti.program_application_id,
1958 wmti.program_id,
1959 wmti.program_update_date
1960 FROM wip_move_txn_interface wmti,
1961 mtl_system_items msi
1962 WHERE msi.organization_id = wmti.organization_id
1963 AND msi.inventory_item_id = wmti.primary_item_id
1964 AND wmti.group_id = g_group_id
1965 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1966 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1967 AND msi.primary_uom_code <> wmti.primary_uom;
1968
1969 END primary_uom;
1970
1971 -- derive overcomplete_primary_quantity from overcomplete_transaction_quantity
1972 -- and transaction_uom provided.
1973 PROCEDURE ocpl_primary_qty IS
1974 l_errMsg VARCHAR2(240);
1975 BEGIN
1976 -- Derive OVERCOMPLETE_PRIMARY_QUANTITY from
1977 -- OVERCOMPLETE_TRANSACTION_QUANTITY and TRANSACTION_UOM provided.
1978
1979 /** Bug fix 5000113. overcompletion_primary_qty should be updated in sync with
1980 * transaction_quantity, and not just when overcompletion_quantity is null.
1981 */
1982
1983 UPDATE wip_move_txn_interface wmti
1984 SET wmti.overcompletion_primary_qty =
1985 (SELECT ROUND(wmti.overcompletion_transaction_qty *
1986 mucv.conversion_rate, WIP_CONSTANTS.INV_MAX_PRECISION)
1987 FROM mtl_uom_conversions_view mucv
1988 WHERE mucv.organization_id = wmti.organization_id
1989 AND mucv.inventory_item_id = wmti.primary_item_id
1990 AND mucv.uom_code = wmti.transaction_uom)
1991 WHERE wmti.group_id = g_group_id
1992 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
1993 AND wmti.process_status = WIP_CONSTANTS.RUNNING
1994 AND wmti.overcompletion_transaction_qty IS NOT NULL;
1995 --AND wmti.overcompletion_primary_qty IS NULL;
1996
1997 -- End of bug fix 5000113.
1998
1999 -- Set Error Message
2000 fnd_message.set_name('MFG', 'MFG_GREATER_THAN');
2001 fnd_message.set_token('ENTITY1', 'OVERCOMPLETION_PRIMARY_QTY');
2002 fnd_message.set_token('ENTITY2', 'zero');
2003 l_errMsg := substrb(fnd_message.get, 1, 240);
2004
2005 -- Error out if OVERCOMPLETION_PRIMARY_QTY is zero
2006 -- Insert error record into WIP_TXN_INTERFACE_ERRORS. Do not update
2007 -- WMTI.PROCESS_STATUS to Error because it is a minor issue. We will
2008 -- continue validating other values.
2009 INSERT INTO wip_txn_interface_errors(
2010 transaction_id,
2011 error_message,
2012 error_column,
2013 last_update_date,
2014 last_updated_by,
2015 creation_date,
2016 created_by,
2017 last_update_login,
2018 request_id,
2019 program_application_id,
2020 program_id,
2021 program_update_date
2022 )
2023 SELECT wmti.transaction_id, -- transaction_id
2024 l_errMsg, -- error_message
2025 'OVERCOMPLETION_PRIMARY_QTY', -- error_column
2029 NVL(wmti.created_by, -1),
2026 SYSDATE, -- last_update_date
2027 NVL(wmti.last_updated_by, -1),
2028 SYSDATE, -- creation_date
2030 wmti.last_update_login,
2031 wmti.request_id,
2032 wmti.program_application_id,
2033 wmti.program_id,
2034 wmti.program_update_date
2035 FROM wip_move_txn_interface wmti
2036 WHERE wmti.group_id = g_group_id
2037 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2038 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2039 AND wmti.overcompletion_primary_qty = 0;
2040
2041 -- Set Error Message
2042 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2043 fnd_message.set_token('ENTITY1', 'OVERCOMPLETION_PRIMARY_QTY');
2044 fnd_message.set_token('ENTITY2', 'OVERCOMPLETION_TRANSACTION_QTY');
2045 l_errMsg := substrb(fnd_message.get, 1, 240);
2046
2047 -- If caller provide this info, it must be consistent with
2048 -- overcompletion_transaction_qty provided
2049 INSERT INTO wip_txn_interface_errors(
2050 transaction_id,
2051 error_message,
2052 error_column,
2053 last_update_date,
2054 last_updated_by,
2055 creation_date,
2056 created_by,
2057 last_update_login,
2058 request_id,
2059 program_application_id,
2060 program_id,
2061 program_update_date
2062 )
2063 SELECT wmti.transaction_id, -- transaction_id
2064 l_errMsg, -- error_message
2065 'OVERCOMPLETION_PRIMARY_QTY', -- error_column
2066 SYSDATE, -- last_update_date
2067 NVL(wmti.last_updated_by, -1),
2068 SYSDATE, -- creation_date
2069 NVL(wmti.created_by, -1),
2070 wmti.last_update_login,
2071 wmti.request_id,
2072 wmti.program_application_id,
2073 wmti.program_id,
2074 wmti.program_update_date
2075 FROM wip_move_txn_interface wmti,
2076 mtl_uom_conversions_view mucv
2077 WHERE mucv.organization_id = wmti.organization_id
2078 AND mucv.inventory_item_id = wmti.primary_item_id
2079 AND mucv.uom_code = wmti.transaction_uom
2080 AND wmti.group_id = g_group_id
2081 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2082 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2083 AND wmti.overcompletion_transaction_qty IS NOT NULL
2084 -- Fixed bug 4900010. Round both transaction_quantity and
2085 -- primary_quantity before making comparison.
2086 AND ROUND(wmti.overcompletion_transaction_qty * mucv.conversion_rate,
2087 WIP_CONSTANTS.INV_MAX_PRECISION) <>
2088 ROUND(wmti.overcompletion_primary_qty,
2089 WIP_CONSTANTS.INV_MAX_PRECISION);
2090 END ocpl_primary_qty;
2091
2092 -- This value must be null. The move processor will be the one who insert
2093 -- child record and link it with parent record
2094 PROCEDURE ocpl_txn_id IS
2095 l_errMsg VARCHAR2(240);
2096 BEGIN
2097 -- Set Error Message
2098 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
2099 fnd_message.set_token('ENTITY', 'OVERCOMPLETION_TRANSACTION_ID');
2100 l_errMsg := substrb(fnd_message.get, 1, 240);
2101
2102 -- This value must be null because New Move Processor will be the one
2103 -- who insert child record and populate this value
2104 INSERT INTO wip_txn_interface_errors(
2105 transaction_id,
2106 error_message,
2107 error_column,
2108 last_update_date,
2109 last_updated_by,
2110 creation_date,
2111 created_by,
2112 last_update_login,
2113 request_id,
2114 program_application_id,
2115 program_id,
2116 program_update_date
2117 )
2118 SELECT wmti.transaction_id, -- transaction_id
2119 l_errMsg, -- error_message
2120 'OVERCOMPLETION_TRANSACTION_ID', -- error_column
2121 SYSDATE, -- last_update_date
2122 NVL(wmti.last_updated_by, -1),
2123 SYSDATE, -- creation_date
2124 NVL(wmti.created_by, -1),
2125 wmti.last_update_login,
2126 wmti.request_id,
2127 wmti.program_application_id,
2128 wmti.program_id,
2129 wmti.program_update_date
2130 FROM wip_move_txn_interface wmti
2131 WHERE wmti.group_id = g_group_id
2132 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2133 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2134 AND wmti.overcompletion_transaction_id IS NOT NULL;
2135
2136 END ocpl_txn_id;
2137
2138 -- This is an optional info. However, if the caller provided some values,
2139 -- it must be valid. If the caller pass reason_name, we will derive the
2140 -- reason_id. If the caller pass both, both value must be consistent to
2141 -- each other.
2142 PROCEDURE reason_id IS
2143 l_errMsg VARCHAR2(240);
2144 BEGIN
2145 -- Derive REASON_ID from REASON_NAME provided
2146 UPDATE wip_move_txn_interface wmti
2147 SET wmti.reason_id =
2148 (SELECT mtr.reason_id
2149 FROM mtl_transaction_reasons mtr
2150 WHERE mtr.reason_name = wmti.reason_name
2151 AND NVL(mtr.disable_date, SYSDATE) >= SYSDATE)
2155 AND wmti.reason_id IS NULL
2152 WHERE wmti.group_id = g_group_id
2153 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2154 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2156 AND wmti.reason_name IS NOT NULL;
2157
2158 -- Set Error Message
2159 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2160 fnd_message.set_token('ENTITY1', 'REASON_ID');
2161 fnd_message.set_token('ENTITY2', 'REASON_NAME');
2162 l_errMsg := substrb(fnd_message.get, 1, 240);
2163
2164 -- If caller provide REASON_ID, it must be consistent with
2165 -- REASON_NAME provided
2166 INSERT INTO wip_txn_interface_errors(
2167 transaction_id,
2168 error_message,
2169 error_column,
2170 last_update_date,
2171 last_updated_by,
2172 creation_date,
2173 created_by,
2174 last_update_login,
2175 request_id,
2176 program_application_id,
2177 program_id,
2178 program_update_date
2179 )
2180 SELECT wmti.transaction_id, -- transaction_id
2181 l_errMsg, -- error_message
2182 'REASON_ID/NAME', -- error_column
2183 SYSDATE, -- last_update_date
2184 NVL(wmti.last_updated_by, -1),
2185 SYSDATE, -- creation_date
2186 NVL(wmti.created_by, -1),
2187 wmti.last_update_login,
2188 wmti.request_id,
2189 wmti.program_application_id,
2190 wmti.program_id,
2191 wmti.program_update_date
2192 FROM wip_move_txn_interface wmti
2193 WHERE wmti.group_id = g_group_id
2194 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2195 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2196 AND (wmti.reason_id IS NOT NULL OR wmti.reason_name IS NOT NULL)
2197 AND NOT EXISTS
2198 (SELECT 'X'
2199 FROM mtl_transaction_reasons mtr
2200 WHERE mtr.reason_id = NVL(wmti.reason_id, mtr.reason_id)
2201 AND mtr.reason_name = NVL(wmti.reason_name, mtr.reason_name)
2202 AND NVL(mtr.disable_date, SYSDATE) >= SYSDATE);
2203
2204 END reason_id;
2205
2206 -- validate scrap_account_id. This value can be either required or optional
2207 -- info for the discrete and repetitive scrap transaction. It depends on the
2208 -- value setup in WIP_PARAMETERS. However it is always an optional info for
2209 -- OSFM txns. If the caller provided this info, it must be valid account_id
2210 PROCEDURE scrap_account_id IS
2211 l_scrap_flag NUMBER;
2212 l_errMsg VARCHAR2(240);
2213 BEGIN
2214 -- Set Error Message
2215 fnd_message.set_name('WIP', 'WIP_NOT_VALID');
2216 fnd_message.set_token('ENTITY', 'SCRAP_ACCOUNT_ID');
2217 l_errMsg := substrb(fnd_message.get, 1, 240);
2218
2219 INSERT INTO wip_txn_interface_errors(
2220 transaction_id,
2221 error_message,
2222 error_column,
2223 last_update_date,
2224 last_updated_by,
2225 creation_date,
2226 created_by,
2227 last_update_login,
2228 request_id,
2229 program_application_id,
2230 program_id,
2231 program_update_date
2232 )
2233 SELECT wmti.transaction_id, -- transaction_id
2234 l_errMsg, -- error_message
2235 'SCRAP_ACCOUNT_ID', -- error_column
2236 SYSDATE, -- last_update_date
2237 NVL(wmti.last_updated_by, -1),
2238 SYSDATE, -- creation_date
2239 NVL(wmti.created_by, -1),
2240 wmti.last_update_login,
2241 wmti.request_id,
2242 wmti.program_application_id,
2243 wmti.program_id,
2244 wmti.program_update_date
2245 FROM wip_move_txn_interface wmti,
2246 wip_parameters wp
2247 WHERE wp.organization_id = wmti.organization_id
2248 AND wmti.group_id = g_group_id
2249 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2250 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2251 AND (wmti.fm_intraoperation_step_type = WIP_CONSTANTS.SCRAP OR
2252 wmti.to_intraoperation_step_type = WIP_CONSTANTS.SCRAP)
2253 AND ((wmti.scrap_account_id IS NULL
2254 AND wp.mandatory_scrap_flag = WIP_CONSTANTS.YES
2255 AND wmti.entity_type NOT IN(WIP_CONSTANTS.LOTBASED,
2256 WIP_CONSTANTS.CLOSED_OSFM))
2257 OR
2258 (wmti.scrap_account_id IS NOT NULL AND
2259 NOT EXISTS
2260 (SELECT 'X'
2261 FROM hr_organization_information hoi,
2262 gl_sets_of_books gsob,
2263 gl_code_combinations gcc
2264 WHERE gcc.chart_of_accounts_id = gsob.chart_of_accounts_id
2265 and gsob.set_of_books_id =
2266 to_number(decode(rtrim(translate(
2267 hoi.org_information1,'0123456789',' ')),
2268 null, hoi.org_information1,
2269 -99999))
2270 and (hoi.org_information_context || '') =
2271 'Accounting Information'
2272 AND hoi.organization_id = wmti.organization_id
2273 AND gcc.code_combination_id = wmti.scrap_account_id
2277 AND TRUNC(wmti.transaction_date) BETWEEN
2274 AND gcc.detail_posting_allowed_flag = 'Y'
2275 AND gcc.summary_flag = 'N'
2276 and gcc.enabled_flag = 'Y'
2278 NVL(gcc.start_date_active,
2279 TRUNC(wmti.transaction_date))
2280 AND NVL(gcc.end_date_active,
2281 TRUNC(wmti.transaction_date)))));
2282
2283 END scrap_account_id;
2284
2285 -- validate last_updated_by against fnd_user table. The caller have an option
2286 -- to provide either last_updated_by or last_updated_by_name. If the caller
2287 -- pass last_updated_by, the id need to be valid. If the caller pass
2288 -- last_updated_by_name, we will derive the ID. If the caller pass both
2289 -- both value must be consistent to each other.
2290 PROCEDURE last_updated_by IS
2291 l_errMsg VARCHAR2(240);
2292 BEGIN
2293 -- Derive LAST_UPDATED_BY if user provided only LAST_UPDATED_BY_NAME
2294 UPDATE wip_move_txn_interface wmti
2295 SET wmti.last_updated_by =
2296 (SELECT fu.user_id
2297 FROM fnd_user fu
2298 WHERE fu.user_name = wmti.last_updated_by_name
2299 AND SYSDATE BETWEEN fu.start_date AND NVL(fu.end_date, SYSDATE))
2300 WHERE wmti.group_id = g_group_id
2301 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2302 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2303 AND wmti.last_updated_by IS NULL
2304 AND wmti.last_updated_by_name IS NOT NULL;
2305
2306 -- Set Error Message
2307 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2308 fnd_message.set_token('ENTITY1', 'LAST_UPDATED_BY');
2309 fnd_message.set_token('ENTITY2', 'LAST_UPDATED_BY_NAME');
2310 l_errMsg := substrb(fnd_message.get, 1, 240);
2311
2312 -- Error out if LAST_UPDATED_BY is not consistent with LAST_UPDATED_BY_NAME
2313 INSERT INTO wip_txn_interface_errors(
2314 transaction_id,
2315 error_message,
2316 error_column,
2317 last_update_date,
2318 last_updated_by,
2319 creation_date,
2320 created_by,
2321 last_update_login,
2322 request_id,
2323 program_application_id,
2324 program_id,
2325 program_update_date
2326 )
2327 SELECT wmti.transaction_id, -- transaction_id
2328 l_errMsg, -- error_message
2329 'LAST_UPDATED_BY/BY_NAME', -- error_column
2330 SYSDATE, -- last_update_date
2331 NVL(wmti.last_updated_by, -1),
2332 SYSDATE, -- creation_date
2333 NVL(wmti.created_by, -1),
2334 wmti.last_update_login,
2335 wmti.request_id,
2336 wmti.program_application_id,
2337 wmti.program_id,
2338 wmti.program_update_date
2339 FROM wip_move_txn_interface wmti
2340 WHERE wmti.group_id = g_group_id
2341 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2342 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2343 AND wmti.last_updated_by IS NULL; -- cannot derive LAST_UPDATED_BY
2344
2345 END last_updated_by;
2346
2347 -- validate created_by against fnd_user table. The caller have an option
2348 -- to provide either created_by or created_by_name. If the caller
2349 -- pass created_by, the id need to be valid. If the caller pass
2350 -- created_by_name, we will derive the ID. If the caller pass both
2351 -- both value must be consistent to each other.
2352 PROCEDURE created_by IS
2353 l_errMsg VARCHAR2(240);
2354 BEGIN
2355 -- Derive CREATED_BY if user provided only CREATED_BY_NAME
2356 UPDATE wip_move_txn_interface wmti
2357 SET wmti.created_by =
2358 (SELECT fu.user_id
2359 FROM fnd_user fu
2360 WHERE fu.user_name = wmti.created_by_name
2361 AND SYSDATE BETWEEN fu.start_date AND NVL(fu.end_date, SYSDATE))
2362 WHERE wmti.group_id = g_group_id
2363 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2364 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2365 AND wmti.created_by IS NULL
2366 AND wmti.created_by_name IS NOT NULL;
2367
2368 -- Set Error Message
2369 fnd_message.set_name('WIP', 'WIP_ID_CODE_COMBINATION');
2370 fnd_message.set_token('ENTITY1', 'CREATED_BY');
2371 fnd_message.set_token('ENTITY2', 'CREATED_BY_NAME');
2372 l_errMsg := substrb(fnd_message.get, 1, 240);
2373
2374 -- Error out if CREATED_BY is not consistent with CREATED_BY_NAME
2375 INSERT INTO wip_txn_interface_errors(
2376 transaction_id,
2377 error_message,
2378 error_column,
2379 last_update_date,
2380 last_updated_by,
2381 creation_date,
2382 created_by,
2383 last_update_login,
2384 request_id,
2385 program_application_id,
2386 program_id,
2387 program_update_date
2388 )
2389 SELECT wmti.transaction_id, -- transaction_id
2390 l_errMsg, -- error_message
2391 'CREATED_BY/BY_NAME', -- error_column
2392 SYSDATE, -- last_update_date
2393 NVL(wmti.last_updated_by, -1),
2394 SYSDATE, -- creation_date
2395 NVL(wmti.created_by, -1),
2396 wmti.last_update_login,
2397 wmti.request_id,
2398 wmti.program_application_id,
2402 WHERE wmti.group_id = g_group_id
2399 wmti.program_id,
2400 wmti.program_update_date
2401 FROM wip_move_txn_interface wmti
2403 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2404 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2405 AND ((wmti.created_by IS NULL) -- cannot derive LAST_UPDATED_BY
2406 OR
2407 (NOT EXISTS
2408 (SELECT 'X'
2409 FROM fnd_user fu
2410 WHERE fu.user_name = NVL(wmti.created_by_name,
2411 fu.user_name)
2412 AND fu.user_id = wmti.created_by
2413 AND SYSDATE BETWEEN fu.start_date AND
2414 NVL(fu.end_date, SYSDATE))));
2415 END created_by;
2416
2417 -- This procedure is used to validate osp transactions. User cannot move into
2418 -- a queue of OSP operation unless the department associated to that operation
2419 -- has a location for PO_RECEIVE. For PO_MOVE the department associated with
2420 -- the next operation after to_op must have location. If to_op is the last op
2421 -- , the department associated to that operation must have location.
2422 -- The user must be a valid employee to perform osp transactions.
2423 PROCEDURE osp_validation IS
2424 l_errMsg VARCHAR2(240);
2425 BEGIN
2426 -- Set Error Message
2427 fnd_message.set_name('WIP', 'WIP_PO_MOVE_LOCATION');
2428 l_errMsg := substrb(fnd_message.get, 1, 240);
2429
2430 -- Error out if user try to move into a queue of OSP operation and the
2431 -- department associated to that operation does not have a location
2432 -- for PO_RECEIVE. For PO_MOVE the department associated with
2433 -- the next operation after to_op must have location. If to_op is the last op
2434 -- the department associated to that operation must have location.
2435 INSERT INTO wip_txn_interface_errors(
2436 transaction_id,
2437 error_message,
2438 error_column,
2439 last_update_date,
2440 last_updated_by,
2441 creation_date,
2442 created_by,
2443 last_update_login,
2444 request_id,
2445 program_application_id,
2446 program_id,
2447 program_update_date
2448 )
2449 SELECT wmti.transaction_id, -- transaction_id
2450 l_errMsg, -- error_message
2451 'TO_OP_SEQ_NUM/CREATED_BY', -- error_column
2452 SYSDATE, -- last_update_date
2453 NVL(wmti.last_updated_by, -1),
2454 SYSDATE, -- creation_date
2455 NVL(wmti.created_by, -1),
2456 wmti.last_update_login,
2457 wmti.request_id,
2458 wmti.program_application_id,
2459 wmti.program_id,
2460 wmti.program_update_date
2461 FROM wip_move_txn_interface wmti
2462 WHERE wmti.group_id = g_group_id
2463 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2464 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2465 AND EXISTS
2466 (SELECT 'X'
2467 FROM bom_departments bd,
2468 wip_operation_resources wor,
2469 wip_operations wo1,
2470 wip_operations wo2
2471 WHERE wor.organization_id = wmti.organization_id
2472 AND wor.wip_entity_id = wmti.wip_entity_id
2473 AND wor.operation_seq_num = wmti.to_operation_seq_num
2474 AND wmti.fm_operation_seq_num < wmti.to_operation_seq_num
2475 AND wmti.to_intraoperation_step_type = WIP_CONSTANTS.QUEUE
2476 AND (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
2477 WIP_CONSTANTS.LOTBASED)
2478 OR
2479 (wmti.entity_type = WIP_CONSTANTS.REPETITIVE AND
2480 wor.repetitive_schedule_id IN
2481 (SELECT wrs.repetitive_schedule_id
2482 FROM wip_repetitive_schedules wrs
2483 WHERE wrs.wip_entity_id = wmti.wip_entity_id
2484 AND wrs.organization_id = wmti.organization_id
2485 AND wrs.line_id = wmti.line_id
2486 AND wrs.status_type IN (WIP_CONSTANTS.RELEASED,
2487 WIP_CONSTANTS.COMP_CHRG))))
2488 AND wo1.organization_id = wor.organization_id
2489 AND wo1.wip_entity_id = wor.wip_entity_id
2490 AND NVL(wo1.repetitive_schedule_id,-1) =
2491 NVL(wor.repetitive_schedule_id,-1)
2492 AND wo1.operation_seq_num = wor.operation_seq_num
2493 AND wo2.organization_id = wo1.organization_id
2494 AND wo2.wip_entity_id = wo1.wip_entity_id
2495 AND NVL(wo2.repetitive_schedule_id,-1) =
2496 NVL(wo1.repetitive_schedule_id,-1)
2497 AND ((wor.autocharge_type = WIP_CONSTANTS.PO_RECEIPT AND
2498 wo2.operation_seq_num = wor.operation_seq_num)
2499 OR
2500 (wor.autocharge_type = WIP_CONSTANTS.PO_MOVE AND
2501 ((wo1.next_operation_seq_num IS NOT NULL AND
2502 wo1.next_operation_seq_num = wo2.operation_seq_num)
2503 OR
2504 (wo1.next_operation_seq_num IS NULL AND
2505 wo2.operation_seq_num = wor.operation_seq_num))))
2506 AND bd.organization_id = wmti.organization_id
2510 -- Set Error Message
2507 AND wo2.department_id = bd.department_id
2508 AND bd.location_id IS NULL);
2509
2511 fnd_message.set_name('WIP', 'WIP_VALID_EMPLOYEE');
2512 l_errMsg := substrb(fnd_message.get, 1, 240);
2513
2514 -- Error out if the user who try to do OSP transaction is not an employee
2515 INSERT INTO wip_txn_interface_errors(
2516 transaction_id,
2517 error_message,
2518 error_column,
2519 last_update_date,
2520 last_updated_by,
2521 creation_date,
2522 created_by,
2523 last_update_login,
2524 request_id,
2525 program_application_id,
2526 program_id,
2527 program_update_date
2528 )
2529 SELECT wmti.transaction_id, -- transaction_id
2530 l_errMsg, -- error_message
2531 'TO_OP_SEQ_NUM/CREATED_BY', -- error_column
2532 SYSDATE, -- last_update_date
2533 NVL(wmti.last_updated_by, -1),
2534 SYSDATE, -- creation_date
2535 NVL(wmti.created_by, -1),
2536 wmti.last_update_login,
2537 wmti.request_id,
2538 wmti.program_application_id,
2539 wmti.program_id,
2540 wmti.program_update_date
2541 FROM wip_move_txn_interface wmti
2542 WHERE wmti.group_id = g_group_id
2543 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2544 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2545 AND EXISTS
2546 (SELECT 'Outside processing resources exist'
2547 FROM wip_operation_resources wor
2548 WHERE wor.organization_id = wmti.organization_id
2549 AND wor.wip_entity_id = wmti.wip_entity_id
2550 AND wor.operation_seq_num = wmti.to_operation_seq_num
2551 AND wmti.fm_operation_seq_num < wmti.to_operation_seq_num
2552 AND wmti.to_intraoperation_step_type = WIP_CONSTANTS.QUEUE
2553 AND wor.autocharge_type IN (WIP_CONSTANTS.PO_RECEIPT,
2554 WIP_CONSTANTS.PO_MOVE)
2555 AND (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
2556 WIP_CONSTANTS.LOTBASED)
2557 OR
2558 (wmti.entity_type = WIP_CONSTANTS.REPETITIVE AND
2559 wor.repetitive_schedule_id IN
2560 (SELECT wrs.repetitive_schedule_id
2561 FROM wip_repetitive_schedules wrs
2562 WHERE wrs.organization_id = wmti.organization_id
2563 AND wrs.wip_entity_id = wmti.wip_entity_id
2564 AND wrs.line_id = wmti.line_id
2565 AND wrs.status_type IN (WIP_CONSTANTS.RELEASED,
2566 WIP_CONSTANTS.COMP_CHRG)))))
2567 AND NOT EXISTS
2568 (SELECT 'Current user is an employee'
2569 FROM fnd_user fu,
2570 per_people_f ppf
2571 WHERE fu.user_id = wmti.created_by
2572 AND fu.employee_id = ppf.person_id);
2573
2574 END osp_validation;
2575
2576 -- validate serial related information. This validation is only useful if
2577 -- user try to do background serialized txns.
2578 PROCEDURE serial_validation IS
2579 BEGIN
2580 -- reset enums table
2581 enums.delete;
2582 -- Users cannot move cross 'Queue' of serialization start op. User need to
2583 -- move 2 step. The first time move to Queue of serialization start op, then
2584 -- serial move. For backward move, do serial move first.
2585 UPDATE wip_move_txn_interface wmti
2586 SET wmti.process_status = WIP_CONSTANTS.ERROR
2587 WHERE wmti.group_id = g_group_id
2588 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2589 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2590 AND EXISTS -- serialized job
2591 (SELECT 'X'
2592 FROM wip_discrete_jobs wdj
2593 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2594 AND wdj.serialization_start_op IS NOT NULL
2595 AND (-- Forward move
2596 (wmti.fm_operation_seq_num < wdj.serialization_start_op AND
2597 (wmti.to_operation_seq_num > wdj.serialization_start_op
2598 OR
2599 (wmti.to_operation_seq_num = wdj.serialization_start_op AND
2600 wmti.to_intraoperation_step_type <> WIP_CONSTANTS.QUEUE)))
2601 OR
2602 -- Backward move
2603 (wmti.to_operation_seq_num < wdj.serialization_start_op AND
2604 (wmti.fm_operation_seq_num > wdj.serialization_start_op
2605 OR
2606 (wmti.fm_operation_seq_num = wdj.serialization_start_op AND
2607 wmti.fm_intraoperation_step_type <> WIP_CONSTANTS.QUEUE)))))
2608 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2609
2610 fnd_message.set_name('WIP', 'WIP_MOVE_CROSS_START_OP');
2611 add_error(p_txn_ids => enums,
2612 p_err_col => 'FM/TO_STEP, FM/TO_OP',
2613 p_err_msg => fnd_message.get);
2614
2615 -- Comment out the validation below because Express Move can be done for more
2616 -- then one quantity. Moreover, this validation was already done through the
2617 -- UI(mobile and MES), and we do not support serilized move in the background.
2618 /*
2619 -- reset enums table
2620 enums.delete;
2624 UPDATE wip_move_txn_interface wmti
2621 -- If user try to do serialized transaction, primary_quantity must be 1.
2622 -- This validation is only for serialized discrete job. For serialized
2623 -- OSFM job, primary_quantity can be more than 1.
2625 SET wmti.process_status = WIP_CONSTANTS.ERROR
2626 WHERE wmti.group_id = g_group_id
2627 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2628 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2629 AND EXISTS -- serialized discrete job and serialized transaction
2630 (SELECT 'X'
2631 FROM wip_discrete_jobs wdj,
2632 wip_entities we
2633 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2634 AND wdj.wip_entity_id = we.wip_entity_id
2635 AND we.entity_type = WIP_CONSTANTS.DISCRETE
2636 AND wdj.serialization_start_op IS NOT NULL
2637 AND wmti.fm_operation_seq_num >= wdj.serialization_start_op
2638 AND wmti.to_operation_seq_num >= wdj.serialization_start_op
2639 AND wmti.primary_quantity <> 1)
2640 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2641
2642 fnd_message.set_name('WIP', 'WIP_INVALID_SERIAL_QTY');
2643 add_error(p_txn_ids => enums,
2644 p_err_col => 'TRANSACTION/PRIMARY_QUANTITY',
2645 p_err_msg => fnd_message.get);
2646 */
2647
2648 -- reset enums table
2649 enums.delete;
2650 -- if user provide serial number information for non-serialized job, or
2651 -- serialized job with non-serialized move, error out.
2652 UPDATE wip_move_txn_interface wmti
2653 SET wmti.process_status = WIP_CONSTANTS.ERROR
2654 WHERE wmti.group_id = g_group_id
2655 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2656 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2657 AND EXISTS -- regular job
2658 (SELECT 'X'
2659 FROM wip_discrete_jobs wdj
2660 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2661 AND (wdj.serialization_start_op IS NULL -- non-serialized job
2662 OR -- serialized job with non-serialized move
2663 (wdj.serialization_start_op IS NOT NULL
2664 AND
2665 (wmti.fm_operation_seq_num < wdj.serialization_start_op OR
2666 (wmti.fm_operation_seq_num = wdj.serialization_start_op AND
2667 wmti.fm_intraoperation_step_type = WIP_CONSTANTS.QUEUE))
2668 AND
2669 (wmti.to_operation_seq_num < wdj.serialization_start_op OR
2670 (wmti.to_operation_seq_num = wdj.serialization_start_op AND
2671 wmti.to_intraoperation_step_type = WIP_CONSTANTS.QUEUE))))
2672 )
2673 AND EXISTS
2674 (SELECT 'X'
2675 FROM wip_serial_move_interface wsmi
2676 WHERE wsmi.transaction_id = wmti.transaction_id)
2677 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2678
2679 fnd_message.set_name('WIP', 'WIP_SERIAL_INFO_NOT_ALLOW');
2680 add_error(p_txn_ids => enums,
2681 p_err_col => 'WSMI.ASSEMBLY_SERIAL_NUMBER',
2682 p_err_msg => fnd_message.get);
2683
2684
2685 -- reset enums table
2686 enums.delete;
2687 -- if user try to do serialized transaction, number of serial records must be
2688 -- equal to wmti.primary_quantity
2689 UPDATE wip_move_txn_interface wmti
2690 SET wmti.process_status = WIP_CONSTANTS.ERROR
2691 WHERE wmti.group_id = g_group_id
2692 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2693 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2694 AND EXISTS -- serialized job and serialized transaction
2695 (SELECT 'X'
2696 FROM wip_discrete_jobs wdj
2697 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2698 AND wdj.serialization_start_op IS NOT NULL
2699 AND wmti.fm_operation_seq_num >= wdj.serialization_start_op
2700 AND wmti.to_operation_seq_num >= wdj.serialization_start_op)
2701 AND wmti.primary_quantity <>
2702 (SELECT COUNT(*)
2703 FROM wip_serial_move_interface wsmi,
2704 mtl_serial_numbers msn
2705 WHERE wsmi.transaction_id = wmti.transaction_id
2706 AND wsmi.assembly_serial_number = msn.serial_number
2707 AND wmti.organization_id = msn.current_organization_id
2708 AND wmti.primary_item_id = msn.inventory_item_id
2709 AND msn.wip_entity_id IS NOT NULL
2710 AND msn.wip_entity_id = wmti.wip_entity_id)
2711 AND wmti.primary_quantity <>
2712 (SELECT COUNT(*)
2713 FROM wip_serial_move_interface wsmi,
2714 wip_entities we,
2715 mtl_serial_numbers msn,
2716 mtl_object_genealogy mog
2717 WHERE wsmi.transaction_id = wmti.transaction_id
2718 AND wsmi.assembly_serial_number = msn.serial_number
2719 AND wmti.organization_id = msn.current_organization_id
2720 AND wmti.primary_item_id = msn.inventory_item_id
2721 AND msn.current_status = WIP_CONSTANTS.IN_STORES
2722 AND wmti.wip_entity_id = we.wip_entity_id
2723 AND ((mog.genealogy_origin = 1 AND
2724 mog.parent_object_id = we.gen_object_id AND
2725 mog.object_id = msn.gen_object_id)
2726 OR
2727 (mog.genealogy_origin = 2 AND
2728 mog.parent_object_id = msn.gen_object_id AND
2729 mog.object_id = we.gen_object_id))
2733 fnd_message.set_name('WIP', 'WIP_SERIAL_QTY_MISSMATCH');
2730 AND mog.end_date_active IS NULL)
2731 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2732
2734 add_error(p_txn_ids => enums,
2735 p_err_col => 'WSMI.ASSEMBLY_SERIAL_NUMBER',
2736 p_err_msg => fnd_message.get);
2737
2738 -- reset enums table
2739 enums.delete;
2740 -- if user try to do serialized transaction, the status of the serial
2741 -- must correspond to the transaction type.
2742 UPDATE wip_move_txn_interface wmti
2743 SET wmti.process_status = WIP_CONSTANTS.ERROR
2744 WHERE wmti.group_id = g_group_id
2745 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2746 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2747 AND EXISTS -- serialized job and serialized transaction
2748 (SELECT 'X'
2749 FROM wip_discrete_jobs wdj
2750 WHERE wdj.wip_entity_id = wmti.wip_entity_id
2751 AND wdj.serialization_start_op IS NOT NULL
2752 AND wmti.fm_operation_seq_num >= wdj.serialization_start_op
2753 AND wmti.to_operation_seq_num >= wdj.serialization_start_op)
2754 AND NOT EXISTS
2755 (SELECT 'X'
2756 FROM wip_serial_move_interface wsmi,
2757 mtl_serial_numbers msn
2758 WHERE wsmi.transaction_id = wmti.transaction_id
2759 AND wsmi.assembly_serial_number = msn.serial_number
2760 AND wmti.organization_id = msn.current_organization_id
2761 AND wmti.primary_item_id = msn.inventory_item_id
2762 AND msn.line_mark_id IS NULL
2763 AND ((wmti.transaction_type = WIP_CONSTANTS.RET_TXN AND
2764 msn.group_mark_id IS NULL AND
2765 msn.wip_entity_id IS NULL AND
2766 msn.current_status = WIP_CONSTANTS.IN_STORES)
2767 OR
2768 (wmti.transaction_type IN (WIP_CONSTANTS.MOVE_TXN,
2769 WIP_CONSTANTS.COMP_TXN) AND
2770 msn.group_mark_id IS NOT NULL AND
2771 msn.wip_entity_id IS NOT NULL AND
2772 wmti.wip_entity_id = msn.wip_entity_id AND
2773 -- Define but not use or Issue out of store.
2774 msn.current_status IN (WIP_CONSTANTS.DEF_NOT_USED,
2775 WIP_CONSTANTS.OUT_OF_STORES))))
2776 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2777
2778 fnd_message.set_name('WIP', 'WIP_INVALID_SERIAL_STATUS');
2779 add_error(p_txn_ids => enums,
2780 p_err_col => 'WSMI.ASSEMBLY_SERIAL_NUMBER',
2781 p_err_msg => fnd_message.get);
2782
2783 END serial_validation;
2784
2785 -- If there are some errors occur, this routine will set
2786 -- PROCESS_STATUS to WIP_CONSTANTS.ERROR. Then it will insert all the errors
2787 -- into WIP_TXN_INTERFACE_ERRORS
2788 PROCEDURE update_interface_tbl IS
2789 BEGIN
2790 -- there are some errors occur, so set the process_status to error so that
2791 -- move processor will not pick up this record
2792 UPDATE wip_move_txn_interface wmti
2793 SET wmti.process_status = WIP_CONSTANTS.ERROR
2794 WHERE wmti.group_id = g_group_id
2795 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2796 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2797 AND EXISTS
2798 (SELECT 'X'
2799 FROM wip_txn_interface_errors wtie
2800 WHERE wtie.transaction_id = wmti.transaction_id);
2801
2802 -- insert error message to WIP_TXN_INTERFACE_ERRORS, and clear error table
2803 load_errors;
2804 END update_interface_tbl;
2805
2806 /* Fixed bug 5056289. Added more validation for assembly to prevent the whole
2807 batch error out when assembly fail inventory validation.
2808 */
2809 -- Validate assembly related information to prevent the whole batch failing
2810 -- if there is something wrong with the assembly like assembly is not
2811 -- transactable, or assembly is not an inventory item. This check is only for
2812 -- EZ Completion and EZ Return.
2813 PROCEDURE assembly_validation IS
2814 BEGIN
2815 -- reset enums table
2816 enums.delete;
2817 -- Users cannot do EZ Completion/EZ Return if an assembly is not transactable
2818 -- or an assembly is not an inventory item.
2819 UPDATE wip_move_txn_interface wmti
2820 SET wmti.process_status = WIP_CONSTANTS.ERROR
2821 WHERE wmti.group_id = g_group_id
2822 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2823 AND wmti.process_status = WIP_CONSTANTS.RUNNING
2824 AND wmti.transaction_type IN (WIP_CONSTANTS.RET_TXN,
2825 WIP_CONSTANTS.COMP_TXN)
2826 AND EXISTS -- Item flag was not set properly.
2827 (SELECT 'X'
2828 FROM mtl_system_items msi
2829 WHERE msi.inventory_item_id = wmti.primary_item_id
2830 AND msi.organization_id = wmti.organization_id
2831 AND (msi.inventory_item_flag = 'N' OR
2832 msi.mtl_transactions_enabled_flag = 'N'))
2833 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
2834
2835 fnd_message.set_name('INV', 'INV_INT_ITMEXP');
2836 add_error(p_txn_ids => enums,
2837 p_err_col => 'PRIMARY_ITEM_ID',
2838 p_err_msg => fnd_message.get);
2839
2840 END assembly_validation;
2841
2842
2843 -- If pass all the validation, and there is no error, this routine will
2844 -- derive all the rest info (fm_operation_code, fm_department_id,
2848 -- update_interface_tbl
2845 -- fm_department_code, to_operation_code, to_department_id, to_department_code)
2846 -- , then update PROCESS_PHASE to WIP_CONSTANTS.MOVE_PROC. This routine
2847 -- should be called after we called all the validation code and
2849 PROCEDURE derive IS
2850 l_PrevOpSeq NUMBER;
2851 l_NextOpSeq NUMBER;
2852 l_OpExists BOOLEAN;
2853 BEGIN
2854
2855 UPDATE wip_move_txn_interface wmti
2856 SET (wmti.fm_operation_code,
2857 wmti.fm_department_id,
2858 wmti.fm_department_code,
2859 wmti.to_operation_code,
2860 wmti.to_department_id,
2861 wmti.to_department_code,
2862 wmti.process_phase) =
2863 (SELECT bso1.operation_code,
2864 wo1.department_id,
2865 bd1.department_code,
2866 bso2.operation_code,
2867 wo2.department_id,
2868 bd2.department_code,
2869 WIP_CONSTANTS.MOVE_PROC
2870 FROM bom_standard_operations bso1,
2871 bom_standard_operations bso2,
2872 bom_departments bd1,
2873 bom_departments bd2,
2874 wip_operations wo1,
2875 wip_operations wo2
2876 WHERE wo1.organization_id = wmti.organization_id
2877 AND wo1.wip_entity_id = wmti.wip_entity_id
2878 AND wo1.operation_seq_num = wmti.fm_operation_seq_num
2879 AND wo2.organization_id = wmti.organization_id
2880 AND wo2.wip_entity_id = wmti.wip_entity_id
2881 AND wo2.operation_seq_num = wmti.to_operation_seq_num
2882 /* Standard operation ID is optional, so we should use outer join */
2883 AND bso1.standard_operation_id(+) = wo1.standard_operation_id
2884 AND bso2.standard_operation_id(+) = wo2.standard_operation_id
2885 AND wo1.department_id = bd1.department_id
2886 AND wo2.department_id = bd2.department_id
2887 AND (wmti.entity_type IN (WIP_CONSTANTS.DISCRETE,
2888 WIP_CONSTANTS.LOTBASED)
2889 OR
2890 (wmti.entity_type = WIP_CONSTANTS.REPETITIVE AND
2891 wo1.repetitive_schedule_id = wmti.repetitive_schedule_id AND
2892 wo2.repetitive_schedule_id = wmti.repetitive_schedule_id)))
2893 WHERE wmti.group_id = g_group_id
2894 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
2895 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
2896
2897 END derive;
2898
2899 PROCEDURE validate(p_group_id IN NUMBER,
2900 p_initMsgList IN VARCHAR2) IS
2901 l_params wip_logger.param_tbl_t;
2902 l_returnStatus VARCHAR2(1);
2903 l_logLevel NUMBER ;
2904
2905 BEGIN
2906 l_logLevel := fnd_log.g_current_runtime_level;
2907 IF(fnd_api.to_boolean(p_initMsgList)) THEN
2908 fnd_msg_pub.initialize;
2909 END IF;
2910
2911 -- write parameter value to log file
2912 if (l_logLevel <= wip_constants.trace_logging) then
2913 l_params(1).paramName := 'p_group_id';
2914 l_params(1).paramValue := p_group_id;
2915 wip_logger.entryPoint(p_procName => 'wip_move_validator.validate',
2916 p_params => l_params,
2917 x_returnStatus => l_returnStatus);
2918 end if;
2919
2920 -- reset global_variable everytime this routine is called
2921 g_group_id := p_group_id;
2922 enums.delete;
2923 -- Call last_updatd_by and created_by first even if it is a low priority
2924 -- validation because we want to insert last_updated_by and created_by
2925 -- into WIP_TXN_INTERFACE_ERRORS
2926 last_updated_by;
2927 created_by;
2928 /*****************************
2929 * Start critical validation *
2930 *****************************/
2931 -- If any of the procedure below error out, set WMTI.PROCESS_STATUS to
2932 -- Error and stop validation.
2933 /* Bug#2956953 - commented call to organization_id procedure as the validation
2934 for organization_id/organization_code are called from wip move manager code
2935 - Changes done as part of the Wip Move Sequencing Project */
2936 -- organization_id;
2937 wip_entity_id;
2938 transaction_type;
2939 transaction_date;
2940 fm_operation;
2941 fm_step;
2942 to_operation;
2943 to_step;
2944 transaction_qty;
2945 transaction_uom;
2946 ocpl_txn_qty;
2947 /*****************************
2948 * End critical validation *
2949 *****************************/
2950
2951 /*********************************
2952 * Start low priority validation *
2953 *********************************/
2954 -- If any of the procedure below error out, continue validating other
2955 -- low priority validation because we support multiple error message
2956 -- for one record.
2957 transaction_id;
2958 primary_qty;
2959 primary_uom;
2960 ocpl_primary_qty;
2961 ocpl_txn_id;
2962 reason_id;
2963 scrap_account_id;
2964
2965 -- need to call this routine before osp_validation because use
2966 -- created_by as a user_id to validate OSP
2967 osp_validation;
2968 serial_validation;
2969 /* Fixed bug 5056289. */
2970 -- Add more validation for assembly to prevent the whole batch failing if
2971 -- there is something wrong with the assembly. This check is only for
2972 -- EZ Completion and EZ Return.
2973 assembly_validation;
2977 -- set WMTI.PROCESS_STATUS to error if there is an error from any
2974 /*******************************
2975 * End low priority validation *
2976 *******************************/
2978 -- validation and insert error message into WIP_TXN_INTERFACE_ERRORS
2979 update_interface_tbl;
2980 -- derive the rest nessary info
2981 derive;
2982 -- write to the log file
2983 if (l_logLevel <= wip_constants.trace_logging) then
2984 wip_logger.exitPoint(p_procName => 'wip_move_validator.validate',
2985 p_procReturnStatus => fnd_api.g_ret_sts_success,
2986 p_msg => 'procedure complete',
2987 x_returnStatus => l_returnStatus);
2988 end if;
2989 EXCEPTION
2990 WHEN others THEN
2991 if (l_logLevel <= wip_constants.trace_logging) then
2992 wip_logger.exitPoint(p_procName => 'wip_move_validator.validate',
2993 p_procReturnStatus => fnd_api.g_ret_sts_unexp_error,
2994 p_msg => 'Unexpected Errors: ' || SQLERRM,
2995 x_returnStatus => l_returnStatus);
2996 end if;
2997
2998 END validate;
2999
3000 PROCEDURE get_move_txn_type(p_move_id IN NUMBER,
3001 p_org_id IN NUMBER DEFAULT NULL,
3002 p_wip_entity_id IN NUMBER DEFAULT NULL,
3003 p_assm_item_id IN NUMBER DEFAULT NULL,
3004 p_txn_type OUT NOCOPY VARCHAR2)
3005 IS
3006 BEGIN
3007 p_txn_type := move_txn_type(p_move_id => p_move_id,
3008 p_org_id => p_org_id,
3009 p_wip_entity_id => p_wip_entity_id,
3010 p_assm_item_id => p_assm_item_id);
3011 END get_move_txn_type;
3012
3013
3014 FUNCTION move_txn_type(p_move_id IN NUMBER,
3015 p_org_id IN NUMBER DEFAULT NULL,
3016 p_wip_entity_id IN NUMBER DEFAULT NULL,
3017 p_assm_item_id IN NUMBER DEFAULT NULL) return VARCHAR2
3018 IS
3019 p_txn_type VARCHAR2(80);
3020 l_org_id NUMBER ;
3021 l_wip_entity_id NUMBER ;
3022 l_assm_item_id NUMBER ;
3023 BEGIN
3024 l_org_id := p_org_id;
3025 l_wip_entity_id := p_wip_entity_id;
3026 l_assm_item_id := p_assm_item_id;
3027
3028
3029 if (l_org_id is NULL or l_wip_entity_id is NULL) then
3030 select organization_id,
3031 wip_entity_id
3032 into l_org_id,
3033 l_wip_entity_id
3034 from wip_move_transactions
3035 where transaction_id = p_move_id;
3036 end if;
3037
3038 if (l_assm_item_id is NULL) then
3039 select wdj.primary_item_id
3040 into l_assm_item_id
3041 from wip_discrete_jobs wdj
3042 where wdj.organization_id = l_org_id
3043 and wdj.wip_entity_id = l_wip_entity_id;
3044 end if;
3045
3046 begin
3047 -- Should have at most one match
3048 select distinct lu.meaning
3049 into p_txn_type
3050 from mfg_lookups lu,
3051 mtl_material_transactions mmt
3052 where mmt.move_transaction_id = p_move_id
3053 and mmt.organization_id = l_org_id
3054 and mmt.transaction_source_id = l_wip_entity_id
3055 and mmt.inventory_item_id = l_assm_item_id
3056 and mmt.transaction_type_id in (wip_constants.CPLASSY_TYPE, wip_constants.RETASSY_TYPE)
3057 and lu.lookup_type = 'WIP_MOVE_TRANSACTION_TYPE'
3058 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);
3059 exception
3060 -- no inv txn involved; just a plain move txn
3061 when no_data_found then
3062 select meaning
3063 into p_txn_type
3064 from mfg_lookups
3065 where lookup_type = 'WIP_MOVE_TRANSACTION_TYPE'
3066 and lookup_code = wip_constants.move_txn;
3067 when others then
3068 p_txn_type := -1;
3069 end;
3070
3071 return p_txn_type;
3072 END move_txn_type;
3073
3074 PROCEDURE validateOATxn(p_group_id IN NUMBER) IS
3075 l_params wip_logger.param_tbl_t;
3076 l_returnStatus VARCHAR2(1);
3077 l_logLevel NUMBER ;
3078
3079 BEGIN
3080 l_logLevel := fnd_log.g_current_runtime_level;
3081
3082 -- write parameter value to log file
3083 if (l_logLevel <= wip_constants.trace_logging) then
3084 l_params(1).paramName := 'p_group_id';
3085 l_params(1).paramValue := p_group_id;
3086 wip_logger.entryPoint(p_procName => 'wip_move_validator.validateOATxn',
3087 p_params => l_params,
3088 x_returnStatus => l_returnStatus);
3089 end if;
3090
3091 -- reset global_variable everytime this routine is called
3092 g_group_id := p_group_id;
3093 enums.delete;
3094
3095 -- Derive ACCT_PERIOD_ID from TRANSACTION_DATE
3096 UPDATE wip_move_txn_interface wmti
3097 SET wmti.acct_period_id =
3098 (SELECT oap.acct_period_id
3099 FROM org_acct_periods oap
3100 WHERE oap.organization_id = wmti.organization_id
3101 -- modified the statement below for timezone project in J
3102 AND TRUNC(inv_le_timezone_pub.get_le_day_for_inv_org(
3103 wmti.transaction_date, -- p_trxn_date
3107 WHERE wmti.group_id = g_group_id
3104 wmti.organization_id -- p_inv_org_id
3105 )) BETWEEN
3106 oap.period_start_date AND oap.schedule_close_date)
3108 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3109 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
3110
3111 -- reset enums table
3112 enums.delete;
3113 -- Error out if there is no open accout period for the TRANSACTION_DATE
3114 -- specified or there is no WIP_PERIOD_BALANCES
3115 UPDATE wip_move_txn_interface wmti
3116 SET wmti.process_status = WIP_CONSTANTS.ERROR
3117 WHERE wmti.group_id = g_group_id
3118 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3119 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3120 AND (wmti.acct_period_id IS NULL
3121 OR
3122 NOT EXISTS
3123 (SELECT 'X'
3124 FROM wip_period_balances wpb
3125 WHERE wpb.acct_period_id = wmti.acct_period_id
3126 AND wpb.wip_entity_id = wmti.wip_entity_id
3127 AND wpb.organization_id = wmti.organization_id))
3128 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3129
3130 fnd_message.set_name('WIP', 'WIP_NO_BALANCE');
3131 add_error(p_txn_ids => enums,
3132 p_err_col => 'TRANSACTION_DATE',
3133 p_err_msg => fnd_message.get);
3134
3135 -- Fixed bug 5310474
3136 -- reset enums table
3137 enums.delete;
3138 -- Error out if FM_OPERATION_SEQ_NUM/FM_INTRAOPERATION_STEP_TYPE has
3139 -- no move shop floor status attached
3140 UPDATE wip_move_txn_interface wmti
3141 SET wmti.process_status = WIP_CONSTANTS.ERROR
3142 WHERE wmti.group_id = g_group_id
3143 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3144 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3145 AND EXISTS
3146 (SELECT 'X'
3147 FROM wip_shop_floor_status_codes wsc,
3148 wip_shop_floor_statuses ws
3149 WHERE wsc.organization_id = wmti.organization_id
3150 AND ws.organization_id = wmti.organization_id
3151 AND ws.wip_entity_id = wmti.wip_entity_id
3152 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
3153 AND ws.operation_seq_num = wmti.fm_operation_seq_num
3154 AND ws.intraoperation_step_type = wmti.fm_intraoperation_step_type
3155 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
3156 AND wsc.status_move_flag = WIP_CONSTANTS.NO
3157 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE
3158 AND (wmti.source_code IS NULL OR
3159 wmti.source_code <> 'RCV' OR
3160 (wmti.source_code = 'RCV' AND
3161 NOT EXISTS
3162 (SELECT 'X'
3163 FROM wip_parameters wp
3164 WHERE wp.organization_id = wmti.organization_id
3165 AND wp.osp_shop_floor_status =
3166 wsc.shop_floor_status_code))))
3167 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3168
3169 fnd_message.set_name('WIP', 'WIP_STATUS_NO_TXN1');
3170 add_error(p_txn_ids => enums,
3171 p_err_col => 'FM_INTRAOPERATION_STEP_TYPE',
3172 p_err_msg => fnd_message.get);
3173
3174 -- reset enums table
3175 enums.delete;
3176 -- Error out if user try to easy complete job/schedule that has No Move shop
3177 -- floor status attached to Tomove of the last operation
3178 UPDATE wip_move_txn_interface wmti
3179 SET wmti.process_status = WIP_CONSTANTS.ERROR
3180 WHERE wmti.group_id = g_group_id
3181 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3182 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3183 AND wmti.transaction_type = WIP_CONSTANTS.COMP_TXN
3184 AND EXISTS
3185 (SELECT 'X'
3186 FROM wip_shop_floor_status_codes wsc,
3187 wip_shop_floor_statuses ws
3188 WHERE wsc.organization_id = wmti.organization_id
3189 AND ws.organization_id = wmti.organization_id
3190 AND ws.wip_entity_id = wmti.wip_entity_id
3191 AND (wmti.line_id IS NULL OR ws.line_id = wmti.line_id)
3192 AND ws.operation_seq_num = wmti.to_operation_seq_num
3193 AND ws.intraoperation_step_type = WIP_CONSTANTS.TOMOVE
3194 AND ws.shop_floor_status_code = wsc.shop_floor_status_code
3195 AND wsc.status_move_flag = WIP_CONSTANTS.NO
3196 AND NVL(wsc.disable_date, SYSDATE + 1) > SYSDATE)
3197 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3198
3199 fnd_message.set_name('WIP', 'WIP_STATUS_NO_TXN2');
3200 add_error(p_txn_ids => enums,
3201 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
3202 p_err_msg => fnd_message.get);
3203 -- End of fix for bug 5310474
3204
3205 -- Validate whether there is no move shopfloor status in between or not.
3206 -- reset enums table
3207 enums.delete;
3208 -- Error out if wip_parameter do not allow move over no_move shop floor
3209 -- status, and there are no_move status in between
3210 UPDATE wip_move_txn_interface wmti
3211 SET wmti.process_status = WIP_CONSTANTS.ERROR
3212 WHERE wmti.group_id = g_group_id
3213 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3214 AND wmti.process_status = WIP_CONSTANTS.RUNNING
3215 AND wip_sf_status.count_no_move_statuses(
3216 wmti.organization_id, -- p_org_id
3217 wmti.wip_entity_id, -- p_wip_id
3218 wmti.line_id, -- p_line_id
3219 wmti.repetitive_schedule_id, -- p_sched_id
3220 wmti.fm_operation_seq_num, -- p_fm_op
3221 wmti.fm_intraoperation_step_type, -- p_fm_step
3222 wmti.to_operation_seq_num, -- p_to_op
3223 wmti.to_intraoperation_step_type, -- p_to_step
3224 -- Fixed bug 2121222
3225 wmti.source_code) > 0 -- p_source_code
3226 RETURNING wmti.transaction_id BULK COLLECT INTO enums;
3227
3228 fnd_message.set_name ('WIP', 'WIP_NO_MOVE_SF_STATUS_BETWEEN');
3229 add_error(p_txn_ids => enums,
3230 p_err_col => 'TO_INTRAOPERATION_STEP_TYPE',
3231 p_err_msg => fnd_message.get);
3232
3233 -- Do OSP related validation.
3234 osp_validation;
3235
3236 -- Set WMTI.PROCESS_STATUS to error if there is an error from any
3237 -- validation and insert error message into WIP_TXN_INTERFACE_ERRORS
3238 update_interface_tbl;
3239
3240 -- Set WMTI.PROCESS_PHASE to WIP_CONSTANTS.MOVE_PROC so that move processing
3241 -- code can process these records.
3242 UPDATE wip_move_txn_interface wmti
3243 SET process_phase = WIP_CONSTANTS.MOVE_PROC
3244 WHERE wmti.group_id = g_group_id
3245 AND wmti.process_phase = WIP_CONSTANTS.MOVE_VAL
3246 AND wmti.process_status = WIP_CONSTANTS.RUNNING;
3247
3248 -- write to the log file
3249 if (l_logLevel <= wip_constants.trace_logging) then
3250 wip_logger.exitPoint(p_procName => 'wip_move_validator.validateOATxn',
3251 p_procReturnStatus => fnd_api.g_ret_sts_success,
3252 p_msg => 'procedure complete',
3253 x_returnStatus => l_returnStatus);
3254 end if;
3255 EXCEPTION
3256 WHEN others THEN
3257 if (l_logLevel <= wip_constants.trace_logging) then
3258 wip_logger.exitPoint(p_procName => 'wip_move_validator.validateOATxn',
3259 p_procReturnStatus => fnd_api.g_ret_sts_unexp_error,
3260 p_msg => 'Unexpected Errors: ' || SQLERRM,
3261 x_returnStatus => l_returnStatus);
3262 end if;
3263
3264 END validateOATxn;
3265
3266 END wip_move_validator;