Un processo aziendale è un insieme di attività che servono a raggiungere uno specifico obiettivo.
Ad esempio il processo di una richiesta di acquisto passa prima di tutto attraverso il suo inserimento in una applicazione gestionale e poi alla sua approvazione; solo dopo aver ottenuto quest’ultima si può mandare l’ordine al fornitore.
Altri esempi abbastanza comuni sono l’evasione di un ordine cliente, l’inserimento dei dati di un nuovo dipendente oppure l’archiviazione dei documenti.
Al giorno d’oggi, soprattutto grazie alla diffusione delle più svariate applicazioni gestionali, l’uso dei workflows come strumenti per ottimizzare i processi aziendali è diventata una prassi abbastanza comune in aziende di ogni dimensione.
I workflows aiutano a tenere sotto controllo l’esecuzione della varie attività e consentono allo stesso tempo di misurarne le performance, tramite l’uso di KPI.
Ma cos’è esattamente un workflow?
Senza scendere troppo nel dettaglio possiamo dire che un workflow, tradotto in italiano come flusso di lavoro, rappresenta un modello digitale di un processo aziendale ottenuto attraverso la sua razionalizzazione e suddivisione in diverse attività, chiamate task.
In generale, i task possono essere sia automatici, quando non richiedono un intervento decisionale umano, oppure manuali.
In questo articolo desidero spiegarti come costruire workflows approvativi in Oracle APEX.
Buona lettura!
IN QUESTO ARTICOLO
Come funzionano i Task in Oracle APEX
Prima di tutto vorrei introdurti ad alcuni concetti base dei Task in Oracle APEX.
Non spaventarti, ti darò solo qualche nozione fondamentale che ti servirà più avanti per capire alcune delle operazioni che andremo a fare nel sistema. Ti prometto che sarò il più sintetico possibile.
In ogni caso, se desideri approfondire gli aspetti più tecnici che stanno dietro ai Tasks di Oracle APEX, ti consiglio di fare riferimento alla documentazione ufficiale.
Altra cosa importante da tenere a mente è che quello che ti andrò a spiegare è valido solo a partire dalla release 22.1 di Oracle APEX.
Iniziamo…
Definizione dei Task
Un Task è l’oggetto su cui lavorano le persone che partecipano ad un workflow.
Quando viene avviato un workflow sarà generato un Task che dovrà essere preso in carico da una persona la quale sarà chiamata a svolgere una specifica attività.
Quando l’attività sarà completata la persona potrà chiudere il Task.
In Oracle APEX un Task, che viene istanziato da un partendo da un template (tra poco vedrai di cosa si tratta), ha diverse caratteristiche come, ad esempio, un titolo e una priorità.
Un’altra caratteristica dei Task sono i suoi partecipanti, ad esempio le persone che dovranno approvare il Task.
Partecipanti al Task
Vediamo quali sono le tipologie di persone che possono partecipare all’esecuzione di un Task:
- Initiator: è la persona che genera il Task.
- Potential Owner: è la persona che dovrà prendere in carico il Task ed evaderlo. È possibile definire, se serve, più di una persona che può prendere in carico un Task.
- Actual Owner: è la persona che in un dato momento ha in carico un Task.
- Business Administrator: è una persona con diritti amministrativi che può controllare un qualunque momento un Tasks.
Azioni sui Task
Durante tutto il ciclo di vita di un Task è possibile eseguire specifiche operazioni di esso.
Quali e quante operazioni possono essere eseguite dipendono dal suo stato e dal tipo di utente che lo sta gestendo in quel momento.
Questa tabella riporta quali azioni possono essere eseguite sui Tasks in funzione del tipo di utente.

