Skip to Content

Recentemente eu tive um pouco de contato com algumas ferramentas dessa nova onda de produtos SAP e resolvi dividir um pouco dessa experiência nesse blog. Vou mostrar como desenvolver uma aplicação UI5 utilizando os conceitos do SAP Fiori, nessa aplicação iremos consumir os dados via “oData” direto do Hana. Antes de mais nada precisamos entender do que se trata essas ferramentas e tecnologia citadas anteriormente no contexto desse blog.

Bom não vou contar a história de cada ferramenta ou tecnologia utilizada para desenvolver essa aplicação, até porque o foco desse blog não e esse, irei apenas dar uma pequena definição sobre cada uma delas.


“SAP UI5” com poucas palavras pode ser definido como sendo uma biblioteca Java script da SAP para criação de aplicações baseadas em HTML5.

“SAP FIORI” e focado na experiência do usuário – 01:01:03 (Um caso de uso, um usuário, três telas) e tem pequenos aplicativos combinados. Tem uma variedade de aplicações que falam a mesma língua, que privilegia o design de informação.

“SAP HANA Podemos pensar no Hana como um pen drive gigante, que armazena só as informações mais relevantes aquelas mais utilizadas, recorrentes, o Hana e uma plataforma cuja combinação de software in-memory e hardware proporciona ao usuario a consulta de múltiplos tipos de origens de dados em tempo real.

“oData” é, na verdade, um serviço que contém uma classe que oferece um conjunto de informações para quem quiser consumir.


Conhecendo um pouco sobre cada uma das ferramentas e tecnologias vamos ao desenvolvimento. Vale a pena citar que estou colocando o oData, as tabelas, tudo no projeto principal por uma questão de simplicidade. Antes de mais nada, vamos abrir nosso ambiente de desenvolvimento, utilizaremos o Eclipse Luna.

Vamos abrir o Eclipse (Hana Studio) e criar um novo projeto clicando em File -> New -> Other -> Application Project.

/wp-content/uploads/2015/06/1_719104.jpg

Agora iremos dar um nome em nossa aplicação, reparem que existe um campo que se chama “Library” e dois checkedboxes, que são o “sap.ui.commons” que nada mais é que um conjunto de controles de interface gráfica próprios para desktops e o “sap.ui.m” que são um conjunto de controles de interface gráfica próprios para dispositivos móveis, em nossa aplicação vamos escolher o recurso para desenvolvimento desktop e prosseguir clicando em “Next”.

/wp-content/uploads/2015/06/2_719183.jpg

 

Vamos escolher o projeto e em seguida definir um nome, logo abaixo escolheremos a opção Java Script, porém é possível de se utilizar também “xml”, “JSON” e “HTML”, bom fazendo isso vamos finalizar a criação de nosso projeto clicando em “Finish”.

/wp-content/uploads/2015/06/3_719184.jpg

Com nossa estrutura do projeto criada iremos primeiro criar nossas tabelas no Hana, para isso  clique com o botão direito em Web Content -> New Folder e definir o nome para o diretório de “tables”.

/wp-content/uploads/2015/06/4_719185.jpg

Dentro do diretório que acabamos de criar com o botão direito escolha a opção New -> Data Base Developer-> DDL Source File.

/wp-content/uploads/2015/06/5_719186.jpg

Logo em seguida defina um nome em nosso arquivo com a extensão “hdbdd”.

/wp-content/uploads/2015/06/6_719187.jpg

Vamos agora abrir o arquivo “funcionário.hdbdd” e criar nossas tabelas conforme mostra o trecho de código a seguir.


namespace tmp.guilherme.appfiori.WebContent.tables;

@Schema: ‘GUILHERME

context func {

                                   type ty_id_cidade: hana.VARCHAR(1);

                                   type ty_id_cargo: hana.VARCHAR(2);

                                   type ty_funcionario: hana.VARCHAR(2);

                                    type ty_descricao: hana.VARCHAR(800);

 

                                    @Catalog.tableType: #COLUMN

                                     entity cidades {

                                     key id_cidade : ty_id_cidade;

                                     ds: ty_descricao;

                                     };

                                    @Catalog.tableType: #COLUMN

                                     entity cargos {

                                     key id_cargo : ty_id_cargo;

                                     cidade: association to func.cidades;

                                     ds: ty_descricao;

                                     };

                                     @Catalog.tableType: #COLUMN

                                     entity funcionarios {

                                     key id_funcionario : ty_funcionario;

                                     cargo : association to func.cargos;

                                     name: hana.VARCHAR(100);

                                     image: hana.VARCHAR(300);

                                     title: hana.VARCHAR(400);

                                     ds: ty_descricao;

               };

      };

