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.0.12000000.2 2007/09/25 15:37:11 adbharga 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)
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 
241 CURSOR c_responderid(p_responder VARCHAR2) IS
242     SELECT nvl((wfu.orig_system_id), -9996)
243     FROM   wf_users wfu
244     WHERE  wfu.name = p_responder
245     AND    wfu.orig_system not in ('HZ_PARTY', 'POS', 'ENG_LIST', 'CUST_CONT');
246 
247 -- Bug 4633202: Cursor to get list of all granters who has provided worklist
248 -- access to current employee. It also lists the current user.
249 
250 CURSOR c_worklist_grants IS
251      SELECT PARAMETER1 AS granter_key
252        FROM FND_GRANTS g,
253             fnd_menus m,
254             fnd_objects o,
255             fnd_object_instance_sets s
256       WHERE g.MENU_ID = m.menu_id
257         AND m.menu_name = 'FND_WF_WORKLIST'
258         AND g.OBJECT_ID = o.object_id
259         AND o.obj_name = 'NOTIFICATIONS'
260         AND g.INSTANCE_SET_ID = s.instance_set_id
261         AND s.instance_set_name = 'WL_PROXY_ACCESS'
262         AND g.GRANTEE_KEY = FND_GLOBAL.USER_NAME
263         AND g.INSTANCE_TYPE = 'SET'
264         AND g.START_DATE <= SYSDATE
265         AND Nvl(g.END_DATE, SYSDATE ) >= SYSDATE
266     UNION
267      SELECT FND_GLOBAL.USER_NAME AS granter_key
268        FROM dual;
269 
270 -- Bug 4633202: Temp variables
271 l_notification_key      wf_notifications.ACCESS_KEY%TYPE;
272 l_granter_key           FND_GRANTS.PARAMETER1%TYPE;
273 l_has_access            BOOLEAN;
274 
275 
276 l_notification_id 	WF_NOTIFICATIONS.notification_id%type;
277 l_responder       	WF_NOTIFICATIONS.responder%type;
278 l_original_recipient_id wf_users.orig_system_id%type;
279 l_recipient_id 		wf_users.orig_system_id%type;
280 l_recipient_role  	WF_NOTIFICATIONS.recipient_role%type;
281 l_original_recipient  	WF_NOTIFICATIONS.ORIGINAL_RECIPIENT%type;
282 
283 Begin
284 	Open getcurrnotif;
285         fetch getcurrnotif into l_notification_id;
286         close getcurrnotif;
287 
288         If l_notification_id = -9995 Then
289            return FALSE;
290         End If;
291 
292 	 -- Bug 4633202.
293         -- Loop for all granters and current user
294         l_has_access := FALSE;
295         FOR r_grants IN c_worklist_grants LOOP
296         BEGIN
297           -- Validate the access
298           l_granter_key := wf_advanced_worklist.Authenticate
299                                    ( username => r_grants.granter_key,
300                                           nid => l_notification_id,
301                                          nkey => l_notification_key
302                                    );
303           -- If we are here, means there is no exception. Access is validated.
304           -- Since one valid record is found, we can exit
305           l_has_access := TRUE;
306           EXIT;
307 
308         EXCEPTION
309            WHEN OTHERS THEN
310               NULL; -- Loop through for other grants
311         END;
312         END LOOP;
313 
314         RETURN l_has_access;
315 
316         /* internal name of responder */
317 	/*  Bug 4633202.
318            This check is not required. WF API itself
319            will take care of all these checks.
320         SELECT wfn.recipient_role, wfn.original_recipient
321         INTO   l_recipient_role, l_original_recipient
322         FROM   wf_notifications wfn
323         WHERE  wfn.notification_id = l_notification_id;
324 
325         OPEN c_responderid(l_recipient_role);
326         FETCH c_responderid INTO l_recipient_id;
327         CLOSE c_responderid;
328 
329         OPEN c_responderid(l_original_recipient);
330         FETCH c_responderid INTO l_original_recipient_id;
331         CLOSE c_responderid;
332 
333         If ((l_recipient_id = x_logged_emp_id) AND
334             (l_original_recipient_id = x_action_emp_id)) Then
335             return TRUE;
336        End If;
337 
338        return FALSE;
339 	*/
340 Exception
341 	when others then
342         return FALSE;
343 
344 End check_for_delegation;
345 
346 END PO_SECURITY_CHECK_SV;