Costruiamo il nostro primo Workflow
Bene, dopo aver appreso i concetti principali dietro alla definizione dei Tasks in Oracle APEX non resta che metterci alla prova, che ne dici?
Scoprirai che non c’è nulla di troppo complicato e anche se qualche concetto potrebbe sembrarti troppo tecnico cercherò di aiutarti passo dopo passo.
Per iniziare con qualcosa di semplice, ho deciso di partire dalla costruzione di un workflow per richiedere un permesso (per ferie oppure per malattia): un classico dei sistemi gestionali HR.
A tal proposito costruiremo una piccola applicazione per la gestione dei dipendenti di una azienda.
Per ciascun dipendente che ha bisogno di sottomettere una richiesta di assenza ci sarà un responsabile che la dovrà approvare o rifiutare.
Prima di iniziare
Per comodità ho deciso di partire da uno dei dataset di demo disponibili in Oracle APEX, in particolare quello che si chiama EMP/DEPT e che rappresenta proprio un elenco di dipendenti di una azienda.
Per ogni dipendente è specificato un ID (colonna EMPNO), un nome (colonna ENAME), il titolo (PRESIDENT, ANALYST, ecc) e il responsabile (colonna MGR)

Per installare il dataset di demo segui le seguenti istruzioni.
- Collegati ad Oracle APEX e vai in SQL Workshop > Utilities > Sample Datasets

- Installa il dataset chiamato EMP/DEPT

In aggiunta, ho creato una tabella che utilizzerò per salvare lo storico delle richieste di assenza che andremo a gestire.
- Collegati ad Oracle APEX e vai in SQL Workshop > SQL Commands ed esegui il seguente script SQL
CREATE TABLE "REQ"
("REQ_ID" NUMBER GENERATED BY DEFAULT ON NULL
AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999
INCREMENT BY 1 START WITH 8000 CACHE 20 NOORDER NOCYCLE NOKEEP NOT NULL ENABLE,
"CREATED_ON" DATE,
"STATUS" VARCHAR2(50),
"EMPNO" NUMBER,
"REQ_TYPE" VARCHAR2(50),
"START_DATE" DATE,
"END_DATE" DATE,
"COMPLETED_BY" NUMBER,
"COMPLETED_ON" DATE,
CONSTRAINT "REQ_PK" PRIMARY KEY ("REQ_ID"));
Creiamo una Applicazione
La prima cosa da fare consiste nel creare una applicazione in APEX.
- Accedi all’APP Builder e clicca Create

- Seleziona New Application.
- Dai un nome all’applicazione (io ho scelto con grande estro e fantasia il nome Sample Approval APP) e premi Create Application

Prima di andare avanti nella costruzione del workflow, creiamo un semplice report che ci servirà per vedere le relazioni tra i vari dipendenti.
- Dall’APP Builder clicca Create Page
- Seleziona l’opzione Interactive Report ed inserisci le informazioni necessarie per costruire il report
- Name: Employees
- Table/View Name: EMP_DEPT_V

Avviamo l’applicazione per vedere le relazioni fra i dipendenti.
Possiamo notare che
- KING è il responsabile dei tre manager BLAKE
- BLAKE è il responsabile di JAMES

Per poter testare l’applicazione che andremo a sviluppare, è necessario creare gli utenti che dovranno inserire ed approvare le richieste di assenza.
Per comodità creeremo gli utenti usando come username l’identificativo del dipendente (ENAME).
- Collegati all’APP Builder e vai in Manage Users and Groups.

- Clicca Create User
- Inserisci una username, una email, una password e premi Create User
- Per proseguire nel tutoriali dovresti creare almeno 3 utenti: KING, BLAKE e JAMES

Configuriamo un Task
Entriamo subito nel vivo e creiamo il nostro workflow.
- Accedi all’APP Builder e vai in Shared Components > Task Definitions e premi Create
- Inserisci le seguenti informazioni:
- Name: Richiesta Assenza
- Subject: Richiesta di &TIPO_RICHIESTA. di &EMP_NAME.
- Static ID: RICHIESTA_ASSENZA
- Priority: 3-Medium

