Objetivo
Possibilitar acesso aos modelos de dados do Protheus através de API RESTFul.
Pré-requisitos
Requisitos Mínimos
Para utilizar certifique-se que:
* Para atualização do ambiente, consulte nossa Central de Download no endereço: http://www.totvs.com.br/suporte
Como utilizar
Os modelos de dados devem ser publicados para serem acessíveis através da API, para isso deve-se utilizar o seguinte comando:
Informações |
---|
PUBLISH MODEL REST NAME <nome> source <fonte> RESOURCE OBJECT <objeto> |
Obs: Cada modelo deverá ser publicado utilizando esse comando. Não é necessário que es estar no mesmo fonte do modelo de dados.
NAME = Nome da API que representará o modelo de dados.
SOURCE = Fonte aonde está o modelo de dados (função modeldef), caso esse comando não for informado, será acatado o fonte atual. (Não é obrigatório)
RESOURCE OBJECT = Classe que deverá herdar da FwRestModel. (Não é obrigatório)
Com este comando os modelos de dados serão acessíveis através do seguinte endereço: <protocol>://<server>:<port>/fwmodel/<name of published model>/<PK>
Exemplo: http://localhost:8084/fwmodel/products
Parametros
<Name of published model> = Nome o modelo informado no comando
<PK> = Valor da chave primaria do alias do modelo em encodado em base64 (Opcional)
Classe FWRestModel (link: FWRestModelObject.prx)
Bloco de código | |
---|---|
|
|
Utilização
Esta API segue o padrão de REST.
Por exemplo:
Para retornar a lista de registros referente ao modelo de dados deve-se efetuar um GET sem informar a <PK>.
Para inserir um registro deve-se efetuar um POST sem informar a <PK> e enviar no body o conteúdo a ser inserido.
Ao informar o parâmetro <PK> será acessado um registro em específico e assim podendo ser utilizado os métodos GET, PUT, DELETE.
QueryStrings
COUNT = Quantidade de registro que devem ser retornados
STARTINDEX = Indica a partir que qual index deverá ser retornado
FILTER = Filtro que será aplicado no método SetFilter()
FIELDDETAIL = Habilita mostrar mais informações nos campos do modelo
FIELDVIRTUAL = Habilita o retorno de campos virtuais
Exemplo de utilização
Ao publicar um modelo de dados, se o mesmo utilizar alias, basta publicá-lo.
Caso o modelo tenha sido desenvolvido utilizando array ou carga manual, deve-se criar uma classe e herda-la da FwRestModel e sobrescrever os métodos necessários para atender a sua necessidade.
Exemplo de modelo de dados com customização da classe REST:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
#INCLUDE "TOTVS.CH"
#INCLUDE "FWMVCDEF.CH"
PUBLISH MODEL REST NAME Branch RESOURCE OBJECT oRestBranch
Class oRestBranch From FwRestModel
Data lSm0Closed
Method Activate()
Method DeActivate()
Method Total()
Method SetAlias()
EndClass
Method Activate() Class oRestBranch
self:lSm0Closed := .F.
If Select("SM0") == 0
self:lSm0Closed := .T.
OpenSm0(, .F.)
EndIf
Return _Super:Activate()
Method DeActivate() Class oRestBranch
If self:lSm0Closed
SM0->(dbCloseArea())
EndIf
Return _Super:DeActivate()
Method Total() Class oRestBranch
Local nRecno := SM0->(Recno())
Local nTotal := 0
If self:Seek()
While !SM0->(Eof())
nTotal++
self:Skip()
End
EndIf
SM0->(dbGoTo(nRecno))
Return nTotal
Method SetAlias() Class oRestBranch
self:cAlias := "SM0"
Return .T.
// MODELO DE DADOS
Static Function Modeldef()
Local oStruSM0 := DefStrModel()
oModel := FWFormModel():New( 'MYFILIAL', {|| }, {|| }, {|| }, {|| } )
oModel:AddFields( 'SM0MASTER', , oStruSM0, {|| }, {|| },{|oM| MyLoad() })
oModel:SetDescription( "Empresas Protheus" )
oModel:GetModel( 'SM0MASTER' ):SetDescription( "Empresas Protheus" )
oModel:SetPrimaryKey( {"M0_CODIGO", "M0_CODFIL"} )
Return oModel
Static Function DefStrModel()
Local oStruct := FWFormModelStruct():New()
Local bValid := { || .T.}
Local bWhen := { || }
Local bRelac := { || }
// TABELA
oStruct:AddTable( "SM0", {}, "Filiais", {|| })
// INDICES
oStruct:AddIndex(1, "1", "M0_CODIGO", "Cód Empresa", "", "", .T.)
// CAMPOS
oStruct:AddField( "Cód Empresa" , "Cód Empresa" , "M0_CODIGO" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Cód Filial" , "Cód Filial" , "M0_CODFIL" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Nome Empresa" , "Nome Empresa" , "M0_NOMECOM", "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "CNPJ" , "CNPJ" , "M0_CGC" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "UF" , "UF" , "M0_ESTENT" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Insc Estadual" , "Insc Estadual" , "M0_INSC" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Insc Municipal", "Insc Municipal" , "M0_INSCM" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Cód Munic" , "Cód Munic" , "M0_CODMUN" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Nome Filial" , "Nome Filial" , "M0_FILIAL" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Município" , "Município" , "M0_CIDENT" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Inscrição" , "Inscrição" , "M0_INSCANT", "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "NIRE" , "NIRE" , "M0_NIRE" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Data do Nire" , "Data do Nire" , "M0_DTRE" , "D", 08, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "End Cob" , "End Cob" , "M0_ENDCOB" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
Return oStruct
Static Function MyLoad()
Local aRet := {}
aRet := {{SM0->M0_CODIGO, SM0->M0_CODFIL, SM0->M0_NOMECOM, SM0->M0_CGC, SM0->M0_ESTENT, SM0->M0_INSC, SM0->M0_INSCM, SM0->M0_CODMUN,;
SM0->M0_FILIAL, SM0->M0_CIDENT, SM0->M0_INSCANT, SM0->M0_NIRE, SM0->M0_DTRE, SM0->M0_ENDCOB}, ;
SM0->(Recno())}
Return aRet |
Fonte da FwRestModel (link: FWRestModelObject.prx)
| ||||||||
#INCLUDE "TOTVS.CH"
#INCLUDE "FWMVCDEF.CH"
#INCLUDE "FILTEREX.CH"
// Função Dummy
Function __FwRestModel__()
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} FwRestModel
Classe base para controlar o acesso aos registros relacionados ao
modelo de dados.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Class FwRestModel
Data cName
Data cAlias
Data cQryAlias
Data aFields
Data oModel
Data lXml
Data lActivate
Data cFilter
Data cOldFilter
Data nStatus
Data cStatus
Data aQueryString
Data lDebug
Method Activate()
Method DeActivate()
Method OnError()
Method SetModel()
Method ClearModel()
Method SetName()
Method GetName()
Method SetAsXml()
Method SetAsJson()
Method StartGetFormat()
Method EscapeGetFormat()
Method EndGetFormat()
Method SetAlias()
Method GetAlias()
Method HasAlias()
Method Seek()
Method Skip()
Method Total()
Method GetData()
Method SaveData()
Method DelData()
Method SetFilter()
Method GetFilter()
Method ClearFilter()
Method DecodePK()
Method ConvertPK()
Method GetStatusResponse()
Method SetStatusResponse()
Method SetQueryString()
Method GetQueryString()
Method GetQSValue()
Method GetHttpHeader()
Method SetFields()
Method debuger()
EndClass
//-------------------------------------------------------------------
/*/{Protheus.doc} Activate
Método de ativação da classe.
@return lActivate Indica que a classe foi ativada.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method Activate() Class FwRestModel
Default self:lDebug := .F.
self:lXml := .T.
Return self:lActivate := .T.
//-------------------------------------------------------------------
/*/{Protheus.doc} DeActivate
Método de desativação da classe.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method DeActivate() Class FwRestModel
FwFreeObj(self:aQueryString)
FwFreeObj(self:aFields)
self:lActivate := .F.
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} OnError
Método que será executado quando algum erro ocorrer no rest.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method OnError() Class FwRestModel
self:DeActivate()
self:ClearModel()
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} SetModel
Método para setar o modelo de dados que será utilizado.
E força a configuração do alias a ser utilizado.
@param oModel Objeto do modelo de dados
@return oModel Objeto do modelo de dados setado.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method SetModel(oModel) Class FwRestModel
self:oModel := oModel
self:SetAlias()
Return oModel
//-------------------------------------------------------------------
/*/{Protheus.doc} ClearModel
Método para efetuar o desroy do modelo de dados.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method ClearModel() Class FwRestModel
If self:oModel != Nil
self:oModel:Destroy()
self:oModel := Nil
EndIf
self:ClearFilter()
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} SetName
Método para setar o nome do rest do modelo de dados.
@return cName Nome do rest do modelo de dados.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method SetName(cName) Class FwRestModel
Return self:cName := cName
//-------------------------------------------------------------------
/*/{Protheus.doc} GetName
Método para retornar o nome do rest do modelo de dados.
@return cName Nome do rest do modelo de dados.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method GetName() Class FwRestModel
Return self:cName
//-------------------------------------------------------------------
/*/{Protheus.doc} SetAsXml
Método para setar o retorno do rest como XML.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method SetAsXml() Class FwRestModel
self:lXml := .T.
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} SetAsJson
Método para setar o retorno do rest como JSON.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method SetAsJson() Class FwRestModel
self:lXml := .F.
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} StartGetFormat
Método retornar o conteúdo inicial do dado de retorno.
@param nTotal Quantidade total de registros do alias que podem ser retornados.
@param nCount Quantidade de registros a serem retornados.
@param nStartIndex Index inicial do registro que será retornado.
@return cRet Conteúdo inicial
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method StartGetFormat(nTotal, nCount, nStartIndex) Class FwRestModel
Local cRet := ""
If self:lXml
cRet += '<?xml version="1.0" encoding="UTF-8"?>'
cRet += '<result>'
cRet += i18n('<total>#1</total><count>#2</count><startindex>#3</startindex>', {nTotal, nCount, nStartIndex})
cRet += '<resources>'
Else
cRet += i18n('{"total":#1,"count":#2,"startindex":#3,"resources":[', {nTotal, nCount, nStartIndex})
EndIf
Return cRet
//-------------------------------------------------------------------
/*/{Protheus.doc} EscapeGetFormat
Método retornar o caracter a ser inserido entre os registros a serem
retornados.
@return cRet Caracter de escape.
@author Felipe Bonvicini Conti
@since 25/06/2015
@version P11, P12
/*/ | ||||||||
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#INCLUDE "TOTVS.CH" #INCLUDE "FWMVCDEF.CH" // Função Dummy Function __FwRestModel__() Return //------------------------------------------------------------------- /*/{Protheus.doc}Method EscapeGetFormat() Class FwRestModel ClasseLocal basecRet para controlar o acesso aos registros relacionados ao modelo de dados. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/:= "" If !self:lXml cRet := "," EndIf Return cRet //------------------------------------------------------------------- Class FwRestModel Data cName Data cAlias Data oModel Data lXml Data lActivate Data cFilter Data cOldFilter Method Activate() Method DeActivate() Method OnError() Method SetModel() Method ClearModel() Method SetName() Method GetName() Method SetAsXml() Method SetAsJson() Method StartGetFormat() Method EscapeGetFormat() Method EndGetFormat() Method SetAlias() Method HasAlias() Method Seek() Method Skip() Method Total() Method GetData() Method SaveData() Method DelData() Method SetFilter() Method GetFilter() Method ClearFilter() Method DecodePK() Method ConvertPK() EndClass /*/{Protheus.doc} EndGetFormat Método retornar o conteúdo final do dado de retorno. @return cRet Conteúdo final @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method EndGetFormat() Class FwRestModel Local cRet := "" If self:lXml cRet := "</resources>" cRet += "</result>" Else cRet := "]}" EndIf Return cRet //------------------------------------------------------------------- /*/{Protheus.doc} ActivateSetAlias Método de ativação da classe. @return lActivate Indica que a classe foi ativada. responsável por setar o alias a ser utilizado. Se o mesmo não for informado, será utilizado o alias do field principal do modelo de dados. @return lRet Indica se o alias foi preenchido @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method ActivateSetAlias(cAlias) Class FwRestModel self:lXmlIf Empty(cAlias) If !Empty(self:oModel) self:cAlias := .T. Return self:lActivateMPGetModelAlias(self:oModel) EndIf Else self:cAlias := .T. cAlias EndIf Return !Empty(self:cAlias) //------------------------------------------------------------------- /*/{Protheus.doc} DeActivateGetAlias Método responsável depor desativaçãoretornar dao classe.alias. @return cAlias Alias @author Felipe Bonvicini Conti @since 2505/0604/20152016 @version P11, P12 /*/ //------------------------------------------------------------------- Method DeActivateGetAlias() Class FwRestModel Return self:ClearModel() self:ClearFilter() self:lActivate := .F. Return //cAlias //--------------------------------------------------------------------------- /*/{Protheus.doc} OnErrorHasAlias Método que será executado quando algum erro ocorrer no rest.responsável informar se o alias foi setado, se não força efetuar o setAlias(). @return lRet Indica se o alias foi preenchido @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method OnErrorHasAlias() Class FwRestModel Local lRet := .T. If Empty(self:cAlias) self:DeActivateSetAlias() Return / lRet := !Empty(self:cAlias) EndIf Return lRet //------------------------------------------------------------------- /*/{Protheus.doc} SetModelSeek Método pararesponsável setarbuscar oum modeloregistro deem dadosespecífico queno seráalias utilizadoselecionado. E força a configuração do alias a ser utilizado. @param oModel Objeto do modelo de dados @return oModel Objeto do modelo de dados setadoSe o parametro cPK não for informaodo, indica que deve-se ser posicionado no primeiro registro da tabela. @param cPK PK do registro. @return lRet Indica se foi encontrado algum registro. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SetModelSeek(oModelcPK) Class FwRestModel self:oModelLocal lRet := oModel .F. Local cQry Local cPkFilter If self:SetAlias() Return oModel //------------------------------------------------------------------- /*/{Protheus.doc} ClearModel Método para efetuar o desroy do modelo de dados. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method ClearModel() Class FwRestModel If self:oModel != Nil self:oModel:Destroy() self:oModel := Nil EndIf Return HasAlias() If !Empty(cPK) cPkFilter := FWAToS(self:oModel:GetPrimaryKey(),"||") + " = '" + cPk + "'" If (self:cAlias)->(FieldPos(PrefixoCpo(self:cAlias)+"_FILIAL")) > 0 cPkFilter := PrefixoCpo(self:cAlias)+"_FILIAL||" + cPkFilter EndIf self:SetFilter(cPkFilter) Endif cQry := createQueryAlias(@self:cQryAlias, self:cAlias, self:cFilter) If self:lDebug .And. self:GetQSValue("showQuery") == "true" i18nConOut("[FWRESTMODELOBJECT] Query: #1#2", {CRLF, cQry}) EndIf If !(self:cQryAlias)->(Eof()) (self:cAlias)->(dbGoTo((self:cQryAlias)->R_E_C_N_O_)) lRet := !(self:cAlias)->(Eof()) EndIf Endif Return lRet //------------------------------------------------------------------- /*/{Protheus.doc} SetNameSkip Método responsável passar para setar o nomeproximo doregistro rest do modelo de dadosalias. @return cNamelRet NomeIndica se doo restalias donão modelochegou deao dadosfim. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SetNameSkip(cNamenSkip) Class FwRestModel ReturnLocal self:cNamelRet := cName //------.F. If self:HasAlias() If !(self:cQryAlias)->(Eof()) (self:cQryAlias)->(DbSkip(nSkip)) (self:cAlias)->(dbGoTo((self:cQryAlias)->R_E_C_N_O_)) lRet := !(self:cAlias)->(Eof()) EndIf EndIf Return lRet //------------------------------------------------------------------- /*/{Protheus.doc} GetNameTotal Método pararesponsável retornar o nome a quantidade total de regitros do rest do modeloalias. Contagem é feita atravez de dadosquery. @return cNamenTotal NomeQuantidade do rest do modelo total de dadosregistros. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method GetNameTotal() Class FwRestModel Return self:cName /Local nTotal := 0 Local cQueryPart := "" If self:HasAlias() cQueryPart += GetFromQryAlias(self:cAlias) cQueryPart += GetWhereQryAlias(self:cAlias, self:cFilter) nTotal := FWTblCount(self:cQryAlias, cQueryPart, .F.) EndIf Return nTotal //------------------------------------------------------------------- /*/{Protheus.doc} SetAsXmlGetData Método responsável parapor setarretornar o retornoregistro do restmodelo no comoformato XML. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SetAsXml() Class FwRestModel self:lXml := .T. Return //------------------------------------------------------------------- /*/{Protheus.doc} SetAsJson Método para setar o retorno do rest como JSON. @author Felipe ou JSON. @param lFieldDetail Indica se retorna o registro com informações detalhadas @param lFieldVirtual Indica se retorna o registro com campos virtuais @param lFieldEmpty Indica se retorna o registro com campos nao obrigatorios vazios @param lFirstLevel Indica se deve retornar todos os modelos filhos ou nao @param lInternalID Indica se deve retornar o ID como informação complementar das linhas do GRID @return cRet Retorna o registro nos formatos XML ou JSON @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SetAsJson(GetData(lFieldDetail, lFieldVirtual, lFieldEmpty, lFirstLevel, lInternalID) Class FwRestModel Local cRet self:lXml := .F. Return //------------------------------------------------------------------- /*/{Protheus.doc} StartGetFormat Método retornar o conteúdo inicial do dado de retorno. @param nTotal Quantidade total de registros do alias que podem ser retornados. @param nCount Quantidade de registros a serem retornados. @param nStartIndex Index inicial do registro que será retornado. @return cRet Conteúdo inicial @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ oModel:SetOperation(MODEL_OPERATION_VIEW) Self:oModel:Activate() If self:lXml cRet := Self:oModel:GetXmlData(lFieldDetail,,,lFieldVirtual,,lFieldEmpty,.F./*lDefinition*/,,.T./*lPK*/,.T./*lPKEncoded*/,self:aFields,lFirstLevel,lInternalID) Else cRet := Self:oModel:GetJsonData(lFieldDetail,,lFieldVirtual,,lFieldEmpty,.T./*lPK*/,.T./*lPKEncoded*/,self:aFields,lFirstLevel,lInternalID) EndIf Self:oModel:DeActivate() Return cRet //------------------------------------------------------------------- Method StartGetFormat(nTotal, nCount, nStartIndex) Class FwRestModel Local cRet := "" If self:lXml cRet += '<?xml version="1.0" encoding="UTF-8"?>' cRet += '<result>' cRet += i18n('<total>#1</total><count>#2</count><startindex>#3</startindex>', {nTotal, nCount, nStartIndex}) cRet += '<resources>' Else cRet += i18n('{"total":#1,"count":#2,"startindex":#3,"resources":[', {nTotal, nCount, nStartIndex}) EndIf Return cRet /*/{Protheus.doc} SaveData Método responsável por salvar o registro recebido pelo metodo PUT ou POST. Se o parametro cPK não for informado, significa que é um POST. @param cPK PK do registro. @param cData Conteúdo a ser salvo @param @cError Retorna o alguma mensagem de erro @return lRet Indica se o registro foi salvo @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- /*/{Protheus.doc} EscapeGetFormat Método retornar o caracter a ser inserido entre os registros a serem retornados. @return cRet Caracter de escape. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method EscapeGetFormat() Class FwRestModel Local cRet := "" If !self:lXml cRet := "," EndIf Return cRet //------------------------------------------------------------------- /*/{Protheus.doc} EndGetFormat Método retornar o conteúdo final do dado de retorno. @return cRet Conteúdo final @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ Method SaveData(cPK, cData, cError) Class FwRestModel local lRet := .T. Default cData := "" If Empty(cPk) self:oModel:SetOperation(MODEL_OPERATION_INSERT) Else self:oModel:SetOperation(MODEL_OPERATION_UPDATE) lRet := self:Seek(cPK) EndIf If lRet self:oModel:Activate() If self:lXml lRet := self:oModel:LoadXMLData(cData) Else lRet := self:oModel:LoadJsonData(cData) EndIf If lRet If self:oModel:lModify // Verifico se o modelo sofreu alguma alteração If !(self:oModel:VldData() .And. self:oModel:CommitData()) lRet := .F. cError := ErrorMessage(self:oModel:GetErrorMessage()) EndIf Else lRet := .F. self:SetStatusResponse(304, "Not Modified") EndIf Else cError := ErrorMessage(self:oModel:GetErrorMessage()) EndIf Self:oModel:DeActivate() Else cError := i18n("Invalid record '#1' on table #2", {cPK, self:cAlias}) EndIf Return lRet //------------------------------------------------------------------- Method EndGetFormat() Class FwRestModel Local cRet := "" If self:lXml cRet := "</resources>" cRet += "</result>" Else cRet := "]}" EndIf Return cRet /*/{Protheus.doc} DelData Método responsável por remover um registro. @param cPK PK do registro. @param @cError Retorna o alguma mensagem de erro @return lRet Indica se o registro foi removido @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- /*/{Protheus.doc} SetAlias Método responsável por setar o alias a ser utilizado. Se o mesmo não for informado, será utilizado o alias do field principal do modelo de dados. @return lRet Indica se o alias foi preenchido @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/Method DelData(cPK, cError) Class FwRestModel local lRet := .F. If !Empty(cPK) If self:Seek(cPK) self:oModel:SetOperation(MODEL_OPERATION_DELETE) self:oModel:Activate() lRet := self:oModel:VldData() .And. self:oModel:CommitData() If !lRet cError := ErrorMessage(self:oModel:GetErrorMessage()) EndIf Self:oModel:DeActivate() Else cError := i18n("Invalid record '#1' on table #2", {cPK, self:cAlias}) EndIf EndIf Return lRet //------------------------------------------------------------------- Method SetAlias(cAlias) Class FwRestModel If Empty(cAlias) If !Empty(self:oModel) self:cAlias := MPGetModelAlias(self:oModel) dbSelectArea(self:cAlias) EndIf Else self:cAlias := cAlias EndIf Return !Empty(self:cAlias) /*/{Protheus.doc} SetFilter Método responsável por setar algum filtro que tenha sido informado por Query String no REST. @param cFilter Valor do filtro a ser aplicado no alias @return lRet Indica se o filtro foi aplicado corretamente @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- /*/{Protheus.doc} HasAlias Método responsável informar se o alias foi setado, se não força efetuar o setAlias(). @return lRet Indica se o alias foi preenchidoMethod SetFilter(cFilter) Class FwRestModel self:cFilter := Alltrim(cFilter) Return .T. //------------------------------------------------------------------- /*/{Protheus.doc} GetFilter Método para retornar o conteúdo do filtro. @return cFilter Conteúdo do filtro @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method HasAliasGetFilter() Class FwRestModel LocalReturn lRet := .T. If Empty(self:cAlias) self:SetAlias() lRet := !Empty(self:cAlias) EndIf Return lRet /self:cFilter //------------------------------------------------------------------- /*/{Protheus.doc} SeekGetFilter Método responsável buscarpro umlimpar registroo em específico no alias selecionadofiltro setado. Se@author oFelipe parametroBonvicini cPK não for informaodo, indica que deve-se ser posicionado no primeiro registro da tabela. @param cPK PK do registro. @return lRet Indica se foi encontrado algum registro. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SeekClearFilter(cPK) Class FwRestModel Local lRet self:cFilter := "" Return .F. Local nOrder If self:HasAlias() If Empty(cPK) (self:cAlias)->(DbGotop()) lRet := !(self:cAlias)->(Eof()) Else nOrder := MPGetBestOrder(self:cAlias, self:oModel:GetPrimaryKey(), 1) (self:cAlias)->(dbSetOrder(nOrder)) lRet := (self:cAlias)->(DbSeek(cPK)) Endif Endif Return lRet //---T. //----------------------------------------------------------------------- /*/{Protheus.doc} SkipDecodePK Método responsávelpara passarindicar parase odeve proximoser registrofeito do alias. @return lRet Indica se o alias não chegou ao fim.o decode do paramtro cPK recebido no REST @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SkipDecodePK() Class FwRestModel Local lRet :=Return .F. If self:HasAlias() (self:cAlias)->(DbSkip()) lRet := !(self:cAlias)->(Eof()) EndIf Return lRet T. //------------------------------------------------------------------- /*/{Protheus.doc} TotalConvertPK Método responsável por retornarconverter a quantidade total de regitros do alias. Contagem é feita atravez de query. @return nTotal Quantidade total de registros. PK. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method TotalConvertPK(cPK) Class FwRestModel Local nTotal := 0 If self:HasAliasDecodePK() nTotalcPK := FWTblCount(self:cAlias,,.T.Decode64(cPK) EndIf Return nTotal cPK //------------------------------------------------------------------- /*/{Protheus.doc} GetDataGetStatusResponse Método responsável por retornar o registrocodigo e descrição do modelostatus node formatoretorno, XML ouquando JSONnecessario. @param lFieldDetail Indica se retorna o registro com informações detalhadas @param lFieldVirtual Indica se retorna o registro com campos virtuais @return cRet Retorna o registro nos formatos XML ou JSON @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 @author Felipe Bonvicini Conti @since 07/07/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method GetDataGetStatusResponse(lFieldDetail, lFieldVirtual) Class FwRestModel Local cRet self:oModel:SetOperation(MODEL_OPERATION_VIEW) Self:oModel:Activate() If self:lXml cRet := Self:oModel:GetXmlData(lFieldDetail,,,lFieldVirtual,,,.F./*lDefinition*/,,.T./*lPK*/,.T./*lPKEncoded*/) Else cRet := Self:oModel:GetJsonData(lFieldDetail,,lFieldVirtual,,,.T./*lPK*/,.T./*lPKEncoded*/) EndIf Self:oModel:DeActivate() Return cRet //------------------------------------------------------------------- /*/{Protheus.doc} SaveData Método responsável por salvar o registro recebido pelo metodo PUT ou POST. Se o parametro cPK não for informado, significa que é um POST. @param cPK PK do registro. @param cData Conteúdo a ser salvo @param @cError Retorna o alguma mensagem de erro @return lRet Indica se o registro foi salvo @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SaveData(cPK, cData, cError) Class FwRestModel local lRet := .T. Default cData := "" If Empty(cPk) self:oModel:SetOperation(MODEL_OPERATION_INSERT) Else self:oModel:SetOperation(MODEL_OPERATION_UPDATE) lRet := self:Seek(cPK) EndIf If lRet self:oModel:Activate() If self:lXml lRet := self:oModel:LoadXMLData(cData) Else lRet := self:oModel:LoadJsonData(cData) EndIf If lRet lRet := (self:oModel:VldData() .And. self:oModel:CommitData()) EndIf If !lRet cError := ErrorMessage(self:oModel:GetErrorMessage()) EndIf Self:oModel:DeActivate() Else cError := i18n("Invalid record '#1' on table #2", {cPK, self:cAlias}) EndIf Return lRet //------------------------------------------------------------------- /*/{Protheus.doc} DelData Método responsável por remover um registro. @param cPK PK do registro. @param @cError Retorna o alguma mensagem de erro @return lRet Indica se o registro foi removido @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method DelData(cPK, cError) Class FwRestModel local lRet := .F. If !Empty(cPK) If self:Seek(cPK) self:oModel:SetOperation(MODEL_OPERATION_DELETE) self:oModel:Activate() lRet := self:oModel:VldData() .And. self:oModel:CommitData() If !lRet cError := ErrorMessage(self:oModel:GetErrorMessage()) EndIf Self:oModel:DeActivate() Else cError := i18n("Invalid record '#1' on table #2", {cPK, self:cAlias}) EndIf EndIf Return lRet //------------------------------------------------------------------- /*/{Protheus.doc} SetFilter Método responsável por setar algum filtro que tenha sido informado por Query String no REST. @param cFilter Valor do filtro a ser aplicado no alias @return lRet Indica se o filtro foi aplicado corretamente @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method SetFilter(cFilter) Class FwRestModel Local lRet := .F. If !Empty(cFilter) self:cFilter := Alltrim(cFilter) If self:HasAlias() self:cOldFilter := (self:cAlias)->(dbFilter()) If !Empty(self:cOldFilter) (self:cAlias)->(dbClearFilter()) EndIf (self:cAlias)->(dbSetFilter(&('{|| '+self:cFilter+'}'), self:cFilter)) lRet := .T. EndIf EndIf Return lRet //------------------------------------------------------------------- /*/{Protheus.doc} GetFilter Método para retornar o conteúdo do filtro. @return cFilter Conteúdo do filtro @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method GetFilter() Class FwRestModel Return self:cFilter //------------------------------------------------------------------- /*/{Protheus.doc} GetFilter Método responsável pro limpar o filtro setado. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method ClearFilter() Class FwRestModel (self:cAlias)->(dbClearFilter()) If !Empty(self:cOldFilter) (self:cAlias)->(dbSetFilter(&('{|| '+AllTrim(self:cOldFilter)+'}'), self:cOldFilter)) self:cOldFilter := Nil EndIf Return //------------------------------------------------------------------- /*/{Protheus.doc} DecodePK Método para indicar se deve ser feito o decode do paramtro cPK recebido no REST @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method DecodePK() Class FwRestModel Return .T. //------------------------------------------------------------------- /*/{Protheus.doc} ConvertPK Método responsável por converter a PK. @author Felipe Bonvicini Conti @since 25/06/2015 @version P11, P12 /*/ //------------------------------------------------------------------- Method ConvertPK(cPK) Class FwRestModel If self:DecodePK() cPK := Decode64(cPK) EndIf Return cPK // ********************* Funcions ********************* Static Function ErrorMessage(aErroMsg) Local cRet := CRLF + " --- Error on Model ---" + CRLF cRet += "Id submodel origin: [" + aErroMsg[1] + "]" + CRLF cRet += "Id field origin: [" + aErroMsg[2] + "]" + CRLF cRet += "Id submodel error: [" + aErroMsg[3] + "]" + CRLF cRet += "Id field error: [" + aErroMsg[4] + "]" + CRLF cRet += "Id error: [" + aErroMsg[5] + "]" + CRLF cRet += "Error menssage: [" + aErroMsg[6] + "]" + CRLF cRet += "Solution menssage: [" + aErroMsg[7] + "]" + CRLF cRet += "Assigned value: [" + cValToChar( aErroMsg[8] ) + "]" + CRLF cRet += "Previous value: [" + cValToChar( aErroMsg[9] ) + "]" + CRLF aErroMsg := aSize(aErroMsg, 0) Return cRet |
Ret
If !(self:nStatus == Nil)
Ret := {self:nStatus, self:cStatus}
EndIf
Return Ret
//-------------------------------------------------------------------
/*/{Protheus.doc} SetStatusResponse
Método responsável por setar o codigo e descrição do status de retorno,
quando necessario.
@author Felipe Bonvicini Conti
@since 07/07/2015
@version P11, P12
/*/
//-------------------------------------------------------------------
Method SetStatusResponse(nStatus, cStatus) Class FwRestModel
self:nStatus := nStatus
self:cStatus := cStatus
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} SetQueryString
Método responsável por setar as query strings recebidas na requisicao.
@author Felipe Bonvicini Conti
@since 29/03/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Method SetQueryString(aQueryString) Class FwRestModel
Default aQueryString := {}
Return self:aQueryString := aQueryString
//-------------------------------------------------------------------
/*/{Protheus.doc} GetQueryString
Método responsável por retornar aa query strings recebidas na requisicao.
@author Felipe Bonvicini Conti
@since 29/03/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Method GetQueryString() Class FwRestModel
Return self:aQueryString
//-------------------------------------------------------------------
/*/{Protheus.doc} GetQSValue
Método responsável por buscar uma query string e retornar seu valor.
@author Felipe Bonvicini Conti
@since 29/03/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Method GetQSValue(cKey) Class FwRestModel
Local cValue := ""
Local nPos
cKey := UPPER(cKey)
nPos := aScan(self:aQueryString, {|x| x[1] == cKey})
If nPos > 0
cValue := self:aQueryString[nPos][2]
EndIf
Return cValue
//-------------------------------------------------------------------
/*/{Protheus.doc} GetHttpHeader
Função de retorno do conteudo do cabeçalho HTTP.
@param cParam Parametro HTTP para busca
@return cReturn Valor do parametro HTTP solicitado. Se retornado NULL, o parametro não foi encontrado.
@author Felipe Bonvicini Conti
@since 30/03/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Method GetHttpHeader(cParam) Class FwRestModel
Return HTTPHeader(cParam)
//-------------------------------------------------------------------
/*/{Protheus.doc} SetFields
Método responsável por setar os campso que serao retornados no modelo
@param aFields Array com os campos a serem filtrados
@return lRet Retorna verdadeiro se os campos forem salvos corretamente
@author Felipe Bonvicini Conti
@since 29/03/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Method SetFields(aFields) Class FwRestModel
Default aFields := ""
self:aFields := StrTokArr(aFields, ",")
Return Len(self:aFields) > 0
//-------------------------------------------------------------------
/*/{Protheus.doc} SetFields
Método responsável por setar os campso que serao retornados no modelo
@param lDebug Parametro para informara se o debug sera habilitado
@return lRet Indica se o begub foi abilitado
@author Felipe Bonvicini Conti
@since 29/03/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Method debuger(lDebug) Class FwRestModel
Default lDebug := .F.
Return self:lDebug := lDebug
// ********************* Functions *********************
//-------------------------------------------------------------------
/*/{Protheus.doc} ErrorMessage
Funcao responsavel por retonar o erro do modelo.
@param aErroMsg Array de erro do modelo de dados
@return cRet Formato texto do array de erro do modelo de dados
@author Felipe Bonvicini Conti
@since 05/04/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Static Function ErrorMessage(aErroMsg)
Local cRet := CRLF + " --- Error on Model ---" + CRLF
cRet += "Id submodel origin: [" + aErroMsg[1] + "]" + CRLF
cRet += "Id field origin: [" + aErroMsg[2] + "]" + CRLF
cRet += "Id submodel error: [" + aErroMsg[3] + "]" + CRLF
cRet += "Id field error: [" + aErroMsg[4] + "]" + CRLF
cRet += "Id error: [" + aErroMsg[5] + "]" + CRLF
cRet += "Error menssage: [" + aErroMsg[6] + "]" + CRLF
cRet += "Solution menssage: [" + aErroMsg[7] + "]" + CRLF
cRet += "Assigned value: [" + cValToChar( aErroMsg[8] ) + "]" + CRLF
cRet += "Previous value: [" + cValToChar( aErroMsg[9] ) + "]" + CRLF
aErroMsg := aSize(aErroMsg, 0)
Return cRet
//-------------------------------------------------------------------
/*/{Protheus.doc} GetFromQryAlias
Funcao responsavel por retornar a clausula from da query de dados
@param cTable Tablea principal
@return cFrom Clausula from da query
@author Felipe Bonvicini Conti
@since 05/04/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Static Function GetFromQryAlias(cTable)
Return " FROM " + RetSqlName( cTable )
//-------------------------------------------------------------------
/*/{Protheus.doc} GetWhereQryAlias
Funcao responsavel por retornar a clausula where da query de dados
@param cTable Tablea principal
@param cFilter Filtro da query
@return cWhere Clausula where da query
@author Felipe Bonvicini Conti
@since 05/04/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Static Function GetWhereQryAlias(cTable, cFilter)
Local cWhere
Local cUsrFilFilter
cWhere := " WHERE D_E_L_E_T_ = ' '"
//Introduz a segurança padrão de acesso as filiais do sistema
If (cTable)->(FieldPos(PrefixoCpo(cTable)+"_FILIAL")) > 0
cUsrFilFilter := FWSQLUsrFilial(cTable)
If !Empty(cUsrFilFilter)
cWhere += " AND " + cUsrFilFilter
EndIf
EndIf
If !Empty(cFilter)
cWhere += " AND " + cFilter
EndIf
Return cWhere
//-------------------------------------------------------------------
/*/{Protheus.doc} GetWhereQryAlias
Funcao responsavel por retornar a query do modelo
@param cQryAlias Alias da query
@param cTable Tablea principal
@param cFilter Filtro da query
@return cQuery Query
@author Felipe Bonvicini Conti
@since 05/04/2016
@version P11, P12
/*/
//-------------------------------------------------------------------
Static Function createQueryAlias(cQryAlias, cTable, cFilter)
Local oStatement
Local cQuery := ""
cQuery += "SELECT R_E_C_N_O_"
cQuery += GetFromQryAlias(cTable)
cQuery += GetWhereQryAlias(cTable, cFilter)
oStatement := FWPreparedStatement():New(cQuery)
cQuery := oStatement:getFixQuery()
cQuery := ChangeQuery(cQuery)
MPSysOpenQuery(cQuery, @cQryAlias)
oStatement:Destroy()
FwFreeObj(oStatement)
Return cQuery |
Utilização
Esta API segue o padrão de REST.
Por exemplo:
Para retornar a lista de registros referente ao modelo de dados deve-se efetuar um GET sem informar a <PK>. Os registros listados terão filtrados pelas filiais que o usuário tem acesso (isso se o campo filial existir.)
Para inserir um registro deve-se efetuar um POST sem informar a <PK> e enviar no body o conteúdo a ser inserido.
Ao informar o parâmetro <PK> será acessado um registro em específico e assim podendo ser utilizado os métodos GET, PUT, DELETE.
QueryStrings
COUNT = Quantidade de registro que devem ser retornados (padrão: 10)
STARTINDEX = Indica a partir que qual index deverá ser retornado (padrão: 1)
FILTER = Filtro que será aplicado no método SetFilter()
FIELDDETAIL = Habilita mostrar mais informações nos campos do modelo (padrão: 10)
FIELDVIRTUAL = Habilita o retorno de campos virtuais (padrão: false)
FIELDEMPTY = Habilita o retorno de campos sem valores (padrão: false)
FIRSTLEVEL = Habilita o retorno dos sub modelos (padrão: true)
FIELDS = Indica os campos a serem filtrados no retorno do modelo, incluindo os sub modelos, caso não informado todos os campos serão retornados
DEBUG = Valor booleano para habilitar o modo debug (padrão: false)
CACHE = Indica se sera feito cache do total de registros por alias, refere-se ao valor do total no retorno (padrão: true)
INTERNALID = Indica se deve retornar o ID(Recno) como informação complementar das linhas do GRID (padrão: false)
Exemplo de utilização
Ao publicar um modelo de dados, se o mesmo utilizar alias, basta publicá-lo.
Caso o modelo tenha sido desenvolvido utilizando array ou carga manual, deve-se criar uma classe e herda-la da FwRestModel e sobrescrever os métodos necessários para atender a sua necessidade.
Exemplo de modelo de dados com customização da classe REST:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
#include "totvs.ch"
#include "fwmvcdef.ch"
PUBLISH MODEL REST NAME Branch RESOURCE OBJECT oRestBranch
Class oRestBranch From FwRestModel
Data lSm0Closed
Method Activate()
Method DeActivate()
Method Total()
Method SetAlias()
Method Skip()
Method Seek()
EndClass
Method Activate() Class oRestBranch
local lRet as logical
If _Super:Activate()
//Por uma regra de negócio, essa API não pode ser acessada aos domingos
If Dow( Date() ) == 1
//Atribuir .F. a propriedade self:lActivate
self:lActivate := .F.
//Retornar .F. no método
lRet := .F.
//( Opcional ) setar a mensagem
SetRestFault(403, "Forbidden access in sundays.")
Else
self:lSm0Closed := .F.
If Select("SM0") == 0
self:lSm0Closed := .T.
OpenSm0(, .F.)
EndIf
EndIf
Else
lRet := .F.
EndIf
Return lRet
Method DeActivate() Class oRestBranch
Local lRet as logical
If ( lRet := _Super:DeActivate() )
If self:lSm0Closed
SM0->(dbCloseArea())
EndIf
EndIf
Return lRet
Method Total() Class oRestBranch
Local nRecno as numeric
Local nTotal as numeric
nRecno := SM0->(Recno())
nTotal := 0
If self:Seek()
While !SM0->(Eof())
nTotal++
self:Skip()
End
EndIf
SM0->(dbGoTo(nRecno))
Return nTotal
Method SetAlias() Class oRestBranch
self:cAlias := "SM0"
Return .T.
Method Skip(nSkip) Class oRestBranch
Local lRet as logical
lRet := .F.
SM0->(DbSkip(nSkip))
lRet := !SM0->(Eof())
Return lRet
Method Seek(cPk) Class oRestBranch
Local lRet as logical
lRet := .F.
If Empty(cPK)
SM0->(DbGotop())
lRet := !SM0->(Eof())
Else
cPK := SubStr(cPK, Len(xFilial("SM0")) + 1) // Removo o valor da filial que e inserido automaticamente pelo model no valor da PK.
SM0->(dbSetOrder(1))
lRet := SM0->(DbSeek(cPK))
Endif
Return lRet
// MODELO DE DADOS
Static Function Modeldef()
Local oStruSM0 as object
Local oModel as object
oStruSM0 := DefStrModel()
oModel := FWFormModel():New( 'MYFILIAL',
{|| }, {|| }
,
{|| }, {|| }
)
oModel:AddFields( 'SM0MASTER', , oStruSM0,
{|| }, {|| }
,
{|oM| MyLoad() }
)
oModel:SetDescription( "Empresas Protheus" )
oModel:GetModel( 'SM0MASTER' ):SetDescription( "Empresas Protheus" )
oModel:SetPrimaryKey(
{"M0_CODIGO", "M0_CODFIL"}
)
Return oModel
Static Function DefStrModel()
Local oStruct as object
Local bValid as codeblock
Local bWhen as codeblock
Local bRelac as codeblock
oStruct := FWFormModelStruct():New()
bValid :=
{ || .T.}
bWhen :=
{ || }
bRelac := { || }
// TABELA
oStruct:AddTable( "SM0", {}, "Filiais",
{|| }
)
// INDICES
oStruct:AddIndex(1, "1", "M0_CODIGO", "Cód Empresa", "", "", .T.)
// CAMPOS
oStruct:AddField( "Cód Empresa" , "Cód Empresa" , "M0_CODIGO" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Cód Filial" , "Cód Filial" , "M0_CODFIL" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Nome Empresa" , "Nome Empresa" , "M0_NOMECOM", "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "CNPJ" , "CNPJ" , "M0_CGC" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "UF" , "UF" , "M0_ESTENT" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Insc Estadual" , "Insc Estadual" , "M0_INSC" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Insc Municipal", "Insc Municipal" , "M0_INSCM" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Cód Munic" , "Cód Munic" , "M0_CODMUN" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Nome Filial" , "Nome Filial" , "M0_FILIAL" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Município" , "Município" , "M0_CIDENT" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Inscrição" , "Inscrição" , "M0_INSCANT", "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "NIRE" , "NIRE" , "M0_NIRE" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "Data do Nire" , "Data do Nire" , "M0_DTRE" , "D", 08, 0, bValid, bWhen, , , bRelac, .F., , , )
oStruct:AddField( "End Cob" , "End Cob" , "M0_ENDCOB" , "C", 50, 0, bValid, bWhen, , , bRelac, .F., , , )
Return oStruct
Static Function MyLoad()
Local aRet := {}
aRet := {{SM0->M0_CODIGO, SM0->M0_CODFIL, SM0->M0_NOMECOM, SM0->M0_CGC, SM0->M0_ESTENT, SM0->M0_INSC, SM0->M0_INSCM, SM0->M0_CODMUN,;
SM0->M0_FILIAL, SM0->M0_CIDENT, SM0->M0_INSCANT, SM0->M0_NIRE, SM0->M0_DTRE, SM0->M0_ENDCOB}, ;
SM0->(Recno())}
Return aRet |
Status do documento | Concluído |
---|---|
Data | 25/06/2015 |
Versão | 1.0 |
Versão anterior | 1.0 |
Autores |