segunda-feira, 17 de junho de 2024

Limpeza buffer de tabela - Problema na visualização do titulo do campo mesmo alterando o elemento de dados

 Fato curioso, eu alterei alguns elementos de dados de uma tabela, quando eu visualizava na SE16N a descrição dos campos na primeira tela de parâmetros estava correta mas ao listar os dados no ALV o título não conferia com os que tinham sido alterado.

Para resolver só consegui usando esse comando no campo do ok-code, vi isso em outro blog e funcionou

  • /$sync (limpeza do buffer);









sexta-feira, 7 de junho de 2024

VS CODE - Alterar idioma de exibição dos dados de teste

 Quando é feito uma execução de teste de uma aplicação fiori pelo VS Code por default o idioma fica em inglês, eu tinha tentado fazer alterações de idioma do index.html mas não funciona, como o acesso é no ambiente SAP o idioma deve ser alteração das configurações especificas para o SAP. 

Nesse caso para teste é só alterar o arquivo flpSandbox.html




    <script id="sap-ui-bootstrap"
        src="../resources/sap-ui-core.js"
        data-sap-ui-libs="sap.m,sap.ui.core,sap.ushell,sap.f,sap.ui.comp,sap.ui.generic.app,sap.suite.ui.generic.template"
        data-sap-ui-async="true"
        data-sap-ui-preload="async"
        data-sap-ui-theme="sap_horizon"
        data-sap-ui-compatVersion="edge"
        data-sap-ui-language="pt"
        data-sap-ui-resourceroots='{"br.szk.testetab3": "../"}'
        data-sap-ui-frameOptions="allow"
        data-sap-ui-flexibilityServices='[{"applyConnector":"br/szk/testetab3/test/changes_loader", "custom":true}, {"connector": "LocalStorageConnector"}]'>
    </script>


NO V4 é diferente




sexta-feira, 31 de maio de 2024

RAP - Annotation valuehelpdefinition - Atribuindo valor contante na busca de valores

 Criei uma entidade para ajuda de pesquisa para o tipo de imposto onde a chave é o tipo TAXTYPE e o grupo de imposto TAXGRP