Bom, iremos subir nossa aplicação para o servidor no Hana, clicando no projeto em Team -> Share Project./wp-content/uploads/2015/06/7_719188.jpg

E preciso definir um diretório para nossa aplicação, para isso clicamos em browser, logo em seguida clicamos em “Finish”.

/wp-content/uploads/2015/06/8_719190.jpg

Subimos nossa aplicação para o servidor no Hana, nossas tabelas estão criadas agora e preciso criar um “oData” para consumir ela, para isso devemos clicar com o botão direito em Web Content e clicar em New -> Folder e definir um nome em nosso “oData”.

/wp-content/uploads/2015/06/9_719191.jpg

Então agora, dentro desse diretório recém-criado com o botão direito clique em New -> XS Odata File e definir um nome para ele.

/wp-content/uploads/2015/06/10_719194.jpg

Vamos agora abrir o arquivo “funcionarios.xsodata” e colocar o seguinte trecho de código para criação do oData.

service namespace “br.com.duxinnovation.appfiori”

{

       association “Cidade_Cargo”

       principal “Cidades”(“id_cidade”) multiplicity “1”

       dependent “Cargos”(“cidade.id_cidade”) multiplicity “*”;

       association “Cargo_Funcionario”

       principal “Cargos”(“id_cargo”) multiplicity “1”

       dependent “Funcionarios”(“cargo.id_cargo”) multiplicity “*”;

       “tmp.guilherme.appfiori.WebContent.tables::func.cidades” as “Cidades”

        navigates (“Cidade_Cargo” as “Cargos”)

        create forbidden

        update forbidden

        delete forbidden

          ;

        “tmp.guilherme.appfiori.WebContent.tables::func.cargos” as “Cargos”

         navigates (“Cargo_Funcionario” as “Funcionarios”)

         create forbidden

         update forbidden

         delete forbidden

           ;

        “tmp.guilherme.appfiori.WebContent.tables::func.funcionarios” as “Funcionarios”

         create forbidden

         update forbidden

         delete forbidden

           ;

}

Acabamos de criar o “oData” de nossa aplicação, iremos agora ativar nosso projeto para que possamos testar o serviço “oData”.

/wp-content/uploads/2015/06/11_719196.jpg

Vamos executar o “oData” já consumindo alguns dados no Hana, teremos o seguinte resultado. /wp-content/uploads/2015/06/12_719197.jpg

Pronto, já estamos com as tabelas criadas e com carga, o serviço “oData” está apto a consumir os dados da aplicação.  Agora é necessário implementar o “oData” em nossa aplicação UI5. Dentro do diretório “WebContent” vamos criar alguns arquivos, primeiramente é necessário se criar um diretório que podemos definir como “diretorio_appfiori”.

/wp-content/uploads/2015/06/13_719198.jpg

Dentro desse diretório devemos criar dois arquivos que serão nossa página inicial de nossa aplicação, podemos definir o nome de “Welcome.view.js ”. Dentro dele definiremos o seguinte trecho de código.

