DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_SECURITY_CHECK_SV

Source


1 PACKAGE BODY PO_SECURITY_CHECK_SV as
2 /* $Header: POXSCHKB.pls 120.2.12020000.2 2013/02/10 19:29:49 vegajula ship $ */
3 
4 /*=============================  PO_SECURITY_CHECK_SV  ===============================*/
5 
6 
7 /*===========================================================================
8 
9   PROCEDURE NAME:	check_before_lock()
10 
11 ===========================================================================*/
12 
13 function  check_for_delegation (x_itemtype      in varchar2,
14                                 x_itemkey       in varchar2,
15                                 x_logged_emp_id in number,
16                                 x_action_emp_id in number) return boolean;
17 
18 PROCEDURE  check_before_lock (x_type_lookup_code in varchar2,
19                                                 x_object_id        in number,
20                                                 x_logged_emp_id in number,
21                                                 x_modify_action in out NOCOPY boolean) IS
22 
23 x_can_approver_modify_flag varchar2(25);
24 x_progress    varchar2(3);
25 x_last_action_emp_id  number;
26 x_document_type_code  varchar2(25);
27 x_document_subtype    varchar2(25);
28 x_count               number := 0;
29 
30 l_authorization_status varchar2(25);
31 
32 x_wf_item_type        po_headers_all.wf_item_type%type := NULL;
33 x_wf_item_key         po_headers_all.wf_item_key%type := NULL;   -- Modified for Bug 2783162
34 
35 BEGIN
36 
37     IF x_type_lookup_code = 'RELEASE' THEN
38 
39 	x_document_type_code := 'RELEASE';
40 	x_document_subtype := 'BLANKET';
41 
42     ELSE
43 
44 	x_document_subtype := x_type_lookup_code;
45 	IF x_type_lookup_code IN ('STANDARD', 'PLANNED') THEN
46 	    x_document_type_code := 'PO';
47 	ELSIF x_type_lookup_code IN ('BLANKET', 'CONTRACT') THEN
48 	    x_document_type_code := 'PA';
49 	ELSIF x_type_lookup_code IN ('INTERNAL', 'PURCHASE') THEN
50 	    x_document_type_code := 'REQUISITION';
51 	ELSIF x_type_lookup_code = 'SCHEDULED' THEN
52 	    x_document_type_code := 'RELEASE';
53         ELSE
54             x_document_type_code := null;
55 	END IF;
56 
57     END IF;
58 
59   /* Bug# 1266226
60   ** Desc: When a document is INCOMPLETE, we need not verify that
61   **       the action history exists or not. The INCOMPLETE status
62   **       signifies that the document has not been submitted for
63   **       approval or has been returned in original status without
64   **       any approval action (approve, forward) being taken on it
65   **       when the document was first submitted for the approval
66   **       process.
67   **
68   **       If the authorization status of the doc is INCOMPLETE
69   **       set x_modify_action := TRUE and return.
70   */
71 
72      x_progress := '005';
73 
74      IF x_document_type_code='REQUISITION' THEN
75 
76         x_progress := '006';       -- Added for bug 2783162
77         select NVL(AUTHORIZATION_STATUS, 'INCOMPLETE'),
78                wf_item_type, wf_item_key
79         into l_authorization_status, x_wf_item_type, x_wf_item_key
80         from po_requisition_headers_all
81         where REQUISITION_HEADER_ID = x_object_id;
82 
83      ELSIF x_document_type_code IN ('PO','PA') THEN
84         x_progress := '007';       -- Added for bug 2783162
85 
86         select NVL(AUTHORIZATION_STATUS, 'INCOMPLETE'),
87                wf_item_type, wf_item_key
88         into l_authorization_status, x_wf_item_type, x_wf_item_key
89         from po_headers_all
90         where PO_HEADER_ID = x_object_id;
91 
92      ELSIF x_document_type_code = 'RELEASE' THEN
93          x_progress := '008';       -- Added for bug 2783162
94 
95          select NVL(AUTHORIZATION_STATUS, 'INCOMPLETE'),
96                wf_item_type, wf_item_key
97          into l_authorization_status, x_wf_item_type, x_wf_item_key
98          from po_releases_all
99          where  PO_RELEASE_ID = x_object_id;
100 
101      END IF;
102 
103   /* Bug# 2454444: kagarwal
104   ** Desc: When a document is in REQUIRES REAPPROVAL status, we need not verify
105   ** the action history. The REQUIRES REAPPROVAL status signifies that the
106   ** document is NOT in between the Approval process hence the buyers can
107   ** modify the document depending on the Security setup.
108   */
109 
110      IF ((l_authorization_status = 'INCOMPLETE') OR
111          (l_authorization_status = 'REQUIRES REAPPROVAL')) THEN
112          x_modify_action := TRUE;
113          return;
114      END IF;
115 
116 /* End Fix Bug# 1266226
117 */
118 
119 
120     -- First check whether there has been any action at all on the
121     -- document. If there has been no action then the document is
122     -- still with the creator (no approval actions) and he can modify.
123 
124     x_progress := '010';
125 
126     select count(*) into x_count
127     from po_action_history pah
128     where
129       pah.object_id = x_object_id  and
130       pah.object_type_code = x_document_type_code and
131       pah.object_sub_type_code = x_document_subtype and
132       pah.action_code is null;
133 
134     if x_count = 0 then -- no records in po_action_history
135       --  dbms_output.put_line('Count is zero');
136        x_modify_action := TRUE;
137        return;
138 
139     else
140       -- check the approver can modify flag
141 
142       x_progress := '020';
143 
144       select nvl(podt.can_approver_modify_doc_flag,'N')
145       into   x_can_approver_modify_flag
146       from   po_document_types podt
147       where
148          podt.document_type_code = x_document_type_code and
149          podt.document_subtype   = x_document_subtype;
150 
151       IF x_can_approver_modify_flag = 'Y' then
152 
153       --  dbms_output.put_line('approver may modify');
154         -- making the assumption that max(sequence_num) would have null action code
155         -- select the last emp_id
156 
157         x_progress := '030';
158         select EMPLOYEE_ID
159         into   x_last_action_emp_id
160         from po_action_history pah
161         where
162           pah.object_id = x_object_id  and
163           pah.object_type_code = x_document_type_code and
164           pah.object_sub_type_code = x_document_subtype and
165           pah.action_code is null;
166         IF x_last_action_emp_id = x_logged_emp_id THEN
167 
168            -- dbms_output.put_line('The employee ids are the same');
169            x_modify_action := TRUE;
170            return;
171 
172         ELSE
173 
174            -- dbms_output.put_line('The employee ids are not the same');
175 
176            /* Bug# 2559747: kagarwal
177            ** Check if this is a delegated doc and if the logged user is the recipient_role
178            ** of the notification then allow the user to modify the doc.
179            */
180            If ((x_wf_item_type is not NULL) AND (x_wf_item_key is not NULL)) Then
181                If (check_for_delegation(x_wf_item_type, x_wf_item_key,
182                                         x_logged_emp_id, x_last_action_emp_id)) Then
183                   x_modify_action := TRUE;
184                   return;
185                End If;
186            End If;
187 
188            x_modify_action := FALSE;
189            return;
190 
191         END IF;
192 
193       ELSE
194 
195          -- dbms_output.put_line('Approver cannot modify document');
196          x_modify_action := FALSE;
197          return;
198 
199       END IF;  -- x_can_approver_modify_flag = Y
200       -- dbms_output.put_line('No records were found in po_action_history');
201      -- dbms_output.put_line('We have a problem here');
202 
203    END IF; -- count(*)
204 
205 EXCEPTION
206      WHEN OTHERS THEN
207           -- dbms_output.put_line('Errors');
208      NULL;
209 /* Bug 2814939 - removed RAISE introduced in bug 2783162
210    The problem with doing this is that this proc is called in
211    many places, and they were not designed to handle raised exceptions
212    from this procedure.  May be refactored in the future.
213      -- Added for bug 2783162
214      -- PO_MESSAGE_S.sql_error('check_before_lock', X_progress, sqlcode);
215      --   RAISE;
216 */
217 
218 end check_before_lock;
219 
220 /* Bug# 2559747: kagarwal
221 ** Added new function check_for_delegation to validate that
222 ** the delegated user is the logged employee.
223 */
224 
225 function  check_for_delegation (x_itemtype      in varchar2,
226                                 x_itemkey       in varchar2,
227                                 x_logged_emp_id in number,
228                                 x_action_emp_id in number)
229 return boolean IS
230 
231 /* use MAX to get the latest notification sent for the wf item */
232 
233 CURSOR getcurrnotif is
234  SELECT NVL(MAX(wf.notification_id), -9995),wf.from_role --Bug 12534279
235  FROM   WF_NOTIFICATIONS WF,
236         WF_ITEM_ACTIVITY_STATUSES WIAS
237  WHERE  WIAS.ITEM_TYPE = x_itemtype  AND
238         WIAS.ITEM_KEY  =  x_itemkey  AND
239         WIAS.NOTIFICATION_ID = WF.group_id
240  GROUP BY wf.from_role;           --Bug 14205891
241 
242 CURSOR c_responderid(p_responder VARCHAR2) IS
243     SELECT nvl((wfu.orig_system_id), -9996)
244     FROM   wf_users wfu
245     WHERE  wfu.name = p_responder
246     AND    wfu.orig_system not in ('HZ_PARTY', 'POS', 'ENG_LIST', 'CUST_CONT');
247 
248 -- Bug 4633202: Cursor to get list of all granters who has provided worklist
249 -- access to current employee. It also lists the current user.
250 
251 CURSOR c_worklist_grants IS
252      SELECT PARAMETER1 AS granter_key
253        FROM FND_GRANTS g,
254             fnd_menus m,
255             fnd_objects o,
256             fnd_object_instance_sets s
257       WHERE g.MENU_ID = m.menu_id
258         AND m.menu_name = 'FND_WF_WORKLIST'
259         AND g.OBJECT_ID = o.object_id
260         AND o.obj_name = 'NOTIFICATIONS'
261         AND g.INSTANCE_SET_ID = s.instance_set_id
262         AND s.instance_set_name = 'WL_PROXY_ACCESS'
263         AND g.GRANTEE_KEY = FND_GLOBAL.USER_NAME
264         AND g.INSTANCE_TYPE = 'SET'
265         AND g.START_DATE <= SYSDATE
266         AND Nvl(g.END_DATE, SYSDATE ) >= SYSDATE
267     UNION
268      SELECT FND_GLOBAL.USER_NAME AS granter_key
269        FROM dual;
270 
271 -- Bug 4633202: Temp variables
272 l_notification_key      wf_notifications.ACCESS_KEY%TYPE;
273 l_granter_key           FND_GRANTS.PARAMETER1%TYPE;
274 l_has_access            BOOLEAN;
275 
276 
277 l_notification_id 	WF_NOTIFICATIONS.notification_id%type;
278 l_responder       	WF_NOTIFICATIONS.responder%type;
279 l_original_recipient_id wf_users.orig_system_id%type;
280 l_recipient_id 		wf_users.orig_system_id%type;
281 l_recipient_role  	WF_NOTIFICATIONS.recipient_role%type;
282 l_original_recipient  	WF_NOTIFICATIONS.ORIGINAL_RECIPIENT%type;
283 
284 l_from_role   WF_NOTIFICATIONS.from_role%TYPE;  --Bug 12534279
285 
286 Begin
287 	Open getcurrnotif;
288         fetch getcurrnotif into l_notification_id, l_from_role; --Bug 12534279
289         close getcurrnotif;
290 
291         If l_notification_id = -9995 Then
292            return FALSE;
293         End If;
294 
295 	 -- Bug 4633202.
296         -- Loop for all granters and current user
297         l_has_access := FALSE;
298         FOR r_grants IN c_worklist_grants LOOP
299         BEGIN
300          IF( r_grants.granter_key <> l_from_role) THEN  --Bug 12534279
301           -- Validate the access
302           l_granter_key := wf_advanced_worklist.Authenticate
303                                    ( username => r_grants.granter_key,
304                                           nid => l_notification_id,
305                                          nkey => l_notification_key
306                                    );
307           -- If we are here, means there is no exception. Access is validated.
308           -- Since one valid record is found, we can exit
309           l_has_access := TRUE;
310           EXIT;
311 
312           END IF;
313 
314         EXCEPTION
315            WHEN OTHERS THEN
316               NULL; -- Loop through for other grants
317         END;
318         END LOOP;
319 
320         RETURN l_has_access;
321 
322         /* internal name of responder */
323 	/*  Bug 4633202.
324            This check is not required. WF API itself
325            will take care of all these checks.
326         SELECT wfn.recipient_role, wfn.original_recipient
327         INTO   l_recipient_role, l_original_recipient
328         FROM   wf_notifications wfn
329         WHERE  wfn.notification_id = l_notification_id;
330 
331         OPEN c_responderid(l_recipient_role);
332         FETCH c_responderid INTO l_recipient_id;
333         CLOSE c_responderid;
334 
335         OPEN c_responderid(l_original_recipient);
336         FETCH c_responderid INTO l_original_recipient_id;
337         CLOSE c_responderid;
338 
339         If ((l_recipient_id = x_logged_emp_id) AND
340             (l_original_recipient_id = x_action_emp_id)) Then
341             return TRUE;
342        End If;
343 
344        return FALSE;
345 	*/
346 Exception
347 	when others then
348         return FALSE;
349 
350 End check_for_delegation;
351 
352 END PO_SECURITY_CHECK_SV;