DBA Data[Home] [Help]

PACKAGE BODY: APPS.HXC_DEPOSIT_CHECKS

Source


1 PACKAGE BODY hxc_deposit_checks AS
2 /* $Header: hxcdpwrck.pkb 120.10 2011/08/23 13:06:49 bbayragi ship $ */
3 --
4 
5 g_debug 	     boolean 	  := hr_utility.debug_enabled;
6 
7 -- Types
8 --
9 TYPE asg_dates is RECORD
10       (start_date date
11       ,end_date   date
12       );
13 
14 Type asg_info is table of asg_dates index by binary_integer;
15 
16 Type block_list is table of number index by binary_integer;
17 
18 -- Package Variables
19 --
20 g_package  varchar2(33) := '  hxc_deposit_checks.';
21 
22 --
23 -- ----------------------------------------------------------------------------
24 -- |-------------------------< can_delete_template >--------------------------|
25 -- ----------------------------------------------------------------------------
26 -- {Start Of Comments}
27 --
28 -- Description:
29 --   This function is called by the deposit controller for self service
30 -- timecard deposit to ensure that the template the user is requesting to
31 -- delete is not set as a default template for any user.  This should only
32 -- be an issue if the user has set one of their own templates as a default
33 -- or if an administrator has created a public template.
34 --
35 -- Prerequisites:
36 --   The template must exist.
37 --
38 -- In Parameters:
39 --   Name                  Reqd Type     Description
40 --   p_template_id             Yes Number   The id of the timecard
41 --                              template
42 --
43 -- Access Status:
44 --   Internal use only.
45 --
46 -- {End Of Comments}
47 --
48 --
49 Procedure can_delete_template
50         (p_template_id in         hxc_time_building_blocks.time_building_block_id%type
51         ,p_messages    in out nocopy hxc_message_table_type) is
52 
53 cursor c_template_details
54      (p_id in hxc_time_building_blocks.time_building_block_id%type) is
55 select TEMPLATE_TYPE from hxc_template_summary
56 where template_id = p_id;
57 
58 l_exists      VARCHAR2(6);
59 l_template_type hxc_template_summary.template_type%type;
60 l_attached_public_temp_grps varchar2(1500);
61 l_pref_value  VARCHAR2(170);
62 
63 Begin
64 
65 l_attached_public_temp_grps := NULL;
66 
67 open c_template_details(p_template_id);
68 fetch c_template_details into l_template_type;
69 if c_template_details%found then
70 
71   if(l_template_type='PUBLIC') then
72   	--Check whether the public template can be deleted.
73 	l_attached_public_temp_grps := hxc_public_temp_group_comp_api.can_delete_public_template(p_template_id=>p_template_id);
74   end if;
75 
76  if(l_attached_public_temp_grps is NULL) then  --Carry out the normal operations for private/public templates.
77 
78   l_pref_value := l_template_type||'|'||p_template_id;
79 
80   l_exists := HXC_PREFERENCE_EVALUATION.num_hierarchy_occurances
81                  ('TC_W_TMPLT_DFLT_VAL_USR'
82                ,1
83                ,l_pref_value);
84   if ( l_exists <> 0 ) THEN
85     hxc_timecard_message_helper.addErrorToCollection
86       (p_messages
87       ,'HXC_CANT_DEL_TEMPL'
88       ,hxc_timecard.c_error
89       ,null
90       ,null
91       ,hxc_timecard.c_hxc
92       ,null
93       ,null
94       ,null
95       ,null
96       );
97   else
98     l_exists := HXC_PREFERENCE_EVALUATION.num_hierarchy_occurances
99                 ('TC_W_TMPLT_DFLT_VAL_ADMIN'
100                  ,1
101                  ,l_pref_value);
102     if ( l_exists <> 0 ) THEN
103       hxc_timecard_message_helper.addErrorToCollection
104      (p_messages
105      ,'HXC_CANT_DEL_TEMPL'
106      ,hxc_timecard.c_error
107      ,null
108      ,null
109      ,hxc_timecard.c_hxc
110      ,null
111      ,null
112      ,null
113      ,null
114      );
115     END if;
116    END IF;
117   else
118 
119   -- Public Template Specific
120 
121     hxc_timecard_message_helper.addErrorToCollection
122       (p_messages
123       ,'HXC_CANT_DEL_PUB_TEMPL'
124       ,hxc_timecard.c_error
125       ,null
126       ,'GROUPS&'||l_attached_public_temp_grps
127       ,hxc_timecard.c_hxc
128       ,null
129       ,null
130       ,null
131       ,null
132       );
133   end if;
134 end if;
135 close c_template_details;
136 
137 End can_delete_template;
138 --
139 -- ----------------------------------------------------------------------------
140 -- |----------------------------< check_inputs >------------------------------|
141 -- ----------------------------------------------------------------------------
142 -- {Start Of Comments}
143 --
144 -- Description:
145 --   This function is called by the deposit controller for self service
146 -- timecard deposit to ensure that the calling process has sent parameters
147 -- that make sense in terms of deposit.
148 --
149 -- Prerequisites:
150 --   None.
151 --
152 -- In Parameters:
153 --   Name                  Reqd Type     Description
154 --   p_blocks                 Yes  BLOCKS   The blocks to deposit
155 --   p_atttributes            Yes  ATTRS    The attributes to deposit
156 --   p_deposit_mode           Yes  Varchar2 The mode of deposit
157 --   p_template               Yes  Varchar2 Is this a template?
158 --   p_messages               Yes  MESSAGES The application messages
159 --
160 --
161 -- Access Status:
162 --   Internal use only.
163 --
164 -- {End Of Comments}
165 --
166 --
167 PROCEDURE check_inputs
168          (p_blocks          in         hxc_block_table_type
169          ,p_attributes      in         hxc_attribute_table_type
170          ,p_deposit_mode       in         varchar2
171          ,p_template        in         varchar2
172          ,p_messages        in out nocopy hxc_message_table_type
173          ) is
174 
175 l_proc varchar2(70) := g_package||'check_inputs';
176 
177 BEGIN
178 
179 --
180 -- We must have at least one block to deposit
181 --
182 if(p_blocks.count <1) then
183 
184   hxc_timecard_message_helper.addErrorToCollection
185     (p_messages
186     ,'HXC_XXXXX_NO_BLOCKS'
187     ,hxc_timecard.c_error
188     ,null
189     ,null
190     ,hxc_timecard.c_hxc
191     ,null
192     ,null
193     ,null
194     ,null
195     );
196 
197 end if;
198 
199 --
200 -- The deposit mode must be SUBMIT, SAVE or AUDIT
201 -- (others not currently supported)
202 --
203 if (NOT ((p_deposit_mode=hxc_timecard.c_submit) OR (p_deposit_mode=hxc_timecard.c_save) OR p_deposit_mode=hxc_timecard.c_audit)) then
204 
205   hxc_timecard_message_helper.addErrorToCollection
206     (p_messages
207     ,'HXC_XXXXX_INVALID_DEP_MODE'
208     ,hxc_timecard.c_error
209     ,null
210     ,'MODE&'||p_deposit_mode
211     ,hxc_timecard.c_hxc
212     ,null
213     ,null
214     ,null
215     ,null
216     );
217 
218 end if;
219 
220 --
221 -- We must have a Y or N value for the template
222 --
223 if (NOT ((p_template='Y') OR (p_template='N'))) then
224 
225   hxc_timecard_message_helper.addErrorToCollection
226     (p_messages
227     ,'HXC_XXXXX_INVALID_TEMPLATE'
228     ,hxc_timecard.c_error
229     ,null
230     ,'VALUE&'||p_template
231     ,hxc_timecard.c_hxc
232     ,null
233     ,null
234     ,null
235     ,null
236     );
237 
238 end if;
239 
240 if ((p_template='Y') AND (p_deposit_mode = hxc_timecard.c_save)) then
241 
242   hxc_timecard_message_helper.addErrorToCollection
243     (p_messages
244     ,'HXC_XXXXX_INVALID_DEP_MODE'
245     ,hxc_timecard.c_error
246     ,null
247     ,'MODE&'||p_deposit_mode
248     ,hxc_timecard.c_hxc
249     ,null
250     ,null
251     ,null
252     ,null
253     );
254 
255 end if;
256 
257 END check_inputs;
258 --
259 -- ----------------------------------------------------------------------------
260 -- |----------------------------< audit_checks >------------------------------|
261 -- ----------------------------------------------------------------------------
262 -- {Start Of Comments}
263 --
264 -- Description:
265 --   This procedure ensures that the user has entered all reasons required
266 -- by the instance audit requirements.
267 --
268 -- Prerequisites:
269 --   A table of audit reasons exists
270 --
271 -- In Parameters:
272 --   Name                  Reqd Type       Description
273 --   p_blocks                 Yes  BLOCKS     The blocks to deposit
274 --   p_attributes             Yes  ATTRIBUTES The attributes
275 --   p_messages               Yes  MESSAGES   The failure messages
276 --                                /Reason messages
277 --
278 --
279 -- Access Status:
280 --   Internal use only.
281 --
282 -- {End Of Comments}
283 --
284 PROCEDURE audit_checks
285         (p_blocks     in         hxc_block_table_type
286         ,p_attributes in         hxc_attribute_table_type
287         ,p_messages   in out nocopy hxc_message_table_type
288         ) is
289 
290 l_index number;
291 l_found  BOOLEAN;
292 l_att_index number;
293 l_missing_reasons hxc_message_table_type;
294 
295 BEGIN
296 
297 l_missing_reasons := hxc_message_table_type();
298 
299 l_index := p_messages.first;
300 
301 LOOP
302   EXIT WHEN NOT p_messages.exists(l_index);
303   IF(p_messages(l_index).message_level = 'REASON') THEN
304      l_found:=TRUE;
305      l_att_index:=p_attributes.first;
306      LOOP
307        EXIT WHEN ((NOT p_attributes.exists(l_att_index)) OR (NOT l_found));
308        if (
309        ( p_attributes(l_att_index).building_block_id=p_messages(l_index).time_building_block_id)
310          and (p_attributes(l_att_index).ATTRIBUTE_CATEGORY = 'REASON')
311 	    AND (p_messages(l_index).MESSAGE_TOKENS=p_attributes(l_att_index).attribute3)
312     	    AND (p_attributes(l_att_index).NEW ='Y')
313 	    AND (p_attributes(l_att_index).attribute1 is not null)
314 	  ) then
315        l_found:=FALSE;
316        end if;
317        l_att_index:=p_attributes.next(l_att_index);
318      END LOOP;
319 
320      IF l_found THEN
321        hxc_timecard_message_helper.addErrorToCollection
322      (p_messages => l_missing_reasons
323      ,p_message_name => 'HXC_REASON_NOT_ENTERED'
324      ,p_message_tokens => NULL
325      ,p_message_level => hxc_timecard.c_error
326      ,p_message_field => NULL
327      ,p_application_short_name => hxc_timecard.c_hxc
328      ,p_time_building_block_id => NULL
329      ,p_time_building_block_ovn => NULL
330      ,p_time_attribute_id => NULL
331      ,p_time_attribute_ovn => NULL
332      );
333      End if;
334    End if;
335    l_index := p_messages.next(l_index);
336 END LOOP;
337 
338 p_messages := l_missing_reasons;
339 
340 End audit_checks;
341 --
342 -- ----------------------------------------------------------------------------
343 -- |--------------------------< timecard_deleted >----------------------------|
344 -- ----------------------------------------------------------------------------
345 -- {Start Of Comments}
346 --
347 -- Description:
348 --   This function checks that if we have an existing timecard in the same
349 -- period as the one we are attempting to deposit, that the blocks we're
350 -- depositing also cause the existing time store timecard to be date effectively
351 -- deleted.  In that case, we can permit deposit.
352 --
353 -- Prerequisites:
354 --   We have found an existing timecard for this period in the time store.
355 --
356 -- In Parameters:
357 --   Name                  Reqd Type     Description
358 --   p_blocks                 Yes  BLOCKS   The blocks to deposit
359 --   p_timecard_id            Yes  NUMBER   The id of the existing
360 --                              timecard, to check that
361 --                              is being deleted with the
362 --                              deposit.
363 --
364 -- Return Values:
365 --   FALSE : The existing timecard is NOT being deleted with this submission.
366 --   TRUE  : The existing timecard is being deleted with this submission.
367 --
368 -- Access Status:
369 --   Internal use only.
370 --
371 -- {End Of Comments}
372 --
373 --
374 FUNCTION timecard_deleted
375         (p_blocks in HXC_BLOCK_TABLE_TYPE
376         ,p_timecard_id in HXC_TIME_BUILDING_BLOCKS.TIME_BUILDING_BLOCK_ID%TYPE
377         ) return BOOLEAN is
378 
379 l_deleted_tc BOOLEAN := false;
380 l_block_count NUMBER;
381 
382 BEGIN
383 
384 l_block_count := p_blocks.first;
385 
386 LOOP
387   EXIT WHEN l_deleted_tc;
388   EXIT WHEN NOT p_blocks.exists(l_block_count);
389 
390   if(p_blocks(l_block_count).time_building_block_id = p_timecard_id) then
391    if(fnd_date.canonical_to_date(p_blocks(l_block_count).date_to) <> hr_general.end_of_time) then
392      l_deleted_tc := true;
393    end if;
394   end if;
395 
396   l_block_count := p_blocks.next(l_block_count);
397 
398 END LOOP;
399 
400 RETURN l_deleted_tc;
401 
402 END timecard_deleted;
403 --
404 -- Overloaded version, to call from deposit wrapper.
405 --
406 FUNCTION timecard_deleted
407         (p_blocks in hxc_self_service_time_deposit.timecard_info
408         ,p_timecard_id in HXC_TIME_BUILDING_BLOCKS.TIME_BUILDING_BLOCK_ID%TYPE
409         ) return BOOLEAN is
410 
411 l_deleted_tc BOOLEAN := false;
412 l_block_count NUMBER;
413 
414 BEGIN
415 
416 l_block_count := p_blocks.first;
417 
418 LOOP
419   EXIT WHEN l_deleted_tc;
420   EXIT WHEN NOT p_blocks.exists(l_block_count);
421 
422   if(p_blocks(l_block_count).time_building_block_id = p_timecard_id) then
423    if(p_blocks(l_block_count).date_to <> hr_general.end_of_time) then
424      l_deleted_tc := true;
425    end if;
426   end if;
427 
428   l_block_count := p_blocks.next(l_block_count);
429 
430 END LOOP;
431 
432 RETURN l_deleted_tc;
433 
434 END timecard_deleted;
435 --
439 -- {Start Of Comments}
436 -- ----------------------------------------------------------------------------
437 -- |------------------------< chk_timecard_exists >--------------------------|
438 -- ----------------------------------------------------------------------------
440 --
441 -- Description:
442 --   This function checks that no current timecards exist within the time
443 --   span of the timecard we're attempting to deposit.
444 --
445 -- Prerequisites:
446 --   We have the timecard resource id, start time, stop time and id which
447 --   we are attempting to deposit.
448 --
449 -- In Parameters:
450 --   Name                  Reqd Type     Description
451 --   p_resource_id            Yes  Number   The resource id
452 --   p_start_time             Yes  Date     The proposed start time
453 --   p_stop_time              Yes  Date     The proposed stop time
454 --   p_time_building_block_id       Yes  Number   The id of this timecard
455 --
456 -- Return Values:
457 --   NULL  : A timecard does not already exist for this period.
458 -- NON-NULL: The value of the time building block id of the timecard
459 --        that already exists, for use in further checks.
460 --
461 -- Access Status:
462 --   Internal use only.
463 --
464 -- {End Of Comments}
465 --
466 --
467 FUNCTION chk_timecard_exists
468         (p_resource_id in HXC_TIME_BUILDING_BLOCKS.RESOURCE_ID%TYPE
469         ,p_start_time in HXC_TIME_BUILDING_BLOCKS.START_TIME%TYPE
470         ,p_stop_time in HXC_TIME_BUILDING_BLOCKS.STOP_TIME%TYPE
471         ,p_time_building_block_id in HXC_TIME_BUILDING_BLOCKS.TIME_BUILDING_BLOCK_ID%TYPE
472         ) RETURN NUMBER is
473 
474 l_existing_timecard_id HXC_TIME_BUILDING_BLOCKS.TIME_BUILDING_BLOCK_ID%TYPE;
475 
476 begin
477 
478  select tbb.time_building_block_id into l_existing_timecard_id
479    from hxc_time_building_blocks tbb
480   where tbb.resource_id = p_resource_id
481     and tbb.scope = 'TIMECARD'
482     and tbb.date_to = hr_general.end_of_time
483     and tbb.start_time <= p_stop_time
484     and tbb.stop_time >= p_start_time
485     and tbb.time_building_block_id <> p_time_building_block_id;
486 
487 
488 RETURN l_existing_timecard_id;
489 
490 EXCEPTION
491   WHEN others then
492   --
493   -- No data found error, so continue with deposit.
494   --
495     RETURN null;
496 
497 END chk_timecard_exists;
498 
499 --
500 -- ----------------------------------------------------------------------------
501 -- |------------------------< chk_timecard_deposit >--------------------------|
502 -- ----------------------------------------------------------------------------
503 -- {Start Of Comments}
504 --
505 -- Description:
506 --   This function checks that no current timecards exist within the time
507 --   span of the timecard we're attempting to deposit.
508 --
509 -- Prerequisites:
510 --   The blocks we're attempting to deposit are populated.
511 --
512 -- In Parameters:
513 --   Name                  Reqd Type     Description
514 --   p_blocks                 Yes  BLOCKS   The blocks to deposit
515 --   p_block_number           Yes  number   The number of the block
516 --                              record to check.
517 --
518 -- Return Values:
519 --   FALSE : No timecard exists within this time period, and deposit can
520 --        continue
521 --   TRUE  : A timecard exists, we should raise an error.
522 --
523 -- Access Status:
524 --   Internal use only.
525 --
526 -- {End Of Comments}
527 --
528 --
529 FUNCTION chk_timecard_deposit
530         (p_blocks in HXC_BLOCK_TABLE_TYPE
531         ,p_block_number in NUMBER
532         ) return BOOLEAN is
533 
534 l_test_tc_id HXC_TIME_BUILDING_BLOCKS.TIME_BUILDING_BLOCK_ID%TYPE;
535 
536 l_proc varchar2(72) := g_package||'chk_timceard_deposit';
537 
538 BEGIN
539 
540 --
541 -- Check that this timecard scope building block is still
542 -- active, and has the right scope - it should do since we
543 -- checked elsewhere, but double check.
544 --
545 if (p_blocks(p_block_number).scope = 'TIMECARD') then
546 
547   if (fnd_date.canonical_to_date(p_blocks(p_block_number).date_to) = hr_general.end_of_time) then
548   --
549   -- Run the check
550   --
551     l_test_tc_id := chk_timecard_exists
552           (p_blocks(p_block_number).resource_id
553           ,fnd_date.canonical_to_date(p_blocks(p_block_number).start_time)
554           ,fnd_date.canonical_to_date(p_blocks(p_block_number).stop_time)
555           ,p_blocks(p_block_number).time_building_block_id
556           );
557 
558     if(l_test_tc_id is null) then
559     --
560     -- No existing timecard, therefore we can
561     -- continue with the deposit
562     --
563        RETURN FALSE;
564     else
565     --
566     -- There is another timecard out there that overlaps this
567     -- period.  Now we check whether this timecard is included
568     -- in the blocks that we are depositing as a deleted block
569     -- in which case this is ok, otherwise, we must stop
570     -- submission.
571     --
572        if(timecard_deleted
573         (p_blocks
574         ,l_test_tc_id
575         )) then
576        --
577        -- We are deleting the existing timecard as part of this
578        -- submission.  This is ok, and submission can continue.
579        --
580        RETURN FALSE;
581 
582        else
583        --
584        -- We aren't deleting the existing timecard
585        -- as part of this submission.  Abort this
586        -- deposit.
587        --
588       RETURN TRUE;
589 
590        end if;
591 
592     end if;
596 end if; -- Is this a timecard scope block?
593 
594   end if; -- is the end date the end of time?
595 
597 
598 --
599 -- If we get here, then we should deposit this block!
600 --
601 
602 RETURN FALSE;
603 
604 END chk_timecard_deposit;
605 --
606 -- Overloaded version for calling from deposit wrapper
607 --
608 FUNCTION chk_timecard_deposit
609         (p_blocks in hxc_self_service_time_deposit.timecard_info
610         ,p_block_number in NUMBER
611         ) return BOOLEAN is
612 
613 l_test_tc_id HXC_TIME_BUILDING_BLOCKS.TIME_BUILDING_BLOCK_ID%TYPE;
614 
615 BEGIN
616 
617 --
618 -- Check that this timecard scope building block is still
619 -- active, and has the right scope - it should do since we
620 -- checked elsewhere, but double check.
621 --
622 if (p_blocks(p_block_number).scope = 'TIMECARD') then
623 
624   if (p_blocks(p_block_number).date_to = hr_general.end_of_time) then
625   --
626   -- Run the check
627   --
628     l_test_tc_id := chk_timecard_exists
629           (p_blocks(p_block_number).resource_id
630           ,p_blocks(p_block_number).start_time
631           ,p_blocks(p_block_number).stop_time
632           ,p_blocks(p_block_number).time_building_block_id
633           );
634 
635     if(l_test_tc_id is null) then
636     --
637     -- No existing timecard, therefore we can
638     -- continue with the deposit
639     --
640        RETURN FALSE;
641     else
642     --
643     -- There is another timecard out there that overlaps this
644     -- period.  Now we check whether this timecard is included
645     -- in the blocks that we are depositing as a deleted block
646     -- in which case this is ok, otherwise, we must stop
647     -- submission.
648     --
649        if(timecard_deleted
650         (p_blocks
651         ,l_test_tc_id
652         )) then
653        --
654        -- We are deleting the existing timecard as part of this
655        -- submission.  This is ok, and submission can continue.
656        --
657        RETURN FALSE;
658 
659        else
660        --
661        -- We aren't deleting the existing timecard
662        -- as part of this submission.  Abort this
663        -- deposit.
664        --
665       RETURN TRUE;
666 
667        end if;
668 
669     end if;
670 
671   end if; -- is the end date the end of time?
672 
673 end if; -- Is this a timecard scope block?
674 
675 --
676 -- If we get here, then we should deposit this block!
677 --
678 
679 RETURN FALSE;
680 
681 END chk_timecard_deposit;
682 
683 Function inactive_detail
684        (p_dates in asg_info
685        ,p_date  in date
686        ) return BOOLEAN is
687 
688 l_inactive  boolean := true;
689 l_index     number;
690 
691 Begin
692 
693 l_index := p_dates.first;
694 Loop
695   Exit when ((NOT p_dates.exists(l_index)) OR (NOT l_inactive));
696 
697   if(p_date between p_dates(l_index).start_date and p_dates(l_index).end_date) then
698 
699     l_inactive := false;
700 
701   end if;
702 
703   l_index := p_dates.next(l_index);
704 End Loop;
705 
706 return l_inactive;
707 
708 End inactive_detail;
709 
710 Procedure check_start_stop_time
711         (p_blocks       	in         hxc_block_table_type
712         ,p_details      	in         hxc_timecard.block_list
713         ,p_messages     	in out nocopy hxc_message_table_type
714         ,p_validate_on_save  in 	      hxc_pref_hierarchies.attribute1%type
715         ) is
716 l_index       number;
717 
718 BEGIN
719 
720 l_index := p_details.first;
721 Loop
722   Exit When Not p_details.exists(l_index);
723   if(hxc_timecard_block_utils.is_active_block(p_blocks(p_details(l_index)))) then
724 
725       IF p_blocks(p_details(l_index)).start_time is not null and
726       p_blocks(p_details(l_index)).stop_time is null  and
727 	 (p_blocks(p_details(l_index)).approval_status = hxc_timecard.c_submitted_status
728 	 or
729 	  p_validate_on_save = hxc_timecard.c_yes
730 	  )
731 	  THEN
732 
733        hxc_timecard_message_helper.addErrorToCollection
734      (p_messages => p_messages
735      ,p_message_name => 'HXC_NULL_STOP_SUBMIT'
736      ,p_message_tokens => NULL
737      ,p_message_level => hxc_timecard.c_error
738      ,p_message_field => NULL
739      ,p_application_short_name => hxc_timecard.c_hxc
740      ,p_time_building_block_id => p_blocks(p_details(l_index)).time_building_block_id
741      ,p_time_building_block_ovn => NULL
742      ,p_time_attribute_id => NULL
743      ,p_time_attribute_ovn => NULL
744      );
745       END IF;
746   end if; -- is this an active detail
747   l_index := p_details.next(l_index);
748 End Loop;
749 
750 END check_start_stop_time;
751 
752 
753 Procedure find_detail_date_extremes
754         (p_blocks       in         hxc_block_table_type
755         ,p_days      in         hxc_timecard.block_list
756         ,p_details      in         hxc_timecard.block_list
757         ,p_early_detail in out nocopy date
758         ,p_late_detail  in out nocopy date
759         ) is
760 l_index       number;
761 l_detail_date date;
762 
763 Begin
764 
765 l_index := p_details.first;
766 
767 Loop
768   Exit When Not p_details.exists(l_index);
769   if(hxc_timecard_block_utils.is_active_block(p_blocks(p_details(l_index)))) then
770     l_detail_date := trunc(
771                  hxc_timecard_block_utils.date_value(
775                       )
772                 p_blocks(
773                   p_days(
774                     p_blocks(p_details(l_index)).parent_building_block_id
776                       ).start_time
777                  ));
778 
779     if(l_detail_date < p_early_detail) then
780       p_early_detail := l_detail_date;
781     end if;
782     if(l_detail_date > p_late_detail) then
783       p_late_detail := l_detail_date;
784     end if;
785   end if; -- is this an active detail
786   l_index := p_details.next(l_index);
787 End Loop;
788 
789 End find_detail_date_extremes;
790 
791 Procedure chk_inactive_details
792        (p_blocks     in         hxc_block_table_type
793        ,p_props      in         hxc_timecard_prop_table_type
794        ,p_days       in         hxc_timecard.block_list
795        ,p_details    in         hxc_timecard.block_list
796        ,p_block_idxs    out nocopy block_list
797        ) is
798 
799 l_early_detail  date := hr_general.end_of_time;
800 l_late_detail   date := hr_general.start_of_time;
801 l_detail_date   date;
802 l_asg_info      asg_info;
803 l_index      number;
804 l_block_index   number;
805 
806 l_all_active    boolean;
807 
808 l_proc       varchar2(70) := g_package||'chk_inactive_details';
809 
810 Begin
811 --
812 -- Calculate earliest and latest detail dates
813 --
814 
815 find_detail_date_extremes
816  (p_blocks       => p_blocks
817  ,p_days      => p_days
818  ,p_details      => p_details
819  ,p_early_detail => l_early_detail
820  ,p_late_detail  => l_late_detail
821  );
822 
823 --
824 -- So 99% Case, check to see if the earliest detail
825 -- and latest detail lie within an active assignment
826 -- period.  Loop over the
827 --
828 
829 l_all_active := false;
830 
831 l_index := p_props.first;
832 
833 Loop
834   Exit When ((Not p_props.exists(l_index)) or l_all_active);
835 
836   if(p_props(l_index).property_name = 'ResourceAssignmentId') then
837     --
838     -- Check to see if the details are contained within this assignment
839     --
840     if((p_props(l_index).date_from <= l_early_detail)
841      AND
842       (p_props(l_index).date_to >= l_late_detail)) then
843 
844       l_all_active := true;
845 
846     end if;
847     --
848     -- Keep a record of the dates, in case we need to do the other
849     -- check
850     --
851     l_asg_info(l_index).start_date := p_props(l_index).date_from;
852     l_asg_info(l_index).end_date := p_props(l_index).date_to;
853 
854   end if;
855 
856   l_index := p_props.next(l_index);
857 End Loop;
858 
859 if(NOT l_all_active) then
860 --
861 -- Ok, not all the details corresponded to one
862 -- active assignment.  Now look across
863 -- assignments.  This is much less likely.
864 --
865 l_all_active := true;
866 
867 l_block_index := p_details.first;
868 
869 Loop
870   Exit When Not p_details.exists(l_block_index);
871   if(hxc_timecard_block_utils.is_active_block(p_blocks(p_details(l_block_index)))) then
872     l_detail_date := trunc(
873                hxc_timecard_block_utils.date_value(
874                  p_blocks(
875                 p_days(
876                   p_blocks(p_details(l_block_index)).parent_building_block_id
877                     )
878                     ).start_time
879                ));
880 
881     if(inactive_detail(l_asg_info,l_detail_date)) then
882 
883       l_all_active := false;
884       p_block_idxs(l_block_index) := l_block_index;
885 
886     end if;
887   end if;
888 
889   l_block_index := p_details.next(l_block_index);
890 End Loop;
891 
892 end if;
893 
894 End chk_inactive_details;
895 
896 --
897 -- ----------------------------------------------------------------------------
898 -- |---------------------------< perform_checks >-----------------------------|
899 -- ----------------------------------------------------------------------------
900 -- {Start Of Comments}
901 --
902 -- Description:
903 --   This procedure performs all the basic checks on the timecard information
904 -- pre-deposit.
905 --
906 -- Prerequisites:
907 --   Middle tier has sent some blocks, attributes.  I.e. we've passed
908 -- check inputs.
909 --
910 -- In Parameters:
911 --   Name                  Reqd Type     Description
912 --   p_blocks                 Yes  BLOCKS   The blocks to deposit
913 --   p_atttributes            Yes  ATTRS    The attributes to deposit
914 --   p_messages               Yes  MESSAGES The application messages
915 --
916 -- Access Status:
917 --   Internal use only.
918 --
919 -- {End Of Comments}
920 --
921 --
922 PROCEDURE perform_checks
923         (p_blocks      in         hxc_block_table_type
924         ,p_attributes     in         hxc_attribute_table_type
925         ,p_timecard_props in         hxc_timecard_prop_table_type
926         ,p_days        in         hxc_timecard.block_list
927         ,p_details     in         hxc_timecard.block_list
928         ,p_messages       in out nocopy hxc_message_table_type
929         ) IS
930 
931 l_tc_index NUMBER;
932 l_index    NUMBER;
933 l_idx      NUMBER;
934 
935 l_inactive_detail_id  hxc_time_building_blocks.time_building_block_id%type;
936 l_inactive_detail_ovn hxc_time_building_blocks.object_version_number%type;
937 l_block_idxs       block_list;
938 
939 l_proc     varchar2(72) := g_package||'perform_checks';
940 
941 l_validate_on_save    hxc_pref_hierarchies.attribute1%type := hxc_timecard.c_no;
945 
942 
943 
944 BEGIN
946 --
947 -- First find the "active" timecard scope building block
948 -- index.
949 --
950 
951 l_tc_index := hxc_timecard_block_utils.find_active_timecard_index
952           (p_blocks => p_blocks);
953 
954 
955 l_validate_on_save := hxc_timecard_properties.find_property_value
956                 (p_timecard_props
957                 ,'TsPerValidateOnSaveValidateOnSave'
958                 ,null
959                 ,null
960                 ,fnd_date.canonical_to_date(p_blocks(l_tc_index).start_time)
961                 ,fnd_date.canonical_to_date(p_blocks(l_tc_index).stop_time)
962                 );
963 
964 
965 --
966 -- 1. Check that we're allowed to deposit this timecard
967 --
968 
969   if (chk_timecard_deposit
970        (p_blocks
971        ,l_tc_index
972        )
973      ) then
974      --
975      -- There is an existing timecard, stop processing.
976      --
977      hxc_timecard_message_helper.addErrorToCollection
978       (p_messages
979       ,'HXC_366333_TIMECARD_EXISTS'
980       ,hxc_timecard.c_error
981       ,null
982       ,null
983       ,hxc_timecard.c_hxc
984       ,null
985       ,null
986       ,null
987       ,null
988       );
989 
990   end if;
991 
992 --
993 -- 2. Check that all the details have start_time and stop_time in submission
994 --
995     check_start_stop_time
996      (p_blocks       		=> p_blocks
997      ,p_details      		=> p_details
998      ,p_messages    		=> p_messages
999      ,p_validate_on_save 	=> l_validate_on_save
1000      );
1001 
1002 --
1003 -- 3. Check that all the details lie within a valid primary
1004 -- assignment range.
1005 --
1006 
1007   chk_inactive_details(p_blocks,p_timecard_props,p_days,p_details,l_block_idxs);
1008 
1009   if(l_block_idxs.count > 0) then
1010 
1011      l_idx := l_block_idxs.first;
1012      Loop
1013        Exit When not l_block_idxs.exists(l_idx);
1014 
1015        hxc_timecard_message_helper.addErrorToCollection
1016      (p_messages
1017      ,'HXC_DETAIL_NON_ACTIVE'
1018      ,hxc_timecard.c_error
1019      ,null
1020      ,null
1021      ,hxc_timecard.c_hxc
1022      ,p_blocks(p_details(l_idx)).time_building_block_id
1023      ,p_blocks(p_details(l_idx)).object_version_number
1024      ,null
1025      ,null
1026      );
1027        l_idx := l_block_idxs.next(l_idx);
1028      End Loop;
1029 
1030   end if;
1031 
1032 END perform_checks;
1033 
1034 Function prohibitedAttributeChange
1035         (p_block      in hxc_block_type,
1036          p_attributes in hxc_attribute_table_type)
1037    Return Boolean is
1038 
1039    cursor c_old_attribute(p_id in hxc_time_attributes.time_attribute_id%type) is
1040      select *
1041        from hxc_time_attributes
1042       where time_attribute_id = p_id;
1043 
1044    l_old_attribute c_old_attribute%rowtype;
1045 
1046    l_prohibited boolean;
1047    l_index pls_integer;
1048 
1049 Begin
1050 
1051    l_prohibited := false;
1052    l_index := p_attributes.first;
1053    Loop
1054       Exit when not p_attributes.exists(l_index);
1055 
1056 
1057       Exit when (
1058             (not p_attributes.exists(l_index))
1059            OR
1060             (l_prohibited)
1061            );
1062       if(p_attributes(l_index).building_block_id = p_block.time_building_block_id) then
1063 
1064       open c_old_attribute(p_attributes(l_index).time_attribute_id);
1065       fetch c_old_attribute into l_old_attribute;
1066       close c_old_attribute;
1067 
1068       if(l_old_attribute.time_attribute_id is null) then
1069          -- A new attribute.  Not allowed.
1070          l_prohibited := true;
1071       else
1072          -- Check for changes.
1073          if(l_old_attribute.attribute_category <> p_attributes(l_index).attribute_category) then
1074             l_prohibited := true;
1075          elsif(nvl(l_old_attribute.attribute1,'A') <> nvl(p_attributes(l_index).attribute1,'A')) then
1076             l_prohibited := true;
1077          elsif(nvl(l_old_attribute.attribute2,'A') <> nvl(p_attributes(l_index).attribute2,'A')) then
1078             l_prohibited := true;
1079          elsif(nvl(l_old_attribute.attribute3,'A') <> nvl(p_attributes(l_index).attribute3,'A')) then
1080             l_prohibited := true;
1081          elsif(nvl(l_old_attribute.attribute4,'A') <> nvl(p_attributes(l_index).attribute4,'A')) then
1082             l_prohibited := true;
1083          elsif(nvl(l_old_attribute.attribute5,'A') <> nvl(p_attributes(l_index).attribute5,'A')) then
1084             l_prohibited := true;
1085          elsif(nvl(l_old_attribute.attribute6,'A') <> nvl(p_attributes(l_index).attribute6,'A')) then
1086             l_prohibited := true;
1087          elsif(nvl(l_old_attribute.attribute7,'A') <> nvl(p_attributes(l_index).attribute7,'A')) then
1088             l_prohibited := true;
1089          elsif(nvl(l_old_attribute.attribute8,'A') <> nvl(p_attributes(l_index).attribute8,'A')) then
1090             l_prohibited := true;
1091          elsif(nvl(l_old_attribute.attribute9,'A') <> nvl(p_attributes(l_index).attribute9,'A')) then
1092             l_prohibited := true;
1093          elsif(nvl(l_old_attribute.attribute10,'A') <> nvl(p_attributes(l_index).attribute10,'A')) then
1094             l_prohibited := true;
1095          elsif(nvl(l_old_attribute.attribute11,'A') <> nvl(p_attributes(l_index).attribute11,'A')) then
1096             l_prohibited := true;
1097          elsif(nvl(l_old_attribute.attribute12,'A') <> nvl(p_attributes(l_index).attribute12,'A')) then
1098             l_prohibited := true;
1102             l_prohibited := true;
1099          elsif(nvl(l_old_attribute.attribute13,'A') <> nvl(p_attributes(l_index).attribute13,'A')) then
1100             l_prohibited := true;
1101          elsif(nvl(l_old_attribute.attribute14,'A') <> nvl(p_attributes(l_index).attribute14,'A')) then
1103          elsif(nvl(l_old_attribute.attribute15,'A') <> nvl(p_attributes(l_index).attribute15,'A')) then
1104             l_prohibited := true;
1105          elsif(nvl(l_old_attribute.attribute16,'A') <> nvl(p_attributes(l_index).attribute16,'A')) then
1106             l_prohibited := true;
1107          elsif(nvl(l_old_attribute.attribute17,'A') <> nvl(p_attributes(l_index).attribute17,'A')) then
1108             l_prohibited := true;
1109          elsif(nvl(l_old_attribute.attribute18,'A') <> nvl(p_attributes(l_index).attribute18,'A')) then
1110             l_prohibited := true;
1111          elsif(nvl(l_old_attribute.attribute19,'A') <> nvl(p_attributes(l_index).attribute19,'A')) then
1112             l_prohibited := true;
1113          elsif(nvl(l_old_attribute.attribute20,'A') <> nvl(p_attributes(l_index).attribute20,'A')) then
1114             l_prohibited := true;
1115          elsif(nvl(l_old_attribute.attribute21,'A') <> nvl(p_attributes(l_index).attribute21,'A')) then
1116             l_prohibited := true;
1117          elsif(nvl(l_old_attribute.attribute22,'A') <> nvl(p_attributes(l_index).attribute22,'A')) then
1118             l_prohibited := true;
1119          elsif(nvl(l_old_attribute.attribute23,'A') <> nvl(p_attributes(l_index).attribute23,'A')) then
1120             l_prohibited := true;
1121          elsif(nvl(l_old_attribute.attribute24,'A') <> nvl(p_attributes(l_index).attribute24,'A')) then
1122             l_prohibited := true;
1123          elsif(nvl(l_old_attribute.attribute25,'A') <> nvl(p_attributes(l_index).attribute25,'A')) then
1124             l_prohibited := true;
1125          elsif(nvl(l_old_attribute.attribute26,'A') <> nvl(p_attributes(l_index).attribute26,'A')) then
1126             l_prohibited := true;
1127          elsif(nvl(l_old_attribute.attribute27,'A') <> nvl(p_attributes(l_index).attribute27,'A')) then
1128             l_prohibited := true;
1129          elsif(nvl(l_old_attribute.attribute28,'A') <> nvl(p_attributes(l_index).attribute28,'A')) then
1130             l_prohibited := true;
1131          elsif(nvl(l_old_attribute.attribute29,'A') <> nvl(p_attributes(l_index).attribute29,'A')) then
1132             l_prohibited := true;
1133          elsif(nvl(l_old_attribute.attribute30,'A') <> nvl(p_attributes(l_index).attribute30,'A')) then
1134             l_prohibited := true;
1135          end if;
1136       end if;
1137       end if;
1138       l_index := p_attributes.next(l_index);
1139    End Loop;
1140 
1141    return l_prohibited;
1142 
1143 End prohibitedAttributeChange;
1144 
1145 Function prohibitedBlockChange
1146            (p_block      in hxc_block_type,
1147             p_attributes in hxc_attribute_table_type)
1148    Return Boolean is
1149 
1150    cursor c_old_block
1151             (p_id in hxc_time_building_blocks.time_building_block_id%type,
1152              p_ovn in hxc_time_building_blocks.object_version_number%type) is
1153      select *
1154        from hxc_time_building_blocks
1155       where time_building_block_id = p_id
1156         and object_version_number = p_ovn;
1157 
1158    l_old_block c_old_block%rowtype;
1159    l_prohibited boolean;
1160 
1161 Begin
1162    if(p_block.process = 'N') then
1163      l_prohibited := false;
1164    else
1165       open c_old_block
1166              (p_block.time_building_block_id,
1167               p_block.object_version_number);
1168       fetch c_old_block into l_old_block;
1169       close c_old_block;
1170 
1171       if(l_old_block.time_building_block_id is null) then
1172          -- How did we get here, must be a new block!
1173          l_prohibited := false;
1174       else
1175          -- Check all user updateable attributes, except
1176          -- approval style id, which Santos do not want
1177          -- included in this check.
1178          if(l_old_block.TYPE <> p_block.TYPE) then
1179             l_prohibited := true;
1180          else
1181             if(round(l_old_block.MEASURE,3) <> round(p_block.MEASURE,3)) then
1182                l_prohibited := true;
1183             else
1184                if(l_old_block.UNIT_OF_MEASURE <> p_block.UNIT_OF_MEASURE) then
1185                   l_prohibited := true;
1186                else
1187                   if(l_old_block.START_TIME <> fnd_date.canonical_to_date(p_block.START_TIME)) then
1188                      l_prohibited := true;
1189                   else
1190                      if(l_old_block.STOP_TIME <> fnd_date.canonical_to_date(p_block.STOP_TIME)) then
1191                         l_prohibited := true;
1192                      else
1193                         if(l_old_block.APPROVAL_STATUS <> p_block.APPROVAL_STATUS) then
1194                            l_prohibited := true;
1195                         else
1196                            if(l_old_block.DATE_TO <> fnd_date.canonical_to_date(p_block.DATE_TO)) then
1197                               l_prohibited := true;
1198                            else
1199                               if(nvl(l_old_block.COMMENT_TEXT,'COMMENT') <> nvl(p_block.COMMENT_TEXT,'COMMENT')) then
1200                                  l_prohibited := true;
1201                                  --
1202                                  -- Ok, all the block attributes are the same
1203                                  -- Are the attributes the same?
1204                                else
1205                                  if(prohibitedAttributeChange(p_block,p_attributes)) then
1206                                    l_prohibited := true;
1207                                  else
1208                                    l_prohibited := false;
1209                                  end if;
1210                               end if;
1211                            end if;
1212                         end if;
1216             end if;
1213                      end if;
1214                   end if;
1215                end if;
1217          end if;
1218       end if;
1219    end if;
1220 
1221    return l_prohibited;
1222 
1223 End prohibitedBlockChange;
1224 
1225 Function never_locked
1226        (p_timecard_props in hxc_timecard_prop_table_type
1227        ,p_early_date     in date
1228        ,p_late_date      in date
1229        ) return boolean is
1230 
1231 l_index     number;
1232 l_found     boolean := false;
1233 l_day_found    boolean := false;
1234 l_detail_found boolean := false;
1235 l_day       boolean := false;
1236 l_detail       boolean := false;
1237 l_result       boolean := false;
1238 l_proc      varchar2(30) := 'never_locked';
1239 Begin
1240 
1241 
1242 l_index := p_timecard_props.first;
1243 Loop
1244   Exit when ((not p_timecard_props.exists(l_index)) or (l_found));
1245 
1246   if(p_timecard_props(l_index).property_name = 'TcWTcrdStAlwEditsModifyApprovedTcDetails') then
1247     if(p_timecard_props(l_index).date_from < p_early_date) then
1248       if(p_timecard_props(l_index).date_to > p_late_date) then
1249      l_detail_found := true;
1250      if((p_timecard_props(l_index).property_value <> 'N') OR (p_timecard_props(l_index).property_value is null))then
1251        l_detail := true;
1252      end if;
1253       end if;
1254     end if;
1255   end if;
1256 
1257   if(p_timecard_props(l_index).property_name = 'TcWTcrdStAlwEditsModifyApprovedTcDays') then
1258     if(p_timecard_props(l_index).date_from < p_early_date) then
1259       if(p_timecard_props(l_index).date_to > p_late_date) then
1260      l_day_found := true;
1261      if((p_timecard_props(l_index).property_value <> 'N') OR (p_timecard_props(l_index).property_value is null))then
1262        l_day := true;
1263      end if;
1264       end if;
1265     end if;
1266   end if;
1267 
1268   if(l_day_found) AND (l_detail_found) then
1269     l_found := true;
1270     if(l_day) and (l_detail) then
1271       l_result := true;
1272     end if;
1273   end if;
1274 
1275   l_index := p_timecard_props.next(l_index);
1276 End Loop;
1277 
1278 --
1279 -- 115.6 Change: Bug 2888528
1280 --
1281 
1282 if(not l_found) then
1283 
1284   if((l_day_found) AND (NOT l_day)) then
1285     l_result := false;
1286   elsif((l_detail_found) AND (NOT l_detail)) then
1287     l_result := false;
1288   else
1289     l_result := true;
1290   end if;
1291 
1292 end if;
1293 
1294 return l_result;
1295 
1296 End never_locked;
1297 
1298 Function find_locking_preference
1299        (p_timecard_props in hxc_timecard_prop_table_type
1300        ,p_date        in date
1301        ,p_preference     in varchar2
1302        ) return varchar2 is
1303 
1304 l_preference varchar2(2) := 'Y';
1305 l_index      number;
1306 l_found      boolean := false;
1307 Begin
1308 
1309 l_index := p_timecard_props.first;
1310 Loop
1311   Exit when ((not p_timecard_props.exists(l_index)) or (l_found));
1312   if(p_preference = 'DAY') then
1313     if(p_timecard_props(l_index).property_name = 'TcWTcrdStAlwEditsModifyApprovedTcDays') then
1314       if(p_date between p_timecard_props(l_index).date_from and p_timecard_props(l_index).date_to) then
1315      l_preference := p_timecard_props(l_index).property_value;
1316      l_found := true;
1317       end if;
1318     end if;
1319   else
1320     if(p_timecard_props(l_index).property_name = 'TcWTcrdStAlwEditsModifyApprovedTcDetails') then
1321       if(p_date between p_timecard_props(l_index).date_from and p_timecard_props(l_index).date_to) then
1322      l_preference := p_timecard_props(l_index).property_value;
1323      l_found := true;
1324       end if;
1325     end if;
1326   end if;
1327   l_index := p_timecard_props.next(l_index);
1328 End Loop;
1329 
1330 return l_preference;
1331 
1332 End find_locking_preference;
1333 
1334 Function day_approved
1335        (p_resource_id    in hxc_time_building_blocks.resource_id%type
1336        ,p_date        in date
1337        ) return boolean is
1338 
1339 cursor c_approved_day
1340      (p_resource_id    in hxc_time_building_blocks.resource_id%type
1341      ,p_date        in date) is
1342   select ap.approval_status
1343     from hxc_time_building_blocks ap, hxc_time_building_blocks tc
1344    where ap.resource_id = p_resource_id
1345      and ap.scope = 'APPLICATION_PERIOD'
1346      and ap.approval_status = 'APPROVED'
1347      and p_date between ap.start_time and ap.stop_time
1348      and ap.resource_id = tc.resource_id
1349      and ap.creation_date >= tc.creation_date
1350      and tc.date_to = hr_general.end_of_time
1351      and tc.scope = 'TIMECARD'
1352      and tc.start_time <= ap.stop_time
1353      and tc.stop_time >= ap.start_time
1354      and NOT exists
1355      (select 'Y'
1356        from hxc_time_building_blocks
1357    where resource_id = p_resource_id
1358      and scope = 'APPLICATION_PERIOD'
1359      and date_to = hr_general.end_of_time
1360      and approval_status = 'REJECTED'
1361      and p_date between start_time and stop_time
1362      );
1363 
1364 l_dummy hxc_time_building_blocks.approval_status%type;
1365 
1366 Begin
1367 
1368 open c_approved_day(p_resource_id,p_date);
1369 fetch c_approved_day into l_dummy;
1370 if(c_approved_day%found) then
1371   close c_approved_day;
1372   return true;
1373 else
1374   close c_approved_day;
1375   return false;
1376 end if;
1377 
1378 End day_approved;
1379 --
1380 -- Added detail_with_day in version 115.115.  This is for the
1381 -- santos locking of approved days functionality.
1382 --
1386    ) RETURN BOOLEAN IS
1383 FUNCTION detail_with_day
1384   (p_date IN DATE,
1385    p_resource_id IN hxc_time_building_blocks.resource_id%TYPE
1387 
1388 CURSOR c_detail_exists
1389   (p_date IN DATE,
1390    p_resource_id IN hxc_time_building_blocks.resource_id%TYPE
1391    ) IS
1392        SELECT 'Y'
1393 	FROM hxc_time_building_blocks detail,
1394 	     hxc_time_building_blocks day,
1395 	     hxc_time_building_blocks parent
1396 	WHERE detail.parent_building_block_id = day.time_building_block_id
1397 	AND detail.parent_building_block_ovn = day.object_version_number
1398 	AND detail.date_to = hr_general.end_of_time
1399 	AND detail.resource_id = p_resource_id
1400 	AND detail.scope = 'DETAIL'
1401 	AND detail.creation_date <=(select max(ap.creation_date)
1402 	    from hxc_time_building_blocks ap
1403 	    where ap.resource_id = p_resource_id
1404 	     and ap.scope = 'APPLICATION_PERIOD'
1405 	     and ap.approval_status = 'APPROVED'
1406 	     and p_date between ap.start_time and ap.stop_time
1407 	     and ap.resource_id = parent.resource_id
1408 	     and ap.creation_date >= parent.creation_date
1409 	     and parent.date_to = hr_general.end_of_time
1410 	     and parent.start_time <= ap.stop_time
1411 	     and parent.stop_time >= ap.start_time)
1412 	AND day.scope = 'DAY'
1413 	AND Trunc(day.start_time) = Trunc(p_date)
1414 	AND day.date_to = hr_general.end_of_time
1415 	AND day.resource_id = p_resource_id
1416      and parent.time_building_block_id=day.parent_building_block_id
1417 	and parent.object_version_number=day.parent_building_block_ovn
1418 	and parent.scope='TIMECARD'
1419 	AND parent.date_to = hr_general.end_of_time
1420 	AND parent.resource_id = p_resource_id;
1421 
1422 l_dummy varchar2(1);
1423 
1424 BEGIN
1425    OPEN c_detail_exists(p_date,p_resource_id);
1426    FETCH c_detail_exists INTO l_dummy;
1427    IF(c_detail_exists%found) THEN
1428       CLOSE c_detail_exists;
1429       RETURN TRUE;
1430     ELSE
1431       CLOSE c_detail_exists;
1432       RETURN FALSE;
1433    END IF;
1434 END detail_with_day;
1435 
1436 Function day_locked
1437        (p_timecard_props in hxc_timecard_prop_table_type
1438        ,p_resource_id    in hxc_time_building_blocks.resource_id%type
1439        ,p_date        in date
1440        ) return boolean is
1441 
1442 l_locked boolean := false;
1443 l_pref   varchar2(2);
1444 
1445 Begin
1446 
1447 l_pref := find_locking_preference
1448         (p_timecard_props
1449         ,p_date
1450         ,'DAY'
1451         );
1452 if(l_pref = 'N') then
1453   if(day_approved(p_resource_id,p_date)) then
1454      IF(detail_with_day(p_date,p_resource_id)) then
1455 	l_locked := true;
1456       ELSE
1457 	l_locked := FALSE;
1458      END IF;
1459   else
1460     l_locked := false;
1461   end if;
1462 else
1463   l_locked := false;
1464 end if;
1465 
1466 return l_locked;
1467 
1468 End day_locked;
1469 
1470    Function detail_locked
1471       (p_timecard_props in hxc_timecard_prop_table_type,
1472        p_resource_id    in hxc_time_building_blocks.resource_id%type,
1473        p_date           in date,
1474        p_detail_id      in hxc_ap_detail_links.time_building_block_id%type,
1475        p_detail_ovn     in hxc_ap_detail_links.time_building_block_ovn%type
1476        ) return boolean is
1477 
1478       cursor c_detail_approved
1479          (p_detail_id in hxc_ap_detail_links.time_building_block_id%type,
1480           p_detail_ovn in hxc_ap_detail_links.time_building_block_ovn%type) is
1481         select 'Y'
1482           from hxc_ap_detail_links adl,
1483                hxc_app_period_summary aps
1484          where adl.time_building_block_id = p_detail_id
1485            and adl.time_building_block_ovn = p_detail_ovn
1486            and adl.application_period_id = aps.application_period_id
1487        and aps.approval_status = hxc_timecard.c_approved_status
1488            and not exists(select 1
1489                             from hxc_ap_detail_links adl2,
1490                                  hxc_app_period_summary aps2
1491                            where adl2.time_building_block_id = adl.time_building_block_id
1492                              and adl2.time_building_block_ovn = adl.time_building_block_ovn
1493                              and adl2.application_period_id <> adl.application_period_id
1494                              and adl2.application_period_id = aps2.application_period_id
1495                              and aps2.approval_status <> hxc_timecard.c_approved_status);
1496 
1497       l_locked boolean := false;
1498       l_pref   varchar2(2);
1499       l_dummy  varchar2(1);
1500 
1501    Begin
1502 
1503       l_pref := find_locking_preference
1504          (p_timecard_props,
1505           p_date,
1506           'DETAIL'
1507           );
1508 
1509       if(l_pref = 'N') then
1510          open c_detail_approved(p_detail_id,p_detail_ovn);
1511          fetch c_detail_approved into l_dummy;
1512          if(c_detail_approved%notfound) then
1513             l_locked := false;
1514          else
1515             l_locked := true;
1516          end if;
1517          close c_detail_approved;
1518       else
1519          l_locked := false;
1520       end if;
1521 
1522       return l_locked;
1523 
1524    End detail_locked;
1525 --
1526 -- ----------------------------------------------------------------------------
1527 -- |----------------------< chk_approved_locked_days >------------------------|
1528 -- ----------------------------------------------------------------------------
1529 -- {Start Of Comments}
1530 --
1531 -- Description:
1532 --   This procedure performs all the basic checks on the timecard information
1536 --
1533 -- pre-deposit, but once the processing state of the blocks in known.  At the
1534 -- the moment, this is simply the implementation of the Santos-built approval
1535 -- locking of days.
1537 -- Prerequisites:
1538 --   Middle tier has sent some blocks, attributes.  I.e. we've passed
1539 -- check inputs.
1540 --
1541 -- In Parameters:
1542 --   Name                  Reqd Type      Description
1543 --   p_blocks                 Yes  BLOCKS    The blocks to deposit
1544 --   p_timecard_props            Yes  PROPS     The preferences
1545 --   p_days                Yes  BlockList The Day building blocks
1546 --   p_details                Yes  Blocklist The detail building blocks
1547 --   p_messages               Yes  MESSAGES  The application messages
1548 --
1549 -- Access Status:
1550 --   Internal use only.
1551 --
1552 -- {End Of Comments}
1553 --
1554 --
1555 PROCEDURE chk_approved_locked_days
1556         (p_blocks      in         hxc_block_table_type,
1557          p_attributes     in         hxc_attribute_table_type
1558         ,p_timecard_props in         hxc_timecard_prop_table_type
1559         ,p_days        in         hxc_timecard.block_list
1560         ,p_details     in         hxc_timecard.block_list
1561         ,p_messages       in out nocopy hxc_message_table_type
1562         ) IS
1563 
1564 l_modify_days    varchar2(2) := 'N';
1565 l_modify_details varchar2(2) := 'N';
1566 l_detail_date    date;
1567 l_detail_index   number;
1568 l_early_detail   date := hr_general.end_of_time;
1569 l_late_detail    date := hr_general.start_of_time;
1570 l_proc        varchar2(72) := g_package||'chk_approved_locked_days';
1571 Begin
1572 
1573 find_detail_date_extremes
1574  (p_blocks       => p_blocks
1575  ,p_days      => p_days
1576  ,p_details      => p_details
1577  ,p_early_detail => l_early_detail
1578  ,p_late_detail  => l_late_detail
1579  );
1580 
1581 if(never_locked(p_timecard_props, l_early_detail, l_late_detail)) then
1582   --
1583   -- No need to check, since the preferences are not set.
1584   --
1585   null;
1586 else
1587   --
1588   -- Check each detail to see if allowed to change.
1589   --
1590   l_detail_index := p_details.first;
1591   Loop
1592     Exit when not p_details.exists(l_detail_index);
1593 
1594     if(((prohibitedBlockChange
1595            (p_blocks(p_details(l_detail_index)),
1596             p_attributes
1597             )
1598          )
1599         OR
1600          (hxc_timecard_block_utils.is_new_block(p_blocks(p_details(l_detail_index)))))
1601       --AND
1602        --(hxc_timecard_block_utils.is_active_block(p_blocks(p_details(l_detail_index))))
1603       )then
1604 
1605       l_detail_date := trunc(hxc_timecard_block_utils.date_value
1606                                (p_blocks(p_days(p_blocks(p_details(l_detail_index)).parent_building_block_id)).start_time
1607                              ));
1608       if(day_locked(p_timecard_props, p_blocks(p_details(l_detail_index)).resource_id,l_detail_date)) then
1609         hxc_timecard_message_helper.addErrorToCollection
1610           (p_messages
1611            ,'HXC_NO_MODIFY_APPROVED_DETAIL'
1612            ,hxc_timecard.c_error
1613            ,null
1614            ,null
1615            ,hxc_timecard.c_hxc
1616            ,p_blocks(p_details(l_detail_index)).time_building_block_id
1617            ,null
1618            ,null
1619            ,null
1620            );
1621       else
1622         if(hxc_timecard_block_utils.is_new_block(p_blocks(p_details(l_detail_index)))) then
1623           --
1624           -- It is ok, this entry is allowed, the day is not locked, and it is a new
1625           -- building block
1626           --
1627           null;
1628         else
1629           if(detail_locked
1630                (p_timecard_props,
1631                 p_blocks(p_details(l_detail_index)).resource_id,
1632                 l_detail_date,
1633                 p_blocks(p_details(l_detail_index)).time_building_block_id,
1634                 p_blocks(p_details(l_detail_index)).object_version_number
1635                 )) then
1636             hxc_timecard_message_helper.addErrorToCollection
1637               (p_messages
1638                ,'HXC_NO_MODIFY_APPROVED_DETAIL'
1639                ,hxc_timecard.c_error
1640                ,null
1641                ,null
1642                ,hxc_timecard.c_hxc
1643                ,p_blocks(p_details(l_detail_index)).time_building_block_id
1644                ,null
1645                ,null
1646                ,null
1647                );
1648           end if;
1649         end if;
1650       end if;
1651     end if; -- is the block new or changed?
1652     l_detail_index := p_details.next(l_detail_index);
1653   End Loop;
1654 end if;
1655 
1656 End chk_approved_locked_days;
1657 --
1658 -- ----------------------------------------------------------------------------
1659 -- |-----------------------< perform_process_checks >-------------------------|
1660 -- ----------------------------------------------------------------------------
1661 -- {Start Of Comments}
1662 --
1663 -- Description:
1664 --       This procedure checks that if the deposit mode is submit, then we're
1665 -- going to process at least one or more block or attribute.  If not, then the
1666 -- approval workflow will not be started, and we should not show the
1667 -- confirmation page to the user.
1668 --
1669 -- Prerequisites:
1670 --   Middle tier has sent some blocks, attributes.  I.e. we've passed
1671 -- check inputs.
1672 --
1673 -- In Parameters:
1674 --   Name                  Reqd Type      Description
1675 --   p_blocks                 Yes  BLOCKS    The blocks to deposit
1676 --   p_atttributes            Yes  ATTRS     The attributes to deposit
1680 --   Internal use only.
1677 --   p_messages               Yes  MESSAGES  The application messages
1678 --
1679 -- Access Status:
1681 --
1682 -- {End Of Comments}
1683 --
1684 --
1685 PROCEDURE chk_some_processing
1686         (p_blocks      in         hxc_block_table_type
1687         ,p_attributes     in         hxc_attribute_table_type
1688         ,p_messages       in out nocopy hxc_message_table_type
1689         ) is
1690 
1691 l_index number;
1692 l_found boolean := false;
1693 
1694 l_proc varchar2(70) := g_package||'chk_some_processing';
1695 
1696 Begin
1697 
1698 IF g_debug THEN
1699   hr_utility.trace(' In HXC_DEPOSIT_CHECKS.chk_some_processing');
1700 END IF;
1701 
1702 
1703 l_index := p_blocks.first;
1704 LOOP
1705   Exit When ((Not p_blocks.exists(l_index)) or (l_found));
1706   if(hxc_timecard_block_utils.process_block(p_blocks(l_index))) then
1707     l_found := true;
1708   end if;
1709   l_index := p_blocks.next(l_index);
1710 END LOOP;
1711 
1712 if (not l_found) then
1713   l_index := p_attributes.first;
1714   LOOP
1715     Exit When ((Not p_attributes.exists(l_index)) or (l_found));
1716     if(hxc_timecard_attribute_utils.process_attribute(p_attributes(l_index))) then
1717       l_found := true;
1718     end if;
1719     l_index := p_attributes.next(l_index);
1720   END LOOP;
1721 end if;
1722 
1723 IF g_debug THEN
1724   if l_found then
1725     hr_utility.trace(' l_found is true');
1726     hr_utility.trace(' g_tc_api_flag ::'||hxc_block_attribute_update.g_tc_api_flag);
1727   else
1728     hr_utility.trace(' l_found is false');
1729     hr_utility.trace(' g_tc_api_flag ::'||hxc_block_attribute_update.g_tc_api_flag);
1730   end if;
1731 END IF;
1732 
1733 
1734 if (not l_found) then
1735   hxc_timecard_message_helper.addErrorToCollection
1736     (p_messages
1737     ,'HXC_TIMECARD_NOT_SUBMITTED'
1738     ,hxc_timecard.c_error
1739     ,null
1740     ,null
1741     ,hxc_timecard.c_hxc
1742     ,null
1743     ,null
1744     ,null
1745     ,null
1746     );
1747 end if;
1748 
1749 -- Added for
1750 if hxc_block_attribute_update.g_tc_api_flag = 'Y' then
1751   hxc_timecard_message_helper.addErrorToCollection
1752     (p_messages
1753     ,'HXC_TIMECARD_NOT_SUBMITTED'
1754     ,hxc_timecard.c_error
1755     ,null
1756     ,null
1757     ,hxc_timecard.c_hxc
1758     ,null
1759     ,null
1760     ,null
1761     ,null
1762     );
1763 end if;
1764 
1765 End chk_some_processing;
1766 --
1767 -- ----------------------------------------------------------------------------
1768 -- |-----------------------< perform_process_checks >-------------------------|
1769 -- ----------------------------------------------------------------------------
1770 -- {Start Of Comments}
1771 --
1772 -- Description:
1773 --   This procedure performs all the basic checks on the timecard information
1774 -- pre-deposit, but once the processing state of the blocks in known.  At the
1775 -- the moment, this is simply the implementation of the Santos-built approval
1776 -- locking of days.
1777 --
1778 -- Prerequisites:
1779 --   Middle tier has sent some blocks, attributes.  I.e. we've passed
1780 -- check inputs.
1781 --
1782 -- In Parameters:
1783 --   Name                  Reqd Type      Description
1784 --   p_blocks                 Yes  BLOCKS    The blocks to deposit
1785 --   p_atttributes            Yes  ATTRS     The attributes to deposit
1786 --   p_timecard_props            Yes  PROPS     The preferences
1787 --   p_days                Yes  BlockList The Day building blocks
1788 --   p_details                Yes  Blocklist The detail building blocks
1789 --   p_template               Yes  VARCHAR2  Is this a template?
1790 --   p_deposit_mode           Yes  VARCHAR2  The current deposit mode
1791 --   p_messages               Yes  MESSAGES  The application messages
1792 --
1793 -- Access Status:
1794 --   Internal use only.
1795 --
1796 -- {End Of Comments}
1797 --
1798 --
1799 PROCEDURE perform_process_checks
1800         (p_blocks      in         hxc_block_table_type
1801         ,p_attributes     in         hxc_attribute_table_type
1802         ,p_timecard_props in         hxc_timecard_prop_table_type
1803         ,p_days        in         hxc_timecard.block_list
1804         ,p_details     in         hxc_timecard.block_list
1805         ,p_template       in         varchar2
1806         ,p_deposit_mode   in         varchar2
1807         ,p_messages       in out nocopy hxc_message_table_type
1808         ) IS
1809 
1810 l_modify_days    varchar2(2) := 'N';
1811 l_modify_details varchar2(2) := 'N';
1812 l_detail_date    date;
1813 l_detail_index   number;
1814 
1815 Begin
1816 
1817 if(p_template <> 'Y') then
1818 
1819   chk_approved_locked_days
1820    (p_blocks      => p_blocks
1821    ,p_attributes     => p_attributes
1822    ,p_timecard_props => p_timecard_props
1823    ,p_days        => p_days
1824    ,p_details     => p_details
1825    ,p_messages       => p_messages
1826    );
1827 
1828   if(p_deposit_mode = 'SUBMIT') then
1829 
1830    hr_utility.trace('In perform_process_checks .. calling chk_some_process proc..');
1831    hr_utility.trace('p_deposit_mode ::'||p_deposit_mode);
1832    chk_some_processing
1833     (p_blocks     => p_blocks
1834     ,p_attributes    => p_attributes
1835     ,p_messages      => p_messages
1836     );
1837   end if;
1838 end if;
1839 
1840 End perform_process_checks;
1841 
1842 END hxc_deposit_checks;