Completeremo la configurazione dei Potential Owner e Business Admin tra poco, per il momento lasciamoli i campi vuoti.
&TIPO_RICHIESTA. e &EMP_NAME. sono delle variabili che verranno valorizzate da Oracle APEX rispettivamente con il tipo richiesta (FERIE, PERMESSO, MALATTIA) e con il nome del dipendente che ha sottomesso la richiesta. Tra poco vedremo come funziona questo meccanismo.
- Premi Create per completare l’operazione

Ora che abbiamo creato il nostro Task possiamo completare la sua configurazione, in particolare dobbiamo prima di tutto collegare il Task agli oggetti del database che sono impattati dalla sua esecuzione.
Mi spiego meglio.
Quando un responsabile approva un richiesta di permesso, sarà necessario mandare una notifica al richiedente e il sistema dovrà salvare nel database, in una tabella specifica, il numero di ferie totali accumulate dal dipendente.
Questa operazione potrà essere definita direttamente all’interno del Task creando delle Actions (Approve e Reject sono due esempi di Action).
Per far queste operazioni il Task dovrà conoscere, ad esempio, l’identificativo univoco dell’impiegato e la sua email.
Per passare questi parametri alle Actions di un Task dobbiamo specificare l’Actions Source che può essere una SQL Query o, come nel nostro caso, la tabella REQ che contiene tutte le informazioni necessarie per gestire la richiesta:
- Action Source: Table
- Table Name: REQ
- Actions Table Primary Key Column: REQ_ID

Sempre nella pagina di setup del Task possiamo generare automaticamente la pagina che Oracle APEX utilizzerà per consentire agli utenti di visualizzare i dettagli del Task
- Clicca Create Task Details Page

- Dovresti vedere il campo Task Details Page URL valorizzato.

Se vai nell’APP Builder troverai una nuova pagina chiamata Task Details

Configuriamo gli Approvatori del Task
Gli approvatori sono quegli utenti che hanno il compito di gestire un Task e vengono indicati come Potential Owner.
Quando ci sono più Potential Owners per una specifica istanza di un Task, l’Owner sarà la prima persona a prendere in carico il Task.
Nel nostro caso, l’approvatore di una richiesta sottomessa da un impiegato è il suo manager di riferimento.
Per configurare i Potential Owner:
- Accedi alla pagina Task Details > Participants e premi Add Row

- Inserisci un nuovo record con questi parametri
- Participant Type: Potential Owner
- Value Type: SQL Query
- Value: inserisci una query che restituisce la username degli utenti della applicazione che potranno approvare il Task. Nel nostro caso gli utenti (impiegati e managers) si collegano all’applicazione usando l’identificativo ENAME quindi la query sarà la seguente
select e.ename emp_name from emp e
where empno=(select mgr from emp
where empno=:EMPNO)
- Inserisci un altro record con questi parametri
- Participant Type: Business Administrator
- Value Type: Static
- Value: KING
Questa dovrebbe essere la configurazione finale della sezione Participants

Configuriamo i Parametri del Task
I parametri di un Task sono gli attributi che verranno visualizzati dall’approvatore e che potranno essere usati nelle Task Actions (lo vedremo tra pochissimo).
Nel nostro caso, chi approva una richiesta deve sapere oltre a chi l’ha sottomessa, qual è il tipo di richiesta (FERIE, PERMESSO o MALATTIA) e il periodo di assenza.
Per definire i parametri di un Task
- Accedi alla pagina Task Definition e vai alla sezione Parameters
- Clicca Add Row ed inserisci una nuova riga per ogni parametro che desideri creare
Per quel che riguarda la nostra applicazione ho creato quattro parametri:
- DATA_INIZIO e DATA_FINE
- EMP_NAME
- TIPO_RICHIESTA

