DBA Data[Home] [Help]

PACKAGE BODY: APPS.MRP_UPDATE_RESOURCE

Source


1 PACKAGE BODY MRP_UPDATE_RESOURCE AS
2 /* $Header: MRPFCAVB.pls 115.6 99/07/16 12:20:37 porting shi $ */
3 
4 TYPE ResRecTyp IS RECORD (
5 	OPERATION				 NUMBER,
6 	ORGANIZATION_ID				 NUMBER,
7 	LINE_ID					 NUMBER,
8 	DEPARTMENT_ID				 NUMBER,
9 	RESOURCE_ID				 NUMBER,
10  	RESOURCE_HOURS                           NUMBER,
11  	MAX_RATE                                 NUMBER,
12  	RESOURCE_UNITS                           NUMBER,
13  	STATUS                                   NUMBER,
14  	APPLIED                                  NUMBER,
15  	RESOURCE_START_DATE            		 DATE,
16  	RESOURCE_END_DATE                        DATE,
17  	UPDATED                          	 NUMBER,
18  	LAST_UPDATE_DATE                 	 DATE,
19  	LAST_UPDATED_BY                  	 NUMBER,
20  	CREATION_DATE                   	 DATE,
21  	CREATED_BY                       	 NUMBER,
22  	LAST_UPDATE_LOGIN                        NUMBER);
23 
24 TYPE ResTabTyp IS TABLE OF ResRecTyp
25 	INDEX by binary_integer;
26 
27 g_resource_exist        boolean;
28 g_error_stat		VARCHAR2(300);
29 g_compile_designator    VARCHAR2(20);
30 g_simulation_set	VARCHAR2(10);
31 g_res_group		VARCHAR2(30);
32 g_cutoff_date		DATE;
33 g_query_id		NUMBER:=0;
34 g_org_id		NUMBER:=0;
35 g_department_id		NUMBER:=0;
36 g_line_id		NUMBER:=0;
37 g_resource_id		NUMBER:=0;
38 g_change_rec 		ResRecTyp;
39 g_res_tab		ResTabTyp;
40 g_tmp_tab		ResTabTyp;
41 i 			binary_integer;
42 j                       binary_integer;
43 k 			binary_integer;
44 OP_ADD_DAY		CONSTANT INTEGER :=0;
45 OP_ADD                  CONSTANT INTEGER :=1;
46 OP_DEL                  CONSTANT INTEGER :=2;
47 OP_SET			CONSTANT INTEGER :=3;
48 OP_DEL_DAY		CONSTANT INTEGER :=4;
49 
50 -- Cursor used to apply simulation for Calculate Resource Supply for ATP
51 CURSOR C_BRC IS
52 	SELECT
53 			DECODE(brc.action_type,1,OP_DEL_DAY,3,OP_ADD_DAY,
54 				DECODE(sign(brc.capacity_change),-1,
55 				OP_DEL,OP_ADD)),
56 			dept.organization_id,
57 			NULL,
58 			bdr.department_id,
59 			bdr.resource_id,
60 			decode(brc.action_type,1,
61 				(nvl(sum(decode(bdr.available_24_hours_flag,
62 				1,24,2,
63 				((decode(least(shifts.to_time,shifts.from_time),
64 				shifts.to_time,shifts.to_time + 24*3600,
65 				shifts.to_time) - shifts.from_time)/3600))),0)),
66 				(decode(least(nvl(brc.from_time,0),
67 				nvl(brc.to_time,1)),
68 				nvl(brc.to_time,1),
69 				24 * 3600 + nvl(brc.to_time,1),
70 				nvl(brc.to_time,1)) -
71 				nvl(brc.from_time,0))/3600),
72 			NULL,
73 			decode(brc.action_type,1,bdr.capacity_units,
74 				abs(brc.capacity_change)),
75 			0,
76 			NULL,
77 			decode(brc.action_type,3,cal.prior_date,brc.from_date),
78 			decode(brc.action_type,2,nvl(brc.to_date,g_cutoff_date),
79 				3,cal.prior_date,brc.from_date),
80 			2,
81 			SYSDATE,
82 			FND_GLOBAL.USER_ID,
83 			SYSDATE,
84 			FND_GLOBAL.USER_ID,
85 			FND_GLOBAL.LOGIN_ID
86 	FROM 	bom_resources res,
87 		bom_departments dept,
88 		bom_shift_times shifts,
89 		mtl_parameters mp,
90 	 	bom_calendar_dates cal,
91 		bom_department_resources bdr,
92 		bom_resource_changes brc
93 	WHERE	res.organization_id = dept.organization_id
94 	AND	bdr.resource_id = res.resource_id
95 	AND	dept.organization_id = g_org_id
96 	AND	NVL(bdr.share_from_dept_id,bdr.department_id)
97 			= dept.department_id
98 	AND	share_from_dept_id is null
99 	AND	brc.shift_num = shifts.shift_num(+)
100 	AND	(mp.calendar_code = shifts.calendar_code
101 		OR shifts.calendar_code IS NULL)
102 	AND	mp.organization_id = dept.organization_id
103 	AND	cal.calendar_date = brc.from_date
104 	AND 	cal.exception_set_id = mp.calendar_exception_set_id
105 	AND	cal.calendar_code = mp.calendar_code
106 	AND	bdr.ctp_flag = 1
107 	AND	nvl(bdr.resource_group_name,'-1') =
108 			nvl(g_res_group,nvl(bdr.resource_group_name,'-1'))
109 	AND	brc.department_id = bdr.department_id
110 	AND	brc.resource_id = bdr.resource_id
111 	AND	brc.simulation_set = g_simulation_set
112         AND     (brc.from_date >= trunc(sysdate)
113 		OR brc.to_date >= trunc(sysdate))
114 	GROUP BY '-1',dept.organization_id, bdr.department_id, bdr.resource_id,
115 		brc.action_type, brc.to_time, brc.from_time, bdr.capacity_units,
116 		brc.capacity_change, brc.from_date, cal.prior_date, brc.to_date,
117 		brc.shift_num;
118 
119 
120 CURSOR C_MFQ IS
121        SELECT
122 			NUMBER1,
123 			NUMBER2,
124 			NUMBER3,
125 			NUMBER4,
126 			NUMBER5,
127                         nvl(NUMBER6,0),
128                         nvl(NUMBER7,0),
129                         nvl(NUMBER8,0),
130 			0,
131 			2,
132                         DATE1,
133                         DATE2,
134 			2,
135                         LAST_UPDATE_DATE,
136                         LAST_UPDATED_BY,
137                         CREATION_DATE,
138                         CREATED_BY,
139                         LAST_UPDATE_LOGIN
140 	FROM MRP_FORM_QUERY
141 	WHERE query_id = g_query_id
142 	ORDER BY number2, number3, number4, number5, number1;
143 
144 CURSOR C_CAR  IS
145        SELECT
146 	      0,
147 	      organization_id,
148 	      line_id,
149 	      department_id,
150 	      resource_id,
151               decode(line_id, null, resource_hours,1),
152               nvl(max_rate,0),
153               nvl(resource_units,0),
154 	      status,
155    	      applied,
156               resource_start_date,
157               resource_end_date,
158               updated,
159  	LAST_UPDATE_DATE,
160         LAST_UPDATED_BY,
161         CREATION_DATE,
162         CREATED_BY,
163         LAST_UPDATE_LOGIN
164         FROM  CRP_AVAILABLE_RESOURCES
165         WHERE (compile_designator=g_compile_designator)
166 	AND (organization_id = g_org_id)
167         AND (    (line_id = g_line_id)
168         	OR (  (line_id IS NULL) AND (g_line_id IS NULL)))
169         AND (    (department_id = g_department_id)
170                  OR (  (department_id IS NULL) AND (g_department_id IS NULL)))
171         AND (    (resource_id = g_resource_id)
172                  OR (  (resource_id IS NULL) AND (g_resource_id IS NULL)))
173 	order by resource_start_date;
174 
175 ---------------------------------------------------------------
176 -- apply simulation
177 -- used by calculate resource supply for ATP
178 ---------------------------------------------------------------
179 PROCEDURE apply_simulation(p_org_id IN NUMBER,
180 			   p_res_group IN VARCHAR2,
181 			   p_simulation_set IN VARCHAR2,
182 			   p_cutoff_date IN VARCHAR2)
183 IS
184    first_record		BOOLEAN :=TRUE;
185    changed_resource	BOOLEAN :=TRUE;
186 BEGIN
187    g_compile_designator := '-1';
188    g_org_id := p_org_id;
189    g_res_group := p_res_group;
190    g_simulation_set := p_simulation_set;
191    g_cutoff_date := to_date(p_cutoff_date,'YYYY/MM/DD HH24:MI:SS');
192    g_department_id         :=0;
193    g_line_id               :=0;
194    g_resource_id           :=0;
195 
196   -- load the simulation changes, if there are changes then
197   -- re-query data from crp_available_resources
198 
199    OPEN C_BRC;
200    LOOP
201 	FETCH C_BRC INTO g_change_rec;
202 	IF C_BRC%NOTFOUND THEN
203 	   IF not first_record THEN
204 	      update_table;
205 	   END IF;
206            CLOSE C_BRC;
207 	   commit;
208 	   exit;
209 	END IF;
210 
211         IF    (g_change_rec.organization_id = g_org_id )
212        	   AND (    (g_change_rec.line_id = g_line_id)
213                	OR (  (g_change_rec.line_id IS NULL) AND (g_line_id IS NULL)))
214            AND (    (g_change_rec.department_id = g_department_id)
215                	OR (  (g_change_rec.department_id IS NULL)
216 			AND (g_department_id IS NULL)))
217            AND (    (g_change_rec.resource_id = g_resource_id)
218                  OR (  (g_change_rec.resource_id IS NULL)
219 			AND (g_resource_id IS NULL))) THEN
220 
221             changed_resource :=FALSE;
222         ELSE
223 
224             changed_resource :=TRUE;
225         END IF;
226 
227 
228 	IF changed_resource THEN
229 
230 	   IF not first_record THEN
231 	   -- update the change for the previous resource
232 	      update_table;
233 	   END IF;
234 
235            g_org_id :=g_change_rec.organization_id;
236            g_department_id :=g_change_rec.department_id;
237            g_resource_id :=g_change_rec.resource_id;
238            g_line_id :=g_change_rec.line_id;
239 
240 	   -- initialize the table for next resource
241 	   initialize_table;
242 
243 	END IF;
244 
245    	calculate_change;
246         first_record :=FALSE;
247 
248    END LOOP;
249 EXCEPTION when others THEN
250    IF (C_BRC%ISOPEN) THEN
251 	close C_BRC;
252    END IF;
253 END apply_simulation;
254 
255 ---------------------------------------------------------------
256 -- apply change
257 ---------------------------------------------------------------
258 PROCEDURE apply_change( p_query_id IN NUMBER,
259 			p_compile_designator IN VARCHAR2 ) IS
260    first_record		BOOLEAN :=TRUE;
261    changed_resource	BOOLEAN :=TRUE;
262 BEGIN
263    g_compile_designator :=p_compile_designator;
264    g_query_id := p_query_id;
265    g_org_id                :=0;
266    g_department_id         :=0;
267    g_line_id               :=0;
268    g_resource_id           :=0;
269 
270 
271   -- load from mrp_form_query for the changes, if the resource changes
272   -- re-query data from crp_available_resources
273 
274    OPEN C_MFQ;
275    LOOP
276         FETCH C_MFQ INTO g_change_rec;
277 
278 	IF C_MFQ%NOTFOUND THEN
279 	   IF not first_record THEN
280 	      update_table;
281 	   END IF;
282            CLOSE C_MFQ;
283 	   commit;
284 	   exit;
285 	END IF;
286 
287         IF    (g_change_rec.organization_id = g_org_id )
288        	   AND (    (g_change_rec.line_id = g_line_id)
289                	OR (  (g_change_rec.line_id IS NULL) AND (g_line_id IS NULL)))
290            AND (    (g_change_rec.department_id = g_department_id)
291                	OR (  (g_change_rec.department_id IS NULL)
292 			AND (g_department_id IS NULL)))
293            AND (    (g_change_rec.resource_id = g_resource_id)
294                  OR (  (g_change_rec.resource_id IS NULL)
295 			AND (g_resource_id IS NULL))) THEN
296 
297             changed_resource :=FALSE;
298         ELSE
299 
300             changed_resource :=TRUE;
301         END IF;
302 
303 
304 	IF changed_resource THEN
305 
306 	   IF not first_record THEN
307 	   -- update the change for the previous resource
308 	      update_table;
309 	   END IF;
310 
311            g_org_id :=g_change_rec.organization_id;
312            g_department_id :=g_change_rec.department_id;
313            g_resource_id :=g_change_rec.resource_id;
314            g_line_id :=g_change_rec.line_id;
315 
316 	   -- initialize the table for next resource
317 	   initialize_table;
318 
319 	END IF;
320 
321    	calculate_change;
322 
323         first_record :=FALSE;
324 
325    END LOOP;
326 EXCEPTION when others THEN
327 
328    IF (C_MFQ%ISOPEN) THEN
329 	close C_MFQ;
330    END IF;
331    raise_application_error(-20000, sqlerrm);
332 END apply_change;
333 
334 ---------------------------------------------------------------------
335 -- to get the values into PL/SQL tables
336 ---------------------------------------------------------------------
337 PROCEDURE initialize_table IS
338 BEGIN
339 
340    -- load from crp_available_resources for all the records
341    -- related to the same resource
342    j :=0;
343    g_res_tab.delete;
344    OPEN C_CAR;
345    LOOP
346 	   j := j+1;
347 	   FETCH C_CAR INTO g_res_tab(j);
348 	   if C_CAR%NOTFOUND then
349              if C_CAR%ROWCOUNT=0 then
350                g_resource_exist :=false;
351              end if;
352              exit;
353            end if;
354 
355    END LOOP;
356    IF C_CAR%ROWCOUNT >0 THEN
357      g_resource_exist :=true;
358    END IF;
359    CLOSE C_CAR;
360 EXCEPTION WHEN others THEN
361   IF (C_CAR%ISOPEN) THEN
362 	close C_CAR;
363   END IF;
364 
365 END initialize_table;
366 
367 ---------------------------------------------------------------------
368 -- to
369 ---------------------------------------------------------------------
370 PROCEDURE calculate_change IS
371 v_start_record 		number;
372 v_end_record            number;
373 
374 BEGIN
375 
376 IF g_resource_exist THEN
377 -- try to find which records in res_tab are affected by the change
378 
379     -- try to find which record the change start date falls
380 
381  j:=g_res_tab.FIRST;
382  IF (g_change_rec.resource_start_date <
383 	g_res_tab(j).resource_start_date ) THEN
384      -- the change record starts before the range
385 	v_start_record :=0;
386  ELSE
387     --find the first record whose start date is greater than change's start date
388     --then the previous record will be where the change starts
389 	While (j is not null) and
390 	   (    g_change_rec.resource_start_date >=
391 		g_res_tab(j).resource_start_date    )
392 	LOOP
393 	   j:=g_res_tab.next(j);
394 	END LOOP;
395    IF j is null THEN
396 	-- if j is null, then the change is on or outside the last record
397 	i :=g_res_tab.LAST;
398 	IF ( g_res_tab(i).resource_end_date is null ) THEN
399 	   v_start_record :=g_res_tab.LAST;
400 	   v_end_record :=g_res_tab.LAST;
401 	ELSE
402 	  IF (g_change_rec.resource_start_date <=
403 		g_res_tab(i).resource_end_date ) THEN
404 	        v_start_record :=g_res_tab.LAST;
405            	v_end_record :=g_res_tab.LAST;
406 	   ELSE
407 	  	v_start_record :=g_res_tab.LAST+1;
408           	v_end_record :=g_res_tab.LAST+1;
409 
410 	   END IF;
411 	END IF;
412    ELSE
413 	-- otherwise, the change is inside the range
414 	-- but it could be on a record or in a gap between two records
415 	IF (g_change_rec.resource_start_date <=
416                 g_res_tab(j-1).resource_end_date ) THEN
417 	--change falls on the previos record
418 		v_start_record := j-1;
419 	ELSE
420 	--change falls on the gap between record j-1 and record j
421 		v_start_record := j-0.5;
422 	END IF;
423 	--go to the previous record to find where change ends
424 	j:=j-1;
425    END IF;
426  END IF;
427 
428 -- try to find which record the change end date fall
429 
430  -- if the change does not have end date, the change extends till the end
431  -- but it could be on the last record, or outside the range
432  IF ( g_change_rec.resource_end_date is null ) THEN
433         i :=g_res_tab.LAST;
434         IF ( g_res_tab(i).resource_end_date is null ) THEN
435 	-- falls on the last record
436            v_end_record :=g_res_tab.LAST;
437         ELSE
438 	--falls outside the last record
439           v_end_record :=g_res_tab.LAST+1;
440         END IF;
441 
442  ELSE
443      IF (    g_change_rec.resource_end_date <
444 	     g_res_tab(1).resource_start_date    ) THEN
445 	-- the change ends before the first record
446 	v_end_record :=0;
447      ELSE
448 
449         While (j is not null) and
450            	 (   g_change_rec.resource_end_date >=
451                      g_res_tab(j).resource_start_date    )
452         LOOP
453               j:=g_res_tab.next(j);
454         END LOOP;
455 
456         IF j is null THEN
457 	-- if j is null, then the change ends on or outside the last record
458            i :=g_res_tab.LAST;
459            IF ( g_res_tab(i).resource_end_date is null ) THEN
460               v_end_record :=g_res_tab.LAST;
461            ELSE
462           	IF (g_change_rec.resource_end_date <=
463                 	g_res_tab(i).resource_end_date ) THEN
464                 	v_end_record :=g_res_tab.LAST;
465            	ELSE
466               		v_end_record :=g_res_tab.LAST+1;
467            	END IF;
468 	   END IF;
469 
470         ELSE
471 	   IF (g_change_rec.resource_end_date <=
472                 g_res_tab(j-1).resource_end_date ) THEN
473 	   -- change ends on the previous record
474 	        v_end_record := j-1;
475 	   ELSE
476 	   -- change ends in the gap between record j-1 and record j
477 		v_end_record := j-0.5;
478 	   END IF;
479    	END IF;
480      END IF;
481  END IF;
482 
483 -- flush the records to tmp_tab
484    k:=0;
485    g_tmp_tab.delete;
486 
487  IF g_change_rec.operation <> OP_SET THEN
488 
489     IF ( v_start_record =0 ) THEN
490 	   IF g_change_rec.operation not in (OP_DEL, OP_DEL_DAY) THEN
491 	   	k:=k+1;
492 	   	g_tmp_tab(k) := g_change_rec;
493 	   	IF (v_end_record <> 0) THEN
494 	      		g_tmp_tab(k).resource_end_date :=
495 			g_res_tab(1).resource_start_date -1;
496 	   	END IF;
497 
498 		-- if add non working day, set the updated field as 1
499 		-- so that when re-plan, it will be treated as work day
500 
501 	 	IF g_change_rec.operation = OP_ADD_DAY THEN
502 			g_tmp_tab(k).updated :=1;
503 		END IF;
504 	   END IF;
505    END IF;
506 
507    j:=g_res_tab.FIRST;
508    While (j is not null)
509    LOOP
510       IF (j < v_start_record) or (j > v_end_record) THEN
511 		-- no change, just copy the old record
512 		k:=k+1;
513 		g_tmp_tab(k):=g_res_tab(j);
514 
515       ELSIF (j > v_start_record) and (j<v_end_record) THEN
516 	       -- the whole record is affected, change the qty
517 			k:=k+1;
518 			g_tmp_tab(k):=g_res_tab(j);
519 			IF g_change_rec.operation = OP_ADD THEN
520                            g_tmp_tab(k).resource_units :=
521                               g_res_tab(j).resource_units +
522                               g_change_rec.resource_units ;
523 			   g_tmp_tab(k).resource_hours :=
524                               g_res_tab(j).resource_hours +
525                               g_change_rec.resource_hours ;
526                            g_tmp_tab(k).max_rate:=
527                              g_res_tab(j).max_rate+
528                              g_change_rec.max_rate;
529 			ELSIF g_change_rec.operation = OP_DEL THEN
530                            g_tmp_tab(k).resource_units :=
531                               g_res_tab(j).resource_units -
532                               g_change_rec.resource_units ;
533 			   g_tmp_tab(k).resource_hours :=
534                               g_res_tab(j).resource_hours -
535                               g_change_rec.resource_hours ;
536                            g_tmp_tab(k).max_rate:=
537                              g_res_tab(j).max_rate-
538                              g_change_rec.max_rate;
539 			END IF;
540                         g_tmp_tab(k).status :=0;
541                         g_tmp_tab(k).applied:=2;
542                         g_tmp_tab(k).last_update_date := sysdate;
543                         g_tmp_tab(k).last_updated_by :=
544                           g_change_rec.last_updated_by;
545 
546 
547       ELSIF (j=v_start_record) and (j = v_end_record) THEN
548 		   -- need to cut the record into three records
549 
550              IF (g_change_rec.resource_start_date <>
551                         g_res_tab(j).resource_start_date ) THEN
552                         -- need to change the date for the first record
553                         k:=k+1;
554                         g_tmp_tab(k):=g_res_tab(j);
555                         g_tmp_tab(k).resource_end_date:=
556                              g_change_rec.resource_start_date - 1;
557                         g_tmp_tab(k).status :=0;
558                         g_tmp_tab(k).applied:=2;
559                         g_tmp_tab(k).last_update_date := sysdate;
560                         g_tmp_tab(k).last_updated_by :=
561                           g_change_rec.last_updated_by;
562 
563 	     END IF;
564 
565 	     -- add a new record
566 	     -- delete work day and add non working day would be caught
567 	     -- here only if it falls inside the range and not in a gap,
568              --	because v_start_record will always = v_end_record in these cases
569 
570 	     IF g_change_rec.operation <> OP_DEL_DAY THEN
571 			k:=k+1;
572                         g_tmp_tab(k):=g_change_rec;
573 
574                         IF g_change_rec.operation = OP_ADD THEN
575                            g_tmp_tab(k).resource_units :=
576                               g_res_tab(j).resource_units +
577                               g_change_rec.resource_units ;
578                            g_tmp_tab(k).resource_hours :=
579                               g_res_tab(j).resource_hours +
580                               g_change_rec.resource_hours ;
581                            g_tmp_tab(k).max_rate:=
582                              g_res_tab(j).max_rate+
583                              g_change_rec.max_rate;
584                         ELSIF g_change_rec.operation = OP_DEL THEN
585                            g_tmp_tab(k).resource_units :=
586                               g_res_tab(j).resource_units -
587                               g_change_rec.resource_units ;
588                            g_tmp_tab(k).resource_hours :=
589                               g_res_tab(j).resource_hours -
590                               g_change_rec.resource_hours ;
591                            g_tmp_tab(k).max_rate:=
592                              g_res_tab(j).max_rate-
593                              g_change_rec.max_rate;
594 
595 			-- don't add onto the quantity of the original record
596 			ELSIF g_change_rec.operation = OP_ADD_DAY THEN
597 			   g_tmp_tab(k).updated :=1;
598 
599                         END IF;
600 	     END IF;
601 
602              IF (g_change_rec.resource_end_date <>
603                         g_res_tab(j).resource_end_date ) or
604 		( g_res_tab(j).resource_end_date is null and
605 		g_change_rec.resource_end_date is not null) THEN
606                         -- need to change the date for the third record
607                         k:=k+1;
608                         g_tmp_tab(k):=g_res_tab(j);
609                         g_tmp_tab(k).resource_start_date:=
610                              g_change_rec.resource_end_date + 1;
611                         g_tmp_tab(k).status :=0;
612                         g_tmp_tab(k).applied:=2;
613                         g_tmp_tab(k).last_update_date := sysdate;
614                         g_tmp_tab(k).last_updated_by :=
615                           g_change_rec.last_updated_by;
616 
617 	     END IF;
618 
619 
620       ELSIF (j=v_start_record) and (j <> v_end_record) THEN
621 		   -- need to cut the record
622 
623              IF (g_change_rec.resource_start_date <>
624                         g_res_tab(j).resource_start_date ) THEN
625                         -- need to change the date
626                         k:=k+1;
627                         g_tmp_tab(k):=g_res_tab(j);
628                         g_tmp_tab(k).resource_end_date:=
629                              g_change_rec.resource_start_date - 1;
630                         g_tmp_tab(k).status :=0;
631                         g_tmp_tab(k).applied:=2;
632                         g_tmp_tab(k).last_update_date := sysdate;
633                         g_tmp_tab(k).last_updated_by :=
634                           g_change_rec.last_updated_by;
635 
636 	     END IF;
637 
638 			-- and add a new record
639 			k:=k+1;
640                         g_tmp_tab(k):=g_change_rec;
641                         g_tmp_tab(k).resource_end_date:=
642                              g_res_tab(j).resource_end_date;
643                         IF g_change_rec.operation = OP_ADD THEN
644                            g_tmp_tab(k).resource_units :=
645                               g_res_tab(j).resource_units +
646                               g_change_rec.resource_units ;
647                            g_tmp_tab(k).resource_hours :=
648                               g_res_tab(j).resource_hours +
649                               g_change_rec.resource_hours ;
650                            g_tmp_tab(k).max_rate:=
651                              g_res_tab(j).max_rate+
652                              g_change_rec.max_rate;
653                         ELSIF g_change_rec.operation = OP_DEL THEN
654                            g_tmp_tab(k).resource_units :=
655                               g_res_tab(j).resource_units -
656                               g_change_rec.resource_units ;
657                            g_tmp_tab(k).resource_hours :=
658                               g_res_tab(j).resource_hours -
659                               g_change_rec.resource_hours ;
660                            g_tmp_tab(k).max_rate:=
661                              g_res_tab(j).max_rate-
662                              g_change_rec.max_rate;
663                         END IF;
664 
665       ELSIF (j=v_end_record) and (j <> v_start_record) THEN
666 		   -- need to cut the record
667 
668 			--  add a new record
669 			k:=k+1;
670                         g_tmp_tab(k):=g_change_rec;
671                         g_tmp_tab(k).resource_start_date:=
672                              g_res_tab(j).resource_start_date;
673                         IF g_change_rec.operation = OP_ADD THEN
674                            g_tmp_tab(k).resource_units :=
675                               g_res_tab(j).resource_units +
676                               g_change_rec.resource_units ;
677                            g_tmp_tab(k).resource_hours :=
678                               g_res_tab(j).resource_hours +
679                               g_change_rec.resource_hours ;
680                            g_tmp_tab(k).max_rate:=
681                              g_res_tab(j).max_rate+
682                              g_change_rec.max_rate;
683                         ELSIF g_change_rec.operation = OP_DEL THEN
684                            g_tmp_tab(k).resource_units :=
685                               g_res_tab(j).resource_units -
686                               g_change_rec.resource_units ;
687                            g_tmp_tab(k).resource_hours :=
688                               g_res_tab(j).resource_hours -
689                               g_change_rec.resource_hours ;
690                            g_tmp_tab(k).max_rate:=
691                              g_res_tab(j).max_rate-
692                              g_change_rec.max_rate;
693                         END IF;
694 
695              IF (g_change_rec.resource_end_date <>
696                         g_res_tab(j).resource_end_date ) or
697 		(g_change_rec.resource_end_date is not null and
698 		g_res_tab(j).resource_end_date is null )THEN
699                         -- need to change the date
700                         k:=k+1;
701                         g_tmp_tab(k):=g_res_tab(j);
702                         g_tmp_tab(k).resource_start_date:=
703                              g_change_rec.resource_end_date + 1;
704                         g_tmp_tab(k).status :=0;
705                         g_tmp_tab(k).applied:=2;
706                         g_tmp_tab(k).last_update_date := sysdate;
707                         g_tmp_tab(k).last_updated_by :=
708                           g_change_rec.last_updated_by;
709 	     END IF;
710       END IF;
711 
712       -- if change starts or ends in the gap, need to insert new row
713       IF g_change_rec.operation not in  (OP_DEL_DAY, OP_DEL) THEN
714 
715          IF (v_start_record >j ) and (v_start_record <j+1 ) THEN
716                k:=k+1;
717                g_tmp_tab(k):=g_change_rec;
718 	    IF (g_change_rec.resource_end_date >=
719                         g_res_tab(j+1).resource_start_date or
720 		g_change_rec.resource_end_date is null) THEN
721 		--the change extends over the gap, need to change the end date
722 		g_tmp_tab(k).resource_end_date:=
723 			g_res_tab(j+1).resource_start_date-1;
724 	    END IF;
725 	 ELSIF (v_end_record >j ) and (v_end_record <j+1 ) THEN
726             k:=k+1;
727             g_tmp_tab(k):=g_change_rec;
728             IF (g_change_rec.resource_start_date <=
729                         g_res_tab(j).resource_end_date ) THEN
730                 --the change extends over the gap, need to change start date
731                 g_tmp_tab(k).resource_start_date:=
732                         g_res_tab(j).resource_end_date+1;
733             END IF;
734 	 END IF;
735       END IF;
736 
737       j:=g_res_tab.next(j);
738    END LOOP;
739 
740    -- if the record falls outside the original range, add a new row
741    i := g_res_tab.LAST;
742    IF (v_end_record = i+1) THEN
743 	   IF g_change_rec.operation not in (OP_DEL_DAY, OP_DEL) THEN
744 	   	k:=k+1;
745            	g_tmp_tab(k):=g_change_rec;
746 	   	IF (v_start_record <> i +1 ) THEN
747            		g_tmp_tab(k).resource_start_date:=
748 				g_res_tab(i).resource_end_date +1;
749 	   	END IF;
750 	 	IF g_change_rec.operation = OP_ADD_DAY THEN
751 			g_tmp_tab(k).updated :=1;
752 		END IF;
753 	   END IF;
754    END IF;
755 
756  ELSIF g_change_rec.operation= OP_SET THEN
757 
758         i := g_res_tab.LAST;
759 
760 	IF (v_start_record = 0) THEN
761 
762 	--if change falls before the range, add a row, go to the end record
763 	--cut record if needed, then go to the next record
764 	   k:=k+1;
765            g_tmp_tab(k):=g_change_rec;
766 	   -- if the set record ends outside the range, don't have to loop
767 	   IF (v_end_record = i+1) THEN
768 		j:='';
769 	   ELSIF (v_end_record=0) THEN
770 	   -- the change ends before the range, loop from record1
771 		j:=g_res_tab.FIRST;
772 	   ELSIF (v_end_record > trunc(v_end_record)) THEN
773 	   -- change falls on a gap, go to the record after the gap
774 		j:=trunc(v_end_record)+1;
775 	  -- if the set record ends outside the range, don't have to loop
776 	   ELSIF (v_end_record < i+1) THEN
777 	   -- go to where the set record ends and add row if needed
778              	j:=v_end_record;
779 
780              IF (g_change_rec.resource_end_date <
781                         g_res_tab(j).resource_end_date ) or
782 		(g_res_tab(j).resource_end_date is null and
783 		g_change_rec.resource_end_date is not null) THEN
784 
785                 -- need to add row for the date change
786                 K:=K+1;
787                 g_tmp_tab(k):=g_res_tab(j);
788                 g_tmp_tab(k).resource_start_date :=
789                         g_change_rec.resource_end_date +1;
790                         g_tmp_tab(k).status :=0;
791                         g_tmp_tab(k).applied:=2;
792                         g_tmp_tab(k).last_update_date := sysdate;
793                         g_tmp_tab(k).last_updated_by :=
794                           g_change_rec.last_updated_by;
795 
796              END IF;
797     	     --go to the next record, and ready for loop
798 	     j:=j+1;
799 	   END IF;
800 	ELSE
801 	   j:=g_res_tab.FIRST;
802 	END IF;
803 
804         IF j < i+1 THEN
805 	While ( j is not null ) LOOP
806 	   IF (j < v_start_record) or (j > v_end_record) THEN
807 		-- no change
808 		   k:=k+1;
809                    g_tmp_tab(k):=g_res_tab(j);
810 
811 	   ELSIF (j=v_start_record) THEN
812 
813 	     IF (g_change_rec.resource_start_date >
814 			g_res_tab(j).resource_start_date ) THEN
815 		-- need to insert row with date change only first
816 		K:=K+1;
817 		g_tmp_tab(k):=g_res_tab(j);
818 		g_tmp_tab(k).resource_end_date :=
819 			g_change_rec.resource_start_date -1;
820                         g_tmp_tab(k).status :=0;
821                         g_tmp_tab(k).applied:=2;
822                         g_tmp_tab(k).last_update_date := sysdate;
823                         g_tmp_tab(k).last_updated_by :=
824                           g_change_rec.last_updated_by;
825 
826 	     END IF;
827 
828 	     -- add new row
829 	     K:=K+1;
830              g_tmp_tab(k):=g_change_rec;
831 
832 	     IF (v_end_record > trunc(v_end_record)) THEN
833              -- change ends on a gap,
834                j:=trunc(v_end_record);
835              ELSIF (v_end_record < i+1) THEN
836 	     -- go the where the set record ends, and add row if needed
837 	        j:=v_end_record;
838                 IF (g_change_rec.resource_end_date <
839                         g_res_tab(j).resource_end_date ) or
840 		   (g_change_rec.resource_end_date is not null and
841 		    g_res_tab(j).resource_end_date is null) THEN
842 
843                 -- need to add row for the date change
844                    K:=K+1;
845                    g_tmp_tab(k):=g_res_tab(j);
846                    g_tmp_tab(k).resource_start_date :=
847                         g_change_rec.resource_end_date +1;
848                    g_tmp_tab(k).status :=0;
849                    g_tmp_tab(k).applied:=2;
850                    g_tmp_tab(k).last_update_date := sysdate;
851                    g_tmp_tab(k).last_updated_by :=
852                       g_change_rec.last_updated_by;
853 		END IF;
854              END IF;
855 
856 	   END IF;
857 
858 	   -- if change starts on a gap
859 	   IF (v_start_record > j) and (v_start_record < j+1) THEN
860              -- add new row
861              K:=K+1;
862              g_tmp_tab(k):=g_change_rec;
863 
864 	     IF (v_end_record > trunc(v_end_record)) THEN
865               -- change ends on a gap,
866                 j:=trunc(v_end_record);
867              ELSIF (v_end_record < i+1) THEN
868              -- go to where the set record ends, and add row if needed
869                 j:=v_end_record;
870                 IF (g_change_rec.resource_end_date <
871                         g_res_tab(j).resource_end_date ) or
872 		   (g_change_rec.resource_end_date is not null and
873 		    g_res_tab(j).resource_end_date is null)  THEN
874 
875                 -- need to add row for the date change
876                    K:=K+1;
877                    g_tmp_tab(k):=g_res_tab(j);
878                    g_tmp_tab(k).resource_start_date :=
879                         g_change_rec.resource_end_date +1;
880                    g_tmp_tab(k).status :=0;
881                    g_tmp_tab(k).applied:=2;
882                    g_tmp_tab(k).last_update_date := sysdate;
883                    g_tmp_tab(k).last_updated_by :=
884                       g_change_rec.last_updated_by;
885 	        END IF;
886              END IF;
887 	   END IF;
888 
889 	   j:=g_res_tab.next(j);
890 
891 	END LOOP;
892        END IF;
893 
894 	-- if the set record starts outside the range
895 	i:=g_res_tab.LAST;
896 	IF (v_start_record = i+1 ) THEN
897                -- need to add row for the date change
898                 K:=K+1;
899                 g_tmp_tab(k):=g_change_rec;
900 	END IF;
901 
902  END IF;
903 
904 ELSE --user enters a resource which is not in crp_available_resource table
905 
906    g_tmp_tab.delete;
907    g_tmp_tab(1) := g_change_rec;
908 END IF;
909 
910  g_res_tab :=g_tmp_tab;
911 
912 END calculate_change;
913 
914 
915 ------------------------------------------------------------------------
916 --to update crp_available_resources table
917 -----------------------------------------------------------------------------
918 PROCEDURE update_table IS
919 m 	INTEGER;
920 BEGIN
921   if g_resource_exist then
922    delete crp_available_resources
923 	where compile_designator = g_compile_designator
924 	and   organization_id = g_org_id
925         AND (    (line_id = g_line_id)
926                 OR (  (line_id IS NULL) AND (g_line_id IS NULL)))
927         AND (    (department_id = g_department_id)
928                  OR (  (department_id IS NULL) AND (g_department_id IS NULL)))
929         AND (    (resource_id = g_resource_id)
930                  OR (  (resource_id IS NULL) AND (g_resource_id IS NULL)));
931   end if;
932 
933    For m in 1 .. g_res_tab.LAST LOOP
934 
935       -- only insert the resources with positive quantity
936       IF (g_res_tab(m).resource_hours > 0 AND
937 	 g_res_tab(m).resource_units > 0) OR
938 	 g_res_tab(m).max_rate >0 THEN
939 
940 	INSERT INTO crp_available_resources
941                 (compile_designator,
942                  organization_id,
943                  line_id,
944                  department_id,
945                  resource_id,
946                  resource_hours,
947                  max_rate,
948                  resource_units,
949                  resource_start_date,
950                  resource_end_date,
951                  status,
952                  applied,
953 		 updated,
954                  last_update_date,
955                  last_updated_by,
956                  creation_date,
957                  created_by,
958                  last_update_login)
959                VALUES
960                 (g_compile_designator,
961                  g_res_tab(m).organization_id,
962                  g_res_tab(m).line_id,
963                  g_res_tab(m).department_id,
964                  g_res_tab(m).resource_id,
965 		 decode( g_res_tab(m).department_id, null, 0,
966                   greatest(0,least(24,g_res_tab(m).resource_hours))),
967                  greatest(0,g_res_tab(m).max_rate),
968 		 decode( g_res_tab(m).department_id, null, 1,
969 		  greatest(0,round(g_res_tab(m).resource_units,6))),
970                  g_res_tab(m).resource_start_date,
971                  g_res_tab(m).resource_end_date,
972               	 g_res_tab(m).status,
973                  g_res_tab(m).applied,
974 		 g_res_tab(m).updated,
975                  g_res_tab(m).last_update_date,
976                  g_res_tab(m).last_updated_by,
977                  g_res_tab(m).creation_date,
978                  g_res_tab(m).created_by,
979                  g_res_tab(m).last_update_login);
980 	END IF;
981    END LOOP;
982 
983 END update_table;
984 
985 END;