采购订单的审批状态异常的处理,审批状态为:预审批或是处理中的单据

针对采购订单的审批状态异常的处理,审批状态为:预审批或是处理中的单据

可删除最后一次审批历史

select hr.name, poh.segment1, poh.org_id
from po_headers_all poh,
hr_all_organization_units hr
where poh.org_id = hr.organization_id and
poh.segment1 = '&Enter_PO_Number';

script:poxrespo.sql

REM dbdrv: none
        /*=======================================================================+
 	 |  Copyright (c) 2009 Oracle Corporation Redwood Shores, California, USA|
 	 |                            All rights reserved.                       |
 	 +=======================================================================*/
 
 /* $Header: poxrespo.sql 120.0.12010000.1 2009/08/11 07:07:51 vrecharl noship $ */
SET SERVEROUTPUT ON
SET VERIFY OFF;


/* PLEASE READ NOTE 390023.1 CAREFULLY BEFORE EXECUTING THIS SCRIPT.

 This script will:
* reset the document to incomplete/requires reapproval status.
* delete/update action history as desired (refere note 390023.1 for more details).
* abort all the related workflows 

 If there is encumbrance entries related to the PO, it will:
* skip the reset action on the document.
*/

set serveroutput on size 100000
prompt
prompt
accept sql_po_number prompt 'Please enter the PO number to reset : ';
accept sql_org_id default NULL prompt 'Please enter the organization id to which the PO belongs (Default NULL) : ';
accept delete_act_hist prompt 'Do you want to delete the action history since the last approval ? (Y/N) ';
prompt

declare
x_stmt varchar2(3000);
NAME_ALREADY_USED EXCEPTION;
PRAGMA Exception_Init(NAME_ALREADY_USED,-955);
begin
x_stmt:= 'create table po_manual_postings_temp 
          (po_distribution_id number,
           budget_account_id  number, 
           debit_amount       number,
           timestamp          date,
	   type               varchar2(5),
	   account            varchar2(285))';

EXECUTE immediate(x_stmt);           
exception
WHEN NAME_ALREADY_USED then
  dbms_output.put_line('table already exists, hence not creating again');
when others then
  dbms_output.put_line('An exception occured creating po_manual_postings_temp table');
  dbms_output.put_line(SQLCODE || '-'|| SQLERRM);
  dbms_output.put_line ('Please contact Oracle Support');
  rollback;
  return;
  
end;
/


DECLARE

/* select only the POs which are in preapproved, in process state and are not finally closed 
   cancelled */
   
CURSOR potoreset(po_number varchar2, x_org_id number) is
SELECT wf_item_type, wf_item_key, po_header_id, segment1,
       revision_num, type_lookup_code,approved_date
FROM po_headers_all
WHERE segment1 = po_number
and NVL(org_id,-99) = NVL(x_org_id,-99)
-- bug 5015493: Need to allow reset of blankets and PPOs also.
-- and type_lookup_code = 'STANDARD'
and authorization_status IN ('IN PROCESS', 'PRE-APPROVED')
and NVL(cancel_flag, 'N') = 'N'
and NVL(closed_code, 'OPEN') <> 'FINALLY_CLOSED';

/* select the max sequence number with NULL action code */

CURSOR maxseq(id number, subtype po_action_history.object_sub_type_code%type) is
SELECT nvl(max(sequence_num), 0)
FROM   po_action_history
WHERE  object_type_code IN ('PO', 'PA')
AND    object_sub_type_code = subtype
AND    object_id = id
AND    action_code is NULL;

/* select the max sequence number with submit action */

CURSOR poaction(id number, subtype po_action_history.object_sub_type_code%type) is
SELECT nvl(max(sequence_num), 0)
FROM   po_action_history
WHERE  object_type_code IN ('PO', 'PA')
AND    object_sub_type_code = subtype
AND    object_id = id
AND    action_code = 'SUBMIT';

cursor wfstoabort(st_item_type varchar2,st_item_key varchar2) is
select level,item_type,item_key,end_date
from wf_items
start with
    item_type = st_item_type and
    item_key =  st_item_key
connect by
    prior item_type = parent_item_type and
    prior item_key = parent_item_key
order by level desc;

wf_rec wfstoabort%ROWTYPE;