sap.ui.jsview(“appfiori.Welcome”, {

/** Specifies the Controller belonging to this View.

/** In the case that it is not implemented, or that “null” is returned.

/** @memberOf appfiori.Welcome

          getControllerName : function() {

        return “appfiori.Welcome”;

                                       },

/** Is initially called once after the Controller has been instantiated.    

/** Since the Controller is given to this method.

/ ** @memberOf appfiori.Welcome

        createContent : function(oController) {

        

                   var oImage = new sap.m.Image({

                        src: “resources/home_.jpg”,

                        width: ‘760px’

                        });

        

                   var oText = new sap.m.Text({

                        text: “”

                         }).addStyleClass(‘welcomeText’);

        

                    return new sap.m.Page({

                    title: “Bem Vindo a Lista de Funcionarios da Empresa X”,

                         content: [

                                     new sap.m.VBox({

                                               items: [oImage,oText],

                                               alignItems: sap.m.FlexAlignItems.Center,

                                               justifyContent: sap.m.FlexJustifyContent.Center

                                       })

                            ]

                  });

        }


Então agora crie um arquivo “Welcome.controller.js”, abra o arquivo e implementar o seguinte trecho de código.

sap.ui.controller(“appfiori.Welcome”,

{

});


Em seguida criaremos um “js” para Cidade, que iremos definir o nome de “Cidade.controler.js” e definir o seguinte trecho de código.

sap.ui.controller(“appfiori.Cidade”, {

* @memberOf appfiori.App

                cidadeListItemPress: function(evt) {

                       

                var router = sap.ui.core.UIComponent.getRouterFor(this);

        

                var context = evt.getSource().getBindingContext(‘funcionarios’);

        

                var path = context.sPath;

        

                var start = path.indexOf(“‘”) + 1;

                var end = path.lastIndexOf(“‘”);

        

                var cidIndex = path.substring(start, end);

        

                var modnav = sap.ui.getCore().byId(“app”).getModel(“nav”);

                modnav.setProperty(“/cid”,cidIndex);

        

             router.navTo(‘cidade’, {cidIndex: cidIndex}); 

    }

});


Logo em seguida vamos criar o arquivo “Cidade.view.js” com o seguinte trecho de código:

sap.ui.jsview(“appfiori.Cidade”, {

/** Specifies the Controller belonging to this View.

/** In the case that it is not implemented, or that “null” is returned.

/** @memberOf appfiori.Cidades    

           getControllerName : function() {

         return “appfiori.Cidade”;

        },

/** @memberOf appfiori.Cidade

           createContent : function(oController) {      

           var oList = new sap.m.List({

                         id: “listId”

            });

        

            oList.bindItems({

           path : “funcionarios>/Cidades”,

                        template : new sap.m.StandardListItem({

                                   title: “{funcionarios>ds}”,

                                            type: sap.m.ListType.Navigation,

                                            press:function(evt){

                                            oController.cidadeListItemPress(evt);

                             }

                      })

                });

        

            return new sap.m.Page({ title: “Cidades”,

               content: [oList]

          });

      });


Acabamos de codificar o controller e a view de “Cidade”, o próximo passo e fazer o mesmo para Cargo de onde e associado a uma cidade. Vamos criar um novo arquivo “Cargo.view.js” e usar o seguinte código em sua estrutura.

sap.ui.jsview(“appfiori.Cargos”, {

/** Specifies the Controller belonging to this View.

/** In the case that it is not implemented, or that “null” is returned.

/** @memberOf appfiori.Cargos  

        getControllerName : function() {

       return “appfiori.Cargos”;

        },

        * @memberOf appfiori.Cargos

        */

        createContent : function(oController) {      

        var oList = new sap.m.List({

                       id: “slistId”,

                            mode: sap.m.ListMode.SingleSelect,

                            select: function(evt) {

                            oController.itemSelect(evt);

                  }

       });   

                       return new sap.m.Page({

                             title: “Cargos”,

                             showNavButton: true,

                             navButtonPress: function() {

                             oController.goBack();

                     },

              });

        }

});


Logo em seguida criaremos o “Cargos.controller.js” e usaremos o seguinte trecho de código.