Configuriamo le Actions del Task
Le Actions servono per definire cosa succede quando avvengono specifiche operazioni sui Taks come, ad esempio, il loro completamento.
In generale una Action può eseguire tutte le operazioni che desideri come mandare una e-mail oppure eseguire del codice PL-SQL.
Nella nostra applicazione creeremo due Actions che andranno ad aggiornare il record della tabella REQ con lo stato APPROVED se la richiesta viene approvata e REJECTED se, invece, la richiesta viene rifiutata.
Inoltre andremo a salvare chi ha completato il Task e la data di completamento.
Per creare la prima Action:
- Dalla pagina Task Details vai in Action e clicca Add Action
- Inserisci i seguenti parametri:
- Name: APPROVA_RICHIESTA_ASSENZA
- Type: Execute Code
- On Event: Complete
- Outcome: Approved
- Success Message: Richiesta Approvata

- Vai alla sezione Code ed inserisci il seguente script PL-SQL e clicca Apply Changes
update req
set status = 'APPROVED',
completed_on = sysdate,
completed_by = (select empno from emp where ename = :APEX$TASK_OWNER)
where req_id = :APEX$TASK_PK;

- Aggiungi un altra Action sempre di tipo Execute Code
- Name: RIFIUTA_RICHIESTA_ASSENZA
- Type: Execute Code
- On Event: Complete
- Outcome: Rejected
- Success Message: Richiesta Rifiutata
- Inserisci il seguente script PL-SQL
update req
set status = 'REJECTED',
completed_on = sysdate,
completed_by = (select empno from emp where ename = :APEX$TASK_OWNER)
where req_id = :APEX$TASK_PK;
Arrivati a questo punto abbiamo finalmente configurato il Task.
Quello che manca è integrare il Task all’interno della nostra applicazione. Per fare questo dovremo:
- costruire una pagina che consenta ad un impiegato di sottomettere una nuova richiesta.
- costruire una pagina che consenta ad un impiegato di monitorare le richieste sottomesse.
- costruire una pagina che consenta ad un manager di vedere l’elenco di tutte le richiesta sottomesse dai propri collaboratori e che devono essere gestite.
Creiamo una pagina per sottomettere una Richiesta
Per sottomettere una nuova richiesta andremo a creare una Form Page.
- Accedi all’APP Builder e clicca Create Page
- Seleziona il tipo pagina Form, compila i parametri come in figura e premi Next
- Name: Nuova Richiesta
- Source Type: Table
- Table/View Name: REQ

- Nella schermata successiva specifica la Primary Key Column 1 e premi Create Page.

Apriamo il Page Builder della Form che abbiamo creato ed completiamo la sua configurazione
- Aggiungi un nuovo Page Item di nome PX_EMP_NAME e di tipo Display Only

- Modifica l’Item Type dei seguenti Page Items ad Hidden Field
- PX_REQ_ID
- PX_CREATED_ON
- PX_STATUS
- PX_EMPNO
- PX_COMPLETED_BY
- PX_COMPLETED_ON

- Crea un nuovo Page Process nelle sezione Before Header, posizionato dopo il Page Process Initialize Form Nuova Richiesta

- Configura il Page Process in questo modo:
- Name: Initialize Form Parameters Nuova Richiesta
- Type: Execute Code
- Language: PL/SQL
- PL/SQL Code: inserisci lo script PL/SQL in figura

- Clicca su tab Processing e crea un nuovo Page Process di nome Submit Nuova Richiesta che deve scattare subito dopo il salvataggio del record nel database (attività eseguita dal Page Process che si chiama Process form Nuova Richiesta)

- Il Page Process Submit Nuova Richiesta serve per inizializzare il Task. Ecco le sue caratteristiche principali
- Identification > Name: Submit Nuova Richiesta
- Identification > Type: Human Task – Create
- Settings > Definition: Richiedi Assenza (seleziona il Task che vuoi collegare a questa form)
- Settings > Details Primary Key Item: PX_REQ_ID

Dopo aver selezionato il Task vedrai apparire i parametri che sono stati configurati e che dovrai mappare con i Page Items della tua pagina.