submitseq po_action_history.sequence_num%type;
nullseq po_action_history.sequence_num%type;

 x_organization_id number ;
 x_po_number varchar2(15);
 po_enc_flag varchar2(1);
 x_open_notif_exist varchar2(1);
 pos potoreset%ROWTYPE;
 
 x_progress varchar2(500);
 x_cont varchar2(10);
 x_active_wf_exists varchar2(1);
 l_delete_act_hist varchar2(1);
 l_change_req_exists varchar2(1);
 l_res_seq po_action_history.sequence_num%TYPE;
 l_sub_res_seq po_action_history.sequence_num%TYPE;
 l_res_act po_action_history.action_code%TYPE;
 l_del_res_hist varchar2(1);
 

 /* For encumbrance actions */
 
 NAME_ALREADY_USED EXCEPTION;
 PRAGMA Exception_Init(NAME_ALREADY_USED,-955);
 X_STMT VARCHAR2(2000);
 disallow_script VARCHAR2(1);
 
TYPE enc_tbl_number is TABLE OF NUMBER;
TYPE enc_tbl_flag   is TABLE OF VARCHAR2(1);

l_dist_id      		enc_tbl_number;
l_enc_flag     		enc_tbl_flag;
l_enc_amount   		enc_tbl_number;
l_gl_amount    		enc_tbl_number;
l_manual_cand  		enc_tbl_flag;
l_req_dist_id  		enc_tbl_number;
l_req_enc_flag 		enc_tbl_flag;
l_req_enc_amount 	enc_tbl_number;
l_req_gl_amount 	enc_tbl_number;
l_req_qty_bill_del  	enc_tbl_number;
l_rate_table	      	enc_tbl_number;
l_price_table       	enc_tbl_number;
l_qty_ordered_table 	enc_tbl_number;
l_req_price_table   	enc_tbl_number;
l_req_encumbrance_flag	varchar2(1);
l_purch_encumbrance_flag varchar2(1);
l_remainder_qty         NUMBER;
l_bill_del_amount  	NUMBER;
l_req_bill_del_amount   NUMBER;
l_qty_bill_del     	NUMBER;
l_timestamp    		date;
l_eff_quantity 		NUMBER;
l_rate         		NUMBER;
l_price        		NUMBER;
l_ordered_quantity 	NUMBER;
l_tax 	       		NUMBER;
l_amount       		NUMBER;
l_precision    		fnd_currencies.precision%type;
l_min_acc_unit 		fnd_currencies.minimum_accountable_unit%TYPE;
l_approved_flag 	po_line_locations_all.approved_flag%TYPE;
i 			number;
j 			number;
k 			number;

BEGIN

select '&delete_act_hist'
	into l_delete_act_hist
	from dual;

select &sql_org_id
  into x_organization_id
  from dual;

select '&sql_po_number'
  into x_po_number
  from dual;


x_progress := '010: start';

   begin
   select 'Y'
    into x_open_notif_exist
    from dual
    where exists (select 'open notifications'
		    from wf_item_activity_statuses wias,
			 wf_notifications wfn,
			 po_headers_all poh
		    where wias.notification_id is not null
		      and wias.notification_id = wfn.group_id
		      and wfn.status = 'OPEN'
		      and wias.item_type = 'POAPPRV'
		      and wias.item_key = poh.wf_item_key
		      and NVL(poh.org_id,-99) = NVL(x_organization_id,-99)
		      and poh.segment1=x_po_number
		      and poh.authorization_status IN ('IN PROCESS', 'PRE-APPROVED'));
   exception 
   when NO_DATA_FOUND then
     null;
   end;
		      
x_progress := '020: selected open notif';

if (x_open_notif_exist = 'Y') then
   dbms_output.put_line('  ');
   dbms_output.put_line('An Open notification exists for this document, you may want to use the notification to process this document. Do not commit if you wish to use the notification');
end if;   

begin
select 'Y'
  into l_change_req_exists
  from dual
  where exists (select 'po with change request'
  		  from po_headers_all h
		  where h.segment1 = x_po_number
		    and nvl(h.org_id, -99) = NVL(x_organization_id, -99)
		    and h.change_requested_by in ('REQUESTER', 'SUPPLIER'));
exception 
   when NO_DATA_FOUND then
     null;
end;

if (l_change_req_exists = 'Y') then
   dbms_output.put_line('  ');
   dbms_output.put_line('ATTENTION !!! There is an open change request against this PO. You should respond to the notification for the same.');
   return;
--   dbms_output.put_line('If you are running this script unaware of the change request, Please ROLLBACK');
end if;
		      