sap.ui.controller(“appfiori.Cargos”, {

/** @memberOf appfiori.Cargos

         onInit: function() {       

        this.router = sap.ui.core.UIComponent.getRouterFor(this);

        this.router.attachRoutePatternMatched(this._handleRouteMatched, this);   

        },

        _handleRouteMatched: function(evt) {

        

     if(“cidades” !== evt.getParameter(“name”))

       {

               return;

       }

        

     this.cidadeIndex = evt.getParameter(“arguments”).cidadeIndex;

     this.cargoIndex = evt.getParameter(“arguments”).cargoIndex;

       var modnav = sap.ui.getCore().byId(“app”).getModel(“nav”);

       var cidIndex = modnav.getProperty(“/cid”);   

       var list = sap.ui.getCore().byId(‘slistId’);

        list.bindItems({

                                              path: “funcionarios>/Cidades(‘” + cidIndex + “‘)/Cargos”,

                                     template: new sap.m.StandardListItem({

                                               title: “{funcionarios>ds}”

                                 })

                    });

        },

        itemSelect: function(evt) {

       var list = sap.ui.getCore().byId(‘slistId’);


        var sItem = list.getSelectedItem();


        var oBindingContext = sItem.getBindingContext(‘funcionarios’);


        var sPath = oBindingContext.sPath;


        var start_subcat = sPath.indexOf(“‘”) + 1;


        var end_subcat = sPath.lastIndexOf(“‘”);


        var subCatIndex = sPath.substring(start_subcat, end_subcat);


        var modnav = sap.ui.getCore().byId(“app”).getModel(“nav”);


        modnav.setProperty(“/cargo”,cargoIndex);

        

         this.router.navTo(“Funcionarios”, {cidIndex:

         this.cidIndex, cargotIndex: cargoIndex});

        },

           goBack: function() {   

         this.router.navTo(“”); 

         }

});


Agora iremos criar mais dois arquivos para funcionário. Primeiro vamos criar o “Funcionario.view.js” com o seguinte trecho de código:

sap.ui.jsview(“appfiori.Funcionarios”, {

/** Specifies the Controller belonging to this View.

/** In the case that it is not implemented, or that “null” is returned.

* @memberOf appfiori.Funcionarios

*/

   getControllerName : function() {

   return “appfiori.Funcionarios”;

},

/** Is initially called once after the Controller has been instantiated.

/** Since the Controller is given to this method.   

* @memberOf appfiori.Funcionarios

*/

createContent : function(oController) {

        

                var oTable = new sap.m.Table(“funcionariosTable”,{

                inset: true,

                columns: [

                          new sap.m.Column({

                                hAlign: “Left”,

                                width: “100px”,

                                demandPopin: true,

                                popinDisplay: “Block”,

                                minScreenWidth: sap.m.ScreenSize.Medium

                                }),

                

                           new sap.m.Column({

                                 hAlign: “Left”,

                                 demandPopin: true,

                                 popinDisplay: “Block”,

                                 minScreenWidth: sap.m.ScreenSize.Medium

                                 }),

                

                          new sap.m.Column({

                                 hAlign: “Left”,

                                 width: “100px”,

                                 demandPopin: true,

                                 popinDisplay: “Block”,

                                 minScreenWidth: sap.m.ScreenSize.Medium }),

                           new sap.m.Column({

                                  hAlign: “Left”,

                                  width: “100px”,

                                  demandPopin: true,

                                  popinDisplay: “Block”,

                                  minScreenWidth: sap.m.ScreenSize.Medium

                            })

                        ]

                });

                        return new sap.m.Page({

                        title: “”,

                              content: [oTable]

                });

        }

});

Iremos criar o “Funcionarios.controller.js” com o seguinte trecho de código.

