Introduzione

Questa esercitazione descrive come implementare uno script Groovy che convalida l'immissione di dati rispetto agli intervalli consentiti memorizzati in un cubo del driver.

Presupposto

In questo esempio, verrà creato uno script che viene eseguito quando gli utenti salvano gli aggiornamenti agli stipendi e ai bonus dei dipendenti da un form di immissione dati. Lo script carica i dati del livello dipendente (salario minimo/massimo consentito e bonus minimo/massimo consentito) da un cubo driver in una griglia temporanea in memoria, quindi convalida i valori di stipendio e bonus immessi in base agli intervalli consentiti.

Prerequisiti

Le esercitazioni pratiche su Cloud EPM potrebbero richiedere l'importazione di uno snapshot nell'istanza di Cloud EPM Enterprise Service. Prima di poter importare uno snapshot dell'esercitazione, è necessario richiedere un'altra istanza di Cloud EPM Enterprise Service o rimuovere l'applicazione e il processo aziendale correnti. Lo snapshot dell'esercitazione non verrà importato nell'applicazione o nel processo aziendale esistente, né sostituirà o ripristinerà automaticamente l'applicazione o il processo aziendale in uso.

Prima di iniziare questo tutorial, è necessario:

  • Consente all'amministratore dei servizi di accedere a un'istanza di Cloud EPM Enterprise Service.
  • Caricare e importare questo snapshot nell'istanza di Planning. Se lo snapshot è stato caricato in precedenza per un'altra esercitazione Groovy, è possibile continuare a utilizzare la stessa istantanea.

Nota

Se si verificano errori di migrazione durante l'importazione dello snapshot, eseguire di nuovo la migrazione escludendo il componente HSS-Shared Services e gli artifact delle preferenze di sicurezza e utente nel componente Core. Per ulteriori informazioni sul caricamento e l'importazione degli snapshot, fare riferimento alla documentazione Amministrazione della migrazione per Oracle Enterprise Performance Management Cloud.

Suggerimento

Gli script necessari per questa esercitazione sono collegati come file di testo all'interno di ciascuna sezione.

Creazione dello script

  1. Aprire Gestione calcoli e creare una regola denominata Convalida dati dipendente Groovy nel cubo Plan1.
  2. Nuovo oggetto
  3. Nell'editor regole, modificare l'opzione Designer in Modifica script e impostare il tipo di script su Script Groovy.
  4. Opzioni editor regole
  5. Copiare lo script e incollarlo nell'editor.
  6. class GradeData {
        Integer Grade
        DataGrid.DataCell minSalary
        DataGrid.DataCell maxSalary
        DataGrid.DataCell minBonus
        DataGrid.DataCell maxBonus
        public String toString() {
            return "minSalary: ${minSalary?.formattedValue}, maxSalary: ${maxSalary?.formattedValue}, minBonus: ${minBonus?.formattedValue}, maxBonus: ${maxBonus?.formattedValue}"
        }
    }
    
    // Create a resource bundle loader containing localized messages needed by this rule.  
    def mbUs = messageBundle( ["validation.missingmember.grade":"No Grades found on the Grid."] )
    def mbl = messageBundleLoader(["en" : mbUs])
    
    Cube lookupCube = operation.application.getCube("Plan1")
    DataGridDefinitionBuilder builder = lookupCube.dataGridDefinitionBuilder()
    builder.addPov(['Years', 'Scenario', 'Currency', 'Period', 'Version', 'Entity'], [['FY16'], ['Current'], ['USD'], ['BegBalance'], 
    
    ['BU Version_1'], ['No Entity']])
    builder.addColumn(['Account'], [ ['Min Salary', 'Max Salary', 'Min Bonus', 'Max Bonus'] ])
    builder.addRow(['Grades'], [ ['ILvl0Descendants("Grades")'] ])
    DataGridDefinition gridDefinition = builder.build()
    
    // Load the data grid from the lookup cube 
    DataGrid dataGrid = lookupCube.loadGrid(gridDefinition, false)
    
    // Create a map of grade data (Min/Max Salary and Bonus) by grade name from the data grid.
    def gradeDataMap = new HashMap()
    if(dataGrid) {
        println("dataGrid is not null")
        dataGrid.dataCellIterator('Min Salary').each {
            def gradeData = new GradeData()
            gradeData.minSalary = it
            gradeData.maxSalary = it.crossDimCell('Max Salary')
            gradeData.minBonus = it.crossDimCell('Min Bonus')
            gradeData.maxBonus = it.crossDimCell('Max Bonus')
            gradeDataMap[(it.getMemberName('Grades'))] = gradeData
            println(it.getMemberName('Grades') + ": " + gradeData)
        }
    }
    
    DataGrid grid = operation.grid
    // Construct an iterator that iterates over all data cells containing the Grade member.
    GridIterator itr = grid.dataCellIterator('Grade')
    
    // Throw a veto exception if the grid has at least one cell but does not contain any cells containing the Grade member.
    if(!grid.empty && !itr.hasNext()) {
        // Found 0 cells with Grade
        throwVetoException(mbl, "validation.missingmember.grade")
    }
    
    // Validate the values in the grid being saved against the values in gradeDataMap.
    itr.each {
        GradeData gradeData = gradeDataMap[it.DataAsSmartListMemberName]  
        if(gradeData == null) {
            println("Unable to locate grade data for grade: ${it.DataAsSmartListMemberName}, with data value: ${it.formattedValue}" )
        } else {  
            println(it.getMemberName('Employee') + ": " + gradeData.toString())
            DataCell salary = it.crossDimCell('Salary')
            if(salary == null)
                println("Unable to locate Salary")
            else if(salary.data < gradeData.minSalary.data || salary.data > gradeData.maxSalary.data) {
                salary.addValidationError(0xFF0000, "Salary is outside of the allowed range.")  
            }
            DataCell bonus = it.crossDimCell('Bonus')
            if(bonus == null) {
                println("Unable to locate Bonus")
            } else if(bonus.data < gradeData.minBonus.data || bonus.data > gradeData.maxBonus.data) {
                bonus.addValidationError(0xFF0000, "Bonus is outside of the allowed range.")  
            }
        }
    }
    
  7. Nella barra degli strumenti fare clic su Salvare (Salva) per salvare lo script, quindi fare clic su Convalida e distribuisci (Convalida e distribuisci) per convalidare e distribuire lo script. Quando richiesto, fare clic su OK. Chiudere Calculation Manager.

