DBA Data[Home] [Help]
Skip to content

PACKAGE BODY: APPS.MSC_UPDATE_RESOURCE

Source


1 PACKAGE BODY Msc_UPDATE_RESOURCE AS
2 /* $Header: MSCFNAVB.pls 120.7 2009/10/12 22:21:39 pabram ship $ */
3 
4 TYPE ResRecTyp IS RECORD (
5         TRANSACTION_ID                           NUMBER,
6 	PARENT_ID				 NUMBER,
7 	AGGREGATE_RESOURCE_ID		         NUMBER,
8         SIMULATION_SET                           VARCHAR2(10),
9  	FROM_TIME                                NUMBER,
10  	TO_TIME                                  NUMBER,
11  	CAPACITY_UNITS                           NUMBER,
12  	STATUS                                   NUMBER,
13  	APPLIED                                  NUMBER,
14  	UPDATED                          	 NUMBER,
15  	LAST_UPDATE_DATE                 	 DATE,
16  	LAST_UPDATED_BY                  	 NUMBER,
17  	CREATION_DATE                   	 DATE,
18  	CREATED_BY                       	 NUMBER,
19  	LAST_UPDATE_LOGIN                        NUMBER,
20 	shift_date                               DATE,
21 	shift_number                             NUMBER);
22 
23 TYPE ResTabTyp IS TABLE OF ResRecTyp
24 	INDEX by binary_integer;
25 
26 TYPE ChangeRecTyp IS RECORD (
27 	OPERATION				 NUMBER,
28 	ORGANIZATION_ID				 NUMBER,
29         SR_INSTANCE_ID                           NUMBER,
30 	DEPARTMENT_ID				 NUMBER,
31 	RESOURCE_ID				 NUMBER,
32         SHIFT_DATE                               DATE,
33         SHIFT_NUMBER                             NUMBER,
34  	FROM_TIME                                NUMBER,
35  	TO_TIME                                  NUMBER,
36  	CAPACITY_UNITS                           NUMBER,
37      	LAST_UPDATED_BY                  	 NUMBER,
38         RES_INST_ID                              NUMBER,
39 	SERIAL_NUMBER                            VARCHAR2(2000));
40 
41 g_resource_exist        boolean;
42 g_res_inst_set_data     boolean;
43 g_error_stat		VARCHAR2(300);
44 g_plan_id               NUMBER;
45 g_simulation_set	VARCHAR2(10);
46 g_res_group		VARCHAR2(30);
47 g_cutoff_date		DATE;
48 g_query_id		NUMBER;
49 g_org_id		NUMBER;
50 g_instance_id           NUMBER;
51 g_department_id		NUMBER;
52 g_resource_id		NUMBER;
53 g_res_inst_id           NUMBER;
54 g_serial_number         VARCHAR2(2000);
55 g_shift_date            DATE;
56 g_shift_number          NUMBER;
57 g_from_time             NUMBER;
58 g_to_time               NUMBER;
59 g_units                 NUMBER;
60 g_change_rec 		ChangeRecTyp;
61 g_res_tab		ResTabTyp;
62 g_res_inst_tab		ResTabTyp;
63 g_tmp_tab		ResTabTyp;
64 i 			binary_integer;
65 j                       binary_integer;
66 k 			binary_integer;
67 OP_ADD_DAY		CONSTANT INTEGER :=0;
68 OP_ADD                  CONSTANT INTEGER :=1;
69 OP_DEL                  CONSTANT INTEGER :=2;
70 OP_SET			CONSTANT INTEGER :=3;
71 OP_DEL_DAY		CONSTANT INTEGER :=4;
72 
73 CURSOR C_MFQ IS
74        SELECT
75 			NUMBER1,
76 			NUMBER2,
77 			NUMBER3,
78 			NUMBER4,
79 			NUMBER5,
80                         DATE1,
81                         NUMBER6,
82                         NUMBER7,
83                         NUMBER8,
84                         NUMBER9,
85                         LAST_UPDATED_BY,
86                         NUMBER10, CHAR1
87 	FROM Msc_FORM_QUERY
88 	WHERE query_id = g_query_id
89 	ORDER BY number2, number3, number4, number5, date1,
90                  number6, number7,number1;
91 
92 CURSOR C_CAR  IS
93        SELECT
94               transaction_id,
95 	      parent_id,
96 	      aggregate_resource_id,
97               simulation_set,
98               from_time,
99               to_time,
100               capacity_units,
101 	      status,
102    	      applied,
103               updated,
104  	LAST_UPDATE_DATE,
105         LAST_UPDATED_BY,
106         CREATION_DATE,
107         CREATED_BY,
108         LAST_UPDATE_LOGIN,
109 	shift_date,
110 	shift_num
111         FROM  MSC_NET_RESOURCE_AVAIL
112         WHERE plan_id=g_plan_id
113 	AND organization_id = g_org_id
114         AND sr_instance_id =g_instance_id
115         AND department_id = g_department_id
116         AND resource_id = g_resource_id
117         and shift_date = g_shift_date
118         and decode(resource_id,-1,-1,shift_num) =
119               decode(resource_id,-1,-1,g_shift_number)
120         and capacity_units >=0
121         and nvl(parent_id,0) <> -1
122 	order by from_time;
123 
124 CURSOR c_car_inst  IS
125        SELECT
126               inst_transaction_id transaction_id,
127 	      parent_id,
128 	      to_number(null) aggregate_resource_id,
129               simulation_set,
130               from_time,
131               to_time,
132               nvl(capacity_units,1) capacity_units,
133 	      status,
134    	      applied,
135               updated,
136  	LAST_UPDATE_DATE,
137         LAST_UPDATED_BY,
138         CREATION_DATE,
139         CREATED_BY,
140         LAST_UPDATE_LOGIN,
141 	shift_date,
142 	shift_num
143         FROM  msc_net_res_inst_avail
144         WHERE plan_id=g_plan_id
145 	AND organization_id = g_org_id
146         AND sr_instance_id =g_instance_id
147         AND department_id = g_department_id
148         AND resource_id = g_resource_id
149 	and res_instance_id = g_res_inst_id
150 	and serial_number = g_serial_number
151         and shift_date = g_shift_date
152         and decode(resource_id,-1,-1,shift_num) = decode(resource_id,-1,-1,g_shift_number)
153         and nvl(capacity_units,1) >=0
154         and nvl(parent_id,0) <> -1
155 	order by from_time;
156 
157 CURSOR date_range IS
158         SELECT distinct mra.shift_date
159         FROM msc_net_resource_avail mra,
160              msc_form_query mfq
161         WHERE mra.plan_id = g_plan_id
162         and mra.organization_id = g_org_id
163         and mra.sr_instance_id = g_instance_id
164         and mra.department_id = g_department_id
165         and mra.resource_id = g_resource_id
166         and nvl(mra.parent_id,0) <> -1
167         and mra.capacity_units >=0
168         and mfq.query_id = g_query_id
169         and trunc(mra.shift_date) between
170                 trunc(mfq.date1) and trunc(mfq.date2)
171 ORDER BY mra.shift_date;
172 
173 -- global variable for move_resource
174   Type NumTab IS TABLE of number INDEX BY BINARY_INTEGER;
175   Type DateTab IS TABLE of DATE INDEX BY BINARY_INTEGER;
176   p_start_time dateTab;
177   p_end_time dateTab;
178   p_resource_units numTab;
179   p_trans_id numTab;
180 
181   TYPE simu_res_type IS RECORD (
182     org_id numTab,
183     inst_id numTab,
184     dept_id numTab,
185     res_id numTab,
186     assign_units numTab,
187     res_hours numTab,
188     op_seq_id numTab,
189     rt_seq_id numTab
190   );
191 
192   sim_res simu_res_type;
193 
194 
195 ---------------------------------------------------------------
196 -- apply change
197 ---------------------------------------------------------------
198 PROCEDURE apply_change( p_query_id IN NUMBER,
199 			p_plan_id IN NUMBER ) IS
200 
201 l_work_day  number;
202 
203   CURSOR NWD is
204    SELECT nvl(dates.seq_num, -1)
205   FROM msc_trading_partners mtp,
206        msc_calendar_dates dates
207   WHERE dates.calendar_date = trunc(g_shift_date)
208     AND dates.calendar_code = mtp.calendar_code
209     AND dates.exception_set_id = mtp.calendar_exception_set_id
210     AND dates.sr_instance_id = mtp.sr_instance_id
211     AND mtp.partner_type = 3
212     AND mtp.sr_tp_id = g_org_id
213     AND mtp.sr_instance_id = g_instance_id;
214 
215 BEGIN
216    g_plan_id :=p_plan_id;
217    g_query_id := p_query_id;
218    g_org_id                :=0;
219    g_instance_id           :=0;
220    g_department_id         :=0;
221    g_resource_id           :=0;
222    g_shift_date            :=to_date(null);
223    g_shift_number          :=null;
224 
225   -- load from mrp_form_query for the changes, if the resource changes
226   -- re-query data from msc_net_resource_avail
227 
228    OPEN C_MFQ;
229    LOOP
230      FETCH C_MFQ INTO g_change_rec;
231      EXIT WHEN C_MFQ%NOTFOUND;
232            g_org_id :=g_change_rec.organization_id;
233            g_instance_id := g_change_rec.sr_instance_id;
234            g_department_id :=g_change_rec.department_id;
235            g_resource_id :=g_change_rec.resource_id;
236            g_res_inst_id := g_change_rec.res_inst_id;
237 	   g_serial_number := g_change_rec.serial_number;
238            g_shift_number :=g_change_rec.shift_number;
239 	   g_from_time := g_change_rec.from_time;
240            g_to_time := g_change_rec.to_time;
241 	   g_units := g_change_rec.capacity_units;
242 
243 	   if (g_change_rec.res_inst_id is not null and g_change_rec.operation = OP_SET) then
244 	     g_res_inst_set_data := true;
245 	   else
246 	     g_res_inst_set_data := false;
247 	   end if;
248 
249        OPEN date_range;
250        LOOP
251           FETCH date_range into g_shift_date;
252           EXIT WHEN date_range%NOTFOUND;
253 
254            OPEN NWD;
255            FETCH NWD into l_work_day;
256            CLOSE NWD;
257            if ( l_work_day <> -1 ) then
258 	     initialize_table;
259    	     calculate_change;
260              update_table;
261            end if;
262        END LOOP;
263        CLOSE date_range;
264    END LOOP;
265    CLOSE C_MFQ;
266    commit;
267 EXCEPTION when others THEN
268 
269    IF (C_MFQ%ISOPEN) THEN
270 	close C_MFQ;
271    END IF;
272   IF date_range%ISOPEN THEN
273         close date_range;
274   END IF;
275    raise_application_error(-20000, sqlerrm);
276 END apply_change;
277 
278 ---------------------------------------------------------------------
279 -- to get the values into PL/SQL tables
280 ---------------------------------------------------------------------
281 PROCEDURE initialize_table IS
282 l_ctr number :=0;
283 BEGIN
284 
285    -- load from crp_available_resources for all the records
286    -- related to the same resource
287 j :=0;
288 g_res_tab.delete;
289 
290    OPEN C_CAR;
291    LOOP
292 	   j := j+1;
293 	   FETCH C_CAR INTO g_res_tab(j);
294 	   if C_CAR%NOTFOUND then
295              if C_CAR%ROWCOUNT=0 then
296                g_resource_exist :=false;
297              end if;
298              exit;
299            end if;
300 
301    END LOOP;
302    IF C_CAR%ROWCOUNT >0 THEN
303      g_resource_exist :=true;
304    END IF;
305    CLOSE C_CAR;
306 
307    if (g_res_inst_set_data) then
308    g_res_inst_tab.delete;
309    open c_car_inst;
310    loop
311 	   l_ctr := l_ctr +1;
312 	   fetch c_car_inst into g_res_inst_tab(l_ctr);
313 	   if c_car_inst%notfound then
314              exit;
315            end if;
316    end loop;
317    close c_car_inst;
318    end if;
319 
320 EXCEPTION WHEN others THEN
321   IF (C_CAR%ISOPEN) THEN
322 	close C_CAR;
323   END IF;
324 
325 END initialize_table;
326 
327 Function insert_undo_data(undo_type number,
328                          j number default null,
329                          v_undo_parent_id number default null) return number is
330   v_undo_id number;
331   net_res_columns msc_undo.changeRGType;
332   x_return_sts varchar2(100);
333   x_msg_count number;
334   x_msg_data varchar2(200);
335   i number;
336 begin
337 
338      select msc_undo_summary_s.nextval
339        into v_undo_id
340        from dual;
341 
342      if undo_type = 2 then -- update
343 
344           i := 1;
345         if g_res_tab(j).capacity_units <>
346               g_tmp_tab(k).capacity_units then
347           net_res_columns(i).column_changed := 'CAPACITY_UNITS';
348           net_res_columns(i).column_changed_text := 'Capacity Units';
349           net_res_columns(i).old_value := to_char(g_res_tab(j).capacity_units);
350           net_res_columns(i).column_type := 'NUMBER';
351           net_res_columns(i).new_value := to_char(g_tmp_tab(k).capacity_units);
352           i := i+1;
353           if (g_res_inst_set_data) then
354 	    g_tmp_tab(k).capacity_units := g_res_tab(j).capacity_units;
355 	  end if;
356         end if;
357 
358         if g_res_tab(j).from_time <>
359               g_tmp_tab(k).from_time then
360           net_res_columns(i).column_changed := 'FROM_TIME';
361           net_res_columns(i).column_changed_text := 'From Time';
362           net_res_columns(i).old_value := to_char(g_res_tab(j).from_time);
363           net_res_columns(i).column_type := 'NUMBER';
364           net_res_columns(i).new_value := to_char(g_tmp_tab(k).from_time);
365           i := i+1;
366         end if;
367 
368         if g_res_tab(j).to_time <>
369               g_tmp_tab(k).to_time then
370           net_res_columns(i).column_changed := 'TO_TIME';
371           net_res_columns(i).column_changed_text := 'To Time';
372           net_res_columns(i).old_value := to_char(g_res_tab(j).to_time);
373           net_res_columns(i).column_type := 'NUMBER';
374           net_res_columns(i).new_value := to_char(g_tmp_tab(k).to_time);
375         end if;
376 
377      end if;
378 
379      msc_undo.store_undo(4, --means msc_net_resource_avail
380                 undo_type,  --2 is update , 1 is insert a record
381                 g_tmp_tab(k).transaction_id,
382                 g_plan_id,
383                 g_instance_id,
384                 v_undo_parent_id,
385                 net_res_Columns,
386                 x_return_sts,
387                 x_msg_count,
388                 x_msg_data,
389                 v_undo_id);
390 
391       return v_undo_id;
392 
393 end insert_undo_data;
394 
395 Function insert_res_inst_undo_data(undo_type number,
396 			 v_trx_id number,
397                          v_old_shift_date varchar2, v_new_shift_date varchar2,
398 			 v_old_shift_number varchar2, v_new_shift_number varchar2,
399 			 v_old_from_time varchar2, v_new_from_time varchar2,
400 			 v_old_to_time varchar2, v_new_to_time varchar2,
401 			 v_old_units varchar2, v_new_units varchar2,
402                          v_undo_parent_id number default null) return number is
403   v_undo_id number;
404   net_res_columns msc_undo.changeRGType;
405   x_return_sts varchar2(100);
406   x_msg_count number;
407   x_msg_data varchar2(200);
408 begin
409      select msc_undo_summary_s.nextval
410        into v_undo_id
411        from dual;
412 
413      if undo_type = 2 then -- update
414 
415           i := 1;
416           net_res_columns(i).column_changed := 'SHIFT_DATE';
417           net_res_columns(i).column_changed_text := 'Shift Date';
418           net_res_columns(i).old_value := v_old_shift_date;
419           net_res_columns(i).column_type := 'DATE';
420           net_res_columns(i).new_value := v_new_shift_date;
421 
422           i := i+1;
423           net_res_columns(i).column_changed := 'SHIFT_NUM';
424           net_res_columns(i).column_changed_text := 'Shift Number';
425           net_res_columns(i).old_value := to_char(v_old_shift_number);
426           net_res_columns(i).column_type := 'NUMBER';
427           net_res_columns(i).new_value := to_char(v_new_shift_number);
428 
429           i := i+1;
430           net_res_columns(i).column_changed := 'FROM_TIME';
431           net_res_columns(i).column_changed_text := 'From Time';
432           net_res_columns(i).old_value := to_char(v_old_from_time);
433           net_res_columns(i).column_type := 'NUMBER';
434           net_res_columns(i).new_value := to_char(v_new_to_time);
435 
436           i := i+1;
437           net_res_columns(i).column_changed := 'TO_TIME';
438           net_res_columns(i).column_changed_text := 'To Time';
439           net_res_columns(i).old_value := to_char(v_old_to_time);
440           net_res_columns(i).column_type := 'NUMBER';
441           net_res_columns(i).new_value := to_char(v_new_to_time);
442 
443           i := i+1;
444           net_res_columns(i).column_changed := 'CAPACITY_UNITS';
445           net_res_columns(i).column_changed_text := 'Capacity Units';
446           net_res_columns(i).old_value := to_char(v_old_units);
447           net_res_columns(i).column_type := 'NUMBER';
448           net_res_columns(i).new_value := to_char(v_new_units);
449      end if;
450 
451      msc_undo.store_undo(8, --means msc_net_resource_avail
452                 undo_type,  --2 is update , 1 is insert a record
453                 v_trx_id,
454                 g_plan_id,
455                 g_instance_id,
456                 v_undo_parent_id,
457                 net_res_Columns,
458                 x_return_sts,
459                 x_msg_count,
463 
460                 x_msg_data,
461                 v_undo_id);
462       return nvl(v_undo_parent_id,v_undo_id);
464 end insert_res_inst_undo_data;
465 
466 ---------------------------------------------------------------------
467 -- to
468 ---------------------------------------------------------------------
469 PROCEDURE calculate_change IS
470 v_start_record 		number;
471 v_end_record            number;
472 v_undo_id number;
473 v_undo_parent_id number;
474 BEGIN
475 
476 IF g_resource_exist THEN
477 -- try to find which records in res_tab are affected by the change
478 
479     -- try to find which record the change start date falls
480 
481  j:=g_res_tab.FIRST;
482  IF (g_change_rec.from_time <
483 	g_res_tab(j).from_time ) THEN
484      -- the change record starts before the range
485 	v_start_record :=0;
486  ELSE
487     --find the first record whose start date is greater than change's start date
488     --then the previous record will be where the change starts
489 	While (j is not null) and
490 	   (    g_change_rec.from_time >=
491 		g_res_tab(j).from_time    )
492 	LOOP
493 	   j:=g_res_tab.next(j);
494 	END LOOP;
495    IF j is null THEN
496 	-- if j is null, then the change is on or outside the last record
497 	i :=g_res_tab.LAST;
498 	IF ( g_res_tab(i).to_time is null ) THEN
499 	   v_start_record :=g_res_tab.LAST;
500 	   v_end_record :=g_res_tab.LAST;
501 	ELSE
502 	  IF (g_change_rec.from_time <=
503 		g_res_tab(i).to_time ) THEN
504 	        v_start_record :=g_res_tab.LAST;
505            	v_end_record :=g_res_tab.LAST;
506 	   ELSE
507 	  	v_start_record :=g_res_tab.LAST+1;
508           	v_end_record :=g_res_tab.LAST+1;
509 
510 	   END IF;
511 	END IF;
512    ELSE
513 	-- otherwise, the change is inside the range
514 	-- but it could be on a record or in a gap between two records
515 	IF (g_change_rec.from_time <=
516                 g_res_tab(j-1).to_time ) THEN
517 	--change falls on the previos record
518 		v_start_record := j-1;
519 	ELSE
520 	--change falls on the gap between record j-1 and record j
521 		v_start_record := j-0.5;
522 	END IF;
523 	--go to the previous record to find where change ends
524 	j:=j-1;
525    END IF;
526  END IF;
527 
528 -- try to find which record the change end date fall
529 
530  -- if the change does not have end date, the change extends till the end
531  -- but it could be on the last record, or outside the range
532  IF ( g_change_rec.to_time is null ) THEN
533         i :=g_res_tab.LAST;
534         IF ( g_res_tab(i).to_time is null ) THEN
535 	-- falls on the last record
536            v_end_record :=g_res_tab.LAST;
537         ELSE
538 	--falls outside the last record
539           v_end_record :=g_res_tab.LAST+1;
540         END IF;
541 
542  ELSE
543      IF (    g_change_rec.to_time <=
544 	     g_res_tab(1).from_time    ) THEN
545 	-- the change ends before the first record
546 	v_end_record :=0;
547      ELSE
548 
549         While (j is not null) and
550            	 (   g_change_rec.to_time >
551                      g_res_tab(j).from_time    )
552         LOOP
553               j:=g_res_tab.next(j);
554         END LOOP;
555 
556         IF j is null THEN
557 	-- if j is null, then the change ends on or outside the last record
558            i :=g_res_tab.LAST;
559            IF ( g_res_tab(i).to_time is null ) THEN
560               v_end_record :=g_res_tab.LAST;
561            ELSE
562           	IF (g_change_rec.to_time <=
563                 	g_res_tab(i).to_time ) THEN
564                 	v_end_record :=g_res_tab.LAST;
565            	ELSE
566               		v_end_record :=g_res_tab.LAST+1;
567            	END IF;
568 	   END IF;
569 
570         ELSE
571 	   IF (g_change_rec.to_time <=
572                 g_res_tab(j-1).to_time ) THEN
573 	   -- change ends on the previous record
574 	        v_end_record := j-1;
575 	   ELSE
576 	   -- change ends in the gap between record j-1 and record j
577 		v_end_record := j-0.5;
578 	   END IF;
579    	END IF;
580      END IF;
581  END IF;
582 
583 -- flush the records to tmp_tab
584    k:=0;
585    g_tmp_tab.delete;
586 
587  IF g_change_rec.operation <> OP_SET THEN
588 
589     IF ( v_start_record =0 ) THEN
590 	   IF g_change_rec.operation not in (OP_DEL, OP_DEL_DAY) THEN
591                 add_new_record(1,false,false);
592                 v_undo_id :=insert_undo_data(1); -- insert
593 	   	IF (v_end_record <> 0) THEN
594 	      		g_tmp_tab(k).to_time :=
595 			g_res_tab(1).from_time;
596 	   	END IF;
597 
598 		-- if add non working day, set the updated field as 1
599 		-- so that when re-plan, it will be treated as work day
600 
601 	 	IF g_change_rec.operation = OP_ADD_DAY THEN
602 			g_tmp_tab(k).updated :=1;
603 		END IF;
604 	   END IF;
605    END IF;
606 
607    j:=g_res_tab.FIRST;
608    While (j is not null)
609    LOOP
610 
611       v_undo_parent_id := null;
612 
613       IF (j < v_start_record) or (j > v_end_record) THEN
614 		-- no change, just copy the old record
615                 add_new_record(j, true,true);
616 
617       ELSIF (j > v_start_record) and (j<v_end_record) THEN
618 	       -- the whole record is affected, change the qty
619                        add_new_record(j, true,true);
620        IF g_change_rec.operation = OP_ADD THEN
621           g_tmp_tab(k).capacity_units :=
622                               g_res_tab(j).capacity_units +
623                               g_change_rec.capacity_units ;
627                               g_change_rec.capacity_units ;
624        ELSIF g_change_rec.operation = OP_DEL THEN
625           g_tmp_tab(k).capacity_units :=
626                               g_res_tab(j).capacity_units -
628 
629        END IF;
630            v_undo_id :=insert_undo_data(2,j); -- update
631       ELSIF (j=v_start_record) and (j = v_end_record) THEN
632 		   -- need to cut the record into three records
633              IF (g_change_rec.from_time <>
634                         g_res_tab(j).from_time ) THEN
635                         -- need to change the date for the first record
636                        add_new_record(j, true,true); -- retain old tran_id
637                         g_tmp_tab(k).to_time:=
638                              g_change_rec.from_time;
639                         v_undo_parent_id :=insert_undo_data(2,j); --update
640 
641 	     END IF;
642 
643 	     -- add a new record
644 	     -- delete work day and add non working day would be caught
645 	     -- here only if it falls inside the range and not in a gap,
646              --	because v_start_record will always = v_end_record in these cases
647 
648 	     IF g_change_rec.operation <> OP_DEL_DAY THEN
649                         if v_undo_parent_id is not null then
650                            add_new_record(j,false,false);
651                         else -- retain old transaction_id
652                            add_new_record(j,false,true);
653                         end if;
654                         IF g_change_rec.operation = OP_ADD THEN
655                            g_tmp_tab(k).capacity_units :=
656                               g_res_tab(j).capacity_units +
657                               g_change_rec.capacity_units ;
658                         ELSIF g_change_rec.operation = OP_DEL THEN
659                            g_tmp_tab(k).capacity_units :=
660                               g_res_tab(j).capacity_units -
661                               g_change_rec.capacity_units ;
662 
663 			-- don't add onto the quantity of the original record
664 			ELSIF g_change_rec.operation = OP_ADD_DAY THEN
665 			   g_tmp_tab(k).updated :=1;
666 
667                         END IF;
668                         if v_undo_parent_id is not null then
669                            v_undo_id :=
670                              insert_undo_data(1,j,v_undo_parent_id); -- insert
671                         else
672                            v_undo_parent_id:=insert_undo_data(2,j); -- update
673                         end if;
674 	     END IF;
675 
676              IF (g_change_rec.to_time <>
677                         g_res_tab(j).to_time ) or
678 		( g_res_tab(j).to_time is null and
679 		g_change_rec.to_time is not null) THEN
680                         -- need to change the date for the third record
681                         if v_undo_parent_id is not null then
682                            add_new_record(j,true,false);
683                         else -- retain old transaction_id
684                            add_new_record(j,true,true);
685                         end if;
686                         g_tmp_tab(k).from_time:=
687                              g_change_rec.to_time;
688                         if v_undo_parent_id is not null then
689                            v_undo_id :=
690                              insert_undo_data(1,j,v_undo_parent_id); -- insert
691                         else
692                            v_undo_parent_id:=insert_undo_data(2,j); -- update
693                         end if;
694 	     END IF;
695 
696       ELSIF (j=v_start_record) and (j <> v_end_record) THEN
697 		   -- need to cut the record
698              IF (g_change_rec.from_time <>
699                         g_res_tab(j).from_time ) THEN
700                         -- need to change the date
701                         add_new_record(j,true,true);
702                         g_tmp_tab(k).to_time:=
703                              g_change_rec.from_time;
704                         v_undo_parent_id :=insert_undo_data(2,j); --update
705 	     END IF;
706 
707 			-- and add a new record
708                         if v_undo_parent_id is not null then
709                            add_new_record(j,false,false);
710                         else -- retain old transaction_id
711                            add_new_record(j,false,true);
712                         end if;
713                         g_tmp_tab(k).to_time:=
714                              g_res_tab(j).to_time;
715                         IF g_change_rec.operation = OP_ADD THEN
716                            g_tmp_tab(k).capacity_units :=
717                               g_res_tab(j).capacity_units +
718                               g_change_rec.capacity_units ;
719                         ELSIF g_change_rec.operation = OP_DEL THEN
720                            g_tmp_tab(k).capacity_units :=
721                               g_res_tab(j).capacity_units -
722                               g_change_rec.capacity_units ;
723                         END IF;
724                         if v_undo_parent_id is not null then
725                            v_undo_id :=
726                              insert_undo_data(1,j,v_undo_parent_id); -- insert
727                         else
728                            v_undo_parent_id:=insert_undo_data(2,j); -- update
729                         end if;
730 
731       ELSIF (j=v_end_record) and (j <> v_start_record) THEN
732 		   -- need to cut the record
733 			--  add a new record
734                         add_new_record(j,false,true);
735                         g_tmp_tab(k).from_time:=
736                              g_res_tab(j).from_time;
737                         IF g_change_rec.operation = OP_ADD THEN
738                            g_tmp_tab(k).capacity_units :=
739                               g_res_tab(j).capacity_units +
743                               g_res_tab(j).capacity_units -
740                               g_change_rec.capacity_units ;
741                         ELSIF g_change_rec.operation = OP_DEL THEN
742                            g_tmp_tab(k).capacity_units :=
744                               g_change_rec.capacity_units ;
745                         END IF;
746                         v_undo_parent_id :=insert_undo_data(2,j);
747              IF (g_change_rec.to_time <>
748                         g_res_tab(j).to_time ) or
749 		(g_change_rec.to_time is not null and
750 		g_res_tab(j).to_time is null )THEN
751                         -- need to change the date
752                         add_new_record(j,true,false);
753                         g_tmp_tab(k).from_time:=
754                              g_change_rec.to_time;
755                         v_undo_id :=insert_undo_data(1,j,v_undo_parent_id);
756 	     END IF;
757       END IF;
758 
759       -- if change starts or ends in the gap, need to insert new row
760       IF g_change_rec.operation not in  (OP_DEL_DAY, OP_DEL) THEN
761 
762          IF (v_start_record >j ) and (v_start_record <j+1 ) THEN
763                add_new_record(j,false,false);
764                v_undo_id :=insert_undo_data(1);
765 	    IF (g_change_rec.to_time >=
766                         g_res_tab(j+1).from_time or
767 		g_change_rec.to_time is null) THEN
768 		--the change extends over the gap, need to change the end date
769 		g_tmp_tab(k).to_time:=
770 			g_res_tab(j+1).from_time;
771 	    END IF;
772 
773 	 ELSIF (v_end_record >j ) and (v_end_record <j+1 ) THEN
774             add_new_record(j,false,false);
775             v_undo_id :=insert_undo_data(1);
776             IF (g_change_rec.from_time <=
777                         g_res_tab(j).to_time ) THEN
778                 --the change extends over the gap, need to change start date
779                 g_tmp_tab(k).from_time:=
780                         g_res_tab(j).to_time;
781             END IF;
782 	 END IF;
783       END IF;
784 
785       j:=g_res_tab.next(j);
786    END LOOP;
787 
788    -- if the record falls outside the original range, add a new row
789    i := g_res_tab.LAST;
790    IF (v_end_record = i+1) THEN
791 	   IF g_change_rec.operation not in (OP_DEL_DAY, OP_DEL) THEN
792                 add_new_record(i,false,false);
793                 v_undo_id :=insert_undo_data(1,j,v_undo_parent_id);
794 	   	IF (v_start_record <> i +1 ) THEN
795            		g_tmp_tab(k).from_time:=
796 				g_res_tab(i).to_time;
797 	   	END IF;
798 	 	IF g_change_rec.operation = OP_ADD_DAY THEN
799 			g_tmp_tab(k).updated :=1;
800 		END IF;
801 	   END IF;
802    END IF;
803 
804  ELSIF g_change_rec.operation= OP_SET THEN
805 
806         i := g_res_tab.LAST;
807 
808 	IF (v_start_record = 0) THEN
809 
810 	--if change falls before the range, add a row, go to the end record
811 	--cut record if needed, then go to the next record
812            add_new_record(1,false,false);
813            v_undo_id :=insert_undo_data(1);
814 	   -- if the set record ends outside the range, don't have to loop
815 	   IF (v_end_record = i+1) THEN
816 		j:='';
817 	   ELSIF (v_end_record=0) THEN
818 	   -- the change ends before the range, loop from record1
819 		j:=g_res_tab.FIRST;
820 	   ELSIF (v_end_record > trunc(v_end_record)) THEN
821 	   -- change falls on a gap, go to the record after the gap
822 		j:=trunc(v_end_record)+1;
823 	  -- if the set record ends outside the range, don't have to loop
824 	   ELSIF (v_end_record < i+1) THEN
825 	   -- go to where the set record ends and add row if needed
826              	j:=v_end_record;
827 
828              IF (g_change_rec.to_time <
829                         g_res_tab(j).to_time ) or
830 		(g_res_tab(j).to_time is null and
831 		g_change_rec.to_time is not null) THEN
832 
833                 -- need to add row for the date change
834                 add_new_record(j,true,false);
835                 g_tmp_tab(k).from_time :=
836                         g_change_rec.to_time;
837                 v_undo_id :=insert_undo_data(1);
838              END IF;
839     	     --go to the next record, and ready for loop
840 	     j:=j+1;
841 	   END IF;
842 	ELSE
843 	   j:=g_res_tab.FIRST;
844 	END IF;
845 
846         IF j < i+1 THEN
847 	While ( j is not null ) LOOP
848 	   IF (j < v_start_record) or (j > v_end_record) THEN
849 		-- no change
850                    add_new_record(j,true,true);
851 	   ELSIF (j=v_start_record) THEN
852  	     v_undo_parent_id := null;
853 	     IF (g_change_rec.from_time >
854 			g_res_tab(j).from_time ) THEN
855 		-- need to insert row with date change only first
856                 add_new_record(j,true,true);
857 		g_tmp_tab(k).to_time :=
858 			g_change_rec.from_time;
859                 v_undo_parent_id :=insert_undo_data(2,j);
860 	     END IF;
861 
862 	     -- add new row
863              if v_undo_parent_id is not null then
864                     add_new_record(j,false,false);
865                     v_undo_id :=
866                              insert_undo_data(1,j,v_undo_parent_id); -- insert
867              else -- retain old transaction_id
868                     add_new_record(j,false,true);
869                     v_undo_parent_id := insert_undo_data(2,j);
870              end if;
871 
872 	     IF (v_end_record > trunc(v_end_record)) THEN
873              -- change ends on a gap,
874                j:=trunc(v_end_record);
875              ELSIF (v_end_record < i+1) THEN
876 	     -- go the where the set record ends, and add row if needed
877 	        j:=v_end_record;
878                 IF (g_change_rec.to_time <
879                         g_res_tab(j).to_time ) or
883                 -- need to add row for the date change
880 		   (g_change_rec.to_time is not null and
881 		    g_res_tab(j).to_time is null) THEN
882 
884                    add_new_record(j,true,false);
885                    g_tmp_tab(k).from_time :=
886                         g_change_rec.to_time;
887                    v_undo_id :=
888                              insert_undo_data(1,j,v_undo_parent_id); -- insert
889 		END IF;
890              END IF;
891 
892 	   END IF;
893 
894 	   -- if change starts on a gap
895 	   IF (v_start_record > j) and (v_start_record < j+1) THEN
896              -- add new row
897              add_new_record(j,false,true);
898              v_undo_parent_id :=insert_undo_data(2,j);
899 	     IF (v_end_record > trunc(v_end_record)) THEN
900               -- change ends on a gap,
901                 j:=trunc(v_end_record);
902              ELSIF (v_end_record < i+1) THEN
903              -- go to where the set record ends, and add row if needed
904                 j:=v_end_record;
905                 IF (g_change_rec.to_time <
906                         g_res_tab(j).to_time ) or
907 		   (g_change_rec.to_time is not null and
908 		    g_res_tab(j).to_time is null)  THEN
909 
910                 -- need to add row for the date change
911                    add_new_record(j,true,false);
912                    g_tmp_tab(k).from_time :=
913                         g_change_rec.to_time;
914                    v_undo_id :=
915                              insert_undo_data(1,j,v_undo_parent_id); -- insert
916 	        END IF;
917              END IF;
918 	   END IF;
919 
920 	   j:=g_res_tab.next(j);
921 	END LOOP;
922        END IF;
923 
924 	-- if the set record starts outside the range
925 	i:=g_res_tab.LAST;
926 	IF (v_start_record = i+1 ) THEN
927                -- need to add row for the date change
928                 add_new_record(i,false,false);
929                 v_undo_id :=insert_undo_data(1);
930 	END IF;
931  END IF;
932 
933 ELSE --user enters a resource which is not in msc_net_resource_avail table
934    g_tmp_tab.delete;
935    add_new_record(0,false,false);
936    v_undo_id :=insert_undo_data(1);
937 END IF;
938 
939  g_res_tab :=g_tmp_tab;
940 
941 END calculate_change;
942 
943 FUNCTION get_inst_trx_id RETURN NUMBER IS
944   v_trx_id NUMBER;
945 BEGIN
946      select msc_net_res_inst_avail_s.nextval
947      into v_trx_id
948      from dual;
949     return v_trx_id;
950 END;
951 ------------------------------------------------------------------------
952 --to update msc_net_resource_avail table
953 -----------------------------------------------------------------------------
954 PROCEDURE update_table IS
955 CURSOR bucket IS
956         SELECT mpb.bkt_start_date, mpb.bkt_end_date
957         FROM   msc_plan_buckets mpb,
958                msc_plans mp
959         where  mp.plan_id = g_plan_id
960           and  mp.plan_id = mpb.plan_id
961           and  mp.organization_id = mpb.organization_id
962           and  mp.sr_instance_id = mpb.sr_instance_id
963           and  mpb.curr_flag =1
964           and  g_shift_date between mpb.bkt_start_date and mpb.bkt_end_date;
965 
966 m 	INTEGER;
967 v_start_date DATE;
968 v_end_date   DATE;
969 v_capacity_units NUMBER;
970 
971   l_units number;
972   l_res_inst_trx_id number;
973   l_res_inst_units number;
974   l_res_inst_undo_id number;
975 BEGIN
976   if g_resource_exist then
977 
978      for m in 1..g_res_tab.LAST loop
979 /*
980 dbms_output.put_line('del for tran='||to_char(g_res_tab(m).transaction_id));
981 dbms_output.put_line('capacity_units='||to_char(g_res_tab(m).capacity_units));
982 */
983        delete from msc_net_resource_avail
984         where plan_id = g_plan_id
985           and transaction_id = g_res_tab(m).transaction_id
986           and g_res_tab(m).from_time <> g_res_tab(m).to_time;
987      end loop;
988 
989      update msc_net_resource_avail
990         set capacity_units = -1,
991             status =0,
992             applied =2,
993             from_time = from_time+1,
994             to_time = to_time +1
995 	where plan_id = g_plan_id
996 	and   organization_id = g_org_id
997         and   sr_instance_id = g_instance_id
998         AND   department_id = g_department_id
999         AND   resource_id = g_resource_id
1000         AND   nvl(parent_id, 0) <> -1
1001         AND   shift_date = g_shift_date
1002         AND   decode(resource_id, -1,-1,shift_num) =
1003                  decode(resource_id,-1,-1,g_shift_number) ;
1004   end if;
1005 
1006   if (g_res_inst_set_data) then
1007    For m in 1 .. g_res_inst_tab.LAST LOOP
1008        update msc_net_res_inst_avail
1009        set capacity_units = 0,
1010             status =0,
1011             applied =2
1012 	where plan_id = g_plan_id
1013           and inst_transaction_id = g_res_inst_tab(m).transaction_id
1014           and g_res_inst_tab(m).from_time <> g_res_inst_tab(m).to_time;
1015    end loop;
1016   end if;
1017 
1018 
1019    For m in 1 .. g_res_tab.LAST LOOP
1020 
1021       IF g_res_tab(m).from_time <> g_res_tab(m).to_time THEN
1022 /*
1023 dbms_output.put_line('insert for tran='||to_char(g_res_tab(m).transaction_id));
1024 dbms_output.put_line('date='||g_shift_date);
1025 dbms_output.put_line('from='||to_char(g_res_tab(m).from_time));
1026 dbms_output.put_line('to='||to_char(g_res_tab(m).to_time));
1027 dbms_output.put_line('simulation='||to_char(g_res_tab(m).simulation_set));
1028 dbms_output.put_line('capacity_units='||to_char(g_res_tab(m).capacity_units));
1029 */
1030         l_units := greatest(g_res_tab(m).capacity_units,0);
1034             if (g_units = 0) then
1031         --dbms_output.put_line('capacity_units 1='||l_units);
1032 	if (g_res_inst_set_data) then
1033 	  if (g_from_time = g_res_tab(m).from_time and g_to_time = g_res_tab(m).to_time) then
1035 	      l_units := greatest(g_res_tab(m).capacity_units,0);
1036 	      l_res_inst_units := 0;
1037 	    else -- g_units = 1
1038 	      l_units := greatest(g_res_tab(m).capacity_units+1,0);
1039 	      l_res_inst_units := 1;
1040 	    end if;
1041 	  else
1042 	      begin
1043 	      l_res_inst_units := g_res_inst_tab(m).capacity_units;
1044 	      exception
1045 	        when others then
1046 	          if (l_units = 0) then
1047   	            l_res_inst_units := 0;
1048                   else
1049   	            l_res_inst_units := 1;
1050 	          end if;
1051 	      end;
1052   	  end if;
1053 	end if;
1054         --dbms_output.put_line('capacity_units 2 ='||l_units);
1055 
1056 	INSERT INTO msc_net_resource_avail
1057                 (plan_id,
1058                  parent_id,
1059                  transaction_id,
1060                  organization_id,
1061                  sr_instance_id,
1062                  department_id,
1063                  resource_id,
1064                  shift_date,
1065                  shift_num,
1066                  from_time,
1067                  to_time,
1068                  capacity_units,
1069                  simulation_set,
1070                  status,
1071                  applied,
1072 		 updated,
1073                  last_update_date,
1074                  last_updated_by,
1075                  creation_date,
1076                  created_by,
1077                  last_update_login)
1078                VALUES
1079                 (g_plan_id,
1080                  -2,
1081                  g_res_tab(m).transaction_id,
1082                  g_org_id,
1083                  g_instance_id,
1084                  g_department_id,
1085                  g_resource_id,
1086 		 g_shift_date,
1087                  decode(g_resource_id, -1, null,g_shift_number),
1088                  g_res_tab(m).from_time,
1089                  g_res_tab(m).to_time,
1090                  l_units,
1091                  g_res_tab(m).simulation_set,
1092               	 g_res_tab(m).status,
1093                  g_res_tab(m).applied,
1094 		 g_res_tab(m).updated,
1095                  g_res_tab(m).last_update_date,
1096                  g_res_tab(m).last_updated_by,
1097                  g_res_tab(m).creation_date,
1098                  g_res_tab(m).created_by,
1099                  g_res_tab(m).last_update_login);
1100 
1101 /*
1102 dbms_output.put_line('RESOURCE -inst trx/shift/from/to/units '|| g_res_tab(m).transaction_id
1103   ||' - '||g_shift_number||' - '||g_res_tab(m).from_time||' - '||g_res_tab(m).to_time||' - '|| l_units);
1104 */
1105 
1106        if (g_res_inst_set_data) then
1107        if (m <= g_res_inst_tab.last) then
1108 /*
1109 dbms_output.put_line('INSTANCE res-inst trx/shift/from/to/units '||g_res_inst_tab(m).transaction_id
1110   ||' - '||g_shift_number||' - '||g_res_tab(m).from_time||' - '||g_res_tab(m).to_time||' - '|| l_res_inst_units);
1111 */
1112 
1113        update msc_net_res_inst_avail
1114        set capacity_units = l_res_inst_units,
1115 	    shift_date = g_shift_date,
1116             shift_num = g_shift_number,
1117 	    from_time = g_res_tab(m).from_time,
1118 	    to_time = g_res_tab(m).to_time,
1119             status =0,
1120             applied =2
1121 	where plan_id = g_plan_id
1122           and inst_transaction_id = g_res_inst_tab(m).transaction_id;
1123 
1124         if (sql%rowcount <> 0) then
1125 	  l_res_inst_undo_id :=  insert_res_inst_undo_data(2,
1126 			 g_res_inst_tab(m).transaction_id,
1127                          fnd_date.date_to_canonical(g_res_inst_tab(m).shift_date),
1128 			 fnd_date.date_to_canonical(g_shift_date),
1129                          g_res_inst_tab(m).shift_number, g_shift_number,
1130                          g_res_inst_tab(m).from_time, g_res_tab(m).from_time,
1131                          g_res_inst_tab(m).to_time, g_res_tab(m).to_time,
1132                          g_res_inst_tab(m).capacity_units, l_res_inst_units,
1133                          null);
1134         end if;
1135 	end if;
1136 
1137         if (sql%rowcount = 0 or m > g_res_inst_tab.last) then
1138 	  l_res_inst_trx_id := get_inst_trx_id;
1139          insert into msc_net_res_inst_avail (
1140            inst_transaction_id,
1141            last_update_date, last_updated_by, creation_date, created_by, last_update_login,
1142 	   plan_id, sr_instance_id, organization_id, department_id, resource_id,
1143 	   res_instance_id, serial_number, shift_num, shift_date,
1144            from_time, to_time, simulation_set, capacity_units)
1145          values (
1146            l_res_inst_trx_id,
1147            sysdate, fnd_global.user_id, sysdate,fnd_global.user_id, fnd_global.user_id,
1148            g_plan_id, g_instance_id, g_org_id, g_department_id, g_resource_id, g_res_inst_id,
1149 	   g_serial_number, g_shift_number, g_shift_date,
1150 	   g_res_tab(m).from_time, g_res_tab(m).to_time, g_res_tab(m).simulation_set, l_res_inst_units);
1151 
1152 	   --dbms_output.put_line('res-inst insert '||l_res_inst_trx_id||' - '||g_shift_number
1153 	     --||' - '||g_res_tab(m).from_time||' - '||g_res_tab(m).to_time||' - '|| l_res_inst_units);
1154 	  l_res_inst_undo_id :=  insert_res_inst_undo_data(1,
1155 			 l_res_inst_trx_id,
1156                          null, null,
1157                          null, null,
1158                          null, null,
1159                          null, null,
1160                          null, null,
1161                          null);
1162 
1163 	end if;
1164 
1165 	end if;
1166 	END IF;
1167    END LOOP;
1168 
1169   -- update the parent record
1170 
1174 
1171    OPEN bucket;
1172    FETCH bucket into v_start_date, v_end_date;
1173    CLOSE bucket;
1175      v_capacity_units :=0;
1176      begin
1177       select round(sum(decode(sign(to_time-from_time),1,(to_time - from_time),
1178                                     (to_time+86400-from_time)
1179                              )/3600*capacity_units),6)
1180       into v_capacity_units
1181       from msc_net_resource_avail
1182       where plan_id = g_plan_id
1183 	and   organization_id = g_org_id
1184         and   sr_instance_id = g_instance_id
1185         AND   department_id = g_department_id
1186         AND   resource_id = g_resource_id
1187         and   nvl(parent_id, 0) <> -1
1188         and   capacity_units >0
1189         and   shift_date between v_start_date and v_end_date;
1190      exception when no_data_found then
1191         v_capacity_units :=0;
1192      end;
1193 
1194      v_capacity_units := nvl(v_capacity_units,0);
1195 
1196  -- update the resource units for parent record
1197      update msc_net_resource_avail
1198      set capacity_units = v_capacity_units,
1199          status =0,
1200          applied =2,
1201          updated =2
1202      where  plan_id = g_plan_id
1203 	and   organization_id = g_org_id
1204         and   sr_instance_id = g_instance_id
1205         AND   department_id = g_department_id
1206         AND   resource_id = g_resource_id
1207         and   shift_date = v_start_date
1208         and   parent_id =-1;
1209 
1210 -- update the parent_id for the added record
1211      update msc_net_resource_avail
1212      set parent_id = g_res_tab(1).parent_id
1213      where  plan_id = g_plan_id
1214 	and   organization_id = g_org_id
1215         and   sr_instance_id = g_instance_id
1216         AND   department_id = g_department_id
1217         AND   resource_id = g_resource_id
1218         and   parent_id = -2 ;
1219 
1220 END update_table;
1221 
1222 ------------------------------------------------------------------------
1223 --to get transaction_id from msc_net_resource_avail table
1224 -----------------------------------------------------------------------------
1225 FUNCTION get_transaction_id RETURN NUMBER IS
1226   v_transaction_id NUMBER;
1227 BEGIN
1228     select msc_net_resource_avail_s.nextval
1229     into v_transaction_id
1230     from dual;
1231 
1232     return v_transaction_id;
1233 END;
1234 
1235 ------------------------------------------------------------------------
1236 --to get transaction_id from msc_net_resource_avail table
1237 -----------------------------------------------------------------------------
1238 PROCEDURE add_new_record(m NUMBER, retain_old boolean default false,
1239                          retain_id boolean default false) IS
1240 
1241   l_units number;
1242 BEGIN
1243     k :=k +1;
1244     if retain_id then
1245        g_tmp_tab(k).transaction_id := g_res_tab(m).transaction_id;
1246     else
1247        g_tmp_tab(k).transaction_id := get_transaction_id;
1248     end if;
1249     g_tmp_tab(k).parent_id := g_res_tab(m).parent_id;
1250     g_tmp_tab(k).aggregate_resource_id :=
1251                g_res_tab(m).aggregate_resource_id;
1252     g_tmp_tab(k).simulation_set := g_res_tab(m).simulation_set;
1253     if retain_old then
1254        g_tmp_tab(k).from_time := g_res_tab(m).from_time;
1255        g_tmp_tab(k).to_time := g_res_tab(m).to_time;
1256        g_tmp_tab(k).capacity_units := g_res_tab(m).capacity_units;
1257     else
1258        g_tmp_tab(k).from_time := g_change_rec.from_time;
1259        g_tmp_tab(k).to_time := g_change_rec.to_time;
1260        if (g_res_inst_set_data) then
1261          if (g_change_rec.capacity_units = 0 ) then
1262 	    l_units := -1;
1263 	 else
1264 	    l_units := 1;
1265 	 end if;
1266          g_tmp_tab(k).capacity_units := greatest(g_res_tab(m).capacity_units + l_units,0);
1267        else
1268          g_tmp_tab(k).capacity_units := g_change_rec.capacity_units;
1269        end if;
1270     end if;
1271     g_tmp_tab(k).status := 0;
1272     g_tmp_tab(k).applied := 2;
1273 --    g_tmp_tab(k).updated := 2;
1274     g_tmp_tab(k).last_update_date := sysdate;
1275     g_tmp_tab(k).last_updated_by := g_change_rec.last_updated_by;
1276     g_tmp_tab(k).creation_date := sysdate;
1277     g_tmp_tab(k).created_by := g_change_rec.last_updated_by;
1278 
1279 /*
1280 dbms_output.put_line('add_new_record tmp-trx-from-to-units '||g_tmp_tab(k).transaction_id||' - '||
1281   g_tmp_tab(k).from_time||' - '||g_tmp_tab(k).to_time||' - '||g_tmp_tab(k).capacity_units);
1282 
1283 dbms_output.put_line('add_new_record res-trx-from-to-units '||g_res_tab(m).transaction_id||' - '||
1284   g_res_tab(m).from_time||' - '||g_res_tab(m).to_time||' - '||g_res_tab(m).capacity_units);
1285 */
1286 END;
1287 
1288 
1289 -------------------------------------------------------------------
1290 -- to group the child record to parent record
1291 -------------------------------------------------------------------
1292 PROCEDURE aggregate_child_records(v_plan_id NUMBER) IS
1293 
1294  CURSOR net_resource IS
1295    SELECT res.department_id, res.resource_id,
1296           res.organization_id, res.sr_instance_id
1297    FROM   msc_department_resources res
1298    WHERE  plan_id = v_plan_id;
1299 
1300  TYPE resource_table IS RECORD
1301  (   dept_id NUMBER,
1302      res_id NUMBER,
1303      org_id NUMBER,
1304      instance_id NUMBER);
1305 
1306  v_res_table resource_table;
1307 
1308  v_dept_id number:=0;
1309  v_res_id number:=0;
1310  v_org_id number:=0;
1311  v_instance_id number:=0;
1312 
1313 BEGIN
1314 
1315    -- loop thru each dept/resource
1316 
1317    open net_resource;
1318    LOOP
1319      FETCH net_resource into v_res_table;
1320      EXIT WHEN net_resource%NOTFOUND;
1321 
1325       v_res_id := v_res_table.res_id;
1322    -- for each new dept/resource
1323 
1324       v_dept_id := v_res_table.dept_id;
1326       v_org_id := v_res_table.org_id;
1327       v_instance_id := v_res_table.instance_id;
1328 
1329    -- delete old parent record first
1330 
1331      delete from msc_net_resource_avail
1332      where plan_id = v_plan_id
1333      AND organization_id = v_org_id
1334      AND sr_instance_id =v_instance_id
1335      AND department_id = v_dept_id
1336      AND resource_id = v_res_id
1337      and parent_id =-1;
1338 
1339       aggregate_one_resource(v_plan_id, v_org_id, v_instance_id,
1340                              v_dept_id, v_res_id);
1341    END LOOP;
1342    close net_resource;
1343 END;
1344 
1345 PROCEDURE aggregate_some_resources(v_plan_id NUMBER,
1346                                   p_org_instance_list varchar2,
1347                                   p_dept_class_list VARCHAR2,
1348                                   p_res_group_list VARCHAR2,
1349                                   p_dept_list varchar2,
1350                                   p_res_list  varchar2,
1351                                   p_line_list VARCHAR2) IS
1352   where_statement varchar2(1000);
1353   TYPE res_cursor_type IS REF CURSOR;
1354   res_cursor res_cursor_type;
1355   sql_statement varchar2(1500);
1356 
1357  TYPE resource_table IS RECORD
1358  (   dept_id NUMBER,
1359      res_id NUMBER,
1360      org_id NUMBER,
1361      instance_id NUMBER);
1362 
1363  v_res_table resource_table;
1364 
1365 BEGIN
1366 
1367 
1368 
1369   IF p_dept_list IS NOT NULL THEN
1370     where_statement := where_statement ||
1371         ' and department_id in (' || p_dept_list || ')';
1372   ELSIF p_dept_class_list IS NOT NULL THEN
1373     where_statement := where_statement ||
1374         ' and department_id in (select distinct department_id ' ||
1375         ' from msc_department_resources where NVL(department_class,''@@@'') '||
1376         ' in (' || p_dept_class_list || ') and plan_id = '
1377            ||to_char(v_plan_id)||
1378         ' and (sr_instance_id, organization_id) in ('||p_org_instance_list ||'))';
1379   ELSIF p_res_group_list IS NOT NULL THEN
1380     where_statement := where_statement ||
1381         ' and (department_id, resource_id) in (select '||
1382         ' department_id, resource_id from msc_department_resources where ' ||
1383         ' NVL(resource_group_name,''@@@'') in ('
1384         || p_res_group_list || ') and '||
1385         ' plan_id = '||to_char(v_plan_id)||
1386         ' and (sr_instance_id, organization_id) in ('||
1387         p_org_instance_list ||'))';
1388   END IF;
1389   IF p_line_list IS NOT NULL THEN
1390     where_statement := where_statement ||
1391         ' and department_id IN (' || p_line_list || ')';
1392   END IF;
1393   IF p_res_list IS NOT NULL THEN
1394     where_statement := where_statement ||
1395         ' and resource_id IN (' || p_res_list || ')';
1396   END IF;
1397 
1398   where_statement := where_statement ||
1399        ' ORDER BY organization_id, sr_instance_id, department_id, resource_id';
1400   if p_org_instance_list is not null then
1401     sql_statement :=
1402         'SELECT distinct department_id, resource_id, '||
1403                        'organization_id, sr_instance_id '||
1404         'FROM msc_net_resource_avail '||
1405         'WHERE plan_id = '||to_char(v_plan_id) ||
1406          ' AND nvl(parent_id, 0) <> -1 ' ||
1407          ' AND (sr_instance_id, organization_id) in ('||
1408                     p_org_instance_list ||')' || where_statement;
1409   else
1410      sql_statement :=
1411         'SELECT distinct department_id, resource_id, '||
1412                        'organization_id, sr_instance_id '||
1413         'FROM msc_net_resource_avail '||
1414         'WHERE plan_id = '||to_char(v_plan_id) ||
1415          ' AND nvl(parent_id, 0) <> -1 ' || where_statement;
1416   end if;
1417 
1418 
1419   OPEN res_cursor FOR sql_statement;
1420   LOOP
1421   FETCH res_cursor INTO v_res_table;
1422      EXIT WHEN res_cursor%NOTFOUND;
1423      aggregate_one_resource(v_plan_id, v_res_table.org_id,
1424                             v_res_table.instance_id,v_res_table.dept_id,
1425                             v_res_table.res_id);
1426   END LOOP;
1427   CLOSE res_cursor;
1428 
1429 END;
1430 
1431 PROCEDURE aggregate_one_resource(v_plan_id NUMBER,
1432                                   p_org_id NUMBER,
1433                                   p_instance_id NUMBER,
1434                                   p_dept_id NUMBER,
1435                                   p_res_id  NUMBER) IS
1436  CURSOR bucket IS
1437    SELECT mpb.bkt_start_date, mpb.bkt_end_date
1438    FROM   msc_plan_buckets mpb,
1439           msc_plans mp
1440    WHERE  mp.plan_id = v_plan_id
1441      and  mp.plan_id = mpb.plan_id
1442      and  mp.sr_instance_id = mpb.sr_instance_id
1443      and  mp.organization_id = mpb.organization_id
1444      and  mpb.curr_flag =1
1445    order by mpb.bucket_index;
1446 
1447  v_new_capacity_units number;
1448  i number;
1449  v_transaction_id number;
1450 
1451   TYPE BucketRecTyp IS RECORD (
1452          start_date  DATE,
1453          end_date    DATE);
1454 
1455   TYPE BucketTabTyp IS TABLE OF BucketRecTyp INDEX BY BINARY_INTEGER;
1456   v_bucket   BucketTabTyp;
1457 
1458  dummy number;
1459 
1460  CURSOR parent_record IS
1461     select 1
1462     from msc_net_resource_avail
1463     where plan_id = v_plan_id
1464       and sr_instance_id = p_instance_id
1465       and organization_id = p_org_id
1466       and department_id = p_dept_id
1467       and resource_id = p_res_id
1468       and parent_id =-1
1469       and rownum <2;
1470 
1474                        )/3600*capacity_units)
1471  CURSOR time_record(v_start_date DATE, v_end_date DATE) IS
1472      select sum(decode(sign(to_time-from_time),-1,(to_time+86400 - from_time),
1473                             (to_time-from_time)
1475        from msc_net_resource_avail
1476        where plan_id = v_plan_id
1477        and   sr_instance_id = p_instance_id
1478        and   organization_id = p_org_id
1479         AND   department_id = p_dept_id
1480         AND   resource_id = p_res_id
1481         and   capacity_units >0
1482         and   nvl(parent_id,0) <> -1
1483         and   trunc(shift_date) between trunc(v_start_date)
1484                     and trunc(v_end_date);
1485 
1486  v_agg_resource number;
1487  CURSOR agg_resource IS
1488    SELECT aggregate_resource_flag
1489      from msc_department_resources
1490     where plan_id = v_plan_id
1491        and   sr_instance_id = p_instance_id
1492        and   organization_id = p_org_id
1493         AND   department_id = p_dept_id
1494         AND   resource_id = p_res_id;
1495 /*
1496 CURSOR agg_record(v_start_date DATE, v_end_date DATE) IS
1497      select sum(capacity_units)
1498        from msc_net_resource_avail
1499        where plan_id = v_plan_id
1500        and   sr_instance_id = p_instance_id
1501        and   organization_id = p_org_id
1502         AND   department_id = p_dept_id
1503         AND   resource_id = p_res_id
1504         and   capacity_units >0
1505         and   trunc(shift_date) between trunc(v_start_date)
1506                     and trunc(v_end_date);
1507 */
1508 
1509 BEGIN
1510 
1511    -- if it is an aggregate resource, don't create parent record
1512     OPEN agg_resource;
1513     FETCH agg_resource INTO v_agg_resource;
1514     CLOSE agg_resource;
1515 
1516 IF nvl(v_agg_resource,2) =2 THEN
1517    -- check if the parent record is created already
1518 
1519     OPEN parent_record;
1520     FETCH parent_record into dummy;
1521     CLOSE parent_record;
1522 IF dummy is null THEN
1523 
1524    -- populate the bucket dates
1525    i :=1;
1526    open bucket;
1527    LOOP
1528        FETCH bucket into v_bucket(i);
1529        EXIT WHEN bucket%NOTFOUND;
1530        i := i+1;
1531    END LOOP;
1532    close bucket;
1533 
1534    For i in 1 .. v_bucket.COUNT LOOP
1535      -- calculate the new capacity units for each bucket
1536 /*
1537     if v_agg_resource = 1 then
1538      OPEN agg_record(v_bucket(i).start_date, v_bucket(i).end_date);
1539      FETCH agg_record into v_new_capacity_units;
1540      CLOSE agg_record;
1541 
1542     else
1543 */
1544      OPEN time_record(v_bucket(i).start_date, v_bucket(i).end_date);
1545      FETCH time_record into v_new_capacity_units;
1546      CLOSE time_record;
1547 
1548       v_new_capacity_units:=nvl(v_new_capacity_units,0);
1549 --    end if;
1550 
1551 -- we will insert one for each bucket, even the resource_units is 0
1552 
1553 --      if nvl(v_new_capacity_units,0) <>0 then
1554 
1555           select msc_net_resource_avail_s.nextval
1556           into v_transaction_id
1557           from dual;
1558 
1559    -- insert parent record
1560 
1561           insert into msc_net_resource_avail
1562            ( TRANSACTION_ID,
1563              parent_id,
1564              PLAN_ID        ,
1565              ORGANIZATION_ID,
1566              SR_INSTANCE_ID     ,
1567              DEPARTMENT_ID                   ,
1568              RESOURCE_ID                     ,
1569              SHIFT_DATE                      ,
1570              CAPACITY_UNITS                 ,
1571              LAST_UPDATE_DATE               ,
1572              LAST_UPDATED_BY                ,
1573              CREATION_DATE                  ,
1574             CREATED_BY
1575            )
1576       values (
1577          v_transaction_id,
1578          -1,
1579          v_plan_id,
1580          p_org_id,
1581          p_instance_id,
1582          p_dept_id,
1583          p_res_id,
1584          v_bucket(i).start_date,
1585          v_new_capacity_units,
1586          sysdate,
1587          1,
1588          sysdate,
1589          1);
1590 
1591         -- now update the parent_id for the child records
1592            update msc_net_resource_avail
1593            set parent_id = v_transaction_id
1594            where plan_id = v_plan_id
1595            and   sr_instance_id = p_instance_id
1596            and   organization_id = p_org_id
1597            AND   department_id = p_dept_id
1598            AND   resource_id = p_res_id
1599            and   capacity_units >=0
1600            AND   nvl(parent_id,0) <> -1
1601            and   trunc(shift_date) between trunc(v_bucket(i).start_date)
1602                     and trunc(v_bucket(i).end_date);
1603 --        end if;
1604        END LOOP;
1605        commit;
1606 END IF;
1607 END IF;
1608 
1609 END;
1610 
1611 PROCEDURE refresh_parent_record(p_plan_id number,
1612                                 p_instance_id number,
1613                                 p_transaction_id number) IS
1614   cursor c_net_res_avail is
1615     select organization_id,
1616            department_id,
1617            resource_id,
1618            shift_date
1619       from msc_net_resource_avail
1620      where plan_id = p_plan_id
1621        and transaction_id = p_transaction_id
1622        and sr_instance_id = p_instance_id;
1623 
1624    v_start_date DATE;
1625    v_end_date   DATE;
1626    v_capacity_units NUMBER;
1627    v_org_id number;
1628    v_dept_id number;
1629    v_res_id number;
1630    v_shift_date date;
1631 
1632    CURSOR bucket IS
1633         SELECT mpb.bkt_start_date, mpb.bkt_end_date
1637           and  mp.plan_id = mpb.plan_id
1634         FROM   msc_plan_buckets mpb,
1635                msc_plans mp
1636         where  mp.plan_id = p_plan_id
1638           and  mp.organization_id = mpb.organization_id
1639           and  mp.sr_instance_id = mpb.sr_instance_id
1640           and  mpb.curr_flag =1
1641           and  v_shift_date between mpb.bkt_start_date and mpb.bkt_end_date;
1642 BEGIN
1643 
1644    OPEN c_net_res_avail;
1645    FETCH c_net_res_avail into v_org_id, v_dept_id, v_res_id,v_shift_date;
1646    CLOSE c_net_res_avail;
1647 
1648    OPEN bucket;
1649    FETCH bucket into v_start_date, v_end_date;
1650    CLOSE bucket;
1651 
1652      v_capacity_units :=0;
1653      begin
1654       select round(sum(decode(sign(to_time-from_time),1,(to_time - from_time),
1655                                     (to_time+86400-from_time)
1656                              )/3600*capacity_units),6)
1657       into v_capacity_units
1658       from msc_net_resource_avail
1659       where plan_id = p_plan_id
1660 	and   organization_id = v_org_id
1661         and   sr_instance_id = p_instance_id
1662         AND   department_id = v_dept_id
1663         AND   resource_id = v_res_id
1664         and   nvl(parent_id, 0) <> -1
1665         and   capacity_units >0
1666         and   shift_date between v_start_date and v_end_date;
1667      exception when no_data_found then
1668         v_capacity_units :=0;
1669      end;
1670 
1671      v_capacity_units := nvl(v_capacity_units,0);
1672 
1673  -- update the resource units for parent record
1674      update msc_net_resource_avail
1675      set capacity_units = v_capacity_units,
1676          status =0,
1677          applied =2,
1678          updated =2
1679      where  plan_id = p_plan_id
1680 	and   organization_id = v_org_id
1681         and   sr_instance_id = p_instance_id
1682         AND   department_id = v_dept_id
1683         AND   resource_id = v_res_id
1684         and   shift_date = v_start_date
1685         and   parent_id =-1;
1686 
1687 END refresh_parent_record;
1688 
1689 FUNCTION isFirstOP(p_plan_id number,
1690                                 p_supply_id number,
1691                                 p_changed_op number,
1692                                 p_changed_res number) RETURN boolean IS
1693   cursor op_c is
1694     select operation_seq_num,resource_seq_num
1695       from msc_resource_requirements
1696       where plan_id = p_plan_id
1697         and supply_id = p_supply_id
1698         and parent_id = 2
1699        order by operation_seq_num,resource_seq_num;
1700    v_op number;
1701    v_res number;
1702 BEGIN
1703    OPEN op_c;
1704    FETCH op_c INTO v_op, v_res;
1705    CLOSE op_c;
1706 
1707    if p_changed_op = v_op and p_changed_res = v_res then
1708       return true;
1709    else
1710       return false;
1711    end if;
1712 END isFirstOP;
1713 
1714 PROCEDURE reset_changes IS
1715 BEGIN
1716   if p_trans_id is not null then
1717      p_trans_id.delete;
1718      p_start_time.delete;
1719      p_end_time.delete;
1720      p_resource_units.delete;
1721   end if;
1722 END reset_changes;
1723 
1724 PROCEDURE set_sim_res_times(p_plan_id NUMBER,
1725                            p_avail_checked number,
1726                            p_sim_start date,
1727                            p_sim_end date,
1728                            p_new_start out nocopy date,
1729                            p_new_end out nocopy date,
1730                            p_error_status out nocopy varchar2) IS
1731    p_sim_new_start date;
1732    p_sim_new_end date;
1733 
1734 BEGIN
1735 
1736    FOR a in 1..nvl(sim_res.org_id.last,0) LOOP
1737      if a <> p_avail_checked then
1738            -- bug5969889, don't use res_units from routing for simultaneous res
1739            get_new_time(p_plan_id, sim_res.org_id(a), sim_res.inst_id(a),
1740                         sim_res.dept_id(a), sim_res.res_id(a),
1741                         p_sim_start,
1742                         sim_res.res_hours(a), sim_res.assign_units(a),
1743                         false,
1744                         p_new_start, p_new_end, p_error_status);
1745            if p_error_status =  'NO_RES_AVAIL' then
1746               exit;
1747            end if;
1748      end if;
1749 
1750      if p_new_start <> p_sim_start or
1751         p_new_end <> p_sim_end then
1752 -- res(a) can not start/end at the same time as other res
1753         p_sim_new_start := p_new_start;
1754         p_sim_new_end := p_new_end;
1755         set_sim_res_times(p_plan_id, a, p_sim_new_start,p_sim_new_end,
1756                           p_new_start,p_new_end,p_error_status);
1757         exit;
1758      end if;
1759 
1760    END LOOP;
1761 
1762 END set_sim_res_times;
1763 
1764 PROCEDURE reset_sim_res IS
1765 BEGIN
1766    sim_res.org_id.delete;
1767    sim_res.inst_id.delete;
1768    sim_res.dept_id.delete;
1769    sim_res.res_id.delete;
1770    sim_res.res_hours.delete;
1771    sim_res.assign_units.delete;
1772    sim_res.op_seq_id.delete;
1773    sim_res.rt_seq_id.delete;
1774 
1775 END reset_sim_res;
1776 
1777 
1778 PROCEDURE calculate_ops(p_plan_id NUMBER,
1779                                 p_supply_id number,
1780                                 p_changed_op number,
1781                                 p_changed_res number,
1782                                 p_changed_date date,
1783                                 p_new_end_date date,
1784                                 p_status out nocopy varchar2 ) IS
1785 
1786   cursor time_c is
1787     select transaction_id, operation_seq_num,resource_seq_num,
1788            organization_id,sr_instance_id,department_id,resource_id,
1792            operation_sequence_id,
1789            resource_hours,assigned_units,
1790            nvl(firm_start_date,start_date),
1791            nvl(firm_end_date,end_date),
1793            routing_sequence_id
1794       from msc_resource_requirements
1795       where plan_id = p_plan_id
1796         and supply_id = p_supply_id
1797         and parent_id = 2
1798        order by operation_seq_num,resource_seq_num;
1799 
1800 
1801   p_op numTab;
1802   p_res numTab;
1803   p_org_id numTab;
1804   p_inst_id numTab;
1805   p_dept_id numTab;
1806   p_res_id numTab;
1807   p_res_hours numTab;
1808   p_assign_units numTab;
1809   p_op_seq_id numTab;
1810   p_rt_seq_id numTab;
1811 
1812   p_new_start date;
1813   p_new_end date;
1814   p_current_op number;
1815   p_current_res number;
1816 
1817   p_sim_start date;
1818   p_sim_end date;
1819 
1820   k number := 0;
1821   p_effective_date date;
1822   p_disable_date date;
1823 BEGIN
1824 
1825   reset_changes;
1826 
1827   OPEN time_c;
1828   FETCH time_c BULK COLLECT INTO p_trans_id, p_op, p_res,
1829                        p_org_id, p_inst_id, p_dept_id, p_res_id,
1830                        p_res_hours, p_assign_units,p_start_time, p_end_time,
1831                        p_op_seq_id, p_rt_seq_id;
1832   CLOSE time_c;
1833 
1834   FOR a in 1..nvl(p_op.last,0) LOOP
1835 
1836      p_resource_units(a) := routing_res_unit(p_plan_id, p_op_seq_id(a),
1837                        p_rt_seq_id(a), p_res_id(a),p_assign_units(a));
1838 
1839      if a = 1 then
1840         p_current_op := p_op(a);
1841         p_current_res := p_res(a);
1842         p_new_start := p_changed_date;
1843         p_new_end := p_new_end_date;
1844 
1845      end if;-- if a = 1 then
1846 
1847      if p_op(a) <> p_current_op or
1848         p_res(a) <> p_current_res then  -- new op/res
1849 
1850         p_current_op := p_op(a);
1851         p_current_res := p_res(a);
1852 
1853         if k > 0 then -- calculate simultaneous resources times
1854 --dbms_output.put_line('k='||k);
1855            set_sim_res_times(p_plan_id,1,
1856                        p_sim_start, p_sim_end,
1857                        p_new_start, p_new_end, p_status);
1858            for i in 1..nvl(sim_res.org_id.last,0) loop
1859                  p_start_time(a-i) := p_new_start;
1860                  p_end_time(a-i) := p_new_end;
1861                  p_resource_units(a-i) := p_assign_units(a-i);
1862            end loop;
1863            k :=0;
1864            reset_sim_res;
1865         end if;
1866             -- use end time of prev op as start time
1867 
1868         get_new_time(p_plan_id, p_org_id(a), p_inst_id(a),
1869                        p_dept_id(a), p_res_id(a),
1870                        p_end_time(a-1), p_res_hours(a), p_resource_units(a),
1871                        false,
1872                        p_new_start, p_new_end, p_status);
1873       elsif a > 1 then -- simultaneous resources
1874           k := k+1;
1875 --dbms_output.put_line('k='||k||', a='||a);
1876           if k = 1 then -- get the first sim res
1877              sim_res.org_id(k) := p_org_id(a-1);
1878              sim_res.inst_id(k) := p_inst_id(a-1);
1879              sim_res.dept_id(k) := p_dept_id(a-1);
1880              sim_res.res_id(k) := p_res_id(a-1);
1881              sim_res.res_hours(k) := p_res_hours(a-1);
1882              sim_res.assign_units(k) := p_assign_units(a-1);
1883              sim_res.op_seq_id(k) := p_op_seq_id(a-1);
1884              sim_res.rt_seq_id(k) := p_rt_seq_id(a-1);
1885              p_sim_start :=  p_start_time(a-1);
1886              p_sim_end :=  p_end_time(a-1);
1887              k := k+1;
1888           end if;
1889           sim_res.org_id(k) := p_org_id(a);
1890           sim_res.inst_id(k) := p_inst_id(a);
1891           sim_res.dept_id(k) := p_dept_id(a);
1892           sim_res.res_id(k) := p_res_id(a);
1893           sim_res.res_hours(k) := p_res_hours(a);
1894           sim_res.assign_units(k) := p_assign_units(a);
1895           sim_res.op_seq_id(k) := p_op_seq_id(a);
1896           sim_res.rt_seq_id(k) := p_rt_seq_id(a);
1897 
1898       end if;
1899 
1900       p_start_time(a) := p_new_start;
1901       p_end_time(a) := p_new_end;
1902 
1903  -- dbms_output.put_line(a||','||to_char(p_start_time(a),'MM/DD/RRRR HH24:MI')||','||to_char(p_end_time(a),'MM/DD/RRRR HH24:MI')||','||p_res_hours(a));
1904 
1905   END LOOP;
1906 
1907   --5578138,
1908    ProcessDates(p_plan_id, p_supply_id, p_effective_date, p_disable_date );
1909   if p_new_end > p_disable_date or
1910      p_new_end < p_effective_date then
1911      p_status := 'SUPPLY_OUTSIDE_PROCESS_DATE';
1912   end if;
1913 
1914 END calculate_ops;
1915 
1916 PROCEDURE move_res_req(p_plan_id number,
1917                                 p_supply_id number) IS
1918   a number;
1919 BEGIN
1920 
1921   forall a in 1..p_trans_id.count
1922         update msc_resource_requirements
1923            set firm_start_date = p_start_time(a),
1924                firm_end_date = p_end_time(a),
1925                assigned_units = p_resource_units(a), --bug 5973698
1926                status = 0,
1927                applied =2,
1928                firm_flag = 7
1929          where plan_id = p_plan_id
1930            and transaction_id = p_trans_id(a);
1931 --dbms_output.put_line('new due date='||to_char(p_new_end,'MM/DD/RRRR HH24:MI'));
1932 
1933   a := nvl(p_trans_id.last,0);
1934   if a > 0 then
1935      update msc_supplies
1936      set       status = 0,
1937                applied =2,
1938                firm_planned_type = 1,
1939                firm_date = p_end_time(a),
1940                firm_quantity = new_order_quantity
1941     where plan_id = p_plan_id
1945 END move_res_req;
1942            and transaction_id = p_supply_id;
1943   end if;
1944 
1946 
1947 PROCEDURE get_new_time(p_plan_id NUMBER,
1948                                   p_org_id NUMBER,
1949                                   p_inst_id NUMBER,
1950                                   p_dept_id NUMBER,
1951                                   p_res_id  NUMBER,
1952                                   p_changed_date date,
1953                                   p_res_hours number,
1954                                   p_assign_units number,
1955                                   p_first_activity boolean,
1956                                   p_new_start out nocopy date,
1957                                   p_new_end out nocopy date,
1958                                   p_error_status out nocopy varchar2) IS
1959   p_valid_start boolean := false;
1960 
1961   p_cum  number := 0;
1962   p_start date;
1963   p_end date;
1964 
1965   cursor avail_c is
1966     select shift_date, from_time, to_time, capacity_units
1967        from msc_net_resource_avail
1968       where plan_id = p_plan_id
1969         and organization_id = p_org_id
1970         and sr_instance_id = p_inst_id
1971         and department_id = p_dept_id
1972         and resource_id = p_res_id
1973         and capacity_units > 0
1974         and nvl(parent_id, 0) <> -1
1975         and shift_date >= trunc(p_changed_date)
1976       order by shift_date, from_time, to_time;
1977 
1978  cursor infinite_c is
1979     select 1
1980        from msc_net_resource_avail
1981       where plan_id = p_plan_id
1982         and organization_id = p_org_id
1983         and sr_instance_id = p_inst_id
1984         and department_id = p_dept_id
1985         and resource_id = p_res_id
1986         and nvl(parent_id, 0) <> -1;
1987 
1988   avail_rec avail_c%ROWTYPE;
1989   v_infinite number;
1990   v_res_minutes_per_unit number;
1991   v_res_minutes number;
1992 
1993 BEGIN
1994 --dbms_output.put_line(p_org_id||','||p_inst_id||','||p_dept_id||','||p_res_id);
1995 --dbms_output.put_line('get new time: '||to_char(p_changed_date,'MM/DD/RRRR HH24:MI')||','||p_res_hours||','||p_assign_units);
1996   OPEN infinite_c;
1997   FETCH infinite_c INTO v_infinite;
1998   CLOSE infinite_c;
1999 
2000   --bug5973236, need to run up to minute level
2001   v_res_minutes := round(p_res_hours*60,0);
2002 
2003   if nvl(p_assign_units,0) <> 0 then
2004      --bug5973236, need to ceil to minute level for per unit time
2005      v_res_minutes_per_unit := ceil(v_res_minutes/p_assign_units);
2006   else
2007      v_res_minutes_per_unit :=  v_res_minutes;
2008   end if;
2009 
2010   if v_infinite is null then
2011      -- dbms_output.put_line('infinite resource');
2012      p_new_start := p_changed_date;
2013      p_new_end := p_new_start + (v_res_minutes_per_unit/(24*60));
2014      return;
2015   end if;
2016 
2017   OPEN avail_c;
2018   LOOP
2019      FETCH avail_c INTO avail_rec;
2020      EXIT WHEN avail_c%NOTFOUND;
2021 
2022         p_start := avail_rec.shift_date + avail_rec.from_time/86400 ;
2023         if avail_rec.to_time > avail_rec.from_time then
2024            p_end := avail_rec.shift_date + avail_rec.to_time/86400 ;
2025         else
2026            p_end := avail_rec.shift_date + avail_rec.to_time/86400 + 1;
2027         end if;
2028 --dbms_output.put_line('avail dates '||to_char(p_start,'MM/DD/RRRR HH24:MI')||','||to_char(p_end,'MM/DD/RRRR HH24:MI'));
2029 
2030         if p_start <= p_changed_date and -- p_changed_date is not in break
2031             p_changed_date <= p_end and
2032             p_assign_units <= avail_rec.capacity_units then
2033            p_valid_start := true;
2034            p_start := p_changed_date;
2035            p_new_start := p_changed_date;
2036 --dbms_output.put_line('p_changed_start='||to_char(p_new_start,'MM/DD/RRRR HH24:MI'));
2037         end if;
2038 
2039         if not(p_valid_start) and
2040            p_changed_date < p_start and  -- p_new_date is in a break
2041            p_assign_units <= avail_rec.capacity_units then
2042            if p_first_activity then -- can start in a break
2043               p_error_status := 'START_IN_BREAK';
2044            end if; -- if p_first_activity then
2045               p_new_start := p_start;  -- need to move the date
2046               p_valid_start := true;
2047 --dbms_output.put_line('p_new_start='||to_char(p_new_start,'MM/DD/RRRR HH24:MI'));
2048         end if; -- if not(p_valid_start) and
2049 
2050         if p_valid_start then -- find the end time
2051  --dbms_output.put_line(round(p_cum,2)||','||to_char(p_start,'MM/DD/RRRR HH24:MI')||','||to_char(p_end,'MM/DD/RRRR HH24:MI'));
2052            if v_res_minutes_per_unit <= p_cum + (p_end-p_start)*24*60 then
2053               p_new_end := p_start +
2054                               (v_res_minutes_per_unit - p_cum)/(24*60);
2055 --dbms_output.put_line('p_new_end='||to_char(p_new_end,'MM/DD/RRRR HH24:MI'));
2056               exit;
2057            else
2058               p_cum := p_cum + (p_end - p_start)*24*60;
2059            end if;
2060         end if; -- if p_valid_start then
2061   END LOOP;
2062 
2063   CLOSE avail_c;
2064 --dbms_output.put_line(to_char(p_start,'MM/DD/RRRR HH24:MI')||','||to_char(p_end,'MM/DD/RRRR HH24:MI')||','||to_char(p_new_start,'MM/DD/RRRR HH24:MI')||','||to_char(p_new_end,'MM/DD/RRRR HH24:MI'));
2065   if p_new_end is null or p_new_start is null then
2066   -- no avail resource found, use the last avail res end time
2067      p_new_start := nvl(p_new_start, nvl(p_start,p_changed_date));
2068      p_new_end := nvl(p_new_end, nvl(p_end, p_new_start+1/60));
2069      p_error_status := 'NO_RES_AVAIL';
2070   end if;
2071 
2072 END get_new_time;
2073 
2074 Procedure ProcessDates(p_plan_id in number,
2075                             p_supply_id in number,
2076                             p_effective_date out nocopy date,
2080      from msc_process_effectivity mpe,
2077                             p_disable_date out nocopy date) IS
2078   CURSOR eff_c IS
2079    select mpe.effectivity_date, mpe.disable_date
2081           msc_supplies ms
2082     where ms.plan_id = p_plan_id
2083       and ms.transaction_id = p_supply_id
2084       and mpe.plan_id = ms.plan_id
2085       and mpe.process_sequence_id = ms.process_seq_id;
2086 BEGIN
2087        OPEN eff_c;
2088        FETCH eff_c INTO p_effective_date, p_disable_date;
2089        CLOSE eff_c;
2090 END ProcessDates;
2091 
2092 FUNCTION routing_res_unit(p_plan_id number, p_op_seq_id number,
2093                       p_rt_seq_id number, p_res_id number,
2094                       p_assign_units number) RETURN number IS
2095   --bug 5846499, get assign_units from routing
2096   CURSOR unit_c IS
2097    select nvl(resource_units, max_resource_units)
2098      from msc_operation_resources
2099     where plan_id = p_plan_id
2100       and operation_sequence_id = p_op_seq_id
2101       and routing_sequence_id = p_rt_seq_id
2102       and resource_id = p_res_id;
2103   v_assign_units number;
2104 BEGIN
2105 
2106   OPEN unit_c;
2107   FETCH unit_c INTO v_assign_units;
2108   CLOSE unit_c;
2109 
2110   /* bug8835167, if units from routing is greater than res_req table, use
2111      the one from res_req  */
2112   if v_assign_units > p_assign_units then
2113      return  p_assign_units;
2114   end if;
2115 
2116   return nvl(v_assign_units,p_assign_units);
2117 END routing_res_unit;
2118 
2119 PROCEDURE verify_data(p_plan_id number, p_supply_id number) IS
2120   p_org_id NUMBER;
2121   p_inst_id NUMBER;
2122   p_dept_id NUMBER;
2123   p_res_id  NUMBER;
2124   p_start_date date;
2125   p_end_date date;
2126   p_start_time date;
2127   p_end_time date;
2128 
2129   cursor mrr_c is
2130     select transaction_id, operation_seq_num,resource_seq_num, assigned_units,
2131            organization_id,sr_instance_id,department_id,resource_id,
2132           to_char(firm_start_date,'MM/DD/RRRR HH24:MI') firm_start_time,
2133            to_char(firm_end_date,'MM/DD/RRRR HH24:MI') firm_end_time,
2134            to_char(start_date,'MM/DD/RRRR HH24:MI') start_time,
2135            to_char(end_date,'MM/DD/RRRR HH24:MI') end_time,
2136            resource_hours, overloaded_capacity
2137       from msc_resource_requirements
2138       where plan_id = p_plan_id
2139         and supply_id = p_supply_id
2140         and parent_id = 2
2141        order by operation_seq_num,resource_seq_num;
2142 
2143   cursor avail_c is
2144     select shift_date, from_time, to_time, capacity_units
2145        from msc_net_resource_avail
2146       where plan_id = p_plan_id
2147         and organization_id = p_org_id
2148         and sr_instance_id = p_inst_id
2149         and department_id = p_dept_id
2150         and resource_id = p_res_id
2151         and capacity_units > 0
2152         and nvl(parent_id, 0) <> -1
2153         and shift_date >= trunc(p_start_time)
2154         and shift_date <= trunc(p_end_time)
2155       order by 1,2,3;
2156 
2157   avail_rec avail_c%ROWTYPE;
2158   mrr_rec mrr_c%ROWTYPE;
2159 
2160 BEGIN
2161  -- dbms_output.put_line(p_plan_id||','||p_supply_id);
2162   OPEN mrr_c;
2163   LOOP
2164    FETCH mrr_c INTO mrr_rec;
2165    EXIT WHEN mrr_c%NOTFOUND;
2166 --dbms_output.put_line('req');
2167       if to_date(mrr_rec.firm_start_time,'MM/DD/RRRR HH24:MI') <
2168          to_date(mrr_rec.start_time,'MM/DD/RRRR HH24:MI') then
2169         p_start_time := to_date(mrr_rec.firm_start_time,'MM/DD/RRRR HH24:MI');
2170       else
2171         p_start_time := to_date(mrr_rec.start_time,'MM/DD/RRRR HH24:MI');
2172       end if;
2173       if to_date(mrr_rec.firm_end_time,'MM/DD/RRRR HH24:MI') >
2174          to_date(mrr_rec.end_time,'MM/DD/RRRR HH24:MI') then
2175         p_end_time := to_date(mrr_rec.firm_end_time,'MM/DD/RRRR HH24:MI');
2176       else
2177         p_end_time := to_date(mrr_rec.end_time,'MM/DD/RRRR HH24:MI');
2178       end if;
2179 /*
2180      dbms_output.put_line(mrr_rec.operation_seq_num||','||
2181                           mrr_rec.resource_seq_num||',au:'||
2182                           mrr_rec.assigned_units||',rh:'||
2183                           mrr_rec.resource_hours||','||
2184                           mrr_rec.firm_start_time||','||
2185                           mrr_rec.firm_end_time||','||
2186                           mrr_rec.start_time||','||
2187                           mrr_rec.end_time);
2188 */
2189        p_org_id := mrr_rec.organization_id;
2190        p_inst_id := mrr_rec.sr_instance_id;
2191        p_dept_id := mrr_rec.department_id;
2192        p_res_id := mrr_rec.resource_id;
2193 
2194 -- dbms_output.put_line('avail ');
2195   OPEN avail_c;
2196   LOOP
2197    FETCH avail_c INTO avail_rec;
2198    EXIT WHEN avail_c%NOTFOUND;
2199 
2200         p_start_date := avail_rec.shift_date + avail_rec.from_time/86400 ;
2201         if avail_rec.to_time > avail_rec.from_time then
2202            p_end_date := avail_rec.shift_date + avail_rec.to_time/86400 ;
2203         else
2204            p_end_date := avail_rec.shift_date + avail_rec.to_time/86400 + 1;
2205         end if;
2206 /*
2207      dbms_output.put_line(avail_rec.shift_date||','||
2208                           avail_rec.from_time||','||
2209                           avail_rec.to_time||','||
2210                           avail_rec.capacity_units||','||
2211                           to_char(p_start_date,'MM/DD/RRRR HH24:MI')||','||
2212                           to_char(p_end_date,'MM/DD/RRRR HH24:MI'));
2213 */
2214   END LOOP;
2215   CLOSE avail_c;
2216   END LOOP;
2217   CLOSE mrr_c;
2218 END verify_data;
2219 
2220 END;