sap.ui.controller(“appfiori.Funcionarios”, {

* @memberOf appfiori.Funcionario

*/

                onInit: function() {

                       this.router = sap.ui.core.UIComponent.getRouterFor(this);

                       this.router.attachRoutePatternMatched(this._handleRouteMatched, this);

                },

                _handleRouteMatched: function(evt) {

                        if(“Funcionarios” !== evt.getParameter(“name”)){

                        return;

                }

                       this.cidIndex = evt.getParameter(“arguments”).cidIndex;

                       this.cargoIndex = evt.getParameter(“arguments”).cargoIndex;

        

                             var modnav = sap.ui.getCore().byId(“app”).getModel(“nav”);

                             var cidIndex = modnav.getProperty(“/cid”);    

                             var cargoIndex = modnav.getProperty(“/cargo”);

        

                             var oTemplate = new sap.m.ColumnListItem({

                             type: sap.m.ListType.Active,

                             cells: [

                                    new sap.m.Image({

                                    src: “{funcionarios>image}”,

                                             height: “100px”

                                        }),

                        

                      new sap.m.Text({

                            text: “{funcionarios>name} \n {funcionarios >title}”

                              }                            

                        ]

                });

        

                oTemplate.attachPress(function(evt) {

             this.funcionarioPress(evt);

                },this);

                sap.ui.getCore().byId(“funcionariosTable”)

                .bindAggregation(

                        “funcionarios>” +

                        “/Cidade(‘” + cidIndex + “‘)”+

                        “/Cargo(‘” + cargoIndex + “‘)” +

                        “/Funcionarios”,

                              oTemplate

                    );

        },

                              funcionarioPress: function(oEvent) {

        

                              var oBindingContext = oEvent.getSource().getBindingContext(‘funcionarios’);

                              var sPath = oBindingContext.sPath;

                              var start = sPath.indexOf(“‘”) + 1;

                              var end = sPath.lastIndexOf(“‘”);

                              var funcionarioIndex = sPath.substring(start, end);

        

                              var modnav = sap.ui.getCore().byId(“app”).getModel(“nav”);

                              modnav.setProperty(“/func”,funcionarioIndex);

                }

});

Vamos  acessar nosso diretório principal e criar um arquivo “Component.js” e codificar da seguinte maneira.

sap.ui.core.UIComponent.extend(“sap.demo.Component”,{

        metadata: {

                routing: {

                        config: {

                               viewType: “JS”,

                               viewPath: “diretorio_appfiori”,

                               targetControl: “splitApp”,

                               clearTarget: false,

                               transition: “slide”

                                },

                                      routes: [ {

                                      pattern: “cidade/{cidIndex}”,

                                      name: “cidade”,

                                      view: “Cargo”,

                                      targetAggregation: “masterPages”,

                                      subroutes:[{

                                                               pattern:  “cidade/{cidIndex}/cargo/{cargoIndex}”,

                                                               name: “Funcionarios”,

                                                               view: “Funcionarios”,

                                                               targetAggregation: “detailPages” },]             

                                   },

                                   {

                                      pattern: “”,

                                      name: “default”,

                                      view: “Cidade”,

                                      targetAggregation: “masterPages”,

                                      subroutes: [

                                                     {

                                                         pattern: “”,

                                                         name: “Welcome”,

                                                        view: “Welcome”,

                                                        targetAggregation: “detailPages”

                                                     }

                                                 ]    

                                 },

             

                        init: function() {

                        jQuery.sap.require(“sap.m.routing.RouteMatchedHandler”);

                        jQuery.sap.require(“sap.ui.core.routing.HashChanger”);

                        //call createContent

                        sap.ui.core.UIComponent.prototype.init.apply(this, arguments);

                        this._router = this.getRouter();

                        this._routeHandler = new sap.m.routing.RouteMatchedHandler(this._router);

                        this._router.initialize();    

          },

                                   createContent: function() {

                                    var oView = sap.ui.view({

                                    id: “app”,

                                    viewName: “appfiori.App”,

                                    type: “JS”,

                                    viewData: {component: this}

                });


                var oModeldata = new sap.ui.model.odata.ODataModel (“/tmp/guilherme/WebContent/oData/funcionarios”);   

                oView.setModel(oModeldata,”funcionarios”);

Bom, agora falta somente codificar o “index.html” que vai ficar da seguinte maneira.

<!DOCTYPE HTML>

<html>

   <head>

      <meta http-equiv=“X-UA-Compatible” content=“IE=edge”>

       <meta http-equiv=‘Content-Type’ content=‘text/html;charset=UTF-8’/>

             <script src=“/sap/ui5/1/resources/sap-ui-core.js”

                           id=“sap-ui-bootstrap”

                           data-sap-ui-libs=“sap.m”

                           data-sap-ui-xx-bindingSyntax = “complex”

                           data-sap-ui-resourceroots = ‘{

                                  “appfiori”: “./appfiori”,

                                  “sap.demo”: “./”

                           }’

                           data-sap-ui-theme=“sap_bluecrystal”>

             </script>

             <!– only load the mobile lib “sap.m” and the “sap_bluecrystal” theme –>

       </head>

       <body class=“sapUiBody” role=“application”>

             <div id=“content”></div>

       </body>

</html>

Bom, terminamos nossa aplicação, se tudo correr certo o resultado final será o seguinte.

/wp-content/uploads/2015/06/14_719199.jpg

Tela inicial da aplicação com as opções de selecionar a cidade e em seguida o cargo.

/wp-content/uploads/2015/06/15_719200.jpg

 

Tela de listagem de funcionários cadastrados em determinado cargo de determinada cidade.

/wp-content/uploads/2015/06/16_719201.jpg

Bom pessoal, espero que tenham gostado desse artigo, tentei ser o mais claro possível e levantar as principais dúvidas que eu também encontrei na criação de minhas primeiras aplicações, bom desenvolvimento a todos e até a próxima.

To report this post you need to login first.

5 Comments

You must be Logged on to comment or reply to a post.

Leave a Reply