open potoreset(x_po_number, x_organization_id);

fetch potoreset into pos;
if potoreset%NOTFOUND then 
   dbms_output.put_line('No PO with PO Number '||x_po_number ||
   			' exists in org '||to_char(x_organization_id) 
			|| ' which requires to be reset');
   return;
end if;
close potoreset;

/* check if any distribution with USSGL code exists - if it does then exit */

disallow_script := 'N';
begin
select 'Y'
  into disallow_script
  from dual
  where exists (select 'dist with USSGL code'
  		 from po_distributions_all
		where po_header_id = pos.po_header_id
		  and ussgl_transaction_code is not null);

Exception 
when NO_DATA_FOUND then
   null;
end;

if disallow_script = 'Y' then
  dbms_output.put_line('You have a public sector installation and USSGL transaction codes are used');
  dbms_output.put_line('The reset script is not allowed in such a scenario, please contact Oracle Support');
   return;
end if;

 x_progress := '030 checking enc action ';

 disallow_script := 'N'; 
 begin
 select 'Y'
 into disallow_script
 from dual
 where exists (select 'encumbrance data'
               from po_bc_distributions
               where je_source_name = 'Purchasing'
	             and je_category_name = 'Purchases'
		     and header_id = pos.po_header_id);
 EXCEPTION
 when NO_DATA_FOUND THEN
   NULL;
 end;

 if disallow_script = 'Y' then
    dbms_output.put_line('This PO has been reserved atleast once previously.');
    dbms_output.put_line('Hence this PO can not be reset');
    return;
 end if;                

      dbms_output.put_line('Processing '||pos.type_lookup_code
                            ||' PO Number: '
                            ||pos.segment1);
      dbms_output.put_line('......................................');
            
      begin 
       select 'Y' 
         into x_active_wf_exists
         from wf_items wfi
        where wfi.item_type = pos.wf_item_type
   	  and wfi.item_key = pos.wf_item_key
	  and wfi.end_date is null;

      exception
      when NO_DATA_FOUND then
      x_active_wf_exists := 'N';
      end;

      if (x_active_wf_exists = 'Y') then
         dbms_output.put_line('Aborting Workflow...');
         open wfstoabort(pos.wf_item_type,pos.wf_item_key);
         loop
         fetch wfstoabort into wf_rec;
	 if wfstoabort%NOTFOUND then
	    close wfstoabort;
	    exit;
	 end if;

	 if (wf_rec.end_date is null) then
	 BEGIN
	   WF_Engine.AbortProcess(wf_rec.item_type, wf_rec.item_key);
         EXCEPTION
           WHEN OTHERS THEN
                dbms_output.put_line(' workflow not aborted :'
		||wf_rec.item_type ||'-'||wf_rec.item_key);
                
         END;

	 end if;
	 end loop;
      end if;
 
      dbms_output.put_line('Updating PO Status..'); 
      UPDATE po_headers_all
         SET authorization_status = decode(pos.approved_date, NULL, 'INCOMPLETE',
                                        'REQUIRES REAPPROVAL'),
          wf_item_type = NULL,
          wf_item_key = NULL,
	  approved_flag = decode(pos.approved_date, NULL, 'N', 'R') 
       WHERE po_header_id = pos.po_header_id;

      OPEN  maxseq(pos.po_header_id, pos.type_lookup_code); 
      FETCH maxseq into nullseq;
      CLOSE maxseq;

      OPEN  poaction(pos.po_header_id, pos.type_lookup_code);
      FETCH poaction into submitseq;
      CLOSE poaction;
      IF nullseq > submitseq THEN
        
	if nvl(l_delete_act_hist,'N') = 'N' then
   	   Update po_action_history
   	      set action_code = 'NO ACTION',
   	          action_date = trunc(sysdate),
   	          note = 'updated by reset script on '||to_char(trunc(sysdate))
           WHERE object_id = pos.po_header_id
             AND  object_type_code = decode(pos.type_lookup_code,
	     				    'STANDARD','PO',
					    'PLANNED', 'PO', --future plan to enhance for planned PO
					    'PA')
             AND object_sub_type_code = pos.type_lookup_code
             AND sequence_num = nullseq
             AND action_code is NULL;
        else

	   Delete po_action_history
	    where object_id = pos.po_header_id
	      and object_type_code = decode(pos.type_lookup_code,
	     				    'STANDARD','PO',
					    'PLANNED', 'PO', --future plan to enhance for planned PO
					    'PA')
	      and object_sub_type_code = pos.type_lookup_code				    
	      and sequence_num >= submitseq
	      and sequence_num <= nullseq;

	end if;
	
      END IF;

      dbms_output.put_line('Done Approval Processing.');
      
 select nvl(purch_encumbrance_flag,'N')
   into l_purch_encumbrance_flag
   from financials_system_params_all fspa
   where NVL(fspa.org_id,-99) = NVL(x_organization_id,-99);
   
   if (l_purch_encumbrance_flag='N') 
      -- bug 5015493 : Need to allow reset for blankets also
      OR (pos.type_lookup_code = 'BLANKET') then
   
      if (pos.type_lookup_code = 'BLANKET') then
      	dbms_output.put_line('document reset successfully');
      	dbms_output.put_line('If you are using Blanket encumbrance, Please ROLLBACK, else COMMIT');
      else
      	dbms_output.put_line('document reset successfully');
      	dbms_output.put_line('please COMMIT data');
      end if;
      return;
   end if;
 