- Questo è ad esempio il setup del parametro Data Inizio

- Similmente dovrai mappare gli altri parametri. Ecco l’elenco completo
- Data Inizio: PX_START_DATE
- Data Fine: PX_END_DATE
- Impiegato: PX_EMP_NAME
- Tipo Richiesta: PX_REQ_TYPE
A questo punto possiamo fare una prova, in particolare vedremo come BLAKE può sottomettere al suo responsabile (KING) una richiesta ferie.
- Collegati alla tua applicazione con utente BLAKE e vai nella pagina Nuova Richiesta
- Inserisci i dati richiesti e premi Create

Se va tutto a buon fine dovresti vedere un messaggio di conferma.

A questo punto, però, ti chiederai..
Come può BLAKE controllare se la sua richiesta è stata presa in carico?
non solo…
Come fa KING a sapere che BLAKE ha richiesto un permesse per ferie?
Dobbiamo creare delle pagine che permettano di controllare le richieste.
Creiamo una pagina per controllare le Richieste che una persona ha sottomesso
Per controllare le richieste che un utente sottomette è possibile utilizzare un componente ad-hoc chiamato Unified Task List.
- Accedi all’APP Builder e clicca Create Page
- Seleziona il tipo pagina Unified Task List

- Specifica i parametri di configurazione come in figura e clicca Create Page:
- Nome: Le Mie Richieste
- Report Context: Initiated by Me (mostra tutti i task creati da me)

Nella pagina che Oracle APEX avrà creato saranno automaticamente visibili tutti i Tasks sottomessi dall’utente corrente.
Quindi, se mi collego nuovamente con l’utente BLAKE dovrei vedere la richiesta sottomessa pochi minuti fa.

Cliccando sul record si aprirà la pagina Task Details (quella che abbiamo creato precedentemente) all’interno della quale troverai diverse sezioni:
- Il titolo del Task con evidenza dello stato
- Alcune informazioni generali come, ad esempio, l’Owner corrente oppure il tipo di Task.
- Una sezione Details contenente tutti i parametri che abbiamo creato quando abbiamo configurato il Taks.

Inoltre, potrò eseguire una serie di azioni su un Task.
Quali e quanti Actions posso eseguire dipendono dallo stato del Task, dal fatto che è assegnato e dal ruolo dell’utente corrente che sta visualizzando i dettagli del Task.
Ad esempio, posso aggiungere un commento.

Ti faccio notare che il componente Unified Task List mostra automaticamente tutti i task sottomessi dall’utente da qualunque applicazione APEX gestita all’interno del workspace.
Questo vuol dire che se vuoi ridurre la lista, dovrai introdurre un filtro.
Ti faccio vedere, ad esempio, come mostrare solo i Task generati all’interno di questa specifica applicazione APEX.
- Apri il Page Builder e seleziona il componente Cards chiamato Initiated by Me – Report

- Vai in Source e sostituisci la Query con la seguente (ho aggiunto la condizione DETAILS_APP_ID = :APP_ID)
select *
from table ( apex_approval.get_tasks ( p_context => 'INITIATED_BY_ME' ) )
where DETAILS_APP_ID = :APP_ID

Creiamo una pagina per approvare le Richieste
Abbiamo visto come un utente può sottomettere una richiesta e come può controllarne lo stato.
Adesso vediamo come creare una pagina dove poter visualizzare le richieste che un manager deve prendere in carico.
Anche in questo caso useremo il componente Unified Task List ma con il contesto My Tasks.

Se proviamo ad eseguire la pagina collegandoci con l’utente KING vedremo tutte le richieste di permesso che devono essere approvate

Cliccando sul record specifico KING può controllare i dettagli del Task e approvare (o rifiutare) la specifica richiesta.

