[Home] [Help]
PACKAGE BODY: APPS.MRP_RESCHEDULE_PO
Source
1 PACKAGE BODY mrp_reschedule_po AS
2 /*$Header: MRPRSPOB.pls 120.3.12010000.2 2008/12/12 15:55:56 eychen ship $ */
3
4 Type CharTab is TABLE of varchar2(2);
5 Type LongCharTab is TABLE of varchar2(240);
6 Type NumTab IS TABLE of number;
7 Type DateTab IS TABLE of DATE;
8
9 PROCEDURE reschedule_po_program
10 (
11 errbuf OUT NOCOPY VARCHAR2
12 ,retcode OUT NOCOPY NUMBER,
13 p_old_need_by_date IN DATE,
14 p_new_need_by_date IN DATE,
15 p_po_header_id IN NUMBER,
16 p_po_line_id IN NUMBER,
17 p_po_number IN VARCHAR2,
18 p_qty IN NUMBER
19 ) IS
20
21 p_instance_id number;
22 p_dblink varchar2(128);
23 sql_stmt varchar2(2000);
24 p_result boolean;
25
26 v_old_need_by_date dateTab;
27 v_new_need_by_date dateTab;
28 v_po_header_id numTab;
29 v_po_line_id numTab;
30 --v_po_line_id2 numTab;
31 v_po_line_location_id numTab;
32 v_po_number LongCharTab;
33 v_po_location_id number;
34 v_action numTab;
35
36
37 TYPE type_cursor IS REF CURSOR;
38 po_cursor type_cursor;
39 p_batch_id number;
40
41 first_left_pare_pos number;
42 first_right_pare_pos number;
43 second_left_pare_pos number;
44 second_right_pare_pos number;
45 third_left_pare_pos number;
46 third_right_pare_pos number;
47
48 l_doc_type VARCHAR2(30);
49 l_doc_subtype VARCHAR2(30);
50 p_allow_release number;
51 p_instance_code varchar2(10);
52 v_release_num number;
53
54 cursor check_rel_flag is
55 select ALLOW_RELEASE_FLAG, instance_code
56 from MRP_AP_APPS_INSTANCES_ALL
57 where instance_id = p_instance_id
58 and nvl(A2M_DBLINK, '-1') = p_dblink;
59
60 X_need_by_dates_old po_tbl_date := po_tbl_date();
61 X_need_by_dates po_tbl_date := po_tbl_date();
62 X_po_line_ids po_tbl_number := po_tbl_number();
63 X_shipment_nums po_tbl_number := po_tbl_number();
64 X_estimated_pickup_dates po_tbl_date := po_tbl_date();
65 X_ship_methods po_tbl_varchar30 := po_tbl_varchar30();
66 a number :=0;
67
68 last_po_number varchar2(250);
69 last_po_header_id number;
70
71 BEGIN
72
73 FND_FILE.PUT_LINE(FND_FILE.LOG,'starting ...');
74 p_batch_id := p_po_header_id;
75 p_instance_id := p_po_line_id;
76 p_dblink := p_po_number;
77
78 retcode :=0;
79 p_allow_release :=0;
80
81 OPEN check_rel_flag;
82 FETCH check_rel_flag INTO p_allow_release, p_instance_code;
83 CLOSE check_rel_flag;
84
85 if p_dblink = '-1' then
86 p_dblink := ' ';
87 else
88 p_dblink := '@'||p_dblink;
89 end if;
90
91 FND_FILE.PUT_LINE(FND_FILE.LOG, 'instance_code:'||p_instance_code||' dblink: '|| p_po_number ||', instance_id='||p_instance_id||', batch_id='||p_batch_id||',allow_release_flag ='||p_allow_release);
92
93
94 if p_allow_release = 1 THEN
95 mo_global.INIT('PO');
96 sql_stmt:=
97 ' select old_need_by_date,'||
98 ' new_need_by_date,'||
99 ' po_header_id,'||
100 ' po_line_id,'||
101 ' po_number,'||
102 ' action'||
103 ' from msc_purchase_order_interface'||p_dblink||
104 ' where sr_instance_id = '||p_instance_id||
105 ' and batch_id ='||p_batch_id ||
106 ' order by action, po_number ';
107
108 OPEN po_cursor FOR sql_stmt;
109 FETCH po_cursor BULK COLLECT INTO v_old_need_by_date,
110 v_new_need_by_date,
111 v_po_header_id,
112 v_po_line_id,
113 v_po_number,
114 v_action;
115 CLOSE po_cursor;
116
117 FOR i in 1..nvl(v_po_line_id.LAST, 0) LOOP
118
119 /* in R12, order number(release number)(line number)(shipment number),
120 but release number could be empty,
121 in 11.5.10 and prior,
122 order number(release number)(shipment number) -- blanket PO or
123 order number(shipment number) -- standard PO */
124
125 first_left_pare_pos := instr(v_po_number(i), '(');
126 second_left_pare_pos := instr(v_po_number(i), '(',1,2);
127 third_left_pare_pos := instr(v_po_number(i), '(',1,3);
128 if third_left_pare_pos > 0 then -- in R12
129 first_right_pare_pos := instr(v_po_number(i), ')');
130 third_right_pare_pos := instr(v_po_number(i), ')', 1,3);
131 v_po_location_id := substr(v_po_number(i),
132 third_left_pare_pos+1,third_right_pare_pos -
133 third_left_pare_pos -1);
134
135 begin
136 v_release_num := substr(v_po_number(i),
137 first_left_pare_pos+1,first_right_pare_pos -
138 first_left_pare_pos -1);
139 exception when others then
140 v_release_num :=null;
141 end;
142
143 if v_release_num is null then
144 l_doc_type := 'PO';
145 l_doc_subtype := 'STANDARD';
146 v_po_number(i) := substr(v_po_number(i), 1,first_left_pare_pos -1);
147 else
148 l_doc_type := 'RELEASE';
149 l_doc_subtype := 'BLANKET';
150 v_po_number(i) := substr(v_po_number(i),1,second_left_pare_pos -1);
151 end if;
152 else -- in 11.5.10 or prior
153 -- -------------------------------------------------
154 -- Bug#4013684 - 16-dec-2004.
155 -- l_doc_type and l_doc_subtype will be derived here
156 -- and will be passed to 'Cancel PO' api.
157 -- -------------------------------------------------
158 if first_left_pare_pos > 0 then -- should not be 0, just in case
159 first_right_pare_pos := instr(v_po_number(i), ')');
160 if second_left_pare_pos = 0 then -- standard po
161 v_po_location_id := substr(v_po_number(i),
162 first_left_pare_pos+1,first_right_pare_pos -
163 first_left_pare_pos -1);
164 v_po_number(i) := substr(v_po_number(i), 1,first_left_pare_pos -1);
165 l_doc_type := 'PO';
166 l_doc_subtype := 'STANDARD';
167 else -- blanket po
168 second_right_pare_pos := instr(v_po_number(i), ')', 1,2);
169 v_po_location_id := substr(v_po_number(i),
170 second_left_pare_pos+1,second_right_pare_pos -
171 second_left_pare_pos -1);
172 v_po_number(i) := substr(v_po_number(i),1,second_left_pare_pos -1);
173 l_doc_type := 'RELEASE';
174 l_doc_subtype := 'BLANKET';
175 end if;
176 end if;
177 end if; -- if third_left_pare_pos > 0
178
179 -- cancel the PO if action = 2 else reschedule it.
180 if v_action(i) = 2 then
181 mrp_cancel_po.cancel_po_program(v_po_header_id(i), v_po_line_id(i),
182 v_po_number(i), v_po_location_id,
183 l_doc_type , l_doc_subtype);
184 else
185 --5137694, for standard po, group by po_header_id,
186 -- for blanket po, group by po_header_id and shipment number
187
188 if i <> nvl(v_po_line_id.FIRST, 0) and
189 v_po_number(i) <> v_po_number(i-1) then
190 --call PO api
191 p_result := reschedule_po(X_need_by_dates_old,
192 X_need_by_dates,
193 v_po_header_id(i-1),
194 X_po_line_ids,
195 v_po_number(i-1),
196 X_shipment_nums,
197 X_estimated_pickup_dates,
198 X_ship_methods);
199 if not(p_result) then
200 retcode :=2;
201 end if;
202 -- reset po table
203 a := 0;
204 x_need_by_dates_old.delete;
205 X_need_by_dates.delete;
206 X_po_line_ids.delete;
207 X_shipment_nums.delete;
208 x_estimated_pickup_dates.delete;
209 x_ship_methods.delete;
210 end if; -- if i <> nvl(v_po_line_id.FIRST, 0) and
211 -- init po tables
212 a := a+1;
213 x_need_by_dates_old.extend;
214 x_need_by_dates_old(a) := v_old_need_by_date(i);
215 X_need_by_dates.extend;
216 X_need_by_dates(a) := v_new_need_by_date(i);
217 X_po_line_ids.extend;
218 X_po_line_ids(a) := v_po_line_id(i);
219 X_shipment_nums.extend;
220 X_shipment_nums(a) := v_po_location_id;
221 x_estimated_pickup_dates.extend;
222 x_estimated_pickup_dates(a) := null;
223 x_ship_methods.extend;
224 x_ship_methods(a) := null;
225 last_po_header_id := v_po_header_id(i);
226 last_po_number := v_po_number(i);
227 end if; -- if v_action = 2 then
228
229 FND_FILE.PUT_LINE(FND_FILE.LOG,' ');
230 END LOOP; -- FOR i in 1..nvl(v_po_line_id.LAST, 0) LOOP
231
232 if a <> 0 then
233 p_result := reschedule_po(X_need_by_dates_old,
234 X_need_by_dates,
235 last_po_header_id,
236 X_po_line_ids,
237 last_po_number,
238 X_shipment_nums,
239 X_estimated_pickup_dates,
240 X_ship_methods);
241 if not(p_result) then
242 retcode :=2;
243 end if;
244 end if; -- if a <> 0
245
246 else -- not allow release
247 FND_FILE.PUT_LINE(FND_FILE.LOG, 'instance '||p_instance_code||' does not allow release ');
248 end if; -- if p_allow_release = 1 then
249 sql_stmt:= ' delete from msc_purchase_order_interface'||p_dblink||
250 ' where sr_instance_id = :p_instance_id '||
251 ' and batch_id = :p_batch_id ';
252
253 EXECUTE IMMEDIATE sql_stmt using p_instance_id, p_batch_id;
254
255 commit;
256
257 exception
258 when others then
259 retcode :=2;
260 raise;
261 END reschedule_po_program;
262
263 FUNCTION reschedule_po( X_old_need_by_dates po_tbl_date,
264 X_new_need_by_dates po_tbl_date,
265 X_po_header_id number,
266 X_po_line_ids po_tbl_number,
267 X_po_number varchar2,
268 X_shipment_nums po_tbl_number,
269 X_estimated_pickup_dates po_tbl_date,
270 X_ship_methods po_tbl_varchar30)
271 return boolean IS
272
273 p_result boolean;
274 v_promised_date dateTab;
275 v_need_by_date dateTab;
276 v_rec NumTab;
277 v_date_changed boolean;
278 v_date date;
279 p_show_msg varchar2(3) := nvl(FND_PROFILE.Value('MRP_DEBUG'),'N');
280
281 cursor po_cur(v_line_id number, v_header_id number, v_ship_num number) is
282 select nvl(poll.promised_date,poll.need_by_date),1
283 from po_line_locations_all poll
284 where poll.po_line_id = v_line_id
285 and poll.po_header_id = v_header_id
286 and poll.shipment_num = nvl(v_ship_num,poll.shipment_num);
287 v_old_need_by_dates po_tbl_date := po_tbl_date();
288
289 CURSOR cur_org(p_po_header_id IN number) IS
290 SELECT org_id
291 FROM po_headers_all
292 WHERE po_header_id = p_po_header_id;
293
294 l_document_org_id NUMBER;
295 l_access_mode VARCHAR2(1);
296 l_current_org_id NUMBER;
297
298 PROCEDURE show_po_details IS
299 BEGIN
300 for i in 1..nvl(X_po_line_ids.last, 0) loop
301 FND_FILE.PUT_LINE(FND_FILE.LOG,'old date in planner workbench: '||
302 to_char(x_old_need_by_dates(i),'MM/DD/RR HH24:MI:SS'));
303 FND_FILE.PUT_LINE(FND_FILE.LOG,'new date: '||
304 to_char(x_new_need_by_dates(i),'MM/DD/RR HH24:MI:SS'));
305 FND_FILE.PUT_LINE(FND_FILE.LOG,'header: '||x_po_header_id);
306 FND_FILE.PUT_LINE(FND_FILE.LOG,'line: '||x_po_line_ids(i));
307 FND_FILE.PUT_LINE(FND_FILE.LOG,'po number: '||x_po_number);
308 FND_FILE.PUT_LINE(FND_FILE.LOG,'shipment no: '||X_shipment_nums(i));
309 end loop;
310 END show_po_details;
311
312 BEGIN
313
314 -- p_show_msg := 'Y';
315
316 begin
317
318 OPEN cur_org(x_po_header_id);
319 FETCH cur_org INTO l_document_org_id;
320 CLOSE cur_org;
321
322 l_access_mode := mo_global.Get_access_mode();
323 l_current_org_id := mo_global.get_current_org_id();
324
325 mo_global.set_policy_context('S',l_document_org_id);
326
327
328 p_result :=po_reschedule_pkg.reschedule
329 (X_old_need_by_dates,
330 X_new_need_by_dates,
331 X_po_header_id,
332 X_po_line_ids,
333 X_po_number,
334 X_shipment_nums,
335 X_estimated_pickup_dates,
336 X_ship_methods);
337 Mo_Global.Set_Policy_Context (p_access_mode => l_access_mode,
338 p_org_id => l_current_org_id);
339 exception when others then
340 FND_FILE.PUT_LINE(FND_FILE.LOG,' error while calling po_reschedule_pkg.reschedule '||sqlerrm);
341 Mo_Global.Set_Policy_Context (p_access_mode => l_access_mode,
342 p_org_id => l_current_org_id);
343 show_po_details;
344 end;
345
346 if p_result is null then
347 FND_FILE.PUT_LINE(FND_FILE.LOG, 'the call to po_reschedule_pkg.reschedule return null value');
348 end if;
349
350 p_result := nvl(p_result, false);
351
352 if not(p_result) then -- p_result is false
353 -- 5030537, it might fail because our PO does not carry seconds,
354 v_date_changed := false;
355 for i in 1..nvl(X_po_line_ids.last, 0) loop
356 if v_rec is not null then
357 v_promised_date.delete;
358 v_rec.delete;
359 end if;
360 v_old_need_by_dates.extend;
361 v_old_need_by_dates(i) := x_old_need_by_dates(i);
362 OPEN po_cur(x_po_line_ids(i), X_po_header_id,X_shipment_nums(i));
363 FETCH po_cur BULK COLLECT INTO
364 v_promised_date, v_rec;
365 CLOSE po_cur;
366
367 For a in 1..nvl(v_rec.last,0) LOOP
368 v_date := v_promised_date(a);
369 if to_date(to_char(x_old_need_by_dates(i), 'MM/DD/RRRR HH24:MI'),
370 'MM/DD/RRRR HH24:MI') =
371 to_date(to_char(v_date, 'MM/DD/RRRR HH24:MI'),
372 'MM/DD/RRRR HH24:MI') then
373 if x_old_need_by_dates(i) <> v_date then
374 FND_FILE.PUT_LINE(FND_FILE.LOG,' call reschedule again by modifying old_need_by_date from '||to_char(x_old_need_by_dates(i), 'MM/DD/RRRR HH24:MI:SS')||
375 ' to '||to_char(v_date, 'MM/DD/RRRR HH24:MI:SS'));
376 v_old_need_by_dates(i) := v_date;
377 v_date_changed := true;
378 end if;
379 exit;
380 end if;
381 END LOOP; -- For a in 1..nvl(v_rec.last,0) LOOP
382 end loop; -- for i in 1..nvl(X_po_line_ids.last, 0) loop
383
384 if v_date_changed then
385 -- call reschedule again with updated old_need_by_date
386
387 p_result :=po_reschedule_pkg.reschedule
388 (v_old_need_by_dates,
389 X_new_need_by_dates,
390 X_po_header_id,
391 X_po_line_ids,
392 X_po_number,
393 X_shipment_nums,
394 X_estimated_pickup_dates,
395 X_ship_methods);
396 end if; -- if v_date_changed then
397 end if; -- if not(p_result) then
398
399 p_result := nvl(p_result, false);
400
401 if p_result then
402 if p_show_msg = 'Y' then
403 FND_FILE.PUT_LINE(FND_FILE.LOG,'reschedule succeeds');
404 end if;
405 else
406 FND_FILE.PUT_LINE(FND_FILE.LOG,'reschedule fails');
407 end if;
408
409 if (p_result and p_show_msg = 'Y') or
410 not(p_result) then
411 show_po_details;
412 end if;
413
414 return p_result;
415 exception when others then
416 FND_FILE.PUT_LINE(FND_FILE.LOG,'error in reschedule_po, error is: '||sqlerrm);
417 show_po_details;
418 return false;
419 END reschedule_po;
420
421 END mrp_reschedule_po;