-- reserve action history stuff
-- check the action history and delete any reserve to submit actions if all the distributions
-- are now unencumbered, this should happen only if we are deleting the action history

if l_delete_act_hist = 'Y' then

   -- first get the last sequence and action code from action history
   begin 
      select sequence_num, action_code
        into l_res_seq, l_res_act
	from po_action_history pah
	WHERE pah.object_id = pos.po_header_id
          AND  pah.object_type_code = decode(pos.type_lookup_code,
    				    'STANDARD','PO',
				    'PLANNED', 'PO', --future plan to enhance for planned PO
				    'PA')
          AND pah.object_sub_type_code = pos.type_lookup_code
	  AND sequence_num in (select max(sequence_num)
	  			from po_action_history pah1
				where pah1.object_id = pah.object_id
          			  AND  pah1.object_type_code =pah.object_type_code
          		          AND  pah1.object_sub_type_code =pah.object_sub_type_code);
   exception
   when TOO_MANY_ROWS then
     dbms_output.put_line('action history needs to be corrected separately ');
   when NO_DATA_FOUND then
     null;
   end;

   -- now if the last action is reserve get the last submit action sequence

   if (l_res_act = 'RESERVE') then
   begin
      select max(sequence_num)
        into l_sub_res_seq
       from  po_action_history pah
      where action_code = 'SUBMIT'
        and  pah.object_id = pos.po_header_id
        and  pah.object_type_code = decode(pos.type_lookup_code,
    				       'STANDARD','PO',
				       'PLANNED', 'PO', --future plan to enhance for planned PO
				       'PA')
        and pah.object_sub_type_code = pos.type_lookup_code;
   exception
   when NO_DATA_FOUND then
     null;
   end;

      -- check if we need to delete the action history, ie. if all the distbributions
      -- are unreserved

      if ((l_sub_res_seq is not null ) and (l_res_seq > l_sub_res_seq)) then

	 begin
         select 'Y'
            into l_del_res_hist
           from dual
           where not exists (select 'encumbered dist'
     			from po_distributions_all pod
			where pod.po_header_id = pos.po_header_id
			  and nvl(pod.encumbered_flag,'N') = 'Y'
			  and nvl(pod.prevent_encumbrance_flag,'N')='N');
         exception
	 when NO_DATA_FOUND then
	    l_del_res_hist := 'N';
         end;

         if l_del_res_hist = 'Y' THEN

	    dbms_output.put_line('deleting reservation action history ... ');

            delete po_action_history pah
              where pah.object_id = pos.po_header_id
                and  pah.object_type_code = decode(pos.type_lookup_code,
       				       'STANDARD','PO',
   				       'PLANNED', 'PO', --future plan to enhance for planned PO
   				       'PA')
                and pah.object_sub_type_code = pos.type_lookup_code
                and sequence_num >= l_sub_res_seq
                and sequence_num <= l_res_seq;
         end if;
       
      end if; -- l_res_seq > l_sub_res_seq

   end if;

end if;

EXCEPTION
WHEN OTHERS THEN
  dbms_output.put_line('some exception occured '||sqlerrm||' rolling back'||x_progress);
  rollback;
END;
/

处理完成后则采购订单的状态就变成需要重新审批:

原文地址:https://www.cnblogs.com/liuweicong39/p/3232001.html