Funzionalità avanzate dei Task
In questa sezione del tutorial ti mostrerò come possiamo estendere il funzionamento dei Task per implementare workflows più avanzati.
Gestione delle Actions e delle notifiche e-mail
Negli esempi che abbiamo fatto fino a questo momento abbiamo creato delle Actions che eseguono del codice PL-SQL.
Questo ci da, come puoi immaginare, numerose possibilità perché possiamo sfruttare tutte le potenzialità del database di Oracle piuttosto che tutte le API PL-SQL messe a disposizione degli sviluppatori.
Tuttavia, trattandosi di Task e Workflow, è abbastanza comune il bisogno di avere un meccanismo di notifica e-mail.
Nessun problema, puoi creare una Action di tipo Send E-Mail che, ricorda bene, funzionerà solo se hai attivati i servizi di email.

Nel setup dell’Action puoi indicare le liste di distribuzione alle quali inviare la mail sia in modo statico (inserendo direttamente gli indirizzi e-mail separati dal carattere ‘,’) che dinamico.
Qui sotto puoi trovare un esempio di configurazione delle liste di distribuzione in cui il destinatario della mail è determinato dinamicamente in funzione del placeholder &USER_MAIL.
Ti ricordo che per sfruttare i placeholders devi definire il relativo parametro nella sezione Task Parameters e valorizzarlo nel modo opportuno.

Ovviamente puoi definire il contenuto del testo dell’e-mail: obbligatorio è il formato il text-plain ma, se lo desideri, puoi definire il messaggio in formato HTML per includere immagini, link web ed eventuali allegati.

Gestione degli Approvatori e degli Amministratori
Negli esempi che abbiamo fatto ciascuna richiesta di permesso che viene inviata da un impiegato deve essere approvata dal responsabile diretto.
Ma cosa succede se, ad esempio, il responsabile è assente oppure se, in generale, possono esserci più responsabili?
Bisognerebbe avere la possibilità di definire più di un Potential Approver.
Facciamo un esempio, supponiamo che MATT sia un HR MANAGER e che, in quanto tale, debba poter approvare tutte le richieste di permesso.
Per fare questo sarà sufficiente aggiungere una riga di tipo Potential Owner dove indicare MATT come approvatore addizionale.

Vediamo cosa succede alla richiesta di permesso sottomessa da BLAKE quando c’è più di un Potential Owner.
- Accedi all’applicazione con utente BLAKE
- Vai alla pagina Nuova Richiesta e sottometti una nuova richiesta di permesso
La richiesta viene generata e viene creata in stato Unassigned.

A questo punto colleghiamoci all’applicazione con utente MATT (che non è il responsabile di BLAKE) e apriamo la pagina Richieste da Approvare.
Come è facilmente prevedibile MATT vedrà la richiesta di permesso sottomessa da BLAKE e, allo stesso tempo, anche KING vedrà la stessa richiesta.

Se MATT visualizza i dettagli del Task può prenderlo in carico usando cliccando su Claim Task

Quando il task viene preso in carico da MATT, sparirà dalla lista delle richieste da approvare di KING e MATT diventerà il Task Owner.

A questo punto MATT può approvare (o rifiutare) la richiesta di BLAKE ma può anche decidere di rilasciare (Release) il task (perché magari lo ha preso in carico per errore) e quindi rimetterlo nella coda generale.
In alternativa può delegarlo direttamente a qualcuno (ad esempio KING).