@AbapCatalog.viewEnhancementCategory: [#NONE]

@AccessControl.authorizationCheck: #NOT_REQUIRED

@EndUserText.label: 'Tipo de imposto'

@Metadata.ignorePropagatedAnnotations: true

@ObjectModel.usageType:{

serviceQuality: #X,

sizeCategory: #S,

dataClass: #MIXED

}

define view entity ZI_TaxType_VH

as select from I_BR_TaxTypeText as _TaxTypeText

inner join j_1baj as _TaxType on _TaxType.taxtyp = _TaxTypeText.BR_TaxType


{

@Search.defaultSearchElement: true

@Search.fuzzinessThreshold: 0.8

@Search.ranking: #HIGH

@ObjectModel.text.element: ['TxtTaxType']


key _TaxTypeText.BR_TaxType as BR_TaxType,

key _TaxType.taxgrp as TaxGrp,

@Semantics.text: true

_TaxTypeText.TaxTypeName as TxtTaxType

}

where

_TaxTypeText.Language = $session.system_language


Na minha tela de cadastro eu tenho campos especificos para o tipo de imposto para grupo de ICMS, IPI, COFINS, etc,


Como a entidade é genérica para exibição da ajuda de pesquisa coloquei uma constante para quando for buscar o tipo de imposto de ICMS, buscar somente por esse Grupo de imposto, para IPI, COFINS o mesmo.


Fiz a association normal e na minha CDS base e na projection fiz a sequinte atribuição na annotation da valuehelpdefinition.




@ObjectModel.foreignKey.association: '_TaxtypeCOFINS'

@Consumption.valueHelpDefinition: [{ entity: {name: 'ZI_TaxType_VH' , element: 'BR_TaxType' },

useForValidation: true,

additionalBinding: [{ element: 'TaxGrp', localConstant: 'COFI', usage: #FILTER }]

}]

@ObjectModel.text.element: [ 'TxtTaxTypeCOFINS' ]

TaxtypCofins,



quinta-feira, 11 de abril de 2024

RAP - Fiori elements com Extend utilizando script XLSX.js para Upload arquivo excel

1 - MÉTODO MAIS TRABALHOSO - A SEGUNDO OPÇÃO É MAIS FÁCIL.


 A principio dá para usar quase tudo q está aqui, 

https://community.sap.com/t5/technology-blogs-by-members/excel-upload-using-rap-part-1/ba-p/13545399

mas para mim não funcionou 100%, foi necessário alguns ajustes.
- a parte do fiori guide development pode seguir igual
- pode criar o fragment
- pode atualizar o controller conforme está no blog

Agora a parte de alterar os arquivos 
- ui5.yaml 
- package.json

Não acho necessário.. 

depois do importe do arquivo utilizando o NPM INSTALL XLXS

copiar o arquivo xlxs.js  que fica criado dentro da pasta xlsx no node_modules









Criar uma pasta tipo "lib" ou "util" dentro da pasta do ext e colar os arquivos
- xlxs.js 
- jzip.js








No arquivo manifest.json incluir a biblioteca dentro de rescursos.









No Controller NÃO pode declarar o objeco XLSX pois dentro do arquivo xlsx.js esse objetos está global.















É possível q tenha erros de conversão na planilha então tem q fazer a conversão.






















Conversão quando é campo numérico null.











========= 2 OPÇÃO UTILIZANDO OUTRA BIBLIOTECA 

Seguindo esse site.
https://docs.spreadsheet-importer.com/pages/GettingStarted/

Criei uma tabela Z

@EndUserText.label : 'teste'

@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE

@AbapCatalog.tableCategory : #TRANSPARENT

@AbapCatalog.deliveryClass : #A

@AbapCatalog.dataMaintenance : #ALLOWED

define table zszk {


key mandt : mandt not null;

key matnr : matnr not null;

kunnr : kunnr;

tipo : char20;

budat : budat;

@Semantics.amount.currencyCode : 'bkpf.waers'

netwr : netwr;


}




Criei a ROOT e PROJECTION view

@AbapCatalog.viewEnhancementCategory: [#NONE]

@AccessControl.authorizationCheck: #NOT_REQUIRED

@EndUserText.label: 'teste'

@Metadata.ignorePropagatedAnnotations: true

@ObjectModel.usageType:{

serviceQuality: #X,

sizeCategory: #S,

dataClass: #MIXED

}

define root view entity ZSZK_TESTE

as select from zszk

{

key matnr as Matnr,

kunnr as Kunnr,

tipo as Tipo,

budat as Budat,

cast( 0 as abap.dec(15,2) ) as Netwr


}


=============================


@EndUserText.label: 'Projec V'

@AccessControl.authorizationCheck: #NOT_REQUIRED

define root view entity ZSZK_TESTE_V

provider contract transactional_query as projection on ZSZK_TESTE

{

@UI.lineItem: [{ position: 10 }]

key Matnr,

@UI.lineItem: [{ position: 20 }]

Kunnr,

@UI.lineItem: [{ position: 30 }]

Tipo,

@UI.lineItem: [{ position: 40 }]

Budat,

@UI.lineItem: [{ position: 50 }]

Netwr

}


Criei o behavior managed 

managed implementation in class zbp_szk_teste unique;

strict ( 2 );


define behavior for ZSZK_TESTE //alias <alias_name>

persistent table zszk

lock master

authorization master ( instance )

//etag master <field_name>

{

create;

update;

delete;


field ( readonly : update ) Matnr;


mapping for zszk {


Kunnr = kunnr;

Matnr = matnr;

Tipo = tipo;

Budat = budat;

Netwr = netwr;

}

}

===============================


projection;

strict ( 2 );


define behavior for ZSZK_TESTE_V //alias <alias_name>

{

use create;

use update;

use delete;

}


Criei os serviços e binding.


- Passo VS code


1. Install from npm

npm install ui5-cc-spreadsheetimporter


2. Add resourceRoots to your manifest.json under sap.ui5


"resourceRoots": {

  "cc.spreadsheetimporter.v1_1_1": "./thirdparty/customcontrol/spreadsheetimporter/v1_1_1"

}


===== Detalhe importante nesse caso a versão é  v1.1.1  mas tem q verificar com a versão q foi instalado no momento do desenvolvimento, é só verifiar no arquivo package.json q vai ter a versão q foi instalada.






3. Add --all to your build script in the package.json
"scripts": {
  ...
  "build": "ui5 build --config=ui5.yaml --all --clean-dest --dest dist",
  ...
}




4. Add componentUsages to your manifest.json under sap.ui5

updating the module. (Explanation here: Version Namespace )
"componentUsages": {
  "spreadsheetImporter": {
    "name": "cc.spreadsheetimporter.v1_1_1"
  }
}


















5. Optional Avoid error component does not exist

If you deploy your app to a SAP System (S/4 On-Premise or SAP BTP ABAP environment), you may get the error component does not exist.

To avoid this error, you can add the following to your manifest.json file:


"sap.app": {

  "embeds": ["thirdparty/customcontrol/spreadsheetimporter/v1_1_1"]

}


6. Adicionando botão customizado
 após SNIPPET











7 Inserir código controller.

sap.ui.define([
    "sap/m/MessageToast"
], function(MessageToast) {
    'use strict';

    return {
        importexcel: async function (event) {
            this.getView().setBusyIndicatorDelay(0);
            this.getView().setBusy(true);
            this.spreadsheetUpload = await this.getView()
              .getController()
              .getOwnerComponent()
              .createComponent({
                usage: "spreadsheetImporter",
                async: true,
                componentData: {
                  context: this,
                },
              });
            this.spreadsheetUpload.openSpreadsheetUploadDialog();
            this.getView().setBusy(false);
          }
    };
});



MANIFEST.JSON
{
    "_version": "1.53.0",
    "sap.app": {
        "embeds": [
            "thirdparty/customcontrol/spreadsheetimporter/v1_1_1"
        ],
        "id": "br.szk.testeupload",
        "type": "application",
        "i18n": "i18n/i18n.properties",
        "applicationVersion": {
            "version": "0.0.1"
        },
        "title": "{{appTitle}}",
        "description": "{{appDescription}}",
        "resources": "resources.json",
        "sourceTemplate": {
            "id": "@sap/generator-fiori:lrop",
            "version": "1.12.4",
            "toolsId": "25a472ea-7893-4fde-81c2-bd5918aed745"
        },
        "dataSources": {
            "mainService": {
                "uri": "/sap/opu/odata/sap/ZSZK_TESTE/",
                "type": "OData",
                "settings": {
                    "annotations": [
                        "ZSZK_TESTE_VAN",
                        "annotation"
                    ],
                    "localUri": "localService/metadata.xml",
                    "odataVersion": "2.0"
                }
            },
            "ZSZK_TESTE_VAN": {
                "uri": "/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='ZSZK_TESTE_VAN',Version='0001')/$value/",
                "type": "ODataAnnotation",
                "settings": {
                    "localUri": "localService/ZSZK_TESTE_VAN.xml"
                }
            },
            "annotation": {
                "type": "ODataAnnotation",
                "uri": "annotations/annotation.xml",
                "settings": {
                    "localUri": "annotations/annotation.xml"
                }
            }
        }
    },
    "sap.ui": {
        "technology": "UI5",
        "icons": {
            "icon": "",
            "favIcon": "",
            "phone": "",
            "phone@2": "",
            "tablet": "",
            "tablet@2": ""
        },
        "deviceTypes": {
            "desktop": true,
            "tablet": true,
            "phone": true
        }
    },
    "sap.ui5": {
        "flexEnabled": true,
        "dependencies": {
            "minUI5Version": "1.114.12",
            "libs": {
                "sap.m": {},
                "sap.ui.core": {},
                "sap.ushell": {},
                "sap.f": {},
                "sap.ui.comp": {},
                "sap.ui.generic.app": {},
                "sap.suite.ui.generic.template": {}
            }
        },
        "contentDensities": {
            "compact": true,
            "cozy": true
        },
        "models": {
            "i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "settings": {
                    "bundleName": "br.szk.testeupload.i18n.i18n"
                }
            },
            "": {
                "dataSource": "mainService",
                "preload": true,
                "settings": {
                    "defaultBindingMode": "TwoWay",
                    "defaultCountMode": "Inline",
                    "refreshAfterChange": false,
                    "metadataUrlParams": {
                        "sap-value-list": "none"
                    }
                }
            },
            "@i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "uri": "i18n/i18n.properties"
            }
        },
        "resources": {
            "css": []
        },
        "routing": {
            "config": {},
            "routes": [],
            "targets": {}
        },
        "resourceRoots": {
            "cc.spreadsheetimporter.v1_1_1": "./thirdparty/customcontrol/spreadsheetimporter/v1_1_1"
        },
        "componentUsages": {
            "spreadsheetImporter": {
                "name": "cc.spreadsheetimporter.v1_1_1"
            }
        },
        "extends": {
            "extensions": {
                "sap.ui.controllerExtensions": {
                    "sap.suite.ui.generic.template.ListReport.view.ListReport": {
                        "controllerName": "br.szk.testeupload.ext.controller.ListReportExt",
                        "sap.ui.generic.app": {
                            "ZSZK_TESTE_V": {
                                "EntitySet": "ZSZK_TESTE_V",
                                "Actions": {
                                    "create1": {
                                        "id": "create1Button",
                                        "text": "Importar Excel",
                                        "press": "importexcel",
                                        "requiresSelection": false
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "sap.ui.generic.app": {
        "_version": "1.3.0",
        "settings": {
            "forceGlobalRefresh": false,
            "objectPageHeaderType": "Dynamic",
            "considerAnalyticalParameters": true,
            "showDraftToggle": false
        },
        "pages": {
            "ListReport|ZSZK_TESTE_V": {
                "entitySet": "ZSZK_TESTE_V",
                "component": {
                    "name": "sap.suite.ui.generic.template.ListReport",
                    "list": true,
                    "settings": {
                        "condensedTableLayout": true,
                        "smartVariantManagement": true,
                        "enableTableFilterInPageVariant": true,
                        "filterSettings": {
                            "dateSettings": {
                                "useDateRange": true
                            }
                        },
                        "dataLoadSettings": {
                            "loadDataOnAppLaunch": "ifAnyFilterExist"
                        }
                    }
                },
                "pages": {
                    "ObjectPage|ZSZK_TESTE_V": {
                        "entitySet": "ZSZK_TESTE_V",
                        "defaultLayoutTypeIfExternalNavigation": "MidColumnFullScreen",
                        "component": {
                            "name": "sap.suite.ui.generic.template.ObjectPage"
                        }
                    }
                }
            }
        }
    },
    "sap.fiori": {
        "registrationIds": [],
        "archeType": "transactional"
    }
}

É só executar...  fazer o download do template.
- testei com data e valor e funciona sem erro.













- Alguns detalhes dessa solução, só deixa fazer o upload depois q vc tenta carregar os dados (clicar no botão GO), isso dá para resolver colocando a instrução no manifest para executar a lista ao carregar o APP. 

        "pages": {
            "ListReport|ZSZK_TESTE_V": {
                "entitySet": "ZSZK_TESTE_V",
                "component": {
                    "name": "sap.suite.ui.generic.template.ListReport",
                    "list": true,
                    "settings": {
                        "condensedTableLayout": true,
                        "smartVariantManagement": true,
                        "enableTableFilterInPageVariant": true,
                        "filterSettings": {
                            "dateSettings": {
                                "useDateRange": true
                            }
                        },
                        "dataLoadSettings":{
                        "loadDataOnAppLaunch": "always" }
                       

--- Erro q encontrei num cliente quando fui fazer o deploy, no próprio site da biblioteca tem essa esquema para fazer



terça-feira, 9 de abril de 2024

RAP - Abstract entity com Value help

 Imagina um cara que sofreu para esse treco funcionar...  


@EndUserText.label: 'Popup material não aplicado'

define abstract entity ZI_RetMatNAPl

{

@Consumption.filter.mandatory: true

@Consumption.valueHelpDefinition: [{ entity: {name: 'I_Customer_VH' , element: 'Customer' }, useForValidation: true }]

@EndUserText.label: 'Cliente'

Kunnr : kunnr;

@Consumption.filter.mandatory: true

@Consumption.valueHelpDefinition: [{ entity: {name: 'I_PlantStdVH' , element: 'Plant' }, useForValidation: true }]

@EndUserText.label: 'Centro'

Werks : werks_d;

}

==== Detalhe importante é o nome do campo que tem estar igual ao declarado no association da entidad principal, no meu caso fiquei penando até descobrir q era por causa da inicial maiúscula









== Não  sei afirmar ao certo se tem q ser dessa forma, mas foi só assim q funcionou para mim 











Não esquecer de remover esse parâmetro no manifest qdo for fazer o deploy




quarta-feira, 20 de março de 2024

RAP - Modificando itens no determination ON SAVE

===== CHAMADA  

determination preenche_campos on save { create; }


====== Implementação do método

  METHOD preenche_campos.


    READ ENTITIES OF ZI_XXXX IN LOCAL MODE

         ENTITY Item

         FIELDS ( posnr )

         WITH CORRESPONDING #( keys )

         RESULT DATA(lt_item).


    READ ENTITIES OF ZI_XXXX IN LOCAL MODE

         ENTITY Header

         FIELDS ( id Opertyp )

         WITH CORRESPONDING #( keys )

         RESULT DATA(lt_header).


    CHECK lt_header IS NOT INITIAL.

    DATA(ls_header) = lt_header[ 1 ].

    CHECK  ls_header-Opertyp = zcl_sd_XXXX=>c_tipo_op-sem_retorno.


    SELECT COUNT( * )

      FROM ztsd_XXXX

     WHERE id = ls_header-Id.


    DATA(lv_posnr) = CONV posnr( sy-dbcnt ) * 10.


    LOOP AT lt_item REFERENCE INTO DATA(lr_item).


      MODIFY ENTITIES OF ZI_XXXX IN LOCAL MODE

        ENTITY Item

        UPDATE FIELDS ( posnr )

        WITH VALUE #( ( %tky = lr_item->%tky posnr = lv_posnr %control-Posnr = if_abap_behv=>mk-on ) ).

    ENDLOOP.


  ENDMETHOD.


segunda-feira, 18 de março de 2024

RAP - Ocultando campos dinamicamente

 É possível ocultar campos dinamicamente mas somente de campos do object page, onde os campos são visualizados individualmente, a principio achei estranho q não tivesse opção para lista mas faz sentido pq cada registro pode ter uma condição diferente e não seria possível ocultar um campo em uma linha e na outra ficar visivel.

No meu caso eu tenho object page com uma lista (composition) que possui outra object page, nesse caso tive q colocar uma regra para o parent e outro para o child

======= Coloquei a condição na root view tanto do parent como do child, poderia ser utilizado o virtual element mas no meu caso como depende de um valor de campo da própria view foi mais fácil. 
- Detalhe importante o tipo tem q ser um ABAP_BOOLEAN

















No meu caso ocultei o campo de ordem de produção, ocultei tanto do datapoint do FACET quanto no campo listado na página do object page