[Home] [Help]
PACKAGE BODY: APPS.MSC_ANALYSIS_BUDGET
Source
1 PACKAGE BODY MSC_ANALYSIS_BUDGET AS
2 /* $Header: MSCAIBB.pls 120.0 2005/05/25 18:45:05 appldev noship $ */
3 --
4 --
5 --
6 RECORD_BUDGET CONSTANT NUMBER := 0;
7 RECORD_SERVICE_LEVEL CONSTANT NUMBER := 1;
8 RECORD_TARGET_SERVICE_LEVEL CONSTANT NUMBER := 2;
9
10 UNDEFINED_CUSTOMER_CODE CONSTANT VARCHAR2(30) := '_MISC'; -- Used in Java
11 UNDEFINED_CUSTOMER_ID CONSTANT NUMBER := -1;
12
13 CALENDAR_TYPE_MFG CONSTANT NUMBER := 1;
14 CALENDAR_TYPE_BIS CONSTANT NUMBER := 0;
15
16 PLAN_BUCKET_WEEK CONSTANT NUMBER := 2;
17 PLAN_BUCKET_PERIOD CONSTANT NUMBER := 3;
18
19 DETAIL_LEVEL_WEEK CONSTANT NUMBER := 1;
20 DETAIL_LEVEL_PERIOD CONSTANT NUMBER := 0;
21
22 BUDGET_CONSTRAINED_OFF CONSTANT NUMBER := 2;
23 BUDGET_CONSTRAINED_ON CONSTANT NUMBER := 1;
24
25 do_debug BOOLEAN := FALSE;
26
27 TYPE Bucket IS RECORD
28 (
29 -- item key data
30 plan_id NUMBER := 0,
31 instance_id NUMBER := 0,
32 org_id NUMBER := 0,
33 org_name VARCHAR2(255) := NULL,
34 sr_category_id NUMBER := 0,
35 category_name VARCHAR2(255) := NULL,
36 plan_name VARCHAR2(255) := NULL,
37 -- bucket key data
38 bkt_start_date DATE := NULL,
39 bkt_end_date DATE := NULL,
40 period_nr NUMBER := 0,
41 week_nr NUMBER := 0,
42 period_start_date DATE := NULL,
43 bucket_type NUMBER := 0,
44 detail_level NUMBER := NULL,
45 -- budget measures
46 achieved_budget_usd NUMBER := 0,
47 -- service level measures
48 delivered_quantity NUMBER := 0,
49 required_quantity NUMBER := 0,
50 target_sl NUMBER := 0,
51 num_target_sl NUMBER := 0,
52 -- service level or safety stock record
53 record_type NUMBER := NULL
54 );
55
56 TYPE Schedule IS TABLE OF Bucket INDEX BY BINARY_INTEGER;
57 TYPE PlanList IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
58
59 FUNCTION get_customer_target_sl(customer_id NUMBER)
60 RETURN NUMBER
61 IS
62 l_target_service_level NUMBER;
63 BEGIN
64 SELECT service_level
65 INTO l_target_service_level
66 FROM msc_trading_partners
67 WHERE partner_type = 2
68 AND partner_id = customer_id;
69 RETURN l_target_service_level;
70 EXCEPTION WHEN OTHERS THEN RETURN NULL;
71 END;
72
73 FUNCTION get_cat_set_id(arg_plan_id number) RETURN NUMBER is
74 l_cat_set_id number;
75 l_def_pref_id number;
76 l_plan_type number;
77 cursor plan_type_c(v_plan_id number) is
78 select curr_plan_type
79 from msc_plans
80 where plan_id = v_plan_id;
81 BEGIN
82 open plan_type_c(arg_plan_id);
83 fetch plan_type_c into l_plan_type;
84 close plan_type_c;
85
86 l_def_pref_id := msc_get_name.get_default_pref_id(fnd_global.user_id);
87 l_cat_set_id:= msc_get_name.GET_preference('CATEGORY_SET_ID',l_def_pref_id, l_plan_type);
88 return l_cat_set_id;
89 END get_cat_set_id;
90
91
92 PROCEDURE schedule_create_bis(mainschedule IN OUT NOCOPY Schedule, p_plan_id NUMBER, calendar_type IN NUMBER)
93 IS
94 CURSOR c1(p_plan_id NUMBER) IS
95 SELECT pd.detail_date, mbp.START_DATE, mbp.end_date
96 FROM
97 (SELECT DISTINCT mbid.detail_date
98 FROM msc_bis_inv_detail mbid
99 WHERE mbid.plan_id = p_Plan_id
100 AND (mbid.period_type IS NULL OR mbid.period_type = 0)) pd,
101 msc_plans mp, msc_bis_periods mbp
102 WHERE mp.plan_id = p_plan_id
103 AND mp.sr_instance_id = mbp.sr_instance_id
104 AND mp.organization_id = mbp.organization_id
105 AND mbp.period_set_name = 'Accounting'
106 AND pd.detail_date = mbp.START_DATE
107 ORDER BY pd.detail_date;
108
109 c1Rec c1%ROWTYPE;
110
111 currentBucket Bucket;
112 current_period_nr NUMBER := 1;
113
114 BEGIN
115
116 OPEN c1(p_plan_id);
117 LOOP
118 FETCH c1 INTO c1Rec;
119 EXIT WHEN c1%NOTFOUND;
120
121 -- These three are only used for MFG calendar data
122 currentBucket.week_nr := NULL;
123 currentBucket.period_start_date := c1Rec.START_DATE;
124 currentBucket.bucket_type := PLAN_BUCKET_PERIOD;
125 -- These are for BIS calendar data
126 currentBucket.bkt_start_date := c1Rec.start_date;
127 currentBucket.bkt_end_date := c1Rec.end_date;
128
129 currentBucket.period_nr := current_period_nr;
130
131 mainschedule(current_period_nr) := currentBucket;
132 current_period_nr := current_period_nr + 1;
133 END LOOP;
134 CLOSE c1;
135
136 END;
137
138 PROCEDURE schedule_create_mfg(mainschedule IN OUT NOCOPY Schedule, p_plan_id NUMBER, calendar_type IN NUMBER)
139 IS
140 CURSOR c1(p_plan_id NUMBER) IS
141 SELECT mp.plan_id, mp.compile_designator, mtp.calendar_code, mpb.bkt_start_date, mpb.bkt_end_date,
142 mpsd.period_start_date, mpb.bucket_type
143 FROM msc_plans mp, msc_trading_partners mtp, msc_plan_buckets mpb, msc_period_start_dates mpsd
144 WHERE mp.plan_id = p_plan_id
145 AND mtp.sr_tp_id = mp.organization_id
146 AND mtp.sr_instance_id = mp.sr_instance_id
147 AND mtp.partner_type = 3
148 AND mp.plan_id = mpb.plan_id
149 AND mp.sr_instance_id = mpb.sr_instance_id
150 AND mp.organization_id = mpb.organization_id
151 AND mtp.sr_Instance_id = mpsd.sr_instance_id
152 AND mtp.calendar_code = mpsd.calendar_code
153 AND mpb.bucket_type in (2,3)
154 AND mpb.sr_instance_id = mpsd.sr_instance_id
155 AND mpsd.exception_set_id = mtp.calendar_exception_set_id
156 AND mpsd.calendar_code = mtp.calendar_code
157 AND (mpb.bkt_start_date >= mpsd.period_start_date AND mpb.bkt_start_date < mpsd.next_date)
158 ORDER BY mpb.bkt_start_date;
159
160 c1Rec c1%ROWTYPE;
161
162 currentBucket Bucket;
163 currentBucketNr NUMBER := 1;
164 current_period_nr NUMBER := 1;
165 previous_period_start_date DATE := NULL;
166 current_week_nr NUMBER := 1;
167
168 BEGIN
169
170 OPEN c1(p_plan_id);
171 LOOP
172 FETCH c1 INTO c1Rec;
173 EXIT WHEN c1%NOTFOUND;
174
175 -- These three are only used for MFG calendar data
176 IF c1Rec.bucket_type = PLAN_BUCKET_WEEK THEN
177 currentBucket.week_nr := current_week_nr;
178 current_week_nr := current_week_nr + 1;
179 ELSE
180 currentBucket.week_nr := NULL;
181 END IF;
182 currentBucket.period_start_date := c1Rec.period_start_date;
183 currentBucket.bucket_type := c1Rec.bucket_type;
184 -- These are for BIS calendar data
185 currentBucket.bkt_start_date := c1Rec.bkt_start_date;
186 currentBucket.bkt_end_date := c1Rec.bkt_end_date;
187
188 IF currentBucket.period_start_date <> previous_period_start_date THEN
189 current_period_nr := current_period_nr + 1;
190 END IF;
191 currentBucket.period_nr := current_period_nr;
192
193 previous_period_start_date := currentBucket.period_start_date;
194 mainschedule(currentBucketNr) := currentBucket;
195 currentBucketNr := currentBucketNr + 1;
196 END LOOP;
197 CLOSE c1;
198 END;
199
200 PROCEDURE schedule_output_record(query_id NUMBER, aRecord Bucket)
201 IS
202 BEGIN
203 INSERT INTO msc_form_query
204 (query_id, last_update_date, last_updated_by, creation_date, created_by,
205 NUMBER1, NUMBER2, NUMBER3,
206 CHAR1, NUMBER4, CHAR2,
207 CHAR3, DATE1, DATE2,
208 NUMBER5, NUMBER6, NUMBER7,
209 NUMBER8, NUMBER9, NUMBER10,
210 NUMBER11, NUMBER12, NUMBER13,
211 NUMBER14,DATE3)
212 VALUES
213 (query_id, SYSDATE, -1, SYSDATE, -1,
214 aRecord.plan_id, aRecord.instance_id, aRecord.org_id,
215 aRecord.org_name, aRecord.sr_category_id, aRecord.category_name,
216 aRecord.plan_name, aRecord.bkt_start_date, aRecord.bkt_end_date,
217 aRecord.period_nr, aRecord.achieved_budget_usd, aRecord.delivered_quantity,
218 aRecord.required_quantity, aRecord.target_sl, aRecord.num_target_sl,
219 aRecord.record_type, aRecord.week_nr, aRecord.bucket_type,
220 aRecord.detail_level,aRecord.period_start_date);
221
222 END;
223
224 PROCEDURE schedule_dump_header
225 IS
226 BEGIN
227 IF do_debug = FALSE THEN
228 RETURN;
229 END IF;
230 dbms_output.put('plan_id,instance_id,org_id,org_name,plan_name,cat_id,cat_name,bucket_type,');
231 dbms_output.put_line('detail_level,start_date,end_date,period_nr,achieved_budget_dollars,record_type,required_qty,delivered_qty,target_sl_qty,nr_target_sl,week_nr,period_start_date');
232 END;
233
234 PROCEDURE schedule_dump_record(aRecord BUCKET)
235 IS
236 BEGIN
237 IF do_debug = FALSE THEN
238 RETURN;
239 END IF;
240 dbms_output.put('"'||aRecord.plan_id || '","' || aRecord.instance_id || '",');
241 dbms_output.put('"'|| aRecord.org_id || '",');
242 DBMS_OUTPUT.put('"' || aRecord.org_name || '","' || aRecord.plan_name || '",');
243 dbms_output.put('"' || aRecord.sr_category_id || '","' || aRecord.category_name || '",');
244 DBMS_OUTPUT.put('"' || aRecord.bucket_type || '",');
245 DBMS_OUTPUT.put('"' || aRecord.detail_level || '",');
246 dbms_output.put('"' || aRecord.bkt_start_date || '",');
247 dbms_output.put('"' || aRecord.bkt_end_date || '",');
248 dbms_output.put('"' || aRecord.period_nr || '",');
249 dbms_output.put('"' || aRecord.achieved_budget_usd || '",');
250 IF aRecord.record_type = RECORD_BUDGET THEN
251 dbms_output.put('"BUDGET",');
252 ELSIF aRecord.record_type = RECORD_SERVICE_LEVEL THEN
253 dbms_output.put('"SERVICE_LEVEL",');
254 ELSIF aRecord.record_type = RECORD_TARGET_SERVICE_LEVEL THEN
255 dbms_output.put('"TARGET_SL",');
256 ELSE
257 dbms_output.put('"NULL",');
258 END IF;
259
260 dbms_output.put('"' || aRecord.required_quantity || '",');
261 dbms_output.put('"' || aRecord.delivered_quantity || '",');
262 dbms_output.put('"' || aRecord.target_sl || '",');
263 dbms_output.put('"' || aRecord.num_target_sl || '",');
264 dbms_output.put('"' || aRecord.week_nr || '",');
265 dbms_output.put_line('"' || aRecord.period_start_date || '"');
266 END;
267
268 PROCEDURE schedule_flush(mainschedule Schedule, query_id NUMBER)
269 IS
270 BEGIN
271 schedule_dump_header;
272 FOR i IN mainschedule.FIRST..mainschedule.LAST LOOP
273 schedule_output_record(query_id, mainschedule(i));
274 schedule_dump_record(mainschedule(i));
275 END LOOP;
276 END;
277
278 FUNCTION is_bucket_match(aBucket Bucket, aRecord Bucket)
279 RETURN BOOLEAN
280 IS
281 BEGIN
282 IF aRecord.bkt_start_date >= aBucket.bkt_start_date AND
283 aRecord.bkt_start_date <= aBucket.bkt_end_date
284 THEN
285 RETURN TRUE;
286 END IF;
287
288 RETURN FALSE;
289 END;
290
291 PROCEDURE bucket_budget_record(mainschedule IN OUT NOCOPY Schedule, aRecord Bucket, end_date DATE)
292 IS
293 BEGIN
294 FOR i IN mainschedule.FIRST..mainschedule.LAST LOOP
295 IF aRecord.detail_level = DETAIL_LEVEL_PERIOD THEN
296 IF mainschedule(i).period_start_date = aRecord.bkt_start_date THEN
297 mainschedule(i).achieved_budget_usd := mainschedule(i).achieved_budget_usd + aRecord.achieved_budget_usd;
298 EXIT;
299 END IF;
300 ELSIF is_bucket_match(mainschedule(i), aRecord) THEN
301 mainschedule(i).achieved_budget_usd := mainschedule(i).achieved_budget_usd + aRecord.achieved_budget_usd;
302 END IF;
303 END LOOP;
304 END;
305
306 PROCEDURE bucket_service_level_record(mainschedule IN OUT NOCOPY Schedule, aRecord Bucket)
307 IS
308 BEGIN
309
310 FOR i IN mainschedule.FIRST..mainschedule.LAST LOOP
311 IF is_bucket_match(mainschedule(i), aRecord) THEN
312 mainschedule(i).delivered_quantity := mainschedule(i).delivered_quantity + aRecord.delivered_quantity;
313 mainschedule(i).required_quantity := mainschedule(i).required_quantity + aRecord.required_quantity;
314 mainschedule(i).target_sl := mainschedule(i).target_sl + aRecord.target_sl;
315 mainschedule(i).num_target_sl := mainschedule(i).num_target_sl + aRecord.num_target_sl;
316 EXIT;
317 END IF;
318 END LOOP;
319 END;
320
321 PROCEDURE schedule_initialize(mainschedule IN OUT NOCOPY Schedule, aRecord Bucket)
322 IS
323 BEGIN
324
325 FOR i IN mainschedule.FIRST..mainschedule.LAST LOOP
326 mainschedule(i).achieved_budget_usd := 0;
327 mainschedule(i).delivered_quantity := 0;
328 mainschedule(i).required_quantity := 0;
329 mainschedule(i).target_sl := 0;
330 mainschedule(i).num_target_sl := 0;
331 mainschedule(i).achieved_budget_usd := 0;
332
333 mainschedule(i).plan_id := aRecord.plan_id;
334 mainschedule(i).instance_id := aRecord.instance_id;
335 mainschedule(i).org_id := aRecord.org_id;
336 mainschedule(i).sr_category_id := aRecord.sr_category_id;
337 mainschedule(i).category_name := aRecord.category_name;
338 mainschedule(i).plan_name := aRecord.plan_name;
339 mainschedule(i).org_name := aRecord.org_name;
340 mainschedule(i).detail_level := aRecord.detail_level;
341 mainschedule(i).record_type := aRecord.record_type;
342
343 END LOOP;
344
345 END;
346
347 FUNCTION is_key_changed(currRecord IN Bucket, prevRecord IN Bucket)
348 RETURN BOOLEAN
349 IS
350 BEGIN
351 IF currRecord.plan_id <> prevRecord.plan_id OR
352 currRecord.org_id <> prevRecord.org_id OR
353 currRecord.instance_id <> prevRecord.instance_id OR
354 currRecord.sr_category_id <> prevRecord.sr_category_id
355 THEN
356 RETURN TRUE;
360 END;
357 ELSE
358 RETURN FALSE;
359 END IF;
361
362 FUNCTION is_budget_key_changed(currRecord IN Bucket, prevRecord IN Bucket)
363 RETURN BOOLEAN
364 IS
365 BEGIN
366
367 IF is_key_changed(currRecord, prevRecord) OR
368 currRecord.detail_level <> prevRecord.detail_level
369 THEN
370 RETURN TRUE;
371 ELSE
372 RETURN FALSE;
373 END IF;
374 END;
375
376 PROCEDURE schedule_bucket_budget(mainschedule IN OUT NOCOPY Schedule, p_plan_id NUMBER, p_sr_instance_id NUMBER,
377 p_sr_tp_id NUMBER, p_sr_cat_instance_id NUMBER, p_sr_cat_id NUMBER,
378 query_id NUMBER, p_calendar_type NUMBER, p_abc_id VARCHAR2)
379 IS
380 currRecord Bucket;
381 prevRecord Bucket;
382
383 l_default_category_set_id NUMBER;
384
385 CURSOR c1 IS
386 SELECT mbid.plan_id, mbid.sr_instance_id AS instance_id, mbid.organization_id as org_id, mtp.organization_code AS org_name,
387 mic.sr_category_id, mic.category_name, mp.compile_designator AS plan_name, mbid.detail_date as bkt_start_date,
388 NULL AS bkt_end_date, NULL AS period_nr,
389 NULL AS week_nr, NULL AS period_start_date, NULL AS bucket_type, NVL(mbid.detail_level, DETAIL_LEVEL_PERIOD) AS detail_level,
390 SUM(nvl(mbid.inventory_value, 0)) AS achieved_budget_usd, NULL as delivered_quantity, 0 as required_quantity,
391 NULL AS target_sl, NULL AS num_target_sl, RECORD_BUDGET AS record_type
392 FROM msc_bis_inv_detail mbid, msc_system_items mis, msc_item_categories mic,
393 msc_trading_partners mtp, msc_plans mp
394 WHERE mbid.plan_id = p_plan_id
395 AND mbid.plan_id = mp.plan_id
396 AND mbid.plan_id = mis.plan_id
397 AND mbid.organization_id = mis.organization_id
398 AND mbid.sr_instance_id = mis.sr_instance_id
399 AND mbid.inventory_item_id = mis.inventory_item_id
400 AND mbid.sr_instance_id = nvl(p_sr_instance_id, mbid.sr_instance_id)
401 AND mbid.organization_id = nvl(p_sr_tp_id, mbid.organization_id)
402 AND NVL(mbid.period_type, CALENDAR_TYPE_BIS) = p_calendar_type
403 AND mis.organization_id = mic.organization_id
404 AND mis.sr_instance_id = mic.sr_instance_id
405 AND mis.inventory_item_id = mic.inventory_item_id
406 AND mic.category_set_id = l_default_category_set_id
407 AND mic.sr_instance_id = nvl(p_sr_cat_instance_id, mic.sr_instance_id)
408 AND mic.sr_category_id = nvl(p_sr_cat_id, mic.sr_category_id)
409 AND mis.organization_id = mtp.sr_tp_id
410 AND mis.sr_instance_id = mtp.sr_instance_id
411 AND mis.budget_constrained = BUDGET_CONSTRAINED_ON
412 AND mtp.partner_type = 3
413 AND nvl(mis.abc_class_name, 'XXXXX') = nvl(p_abc_id, nvl(mis.abc_class_name, 'XXXXX'))
414 GROUP BY mbid.plan_id, mbid.sr_instance_id, mbid.organization_id, mtp.organization_code,
415 mic.sr_category_id, mic.category_name, mp.compile_designator, mbid.detail_date, NVL(mbid.detail_level, DETAIL_LEVEL_PERIOD)
416 ORDER BY mbid.plan_id, mbid.organization_id, mbid.sr_instance_id, mtp.organization_code,
417 mic.sr_category_id, mic.category_name, NVL(mbid.detail_level, DETAIL_LEVEL_PERIOD), mbid.detail_date;
418
419 BEGIN
420
421 l_default_category_set_id := get_cat_set_id(p_plan_id);
422
423 prevRecord.bkt_start_date := NULL; -- Used to test if the previous record was assigned
424 OPEN c1;
425 LOOP
426 FETCH c1 INTO currRecord;
427 IF c1%FOUND THEN
428 IF prevRecord.bkt_start_date IS NOT NULL THEN -- prev record exists
429 IF is_budget_key_changed(currRecord, prevRecord) THEN
430 bucket_budget_record(mainschedule, prevRecord, mainschedule(mainschedule.LAST).bkt_start_date + 1);
431 schedule_flush(mainschedule, query_id);
432 schedule_initialize(mainschedule, currRecord);
433 ELSE
434 bucket_budget_record(mainschedule, prevRecord, currRecord.bkt_start_date);
435 END IF;
436 ELSE
437 schedule_initialize(mainschedule, currRecord);
438 END IF;
439 prevRecord := currRecord;
440 ELSE
441 IF prevRecord.bkt_start_date IS NOT NULL THEN
442 bucket_budget_record(mainschedule, prevRecord, mainschedule(mainschedule.LAST).bkt_start_date + 1);
443 schedule_flush(mainschedule, query_id);
444 END IF;
445 EXIT;
446 END IF;
447 END LOOP;
448 CLOSE c1;
449 END;
450
451 PROCEDURE schedule_bucket_servicelevel(mainschedule IN OUT NOCOPY Schedule, p_plan_id NUMBER, p_sr_instance_id NUMBER,
452 p_sr_tp_id NUMBER, p_sr_cat_instance_id NUMBER, p_sr_cat_id NUMBER,
453 p_abc_id VARCHAR2, query_id NUMBER)
454 IS
455 currRecord Bucket;
456 prevRecord Bucket;
457
458 l_default_category_set_id NUMBER;
459 CURSOR c1 IS
460 SELECT msd.plan_id AS plan_id,
461 msd.sr_instance_id AS instance_id,
462 msd.organization_id AS org_id,
463 mtp.organization_code AS org_name,
464 mic.sr_category_id AS sr_category_id,
468 NULL AS bkt_end_date,
465 mic.category_name AS category_name,
466 mp.compile_designator AS plan_name,
467 trunc(msd.using_assembly_demand_date) AS bkt_start_date,
469 NULL AS period_nr,
470 NULL AS week_nr, NULL AS period_start_date, NULL AS bucket_type, NULL AS detail_level,
471 0 AS achieved_budget_usd,
472 sum(nvl(msd.old_demand_quantity,0)*
473 nvl(msd.probability,1)) AS delivered_quantity,
474 sum(nvl(msd.using_requirement_quantity, 0)*
475 nvl(msd.probability,1)) AS required_quantity,
476 sum(nvl(msd.service_level, 50)) AS target_service_level,
477 count(*) AS num_target_service_level,
478 RECORD_SERVICE_LEVEL AS record_type
479 FROM msc_plans mp, msc_plan_organizations mpo, msc_demands msd, msc_system_items msi,
480 msc_item_categories mic, msc_trading_partners mtp
481 WHERE mp.plan_id = p_plan_id
482 AND mp.plan_id = mpo.plan_id
483 AND mpo.plan_id = msd.plan_id
484 AND mpo.sr_instance_id = msd.sr_instance_id
485 AND mpo.organization_id = msd.organization_id
486 AND msd.plan_id = msi.plan_id
487 AND msd.origination_type IN (6,7,8,9,11,12,15,22,28,29,30)
488 AND msd.sr_instance_id = msi.sr_instance_id
489 AND msd.organization_id = msi.organization_id
490 AND msd.using_assembly_item_id = msi.inventory_item_id
491 AND msd.plan_id = mp.plan_id
492 AND msi.organization_id = mic.organization_id
493 AND msi.sr_instance_id = mic.sr_instance_id
494 AND msi.budget_constrained = BUDGET_CONSTRAINED_ON
495 AND mic.category_set_id = l_default_category_set_id
496 AND msi.inventory_item_id = mic.inventory_item_id
497 AND msd.organization_id = mtp.sr_tp_id
498 AND msd.sr_instance_id = mtp.sr_instance_id
499 AND mtp.sr_instance_id = nvl(p_sr_instance_id, mtp.sr_instance_id)
500 AND mtp.sr_tp_id = nvl(p_sr_tp_id, mtp.sr_tp_id)
501 AND mic.sr_instance_id = nvl(p_sr_cat_instance_id, mic.sr_instance_id)
502 AND mic.sr_category_id = nvl(p_sr_cat_id, mic.sr_category_id)
503 AND nvl(msi.abc_class_name, 'XXXXX') = nvl(p_abc_id, nvl(msi.abc_class_name, 'XXXXX'))
504 GROUP BY msd.plan_id, msd.sr_instance_id, msd.organization_id, mtp.organization_code,
505 mic.sr_category_id, mic.category_name, mp.compile_designator, trunc(msd.using_assembly_demand_date)
506 ORDER BY msd.plan_id, msd.organization_id, msd.sr_instance_id, mtp.organization_code,
507 mic.sr_category_id, mic.category_name, trunc(msd.using_assembly_demand_date);
508 BEGIN
509
510 l_default_category_set_id := get_cat_set_id(p_plan_id);
511
512 prevRecord.bkt_start_date := NULL; -- Used to test if the previous record was assigned
513 OPEN c1;
514 LOOP
515 FETCH c1 INTO currRecord;
516 IF c1%FOUND THEN
517 IF prevRecord.bkt_start_date IS NOT NULL THEN -- prev record exists
518 bucket_service_level_record(mainschedule, prevRecord);
519 IF is_key_changed(currRecord, prevRecord) THEN
520 schedule_flush(mainschedule, query_id);
521 schedule_initialize(mainschedule, currRecord);
522 END IF;
523 ELSE
524 schedule_initialize(mainschedule, currRecord);
525 END IF;
526 prevRecord := currRecord;
527 ELSE
528 IF prevRecord.bkt_start_date IS NOT NULL THEN
529 bucket_service_level_record(mainschedule, prevRecord);
530 schedule_flush(mainschedule, query_id);
531 END IF;
532 EXIT;
533 END IF;
534 END LOOP;
535 CLOSE c1;
536 END;
537
538 PROCEDURE schedule_target_service_level(
539 mainschedule IN OUT NOCOPY Schedule, p_plan_id NUMBER, p_sr_instance_id NUMBER,
540 p_sr_tp_id NUMBER, p_sr_cat_instance_id NUMBER, p_sr_cat_id NUMBER,
541 p_abc_id VARCHAR2, p_calendar_type NUMBER, query_id NUMBER)
542 IS
543 l_default_category_set_id NUMBER;
544
545 CURSOR c1 IS
546 SELECT plan_id, instance_id, org_id, sr_category_id, category_name, plan_name, org_name, SUM(target_sl) AS target_sl, COUNT(*) AS num_target_sl
547 FROM
548 (
549 SELECT plan_id, instance_id, org_id, sr_category_id, category_name, plan_name, org_name, item_id, item_name, AVG(target_sl) AS target_sl
550 FROM
551 (
552 SELECT plan_id, instance_id, org_id,
553 sr_category_id, category_name,
554 plan_name,
555 org_name, item_id, item_name,
556 nvl(get_customer_target_sl(partner_id) ,
557 msc_get_bis_values.service_target(plan_id,instance_id,org_id,item_id)) AS target_sl
558 FROM
559 (
560 SELECT DISTINCT msi.plan_id AS plan_id, msi.sr_instance_id AS instance_id, msi.organization_id AS org_id,
561 msi.inventory_item_id AS item_id,
562 mic.sr_category_id AS sr_category_id, mic.category_name AS category_name,
563 mp.compile_designator AS plan_name,
564 mtp.organization_code AS org_name,
565 msi.item_name AS item_name, msd.customer_id AS partner_id
566 FROM msc_plans mp, msc_system_items msi, msc_item_categories mic, msc_trading_partners mtp,
570 WHERE demands.origination_type IN (6,7,8,9,11,12,15,22,28,29,30)) msd,
567 (SELECT demands.plan_id, demands.sr_instance_id, demands.organization_id, demands.using_assembly_item_id,
568 demands.customer_id, demands.demand_id
569 FROM msc_demands demands
571 (SELECT kpi.inventory_item_id, kpi.sr_instance_id, kpi.organization_id, kpi.plan_id
572 FROM msc_bis_inv_detail kpi
573 WHERE NVL(kpi.period_type, CALENDAR_TYPE_BIS) = p_calendar_type
574 AND kpi.plan_id = p_plan_id) mbid
575 WHERE mp.plan_id = p_plan_id
576 AND mp.plan_id = msi.plan_id
577 AND msi.organization_id = mic.organization_id
578 AND msi.sr_instance_id = mic.sr_instance_id
579 AND msi.inventory_item_id = mic.inventory_item_id
580 AND mic.category_set_id = l_default_category_set_id
581 AND mic.sr_instance_id = nvl(p_sr_cat_instance_id, mic.sr_instance_id)
582 AND mic.sr_category_id = nvl(p_sr_cat_id, mic.sr_category_id)
583 AND msi.organization_id = mtp.sr_tp_id
584 AND msi.sr_instance_id = mtp.sr_instance_id
585 AND mtp.partner_type = 3
586 AND mtp.sr_instance_id = nvl(p_sr_instance_id, mtp.sr_instance_id)
587 AND mtp.sr_tp_id = nvl(p_sr_tp_id, mtp.sr_tp_id)
588 AND msi.inventory_item_id = mbid.inventory_item_id (+)
589 AND msi.organization_id = mbid.organization_id (+)
590 AND msi.sr_instance_id = mbid.sr_instance_id (+)
591 AND msi.inventory_item_id = mbid.inventory_item_id (+)
592 AND msi.plan_id = mbid.plan_id (+)
593 AND msi.sr_instance_id = nvl(p_sr_instance_id, msi.sr_instance_id)
594 AND msi.organization_id = nvl(p_sr_tp_id, msi.organization_id)
595 AND msi.plan_id = msd.plan_id (+)
596 AND msi.sr_instance_id = msd.sr_instance_id (+)
597 AND msi.organization_id = msd.organization_id (+)
598 AND msi.inventory_item_id = msd.using_assembly_item_id (+)
599 AND msi.budget_constrained = BUDGET_CONSTRAINED_ON
600 AND nvl(msi.abc_class_name, 'XXXXX') = nvl(p_abc_id, nvl(msi.abc_class_name, 'XXXXX'))
601 AND (mbid.plan_id IS NOT NULL OR msd.demand_id IS NOT NULL)
602 ))
603 GROUP BY plan_id, instance_id, org_id,
604 sr_category_id, category_name,
605 plan_name,
606 org_name, item_id, item_name)
607 GROUP BY plan_id, instance_id, org_id,
608 sr_category_id, category_name,
609 plan_name,
610 org_name;
611
612 currRecord Bucket;
613 l_target_service_level NUMBER;
614 BEGIN
615 -- Get default category set
616 l_default_category_set_id := get_cat_set_id(p_plan_id);
617
618 -- item,org,inst,plan service levels
619 schedule_dump_header;
620 OPEN c1;
621 LOOP
622 FETCH c1 INTO currRecord.plan_id,currRecord.instance_id,currRecord.org_id,
623 currRecord.sr_category_id,currRecord.category_name,
624 currRecord.plan_name,currRecord.org_name,
625 currRecord.target_sl, currRecord.num_target_sl;
626 EXIT WHEN c1%NOTFOUND;
627
628 currRecord.record_type := RECORD_TARGET_SERVICE_LEVEL;
629
630 schedule_output_record(query_id, currRecord);
631 schedule_dump_record(currRecord);
632 END LOOP;
633 CLOSE c1;
634
635 END;
636
637 FUNCTION validate_plan(p_plan_id NUMBER)
638 RETURN BOOLEAN
639 IS
640 CURSOR c1(p_plan_id NUMBER) IS
641 SELECT 1
642 FROM msc_plans_tree_v mpt, msc_plans mp
643 WHERE mpt.curr_plan_type = 4
644 AND mpt.plan_id = mp.plan_id
645 AND mp.plan_start_date IS NOT NULL
646 AND mp.plan_id = p_plan_id;
647
648 l_result NUMBER := NULL;
649 BEGIN
650
651 OPEN c1(p_plan_id);
652 FETCH c1 INTO l_result;
653 CLOSE c1;
654
655 IF l_result = 1 THEN
656 RETURN TRUE;
657 ELSE
658 RETURN FALSE;
659 END IF;
660
661 EXCEPTION
662 WHEN OTHERS THEN
663 RETURN FALSE;
664 END;
665
666 FUNCTION get_sr_tp_id_from_org_key(org_id VARCHAR2)
667 RETURN NUMBER
668 IS
669 dash NUMBER;
670 BEGIN
671 IF org_id IS NULL THEN
672 RETURN NULL;
673 END IF;
674
675 dash := INSTR(org_id, '-');
676
677 IF dash = 0 OR dash = 1 THEN
678 RETURN NULL;
679 END IF;
680
681 RETURN SUBSTR(org_id, dash + 1);
682 END;
683
684 FUNCTION get_inst_id_from_org_key(org_id VARCHAR2)
685 RETURN NUMBER
686 IS
687 dash NUMBER;
688 BEGIN
689 IF org_id IS NULL THEN
690 RETURN NULL;
691 END IF;
692
693 dash := INSTR(org_id, '-');
694
695 IF dash = 0 OR dash = 1 THEN
696 RETURN NULL;
697 END IF;
698
699 RETURN SUBSTR(org_id, 1, dash - 1);
700 END;
701
702 FUNCTION get_sr_cat_id_from_cat_key(cat_id VARCHAR2)
703 RETURN NUMBER
704 IS
705 dash NUMBER;
706 BEGIN
707 IF cat_id IS NULL THEN
708 RETURN NULL;
709 END IF;
710
711 dash := INSTR(cat_id, '-');
712
713 IF dash = 0 OR dash = 1 THEN
714 RETURN NULL;
715 END IF;
716
717 RETURN SUBSTR(cat_id, dash + 1);
718 END;
719
720 FUNCTION get_inst_id_from_cat_key(cat_id VARCHAR2)
721 RETURN NUMBER
722 IS
723 dash NUMBER;
724 BEGIN
725 IF cat_id IS NULL THEN
726 RETURN NULL;
727 END IF;
728
729 dash := INSTR(cat_id, '-');
730
731 IF dash = 0 OR dash = 1 THEN
732 RETURN NULL;
733 END IF;
734
735 RETURN SUBSTR(cat_id, 1, dash - 1);
736 END;
737
738 PROCEDURE parse_planlist(p_plans VARCHAR2, p_planlist IN OUT NOCOPY PlanList)
739 IS
740 occurrence NUMBER := 1;
741 stringstart NUMBER := 1;
742 stringend NUMBER := 1;
743 planfound NUMBER := 1;
744 pos NUMBER;
745 token NUMBER;
746 BEGIN
747
748 LOOP
749 pos := INSTR(p_plans, ',', 1, occurrence);
750 occurrence := occurrence + 1;
751 IF pos = 0 THEN
752 stringend := LENGTH(p_plans);
753 token := to_number(SUBSTR(p_plans, stringstart, stringend - stringstart + 1));
754 IF token IS NOT NULL THEN
755 p_planlist(planfound) := token;
756 planfound := planfound + 1;
757 END IF;
758 EXIT;
759 END IF;
760 stringend := pos - 1;
761 token := to_number(SUBSTR(p_plans, stringstart, stringend - stringstart + 1));
762 IF token IS NOT NULL THEN
763 p_planlist(planfound) := token;
764 planfound := planfound + 1;
765 END IF;
766 stringstart := stringend + 2;
767 END LOOP;
768
769 END;
770
771 PROCEDURE schedule_retrieve(query_id OUT NOCOPY NUMBER, plan_id IN VARCHAR2, org_id IN VARCHAR2, cat_id IN VARCHAR2,
772 abc_id IN VARCHAR2, calendar_type IN NUMBER)
773 IS
774 mainschedule Schedule;
775 sr_instance_id NUMBER;
776 sr_tp_id NUMBER;
777 sr_cat_instance_id NUMBER;
778 sr_cat_id NUMBER;
779 l_planlist PlanList;
780
781 BEGIN
782
783 SELECT msc_form_query_s.nextval
784 INTO query_id
785 FROM dual;
786
787 IF org_id IS NOT NULL THEN
788 sr_instance_id := get_inst_id_from_org_key(org_id);
789 sr_tp_id := get_sr_tp_id_from_org_key(org_id);
790 END IF;
791
792 IF cat_id IS NOT NULL THEN
793 sr_cat_instance_id := get_inst_id_from_cat_key(cat_id);
794 sr_cat_id := get_sr_cat_id_from_cat_key(cat_id);
795 END IF;
796
797 parse_planlist(plan_id, l_planlist);
798 IF l_planlist.COUNT = 0 THEN
799 query_id := -1;
800 RETURN;
801 END IF;
802
803 FOR l_index IN l_planlist.FIRST..l_planlist.LAST LOOP
804 IF validate_plan(l_planlist(l_index)) = FALSE THEN
805 query_id := -1;
806 RETURN;
807 END IF;
808
809 IF calendar_type = CALENDAR_TYPE_BIS THEN
813 END IF;
810 schedule_create_bis(mainschedule, l_planlist(l_index), calendar_type);
811 ELSE
812 schedule_create_mfg(mainschedule, l_planlist(l_index), calendar_type);
814
815 schedule_bucket_budget(mainschedule, l_planlist(l_index), sr_instance_id, sr_tp_id,
816 sr_cat_instance_id, sr_cat_id, query_Id, calendar_type, abc_id);
817
818 schedule_bucket_servicelevel(mainschedule, l_planlist(l_index), sr_instance_id, sr_tp_id,
819 sr_cat_instance_id, sr_cat_id, abc_id, query_Id);
820
821 schedule_target_service_level(mainschedule, l_planlist(l_index), sr_instance_id, sr_tp_id,
822 sr_cat_instance_id, sr_cat_id, abc_id, calendar_type, query_id);
823
824 END LOOP;
825 END;
826
827 END;