Approvazioni Multi-Livello
Arrivati a questo punto abbiamo capito come usare i Task per gestire workflow approvativi che potremmo chiamare mono-livello nel senso che richiedono un solo Task per essere completati.
Tuttavia, non è raro, soprattutto nelle realtà aziendali più complesse, che siano necessarie approvazioni multi-livello.
Facciamo un esempio abbastanza comune, ovvero il flusso delle richieste di acquisto (o RDA).
Una richiesta di acquisto è un processo interno all’azienda con il quale si autorizza l’ufficio acquisti ad acquistare articoli o servizi.
Una volta approvata una richiesta di acquisto, questa può essere utilizzata per generare un ordine al fornitore.
Di solito l’approvazione di una RDA può richiedere più livelli di approvazione che dipendono dall’importo.
Facciamo un esempio.
Supponiamo che JAMES abbia bisogno di acquistare una licenza software per un valore di 200 euro.
JAMES inserisce una richiesta di acquisto che, visto l’importo contenuto, può essere approvata in via definitiva dal suo responsabile, ossia BLAKE.
Tuttavia la questione cambia se JAMES decide di acquistare un pacchetto di licenze per un valore complessivo di 2000 euro.
In questo caso BLAKE deve sicuramente verificare se la richiesta di JAMES è lecita (quindi deve approvare una prima volta l’RDA) ma non basta: visto l’importo, sicuramente non trascurabile, è necessario che anche KING (che è il responsabile di BLAKE nonché presidente della compagnia) approvi la richiesta.
È possibile costruire un flusso di approvazione multi-livello usando i Task di Oracle APEX usando le API PL-SQL di Oracle APEX.
In particolare utilizzeremo il package APEX_APPROVAL.
- Prima di tutto creiamo nel database una tabella per tracciare le richieste di acquisto, in maniera del tutto analoga a quanto abbiamo già visto per le richieste di permesso.
CREATE TABLE "RDA_REQUEST"
("REQ_ID" NUMBER GENERATED BY DEFAULT ON NULL
AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999
INCREMENT BY 1 START WITH 8000 CACHE 20 NOORDER NOCYCLE NOKEEP NOT NULL ENABLE,
"EMP_NO" NUMBER,
"DESCRIPTION" VARCHAR2(250),
"COST" NUMBER,
"CREATED_ON" DATE,
"STATUS" VARCHAR2(50),
"COMPLETED_BY" NUMBER,
"COMPLETED_ON" DATE,
CONSTRAINT "RDA_REQUEST_PK" PRIMARY KEY ("REQ_ID"));
- Configuriamo, come visto nei paragrafi precedenti, un Task di nome Richiesta di Acquisto.

- Colleghiamo il Task alla tabella RDA_REQUEST e generiamo la pagina Task Details

- Configuriamo gli approvatori del primo livello con una query SQL che restituisce come approvatore il manager dell’utente corrente (quello che sta generando il Task)

- Aggiungiamo tre parametri: DESCRIPTION, COST e REQUESTOR

- Creiamo una Action Complete di tipo PL-SQL per gestire l’approvazione o l’eventuale inoltro della richiesta di acquisto.

Questa Action dovrà verificare l’importo dell’RDA:
- se l’importo è inferiore a 500 euro l’RDA è approvata
- se l’importo è superiore a 500 euro e l’approvatore corrente è KING allora l’RDA è approvata mentre se l’approvatore corrente non è KING deve essere generato un Task di approvazione in carico a KING.
declare
l_mgr number;
l_task_id number;
begin
if :APP_USER = 'KING' or :COST < 500 then -- the approval is complete
update rda_request
set status = 'APPROVED',
completed_on = sysdate,
completed_by = (select empno from emp where ename = :APEX$TASK_OWNER)
where req_id = :APEX$TASK_PK;
else
-- the request needs to go through another level of approval
-- updated the request record with details of the current approver in the chain of approvers
update rda_request
set completed_by = (select empno from emp where ename = :APEX$TASK_OWNER)
where req_id = :APEX$TASK_PK;
-- create a new task assigned to the manager of the current approver
l_task_id := apex_approval.create_task(
p_application_id => :APP_ID,
p_task_def_static_id => 'RICHIESTA_DI_ACQUISTO',
p_initiator => :REQUESTOR, -- ensure initiator is the original requestor and not the current task owner
p_parameters => apex_approval.t_task_parameters(
1 => apex_approval.t_task_parameter(static_id => 'DESCRIPTION', string_value => :DESCRIPTION),
2 => apex_approval.t_task_parameter(static_id => 'COST', string_value => :COST),
3 => apex_approval.t_task_parameter(static_id => 'REQUESTOR', string_value => :REQUESTOR)
),
p_detail_pk => :APEX$TASK_PK);
end if;
end;
- Crea una Action Complete di tipo PL-SQL per gestire il rifiuto della richiesta di acquisto
update rda_request
set status = 'REJECTED',
completed_on = sysdate,
completed_by = (select empno from emp where ename = :APEX$TASK_OWNER)
where req_id = :APEX$TASK_PK;
Esattamente come fatto per il flusso della richiesta di permesso, crea una Form Page per consentire agli utenti di sottomettere una RDA.
- Dall’APP Builder di Oracle APEX crea una nuova Pagina di tipo Form e collegala alla tabella RDA_REQUEST
- Aggiungi un Page Item di nome PX_EMP_NAME e tipo Display Only

