DBA Data[Home] [Help]

PACKAGE BODY: APPS.WIP_MASSLOAD_PUB

Source


1 package body wip_massload_pub as
2  /* $Header: wipmlppb.pls 120.7.12010000.2 2008/08/15 00:54:36 kboonyap ship $ */
3 
4   g_pkgName constant varchar2(30) := 'wip_massload_pub';
5   g_wipMLError constant number := 1;
6   g_wipMLWarning constant number := 2;
7 
8   procedure processSerStartOp(p_rowid in rowid,
9                               p_interfaceID in number,
10                               x_returnStatus out nocopy varchar2,
11                               x_errorMsg     out nocopy varchar2);
12 
13   --
14   -- Currently, this API does not support the creation of repetitive schedule.
15   --
16   procedure massLoadJobs(p_groupID         in number,
17                          p_validationLevel in number,
18 			 p_commitFlag     in number,
19                          x_returnStatus out nocopy varchar2,
20                          x_errorMsg     out nocopy varchar2) is
21     l_params wip_logger.param_tbl_t;
22     l_procName varchar2(30) := 'massLoadJobs';
23     l_logLevel number := to_number(fnd_log.g_current_runtime_level);
24     l_retStatus varchar2(1);
25     l_totalNum number;
26     l_errorCode varchar2(240);
27     l_errRecCount number := 0;
28     l_requestCount number;
29     l_wdj_old_status_type NUMBER;/*Added for bug 6641029*/
30     l_wjsi_new_status_type NUMBER;/*Added for bug 6641029*/
31     l_wdj_wip_entity_id NUMBER;/*Added for bug 6641029*/
32     l_wdj_organization_id NUMBER;/*Added for bug 6641029*/
33 
34     cursor c_allrows is
35       select 1
36         from wip_job_schedule_interface
37        where group_id = p_groupID
38          and process_status = wip_constants.pending
39          and process_phase = wip_constants.ml_validation
40          and load_type <> wip_constants.create_sched
41       for update nowait;
42 
43     cursor c_wjsi is
44       select rowid,
45              header_id,
46              interface_id
47         from wip_job_schedule_interface
48        where group_id = p_groupID
49          and process_phase = wip_constants.ml_validation
50          and process_status in (wip_constants.running, wip_constants.warning)
51          and load_type <> wip_constants.create_sched;
52   begin
53     x_returnStatus := fnd_api.g_ret_sts_success;
54     if (l_logLevel <= wip_constants.trace_logging) then
55       l_params(1).paramName := 'p_groupID';
56       l_params(1).paramValue := p_groupID;
57       l_params(2).paramName := 'p_validationLevel';
58       l_params(2).paramValue := p_validationLevel;
59       wip_logger.entryPoint(p_procName     => g_pkgName || '.' || l_procName,
60                             p_params       => l_params,
61                             x_returnStatus => x_returnStatus);
62       if(x_returnStatus <> fnd_api.g_ret_sts_success) then
63         raise fnd_api.g_exc_unexpected_error;
64       end if;
65     end if;
66 
67     -- print the no.of discrete requests to log
68 
69     select count(*) into l_requestCount
70         from wip_job_schedule_interface
71        where group_id = p_groupID
72          and process_status = wip_constants.pending
73          and process_phase = wip_constants.ml_validation
74          and load_type <> wip_constants.create_sched;
75 
76     if (l_logLevel <= wip_constants.trace_logging) then
77           wip_logger.log(l_requestCount || ' pending request(s) found for group_id' || p_groupID || ' for discrete processing', l_retStatus);
78     end if;
79 
80     -- lock all the records
81     open c_allrows;
82     if ( c_allrows%isopen ) then
83       close c_allrows;
84     end if;
85 
86     -- assign interface_id and set process_status to running
87     update wip_job_schedule_interface
88        set interface_id = wip_interface_s.nextval,
89            process_status = wip_constants.running
90      where group_id = p_groupID
91        and process_status = wip_constants.pending
92        and process_phase = wip_constants.ml_validation
93        and load_type <> wip_constants.create_sched;
94 
95     if (p_commitFlag <> 0) then
96 	commit;
97     end if;
98     --
99     -- ?? here, we should assign a different group_id for those records with load type being
100     --    create repetitive schedule
101     --
102 
103     -- do the validation for those records
104     wip_validateMLHeader_pvt.validateMLHeader(p_groupID => p_groupID,
105                                               p_validationLevel => p_validationLevel,
106                                               x_returnStatus => x_returnStatus,
107                                               x_errorMsg => x_errorMsg);
108     if ( x_returnStatus <> fnd_api.g_ret_sts_success ) then
109       raise fnd_api.g_exc_unexpected_error;
110     end if;
111 
112     -- process every row which pass validation
113     for wjsi_rec in c_wjsi loop
114       begin
115         savepoint wip_massload_start;
116 
117         wip_massload_pvt.processWJSI(wjsi_rec.rowid, l_retStatus, x_errorMsg);
118         if ( l_retStatus <> fnd_api.g_ret_sts_success ) then
119           raise fnd_api.g_exc_unexpected_error;
120         end if;
121 
122         select count(*)
123           into l_totalNum
124           from wip_job_schedule_interface wjsi,
125                wip_job_dtls_interface wjdi
126          where wjdi.parent_header_id = wjsi.header_id
127            and wjdi.group_id = wjsi.group_id
128            and wjdi.process_phase = wip_constants.ml_validation
129            and wjdi.process_status = wip_constants.pending
130            and wjsi.rowid = wjsi_rec.rowid
131            and wjsi.load_type in (wip_constants.create_job,
132                                   wip_constants.create_ns_job,
133                                   wip_constants.resched_job);
134 
135         if (l_logLevel <= wip_constants.trace_logging) then
136           wip_logger.log('There are ' || l_totalNum || ' detail records....', l_retStatus);
137         end if;
138 
139         if ( l_totalNum > 0 ) then
140           wip_job_details.load_all_details(p_group_id => p_groupID,
141                                            p_parent_header_id => wjsi_rec.header_id,
142                                            p_std_alone => 0,
143                                            x_err_code => l_errorCode,
144                                            x_err_msg => x_errorMsg,
145                                            x_return_status => l_retStatus);
146           if ( l_retStatus <> fnd_api.g_ret_sts_success ) then
147             raise fnd_api.g_exc_unexpected_error;
148           end if;
149         end if;
150 
151         -- only here an we do validation for serialization_start_op because it depends on the routing
152         -- explosion and detail loading
153         processSerStartOp(wjsi_rec.rowid,
154                           wjsi_rec.interface_id,
155                           l_retStatus,
156                           x_errorMsg);
157         if ( l_retStatus <> fnd_api.g_ret_sts_success ) then
158           raise fnd_api.g_exc_unexpected_error;
159         end if;
160 /*6641029 Start- Added code to create requisition*/
161  select wdj.status_type,
162         wjsi.status_type,
163         wdj.wip_entity_id,
164         wdj.organization_id
165         into l_wdj_old_status_type,
166              l_wjsi_new_status_type,
167              l_wdj_wip_entity_id,
168              l_wdj_organization_id
169          from wip_discrete_jobs wdj,
170              wip_job_schedule_interface wjsi
171        where wjsi.rowid = wjsi_rec.rowid
172          and wdj.wip_entity_id = wjsi.wip_entity_id
173          and wdj.organization_id = wjsi.organization_id
174          and wjsi.load_type in (WIP_CONSTANTS.CREATE_JOB,
175                                 WIP_CONSTANTS.CREATE_NS_JOB,
176                                 WIP_CONSTANTS.CREATE_EAM_JOB,
177                                 WIP_CONSTANTS.RESCHED_EAM_JOB,
178                                 WIP_CONSTANTS.RESCHED_JOB) ;
179          if (l_wjsi_new_status_type IN (WIP_CONSTANTS.RELEASED,WIP_CONSTANTS.HOLD))  then
180              if((wip_osp.po_req_created( l_wdj_wip_entity_id,
181                                     null,
182                                     l_wdj_organization_id,
183                                     null,
184                                     WIP_CONSTANTS.DISCRETE
185                                  ) = FALSE) or l_wdj_old_status_type in (WIP_CONSTANTS.UNRELEASED))  then
186                 wip_osp.release_validation(l_wdj_wip_entity_id,
187                                            l_wdj_organization_id,
188                                            NULL) ;
189              end if ;
190         end if ;
191 /*6641029 End*/
192       exception
193       when fnd_api.g_exc_unexpected_error then
194         rollback to wip_massload_start;
195         wip_validateMLHeader_pvt.setInterfaceError(wjsi_rec.rowid,
196                                                    wjsi_rec.interface_id,
197                                                    x_errorMsg,
198                                                    g_wipMLError);
199         if (l_logLevel <= wip_constants.trace_logging) then
200           wip_logger.log('interface ' || wjsi_rec.interface_id || ' failed: ' || x_errorMsg, l_retStatus);
201         end if;
202       end;
203     end loop;
204 
205     update wip_job_schedule_interface
206        set process_status = wip_constants.completed,
207            process_phase = wip_constants.ml_complete
208      where group_id = p_groupID
209        and process_status in (wip_constants.running, wip_constants.warning)
210        and process_phase = wip_constants.ml_validation
211        and load_type <> wip_constants.create_sched;
212 
213     if (p_commitFlag <> 0) then
214 	commit;
215     end if;
216 
217     select count(*) into l_errRecCount
218       from wip_job_schedule_interface
219      where group_id = p_groupID
220        and process_status = wip_constants.error;
221 
222     if(l_errRecCount > 0) then
223       x_returnStatus := fnd_api.g_ret_sts_error;
224     else
225       x_returnStatus := fnd_api.g_ret_sts_success;
226     end if;
227 
228     if (l_logLevel <= wip_constants.trace_logging) then
229       wip_logger.exitPoint(p_procName         => g_pkgName || '.' || l_procName,
230                            p_procReturnStatus => x_returnStatus,
231                            p_msg              => 'success',
232                            x_returnStatus     => l_retStatus);
233     end if;
234   exception
235   when wip_constants.records_locked then
236     x_returnStatus := fnd_api.g_ret_sts_unexp_error;
237     if (l_logLevel <= wip_constants.trace_logging) then
238       wip_logger.exitPoint(p_procName => g_pkgName || '.' || l_procName,
239                            p_procReturnStatus => x_returnStatus,
240                            p_msg => 'records locked',
241                            x_returnStatus => l_retStatus);
242     end if;
243     fnd_message.set_name('WIP', 'WIP_LOCKED_ROW_ALREADY_LOCKED');
244     x_errorMsg := fnd_message.get;
245   when fnd_api.g_exc_unexpected_error then
246     x_returnStatus := fnd_api.g_ret_sts_unexp_error;
247     if (l_logLevel <= wip_constants.trace_logging) then
248       wip_logger.exitPoint(p_procName => g_pkgName || '.' || l_procName,
249                            p_procReturnStatus => x_returnStatus,
250                            p_msg => x_errorMsg,
251                            x_returnStatus => l_retStatus);
252     end if;
253   end massLoadJobs;
254 
255 
256   -- this API is used to create one job for the given interface id. Please note that there should be no
257   -- other records under the same group id as the given interface id. This API will fail that case.
258   -- also, the load type for this record must be create standard or non-std job.
259   procedure createOneJob(p_interfaceID in number,
260                          p_validationLevel in number,
261                          x_wipEntityID out nocopy number,
262                          x_returnStatus out nocopy varchar2,
263                          x_errorMsg     out nocopy varchar2) is
264     l_params wip_logger.param_tbl_t;
265     l_procName varchar2(30) := 'createOneJob';
266     l_logLevel number := to_number(fnd_log.g_current_runtime_level);
267     l_retStatus varchar2(1);
268     l_totalNum number;
269     l_groupID number;
270     l_headerID number;
271     l_rowid rowid;
272     l_errorCode varchar2(240);
273 
274     cursor c_allrows is
275       select 1
276         from wip_job_schedule_interface
277        where interface_id = p_interfaceID
278       for update nowait;
279   begin
280     x_returnStatus := fnd_api.g_ret_sts_success;
281     if (l_logLevel <= wip_constants.trace_logging) then
282       l_params(1).paramName := 'p_interfaceID';
283       l_params(1).paramValue := p_interfaceID;
284       l_params(2).paramName := 'p_validationLevel';
285       l_params(2).paramValue := p_validationLevel;
286       wip_logger.entryPoint(p_procName     => g_pkgName || '.' || l_procName,
287                             p_params       => l_params,
288                             x_returnStatus => x_returnStatus);
289       if(x_returnStatus <> fnd_api.g_ret_sts_success) then
290         raise fnd_api.g_exc_unexpected_error;
291       end if;
292     end if;
293 
294     select rowid, group_id, header_id
295       into l_rowid, l_groupID, l_headerID
296       from wip_job_schedule_interface
297      where interface_id = p_interfaceID;
298 
299     select count(*)
300       into l_totalNum
301       from wip_job_schedule_interface
302      where interface_id = p_interfaceID
303        and process_status = wip_constants.pending
304        and process_phase = wip_constants.ml_validation
305        and load_type in (wip_constants.create_job, wip_constants.create_ns_job);
306 
307     if ( l_totalNum <> 1 ) then
308       fnd_message.set_name('WIP', 'WIP_WJSI_ONE_ROW');
309       x_errorMsg := fnd_message.get;
310       raise fnd_api.g_exc_unexpected_error;
311     end if;
312 
313     select count(*)
314       into l_totalNum
315       from wip_job_schedule_interface wjsi
316      where wjsi.group_id = l_groupID;
317 
318     if ( l_totalNum <> 1 ) then
319       fnd_message.set_name('WIP', 'WIP_WJSI_ONE_ROW');
320       x_errorMsg := fnd_message.get;
321       raise fnd_api.g_exc_unexpected_error;
322     end if;
323 
324     -- lock all the records
325     open c_allrows;
326     if ( c_allrows%isopen ) then
327       close c_allrows;
328     end if;
329 
330     update wip_job_schedule_interface
331        set process_status = wip_constants.running
332      where interface_id = p_interfaceID;
333 
334     -- do the validation for those records
335     wip_validateMLHeader_pvt.validateMLHeader(p_groupID => l_groupID,
336                                               p_validationLevel => p_validationLevel,
337                                               x_returnStatus => x_returnStatus,
338                                               x_errorMsg => x_errorMsg);
339     if ( x_returnStatus <> fnd_api.g_ret_sts_success ) then
340       raise fnd_api.g_exc_unexpected_error;
341     end if;
342 
343     select count(*)
344       into l_totalNum
345       from wip_job_schedule_interface
346      where interface_id = p_interfaceID
347        and process_status in (wip_constants.running, wip_constants.warning);
348 
349     if ( l_totalNum <> 1 ) then
350       fnd_message.set_name('WIP', 'WIP_WJSI_VAL_FAILED');
351       x_errorMsg := fnd_message.get;
352       raise fnd_api.g_exc_unexpected_error;
353     end if;
354 
355     wip_massload_pvt.processWJSI(l_rowid, x_returnStatus, x_errorMsg);
356     if ( x_returnStatus <> fnd_api.g_ret_sts_success ) then
357       raise fnd_api.g_exc_unexpected_error;
358     end if;
359 
360     select count(*)
361       into l_totalNum
362       from wip_job_schedule_interface wjsi,
363            wip_job_dtls_interface wjdi
364      where wjdi.parent_header_id = wjsi.header_id
365        and wjdi.group_id = wjsi.group_id
366        and wjdi.process_phase = wip_constants.ml_validation
367        and wjdi.process_status = wip_constants.pending
368        and wjsi.rowid = l_rowid;
369 
370     if (l_logLevel <= wip_constants.trace_logging) then
371       wip_logger.log('There are ' || l_totalNum || ' detail records....', l_retStatus);
372     end if;
373 
374     if ( l_totalNum > 0 ) then
375       wip_job_details.load_all_details(p_group_id => l_groupID,
376                                        p_parent_header_id => l_headerID,
377                                        p_std_alone => 0,
378                                        x_err_code => l_errorCode,
379                                        x_err_msg => x_errorMsg,
380                                        x_return_status => l_retStatus);
381       if ( l_retStatus <> fnd_api.g_ret_sts_success ) then
382         raise fnd_api.g_exc_unexpected_error;
383       end if;
384     end if;
385 
386     -- only here an we do validation for serialization_start_op because it depends on the routing
387     -- explosion and detail loading
388     processSerStartOp(l_rowid,
389                       p_interfaceID,
390                       l_retStatus,
391                       x_errorMsg);
392     if ( l_retStatus <> fnd_api.g_ret_sts_success ) then
393       raise fnd_api.g_exc_unexpected_error;
394     end if;
395 
396     select wip_entity_id
397       into x_wipEntityID
398       from wip_job_schedule_interface
399      where rowid = l_rowid;
400 
401     update wip_job_schedule_interface
402        set process_status = wip_constants.completed
403      where rowid = l_rowid;
404 
405     if (l_logLevel <= wip_constants.trace_logging) then
406       wip_logger.exitPoint(p_procName         => g_pkgName || '.' || l_procName,
407                            p_procReturnStatus => x_returnStatus,
408                            p_msg              => 'success',
409                            x_returnStatus     => l_retStatus);
410     end if;
411   exception
412   when wip_constants.records_locked then
413     x_returnStatus := fnd_api.g_ret_sts_unexp_error;
414     fnd_message.set_name('WIP', 'WIP_LOCKED_ROW_ALREADY_LOCKED');
415     x_errorMsg := fnd_message.get;
416     wip_validateMLHeader_pvt.setInterfaceError(l_rowid,
417                                                p_interfaceID,
418                                                x_errorMsg,
419                                                g_wipMLError);
420     if (l_logLevel <= wip_constants.trace_logging) then
421       wip_logger.exitPoint(p_procName => g_pkgName || '.' || l_procName,
422                            p_procReturnStatus => x_returnStatus,
423                            p_msg => 'records locked',
424                            x_returnStatus => l_retStatus);
425     end if;
426   when fnd_api.g_exc_unexpected_error then
427     x_returnStatus := fnd_api.g_ret_sts_unexp_error;
428     wip_validateMLHeader_pvt.setInterfaceError(l_rowid,
429                                                p_interfaceID,
430                                                x_errorMsg,
431                                                g_wipMLError);
432     if (l_logLevel <= wip_constants.trace_logging) then
433       wip_logger.exitPoint(p_procName => g_pkgName || '.' || l_procName,
434                            p_procReturnStatus => x_returnStatus,
435                            p_msg => x_errorMsg,
436                            x_returnStatus => l_retStatus);
437     end if;
438   end createOneJob;
439 
440 
441   procedure processSerStartOp(p_rowid in rowid,
442                               p_interfaceID in number,
443                               x_returnStatus out nocopy varchar2,
444                               x_errorMsg     out nocopy varchar2) is
445     l_msg varchar2(80);
446     l_dummy number;
447 
448     l_wjsiSerOp number;
449     l_wdjSerOp number;
450     l_wipEntityID number;
451     l_loadType number;
452     l_primaryItemID number;
453     l_orgID number;
454 
455     l_curOpSeq number;
456     l_rtgExists boolean := false;
457     l_opFound boolean := false;
458 
459     cursor c_ops(v_wipEntityID number) is
460       select operation_seq_num
461         from wip_operations
462        where wip_entity_id = v_wipEntityID;
463 
464   begin
465     x_returnStatus := fnd_api.g_ret_sts_success;
466     l_msg := 'WIP_ML_SERIAL_START_OP';
467 
468     select wip_entity_id,
469            serialization_start_op,
470            load_type,
471            primary_item_id,
472            organization_id
473       into l_wipEntityID,
474            l_wjsiSerOp,
475            l_loadType,
476            l_primaryItemID,
477            l_orgID
478       from wip_job_schedule_interface
479      where rowid = p_rowid;
480 
481     if ( l_wjsiSerOp is null and l_loadType = wip_constants.resched_job ) then
482     -- due to re-exploding, we may need to clear out the serialization start op
483       update wip_discrete_jobs wdj
484          set serialization_start_op = null
485        where wip_entity_id = l_wipEntityID
486          and serialization_start_op <> 1
487          and not exists(select 1
488                           from wip_operations wo
489                          where wo.wip_entity_id = wdj.wip_entity_id
490                            and wo.operation_seq_num = wdj.serialization_start_op);
491       return;
492     end if;
493 
494     -- when the flow comes here, regardless reschedule or job creation, we already updated wdj
495     -- with the right value for serialization_start_op from the interface table or the defaulting
496     -- logic. the column value might be different between wjsi and wdj because we do update for wdj if
497     -- wjsi is null for job creation. Otherwise, the value should be the same.
498     select serialization_start_op
499       into l_wdjSerOp
500       from wip_discrete_jobs
501      where wip_entity_id = l_wipEntityID;
502 
503     if ( l_wdjSerOp is null ) then
504       return;
505     end if;
506 
507     --job must have an assembly, and the assembly must be serial controlled (predefined).
508     select 1
509       into l_dummy
510       from wip_discrete_jobs wdj,
511            mtl_system_items msi
512      where wdj.primary_item_id = msi.inventory_item_id
513        and wdj.organization_id = msi.organization_id
514        and wdj.wip_entity_id = l_wipEntityID
515        and msi.serial_number_control_code = wip_constants.full_sn;
516 
517     open c_ops(l_wipEntityID);
518     loop
519       fetch c_ops into l_curOpSeq;
520       exit when c_ops%NOTFOUND;
521       l_rtgExists := true;
522       if(l_curOpSeq = l_wdjSerOp) then
523         l_opFound := true;
524         exit;
525       end if;
526     end loop;
527     close c_ops;
528 
529     --The routing exists, but an invalid op seq was provided
530     if ( l_rtgExists and not l_opFound ) then
531       raise fnd_api.g_exc_unexpected_error;
532     end if;
533 
534     --If no routing exsts, the serialization op must be 1.
535     if ( not l_rtgExists and l_wdjSerOp <> 1 ) then
536       raise fnd_api.g_exc_unexpected_error;
537     end if;
538 
539     --job must be unreleased to change the serialization op on a reschedule request.
540     if ( l_loadType = wip_constants.resched_job and l_wjsiSerOp is not null ) then
541       select 1
542         into l_dummy
543         from wip_discrete_jobs
544       where wip_entity_id = l_wipEntityID
545         and status_type = wip_constants.unreleased;
546     end if;
547 
548     l_msg := 'WIP_ML_SER_DEF_FAILURE';
549     wip_job_dtls_substitutions.default_serial_associations(p_rowid => p_rowid,
550                                                            p_wip_entity_id => l_wipEntityID,
551                                                            p_organization_id => l_orgID,
552                                                            x_err_msg => x_errorMsg,
553                                                            x_return_status => x_returnStatus);
554     if ( x_returnStatus <> fnd_api.g_ret_sts_success ) then
555       raise fnd_api.g_exc_unexpected_error;
556     end if;
557   exception
558   when others then
559     x_returnStatus := fnd_api.g_ret_sts_unexp_error;
560     fnd_message.set_name('WIP', l_msg);
561     if ( l_msg = 'WIP_ML_SER_DEF_FAILURE' ) then
562       fnd_message.set_token('MESSAGE', x_errorMsg);
563     end if;
564     x_errorMsg := fnd_message.get;
565   end processSerStartOp;
566 
567 end wip_massload_pub;