Jump to content
Fivewin Brasil

coutinho.amauri

Membros
  • Posts

    188
  • Joined

  • Last visited

Posts posted by coutinho.amauri

  1.  

    faço assim logo assim q conetco ao banco 

      cCMDSQL := 'SET GLOBAL connect_timeout=28800'
      oSql:exec( cCMDSQL )    
      
      cCMDSQL := 'SET GLOBAL interactive_timeout=28800'
      oSql:exec( cCMDSQL )    
      
      cCMDSQL := 'SET GLOBAL wait_timeout=28800'
      oSql:exec( cCMDSQL )    

  2. a soluçao e grande vou postar algum exemplo 

     

    /**************************************************************************************/
    FUNCTION OBTER_TOKEN()
    /**************************************************************************************/

        LOCAL oWeb
        LOCAL hHash            := HASH()
        LOCAL aRetorno         := ''
       LOCAL Cliente_id       := ''
       LOCAL Cliente_secret   := ''
       LOCAL cPath            := CurDrive()+":\"+CurDir()+'\'
       LOCAL cParam           := ''
       
       LOCAL cTxt[3]

        IF ! IsInternet()
           MSGALERT("Sem Conexão a Internet","Verifique")
           RETURN NIL
        ENDIF

        TRY
            oWeb  := CreateObject( 'MSXML2.ServerXMLHTTP.6.0' ) 
        CATCH
            oWeb  := CreateObject( 'MSXML2.XMLHTTP' )
        END

        //-- validaçoes 
        IF ! FILE( cPath + cIniIFOOD )
           MSGALERT("Arquivo de Credenciamento não Encontrado","Alerta")
           RETURN NIL
        ENDIF   

        //-- pega os dados do INI 
        
       Cliente_id      := GetPvProfString( 'Ifood' , 'Cliente_id'           , "" , cIniIFOOD ) 
       Cliente_secret  := GetPvProfString( 'Ifood' , 'Cliente_secret'       , "" , cIniIFOOD ) 
        
        IF EMPTY(Cliente_id) .OR. EMPTY(Cliente_secret) 
           MSGALERT("Credenciamento Inválido","Alerta")
            RETURN NIL
         ENDIF   

        //-- monta o parametro
       cParam := '{"client_id":' + '"' + Cliente_id + '"' + "," + '"client_secret":' + '"' + Cliente_secret + '"' + "}"

        oWeb:Open( 'POST', Urlsitemerc + '/api/v1/oauth/token' ,  .F. ) 
       oWeb:setRequestHeader('Content-Type'    , 'application/json; charset=utf-8')
       
        TRY
        
           //-- envia o parametro
            oWeb:Send( cParam )  

            //-- pega o retorno
           aRetorno := oWeb:ResponseText()
           
           //-- json
          hb_jsondecode( aRetorno, @hHash )
          
            cTxt[1] := hHash["access_token"]
            cTxt[2] := hHash["token_type"]
            cTxt[3] := hHash["expires_in"]
          
          WritePProString( 'Ifood' , 'acess_token'      , cTxt[1]      , cIniIFOOD )
          WritePProString( 'Ifood' , 'token_type'       , cTxt[2]       , cIniIFOOD )
          WritePProString( 'Ifood' , 'expires_in'       , cTxt[3]       , cIniIFOOD )
            
        CATCH ; END
        
    RETURN NIL
     

    /**************************************************************************************/
    FUNCTION SINCRONIZAR_PRODUTOS()
    /**************************************************************************************/

        LOCAL oWeb
        
        LOCAL hHash            := HASH()
        LOCAL aRetorno         := ''
       LOCAL cPath            := CurDrive()+":\"+CurDir()+'\'
       LOCAL cParam           := ''
       LOCAL cToken           := ''
       LOCAL nVALOR           := '0'

        //-- validaçoes 
        IF ! FILE( cPath + cIniIFOOD )
           MSGALERT("Arquivo de Credenciamento não Encontrado","Alerta")
           RETURN NIL
        ENDIF   

        //-- pega os dados do INI 
       Id_loja := GetPvProfString('Ifood','Id_loja',"",cIniIFOOD) 
        
        IF EMPTY(Id_loja) 
           MSGALERT("Credenciamento Inválido","Id_loja")
            RETURN NIL
         ENDIF   

        //-- token
        OBTER_TOKEN()

        cToken := GetPvProfString('Ifood','acess_token' , "" , cIniIFOOD) 

        ABRIR("PRODUTOS",.T.)
        
        cParam := '['
        
        WHILE ! PRODUTOS->( EOF() )
        
         cParam += '{'
         cParam += '"idLoja": '                  +  Id_loja                                                  + ','
         cParam += '"departamento": "'           +  RemoveAcentuacao(ALLTRIM(PRODUTOS->NOMSEC)) + '"'        + ','  
         cParam += '"categoria": "'              +  RemoveAcentuacao(ALLTRIM(PRODUTOS->NOMGRU)) + '"'        + ','  
         cParam += '"subCategoria": "'           +  RemoveAcentuacao(ALLTRIM(PRODUTOS->NOMSGR)) + '"'        + ',' 
         cParam += '"marca": "'                  +  ''                        + '"'                          + ',' 
         cParam += '"unidade": "'                +  ALLTRIM(PRODUTOS->UND)    + '"'                          + ',' 
         cParam += '"volume": "'                 +  ''                        + '"'                          + ',' 
         cParam += '"codigoBarra": "'            +  ALLTRIM(PRODUTOS->CODBAR) + '"'                          + ',' 
         cParam += '"nome": "'                   +  RemoveAcentuacao(ALLTRIM(PRODUTOS->NOMPRO)) + '"'        + ',' 
         cParam += '"valor": '                   +  ALLTRIM(TRANSFORM(PRODUTOS->PRE_VEN,"999,999.9999"))     + ',' 
         cParam += '"valorPromocao": '           +  nVALOR                                                   + ',' 
         cParam += '"valorAtacado": '            +  nVALOR                                                   + ',' 
         cParam += '"valorCompra": '             +  ALLTRIM(TRANSFORM(PRODUTOS->PRE_CUS,"999,999.9999"))     + ',' 
         cParam += '"quantidadeEstoqueAtual": '  +  ALLTRIM(TRANSFORM(PRODUTOS->EST_ATU,"999,999.9999"))     + ',' 
         cParam += '"quantidadeEstoqueMinimo": ' +  ALLTRIM(TRANSFORM(PRODUTOS->EST_MIN,"999,999.9999"))     + ',' 
         cParam += '"quantidadeAtacado": '       +  nVALOR                                                   + ',' 
         cParam += '"descricao": "'              +  RemoveAcentuacao(ALLTRIM(PRODUTOS->NOMCOM)) + '"'        + ',' 
         cParam += '"ativo": '                   +  'true'                                                   + ',' 
         cParam += '"plu": "'                    +  '0'                       + '"'                          + ',' 
         cParam += '"validadeProxima": '         +  'false'        
         cParam += "}"   
                                             
          PRODUTOS->( DBSKIP() )
          
          IF ! PRODUTOS->( EOF() )
             cParam += ","   
          ELSE
             cParam += "]"   
          ENDIF   

        END

          CLOSE_DBF("PRODUTOS")
          
          MemoWrit( 'produtos.json' , cParam  )

        TRY
            oWeb  := CreateObject( 'MSXML2.ServerXMLHTTP.6.0' ) 
        CATCH
            oWeb  := CreateObject( 'MSXML2.XMLHTTP' )
        END

        oWeb:Open( 'POST', Urlsitemerc + '/api/v1/produtointegracao' ,  .F. ) 
       oWeb:setRequestHeader('Authorization'    , 'Bearer ' + cToken   )
       oWeb:setRequestHeader('Content-Type'    , 'application/json; charset=utf-8')
       
        
        TRY
        
           //-- envia o parametro
            oWeb:Send( cParam )  

            //-- pega o retorno
           aRetorno := oWeb:ResponseText()
           
           //-- json
          hb_jsondecode( aRetorno, @hHash )

          //-- mensagem de exportação
          MsgInfo("Exportação Concluida","Atenção")
       
          //-- mostra o retorno
           xbrowse(hHash)

        CATCH ; END   
        
    RETURN NIL
     

     

  3. boa tarde Marcio

    essa e a rotina de transaçao do pix no sitef (TEF dedicado) que ja recebe pagamento via PIX 

    Pix via CardSE

    Esta documentação descreve a integração com PIX através do e-SiTef, utilizando o roteamento CardSE via SiTef.

    Informações cadastrais

    Além das informações usuais para cadastro no e-SiTef, para integração com Pix será necessário mais um dado:

    Campo Descrição Formato Obrigatório
    psp Prestador de serviços de pagamento. Se não for enviado, será utilizado o valor cadastrado no SiTef. < 8 N NÃO

    Pagamento REST

    Fluxo

    roteamento-cardse-pix-fluxo-ws.png

    1. O lojista cria a transação no e-SiTef passando algumas informações adicionais do Pix e recebe o NIT como resposta.
    2. A loja chama o serviço de efetivação de pagamento e recebe um QR code e a transação com status PEN (pendente).
    3. A loja virtual exibe o QR code para o comprador.
    4. O comprador escaneia o QR code com o aplicativo Pix e passa pelo procedimento de confirmação do pagamento solicitado pelo autorizador.
    5. Enquanto o comprador finaliza o pagamento, o e-SiTef sondará a situação da compra no autorizador até que a transação se encerre.
    6. A loja, por sua vez, deve consultar o status da transação do e-SiTef até que ela saia do status PEN.

    Atenção:

    Se o status da transação permanecer pendente (PEN) após aproximadamente 3 (três) minutos, o e-SiTef irá desfazer a transação junto ao Pix.

    Informações adicionais na criação da transação

    Para transações com Pix, deve ser utilizado authorizer_id = 440.

    Abaixo estão parâmetros adicionais que podem ser enviados em transações Pix:

    Parâmetro Descrição Formato Obrigatório
    additional_data  
    pix_psp Prestador de serviços de pagamento. Se não for enviado, será utilizado o valor cadastrado no e-SiTef. < 8 AN NÃO
    pix_question Pergunta do lojista para o comprador (será exibida no aplicativo). < 140 AN NÃO
    additional_data.pix_data[] Lista de conteúdo livre. Permite enviar dados ao aplicativo do cliente como lista de serviços adquiridos, informações promocionais ou outros dados desejados.
    key Identificação do campo. < 50 AN NÃO
    value Valor do campo. < 200 AN NÃO
    additional_data.items[]  
    ean Código EAN do produto.

    Atenção: caso o EAN e o SKU sejam enviados simultaneamente, apenas o EAN será considerado.
    < 255 AN NÃO
    sku Código SKU do produto.

    Atenção: caso o EAN e o SKU sejam enviados simultaneamente, apenas o EAN será considerado.
    < 255 AN NÃO
    description Descrição do produto. < 255 AN NÃO
    quantity Quantidade do produto a ser adquirido. < 15 N NÃO
    quantity_type Tipo da quantidade:
    • u - Unidades
    • g - Gramas
    • ml - Mililitros
    < 2 AN NÃO
    unit_price Preço unitário do produto em centavos. < 12 N NÃO

    Exemplo:

    curl
    --request POST "https://esitef-homologacao.softwareexpress.com.br/e-sitef/api/v1/transactions"
    --header "Content-Type: application/json"
    --header "merchant_id: xxxxxxxx"
    --header "merchant_key: xxxxxxxxxxx"
    --data-binary
    {
       "merchant_usn":"12042142155",
       "order_id":"12042142155",
       "installments":"1",
       "installment_type":"4",
       "authorizer_id":"440",
       "amount":"1000",
       "additional_data":{
          "pix_psp":"12345678",
          "pix_question":"Deseja receber 10% de desconto para sua proxima compra?",
          "pix_data":[
             {
                "key":"Pontos Ganhos",
                "value":"23"
             },
             {
                "key":"NumPromo",
                "value":"234523452345"
             }
          ],
          "items":[
             {
                "description":"ItemTeste",
                "quantity":"1",
                "sku":"1487337308522",
                "unit_price":"1000",
                "quantity_type":"u"
             },
             {
                "description":"ItemTeste2",
                "quantity":"3",
                "ean":"9283746529384675",
                "unit_price":"2500",
                "quantity_type":"g"
             }
          ]
       }
    }
    --verbose
    
    Copiar

    Requisição da efetivação do pagamento

    Na integração com Pix, não será necessário o envio de nenhum dado do cartão.

    Exemplo:

    curl
    --request POST "https://esitef-homologacao.softwareexpress.com.br/e-sitef/api/v1/payments/1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr"
    --header "Content-Type: application/json"
    --header "merchant_id: xxxxxxxx"
    --header "merchant_key: xxxxxxxxxxx"
    --data-binary
    {}
    --verbose
    
    Copiar

    Retornos na efetivação do pagamento com tamanho diferente do padrão

    Parâmetro Descrição Formato
    authorization_number Número de autorização. < 100 AN

    Retornos adicionais na efetivação do pagamento

    Parâmetro Descrição Formato
    payment  
    pix_psp Prestador de serviços de pagamento. < 8 AN
    pix_answer Resposta ao pix_question. < 140 AN
    qr_code QR code a ser exibido ao comprador. < 9999 AN

    Atenção:

    Em caso de erro de comunicação nesta operação, será necessário criar outra transação.

    Exemplo:

    {
       "code":"0",
       "message":"OK. Transaction successful.",
       "payment":{
          "authorizer_code":"000",
          "authorizer_message":"Transacao OK",
          "status":"PEN",
          "nit":"1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr",
          "order_id":"13034649671",
          "authorizer_id":"2",
          "acquirer_id":"1271",
          "acquirer_name":"CardSE",
          "authorizer_date":"13/07/2017T15:52",
          "authorization_number":"132030",
          "merchant_usn":"13034649671",
          "esitef_usn":"170713097340300",
          "sitef_usn":"132030",
          "host_usn":"000000000",
          "payment_date":"13/07/2017T15:52",
          "amount":"1000",
          "authorizer_merchant_id":"000000000000005",
          "pix_psp":"12345678",
          "pix_answer":"No",
          "qr_code":"The quick brown fox jumps over the lazy dog"
       }
    }
    
    Copiar

    Pagamento HTML

    Não há diferenças no fluxo para a loja.

    Assim como no Pagamento REST, podem ser enviados parâmetros adicionais na criação da transação, usando o mesmo formato.

    Cancelamento REST

    Requisição da efetivação do cancelamento

    Na integração com Pix, não será necessário o envio de nenhum dado do cartão.

    Exemplo:

    curl
    --request PUT "https://esitef-homologacao.softwareexpress.com.br/e-sitef/api/v1/cancellations/1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr"
    --header "Content-Type: application/json"
    --header "merchant_id: xxxxxxxxxxx"
    --header "merchant_key: xxxxxxxxxxx"
    --data-binary
    {
       "amount":"1000"
    }
    --verbose
    
    Copiar

    Retornos adicionais na efetivação do cancelamento

    Parâmetro Descrição Formato
    cancellation  
    pix_psp Prestador de serviços de pagamento. < 8 AN

    Exemplo:

    {
       "code":"0",
       "message":"OK. Transaction successful.",
       "cancellation":{
          "authorizer_code":"000",
          "authorizer_message":"Transacao OK",
          "status":"CON",
          "nit":" 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr",
          "order_id":"09062259711",
          "customer_receipt":"=== COMPROVANTE ===",
          "merchant_receipt":"=== COMPROVANTE ===",
          "authorizer_id":"2",
          "acquirer_id":"1271",
          "acquirer_name":"CardSE",
          "authorizer_date":"09/11/2017T18:23",
          "authorization_number":"092423",
          "merchant_usn":"9062259711",
          "esitef_usn":"171109108051261",
          "sitef_usn":"092424",
          "host_usn":"999092424   ",
          "amount":"1000",
          "payment_type":"O",
          "authorizer_merchant_id":"000000000000000",
          "esitef_date":"09/11/2017T18:23",
          "pix_psp":"12345678"
       }
    }
    
    Copiar

    Geração de link de pagamento no Portal do Lojista

    Também é possível fazer pagamentos com Pix através de funcionalidade de link de pagamento do Portal Lojista. No entanto, ainda não está disponível a possibilidade do envio das informações adicionais do Pix.

    Cadastro de chaves Pix no Portal do Lojista

    Ao acessar a configuração de uma autorizadora Pix, será exibido um botão para cadastrar suas chaves Pix:

    roteamento-cardse-pix-cadastro-botao.png

    Ao clicar no botão "Cadastrar Chaves", o usuário será redirecionado para uma tela contendo informações da loja e uma listagem de PSPs:

    roteamento-cardse-pix-cadastro-tela.png

    Selecione o PSP (prestador de serviços de pagamento) que deseja utilizar e clique em "Adicionar":

    roteamento-cardse-pix-cadastro-psp-adica

    Preencha a sua chave Pix e suas informações de credencial e clique em "Salvar". Após submeter os seus dados, caso deseje alterar suas informações, clique em "Editar". Se quiser apagá-las, clique em "Remover":

    roteamento-cardse-pix-cadastro-psp-alter

    Após realizar todas as alterações desejadas, clique em "Salvar".

  4. o problema esta no seu projeto criado pelo xdev versao 0.72 que vc instalou anteriormente

    tem q retirar umas linhas q estao no seu projeto q foi aberto pela versao 0.72

    apague as linhas abaixo dessa palavra webframework  (essa linha tambem)

    obs abra o arquivo do projeto .xdev num outro editor

  5. /******************************************************************************/
    METHOD ConsultaNFe( cAmb, cChave ) CLASS hbNFe
    /*****************************************************************************/

        LOCAL aRETORNO            := HASH()
        LOCAL cServ               := 'CONSULTAR'
        LOCAL cVersao             := ::Ini_versaoSistema
        LOCAL cStatus             := "" 
        LOCAL cMotivo             := "" 
        LOCAL cProt               := ""
        LOCAL cDataHoraAutorizada := "" 

        aRETORNO['STATUS']    := .F.
        aRETORNO['MSG']       := ''
        aRETORNO['PROTOCOLO'] := ''
        aRetorno['RETORNO'  ] := ''
        aRetorno['DATAAUTO' ] := ''

        IF EMPTY(cChave)
            aRETORNO['MSG'] := 'Favor informar a Chave'
            RETURN aRETORNO
        ENDIF

        IF EMPTY(cAmb)
            aRETORNO['MSG'] := 'Favor informar o Ambiente'
            RETURN aRETORNO
        ENDIF

        ::Ide_nNfe:= cChave

        ::cXML := ''
        ::cXML += '<consSitNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="' + cVersao + '">'
        ::cXML +=      '<tpAmb>'  + cAmb    + '</tpAmb>'
        ::cXML +=   '<xServ>'  + cServ   + '</xServ>'
        ::cXML +=   '<chNFe>'  + cChave  + '</chNFe>'
        ::cXML += '</consSitNFe>'

       MEMOWRIT( ::Ini_pastaXML +"\Consultas\Envio" + '\NFe_Cons' + cChave +'.xml' , ::cXML , .F.)

       aRETORNO := ::ComunicaWebService( 2 )

        IF ! aRETORNO['STATUS']
            RETURN(aRETORNO)
        ENDIF

        cStatus:= cMotivo:= cProt:= ""

        * le o arquivo de retorno
        ::XML_GetNode(aRETORNO['XML'], "cStat"  , @cStatus )
        ::XML_GetNode(aRETORNO['XML'], "xMotivo", @cMotivo )
        ::XML_GetNode(aRETORNO['XML'], "nProt"  , @cProt )
        ::XML_GetNode(aRETORNO['XML'], "dhRecbto", @cDataHoraAutorizada )


        IF Empty(cStatus) .OR. Empty(cMotivo)
            aRETORNO['MSG']   := "Erro ao obter retorno do Web Service"
            RETURN(aRETORNO)
        ENDIF

        * Possiveis erros:
        * O processamento do pedido de consulta de status de NF-e pode resultar em uma
        * mensagem de erro ou retornar a situação atual da NF-e consultada.
        * No caso de localização da NF-e retornar o cStat com os valores “100-Autorizado o Uso”,
        * “101-Cancelamento de NF-e Homologado” ou “110-Uso Denegado”.

        IF cStatus == "100" // 100-Autorizado o Uso
            aRETORNO['STATUS']   := .T.
        ELSE
            aRETORNO['STATUS']   := .F.
        ENDIF

       aRETORNO['PROTOCOLO']:= cProt
       aRETORNO['RETORNO'  ]:= cStatus
       aRETORNO['MSG']      := cStatus +" - "+ cMotivo
       aRetorno['DATAAUTO' ]:= cDataHoraAutorizada

    RETURN(aRETORNO)
     

  6. cConString1 := "pgs="+cConnName + ";" //-- conexao com postgre
    "uid="+lower(ALLTRIM(cConnUsrs))+ ";" //-- usuario cdastrado no banco de dados postgre
    "dtb="+alltrim(LOWER(cConnBase))+ ";" //-- banco de dados a conectar (schema)
    "pwd="+lower(ALLTRIM(cConnPass))+";   //-- senha do banco de dados postgre
    PRT=5432"                             //-- porta de conexao do banco
     

  7.       tente assim

           vSql := 'Create TABLE USUARIO ('
            vSql += 'CODUSUARIO Integer(3) NOT NULL AUTO_INCREMENT Primary Key ,'
            vSql += 'USUARIO    VarChar(20)    NULL DEFAULT NULL               ,'
            vSql += 'SENHA      VarChar(6)     NULL DEFAULT NULL               ,'
            vSql += 'EMAIL      VarChar(100)   NULL DEFAULT NULL               ,'
            vSql += 'SETOR      VarChar(1)     NULL DEFAULT NULL               ,'
            vSql += 'DESCONTO   Decimal(10,2)  NULL DEFAULT "0.00"             ,'
            vSql += 'VENDEDOR   Integer(3)     NULL DEFAULT "0"                ,'
            vSql += 'PERIODO    Date       NOT NULL DEFAULT "0001-01-01"       )'

           oSql := SR_GetConnection() 

          oSql:Execute( vSql )      //-- Executa a operação no banco
          oSql:Commit()             //-- Atualiza o banco
     

  8. Faço assim 

     

    ******************************************************************************
    FUNCTION CONECTAR(cConnTipo,cConnBase,cConnName,cConnPass,cConnUsrs,nConx,cCPorta)
    ******************************************************************************
      
      LOCAL cConString1 := ''

       cConString1    := "MySQL=" + lower(ALLTRIM(cConnName)) + ";" + ;
                       "UID="   + lower(ALLTRIM(cConnUsrs)) + ";" + ;
                            "pwd="   + lower(ALLTRIM(cConnPass)) + ";" + ;
                            "dtb="   + alltrim(LOWER(cConnBase))       + ;
                            ";PRT="  + alltrim(cCPorta)
       
       nConx         := SR_AddConnection( CONNECT_MYSQL, cConString1 )
       
       IF nConx < 0
       
          cConString1 := "MySQL=" + lower(ALLTRIM(cConnName)) + ";" + ;
                           "UID="   + lower(ALLTRIM(cConnUsrs)) + ";" + ;
                                "pwd="   + lower(ALLTRIM(cConnPass)) + ";" + ; 
                                "dtb=mysql"                                + ;
                                ";PRT="  + alltrim(cCPorta)
             
           nConx := SR_AddConnection( CONNECT_MYSQL, cConString1 )
           
           IF nConx < 0
           
               MsgInfo("Erro de Conexão. Veja o Arquivo Sqlerror.log para mais Detalhes.", "Atenção, Erro")
               RETURN (.F.)
               
           ELSE
           
               oSql := SR_GetConnection() 
               
               MsgRun("Criando o Database...","Aguarde...",{|| oSql:exec("CREATE DATABASE "+alltrim(LOWER(cConnBase))) })
               
                MsgWait( "Novo DataBase Criado "+alltrim(LOWER(cConnBase)), "OK",2 )
                
                SR_EndConnection( nConx )  
                
               cConString1 := "MySQL=" + lower(ALLTRIM(cConnName)) + ";" + ;
                               "UID="   + lower(ALLTRIM(cConnUsrs)) + ";" + ;
                                    "pwd="   + lower(ALLTRIM(cConnPass)) + ";" + ;
                                    "dtb="   + alltrim(LOWER(cConnBase))       + ;
                                    ";PRT="  + alltrim(cCPorta)
               
               nConx := SR_AddConnection( CONNECT_MYSQL, cConString1 )
               
            ENDIF                    
          
       ENDIF    
        
                  
    RETURN NIL
     

×
×
  • Create New...