- Aggiungi un Page Process nella sezione Before Header di tipo Execute Code che servirà per inizializzare alcuni campi della form

- Codice del Page Process:
select empno, ename, sysdate
into :P5_EMP_NO, :P5_EMP_NAME, :P5_CREATED_ON
from emp
where ename=:APP_USER;
- Clicca sul tab Processes e aggiungi un nuovo Page Process di tipo Human Task – Create

- Vai alle impostazione del Process e specifica nel campo Definition il tipo di task da creare (Richiesta di Acquisto) e la chiave primaria (PX_REQ_ID)

- Infine configura i tre parametri collegandoli ai rispettivi Page Items della form
- Description: PX_DESCRIPTION
- Cost: PX_COST
- Requestor: PX_EMP_NAME
Ora proviamo la nostra applicazione.
- Colleghiamo con utente JAMES ed inseriamo due RDA, una per 50 euro ed una per 5000 euro

- Colleghiamo con utente BLAKE che, in qualità di approvatore di primo livello, può confermare la richiesta di JAMES.

- Se ci colleghiamo nuovamente con utente JAMES vedremo che la prima richiesta (quella per il pacchetto di licenze) adesso è in carico a KING mentre la seconda è stata completata

Conclusioni
Bene, direi che per il momento è tutto.
Ti lascio qui sotto i link alle risorse che ho usato per scrivere questo tutorial
- Introducing Approvals Component in Oracle APEX
- APEX Approvals Component Continued – Do More With Less
- Implementing Multi-Approvals in Oracle APEX 22.1
Questo è invece il link alla documentazione ufficiale:
Fammi sapere se hai trovato questa guida utile e se ti fa piacere condividila, mi farà davvero molto contento!
Un abbraccio
Daniele
Hi Daniele,
First of all many thanks for your step-by-step tutorial with detail explanation, really very well blogged.
I have tried to implement the same but getting an error on when try to Approve a Purchase Req under Multiple Approval part when Cost = 5000. I am getting an error as please check the Action. I have below code:
declare
l_mgr number;
l_task_id number;
begin
if :APP_USER = ‘KING’ or :COST :APP_ID,
p_task_def_static_id => ‘REQAPPROVALS’,
p_initiator => :REQUESTOR, — ensure initiator is the original requestor and not the current task owner
p_parameters => apex_approval.t_task_parameters(
1 => apex_approval.t_task_parameter(static_id => ‘DESCRIPTION’, string_value => :DESCRIPTION),
2 => apex_approval.t_task_parameter(static_id => ‘COST’, string_value => :COST),
3 => apex_approval.t_task_parameter(static_id => ‘REQUESTOR’, string_value => :REQUESTOR)
),
p_detail_pk => :APEX$TASK_PK);
end if;
end;
Can you please help me to sort out this issue?
Your help and support would be appreciated.
Ciao Bhavin,
I think you badly copied PL-SQL because the one you provided is not correct.
Fix the script and try again (you can use SQL Developer if you prefer).