Spiegazione della logica dello script

In questa sezione, descriveremo la logica dello script una sezione alla volta.

  1. Creare una classe.

    class GradeData { 
        Integer Grade
        DataGrid.DataCell minSalary
        DataGrid.DataCell maxSalary
        DataGrid.DataCell minBonus
        DataGrid.DataCell maxBonus
        public String toString() {
            return "minSalary: ${minSalary?.formattedValue}, 
                    maxSalary: ${maxSalary?.formattedValue}, 
                    minBonus: ${minBonus?.formattedValue}, 
                    maxBonus: ${maxBonus?.formattedValue}" 
        }
    }

    Creare una classe, GradeData, per memorizzare i dati del livello dipendente (stipendio minimo/massimo consentito e bonus minimo/massimo consentito) da un cubo driver.

    Il metodo toString() restituisce una rappresentazione stringa dell'oggetto GradeData. Il metodo utilizza l'operatore null safe (?.) fornito da Groovy. Se la variabile prima del punto interrogativo è nulla, non procederà e restituirà NULL. Ad esempio, {minSalary?.formattedValue} restituisce il valore NULL invece di generare un'eccezione NullPointerException se minSalary è nullo.

  2. Creare un programma di caricamento bundle.
  3. // Create a resource bundle loader containing localized messages needed by this rule.  
    def mbUs = messageBundle( ["validation.missingmember.grade":"No Grades found on the Grid."] ) 
    def mbl = messageBundleLoader(["en" : mbUs])
    
    Cube lookupCube = operation.application.getCube("Plan1") 
    DataGridDefinitionBuilder builder = lookupCube.dataGridDefinitionBuilder() 
    builder.addPov(['Years', 'Scenario', 'Currency', 'Period', 'Version', 'Entity'], [['FY16'], 
    	['Current'], ['USD'], ['BegBalance'], ['BU Version_1'], ['No Entity']])
    builder.addColumn(['Account'], [ ['Min Salary', 'Max Salary', 'Min Bonus', 'Max Bonus'] ])
    builder.addRow(['Grades'], [ ['ILvl0Descendants("Grades")'] ])
    DataGridDefinition gridDefinition = builder.build() 
    

    Creare un programma di caricamento del bundle di risorse contenente i messaggi localizzati necessari per questa regola.

    Recupera il cubo driver/ricerca.

    Ottenere un valore DataGridDefinitionBuilder per il cubo. Utilizzare la Costruzione guidata per creare un'area da cui caricare i dati aggiungendo i membri POV, i membri colonna e le righe.

    Creare l'oggetto DataGridDefinition.

  4. Caricare la griglia dati dal cubo di ricerca per l'area definita dall'oggetto DataGridDefinition.
  5. DataGrid dataGrid = lookupCube.loadGrid(gridDefinition, false)  
  6. Creare una mappa di dati livello (Stipendio minimo/massimo e bonus) in base al nome livello dalla griglia dati.
    def gradeDataMap = new HashMap<String, GradeData>() 
    if(dataGrid) {
        println("dataGrid is not null")
        dataGrid.dataCellIterator('Min Salary').each { 
            def gradeData = new GradeData()
            gradeData.minSalary = it
            gradeData.maxSalary = it.crossDimCell('Max Salary')
            gradeData.minBonus = it.crossDimCell('Min Bonus')
            gradeData.maxBonus = it.crossDimCell('Max Bonus')
            gradeDataMap[(it.getMemberName('Grades'))] = gradeData
            println(it.getMemberName('Grades') + ": " + gradeData)
        }
    }

    Creare una mappa denominata gradeDataMap dei dati relativi al livello (stipendio minimo/massimo e bonus) in base al nome del livello.

    Inserire i dati del livello nella mappa gradeDataMap per ogni livello. Livello è la chiave e l'oggetto GradeData popolato con lo stipendio minimo/massimo e il bonus è il valore.

  7. Costruisce un iteratore che esegue l'iterazione su tutte le celle dati contenenti il membro Livello nella griglia di input corrente.
  8. DataGrid grid = operation.grid
    GridIterator itr = grid.dataCellIterator('Grade')
  9. Getta un'eccezione di veto.
  10. // Throw a veto exception if the grid has at least one cell but does not contain any cells containing the Grade member.
    if(!grid.empty && !itr.hasNext()) {  
        // Found 0 cells with Grade
        throwVetoException(mbl, "validation.missingmember.grade")
    }

    Verificare che la griglia di input contenga almeno una cella contenente il membro Livello. In caso contrario, genera un'eccezione di veto con il messaggio localizzato.

  11. Convalidare i valori della griglia.
  12. // Validate the values in the grid being saved against the values in gradeDataMap.
    itr.each {  
        GradeData gradeData = gradeDataMap[it.DataAsSmartListMemberName]  
        if(gradeData == null) {
            println("Unable to locate grade data for grade: ${it.DataAsSmartListMemberName}, 
            	with data value: ${it.formattedValue}" )
        } else {  
            println(it.getMemberName('Employee') + ": " + gradeData.toString())
            DataCell salary = it.crossDimCell('Salary') 
            if(salary == null)
                println("Unable to locate Salary")
            else if(salary.data < gradeData.minSalary.data || salary.data > gradeData.maxSalary.data) 
            	{
                salary.addValidationError(0xFF0000, "Salary is outside of the allowed range.")  
            }
            DataCell bonus = it.crossDimCell('Bonus') 
            if(bonus == null) {
                println("Unable to locate Bonus")
            } else if(bonus.data < gradeData.minBonus.data || bonus.data > gradeData.maxBonus.data) {
                bonus.addValidationError(0xFF0000, "Bonus is outside of the allowed range.")  
            }
        }
    }

    Convalidare i valori nella griglia di input in fase di salvataggio rispetto ai valori in gradeDataMap. Il livello nella griglia di input è un conto di tipo smartlist derivato dalla gerarchia di livelli definita nel cubo di ricerca. La chiamata a it.DataAsSmartListMemberName consente di ottenere il nome del membro da cui deriva il valore della smartlist della cella corrente, che può quindi essere utilizzato come chiave nella mappa per ottenere i dati del livello.

    Passare la dimensione nella cella Stipendio e convalidare lo stipendio rispetto allo stipendio consentito nei dati del livello.

    Passare dim nella cella Bonus e convalidare il bonus rispetto al bonus consentito nei dati del livello. Se lo stipendio o il bonus non rientra nei limiti consentiti, impostare il colore di sfondo della cella su rosso e aggiungere un errore di convalida nella cella richiamando l'API addValidationError(). Il messaggio di errore verrà impostato come descrizione comandi della cella e verrà visualizzato anche nei messaggi di convalida della griglia. Inoltre, se questa regola viene eseguita dopo il salvataggio, il sistema metterà il veto sull'operazione di salvataggio.

Test dello script

  1. In Form Manager modificare il form ManageEmployees e associare la regola Convalida dati dipendente Groovy per l'esecuzione di Dopo il caricamento e Prima del salvataggio (potrebbe essere necessario selezionare prima Plan1 dall'elenco Cubo).
  2. Il form ManageEmployees con la regola associata.
  3. Salvare la maschera e chiudere la finestra Gestione maschera.
  4. Aprire il dashboard Dipendenti. Aggiungere un bonus di 1000 per il dipendente 1, aumentare lo stipendio per il dipendente 2 a 65000. Nella barra degli strumenti del form, fare clic su Salvare (Salva).
  5. Dashboard Dipendenti.
  6. Nella finestra di dialogo Messaggio di errore, fare clic su OK.
  7. Dashboard Dipendenti.
  8. Passa il mouse sopra le celle rosse per visualizzare i messaggi di errore dettagliati come suggerimenti.

    Viene visualizzato il messaggio di errore

    Viene visualizzato il messaggio di errore

  9. Chiudere il dashboard e aprire la console Job.
  10. Riquadro Attività recente della Console job.
  11. Fare clic su Convalida dati dipendente per visualizzare i dettagli della mansione. Fare clic sullo stato Completato per visualizzare i dati del livello caricati dal cubo di ricerca e i dati del livello per ogni livello del dipendente.
  12. Messaggi di log.

Altre risorse di apprendimento

Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti di formazione gratuiti sul canale YouTube di Oracle Learning. Inoltre, visita Oracle University per visualizzare le risorse di formazione disponibili.

Per la documentazione del prodotto, visitare Oracle Help Center.